[TIL] 24/01/11 [최종] [React/Next] 에디터 구현 - Tip-Tap 뽀시기 (EditorProvider)
오늘도 화이팅!
TipTap 뽀시기
prep) 설치
npm install @tiptap/react @tiptap/pm @tiptap/starter-kit
//나는 얀 쓰니까
yarn add @tiptap/react @tiptap/pm @tiptap/starter-kit
일단 어제까지의 작업 : 모든 것은 아래 예제 코드에서 시작... 일단 button 으로 구현된 메뉴들은 하나하나 아이콘으로 바꿔보았다.
h1 부터 p까지는 아이콘 아니고 그냥 버튼인데, 나중에 셀렉트 박스로 바꿀예정.
예제 : https://tiptap.dev/docs/editor/examples/default
아이콘은 React icons : https://react-icons.github.io/react-icons/icons/md/
1. EditorProvider
예제를 복붙했다가, provider로 쓰는 예제여서 그안에 child를 넣어주어야 하는것이 이상했는데,
에디터를 쓰고싶은 차일드들 겉에 provider로 감싸서 주입해주고,
child component 어느 곳에서든지 useCurrentEditor hook으로 불러와서 쓸 수 있는 거였다.
(리액트 쿼리나 리덕스 등등과 사용법과 다르지 않아서, provider는 항상 이런 느낌인거구나.. 이제 알았..)
* 결국 공식 문서 복붙이지만 다시 이해해서 써보는 중 : https://tiptap.dev/docs/editor/installation/react
// src/Tiptap.jsx
import { EditorProvider, FloatingMenu, BubbleMenu } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
// define your extension array
const extensions = [
StarterKit,
]
const content = '<p>Hello World!</p>'
const Tiptap = () => {
return (
<EditorProvider extensions={extensions} content={content}>
<FloatingMenu>This is the floating menu</FloatingMenu>
<BubbleMenu>This is the bubble menu</BubbleMenu>
</EditorProvider>
)
}
export default Tiptap
Important Note: You can always
1-1 Editor를 단순히 여기에서만 쓴다고하면 useEditor 로만 사용해도 된다.
// src/Tiptap.jsx
import { useEditor, EditorContent, FloatingMenu, BubbleMenu } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
// define your extension array
const extensions = [
StarterKit,
]
const content = '<p>Hello World!</p>'
const Tiptap = () => {
const editor = useEditor({
extensions,
content,
})
return (
<>
<EditorContent editor={editor} />
<FloatingMenu editor={editor}>This is the floating menu</FloatingMenu>
<BubbleMenu editor={editor}>This is the bubble menu</BubbleMenu>
</>
)
}
export default Tiptap
2. EditorProvider 사용 시 하위 component 에서 editor 사용하는 법
- 프리뷰하는 예제 인것 같다. 해봐야지..
import { useCurrentEditor } from '@tiptap/react'
const EditorJSONPreview = () => {
const { editor } = useCurrentEditor()
return (
<pre>
{JSON.stringify(editor.getJSON(), null, 2)}
</pre>
)
}
3. Editor 앞뒤에 툴바 추가하는 법
...은 약간 불편쓰
EditorContent 구성 요소는 EditorProvider구성 요소에 의해 렌더링되므로 이제 편집기 콘텐츠 전후에 렌더링할 위치를 직접 정의할 수 없습니다. 이를 위해 slotBefore & slotAfter 를 사용할 수 있습니다
<EditorProvider
extensions={extensions}
content={content}
slotBefore={<MyEditorToolbar />}
slotAfter={<MyEditorFooter />}
/>
4. style 방법
자체적으로 .tiptap class가 다 붙어 있으므로 일반적인 css 방식에서 .tiptap p 로 접근해서 스타일링해주면 되고,
class명을 넣어주는 방법도 있어서 tailwind로 사용할 때도 좋다.
Tailwind CSS를 사용할 때는 @tailwindcss/typography 플러그인이 필요한 것 같다...?
https://tiptap.dev/docs/editor/guide/styling#option-1-style-the-plain-html
이것도 어제 읽으니까 안읽히던데 이제 알겠다... 얼른 공식문서 같이 읽기 페이지 만들자 우리..
5. h1같은거 왜안됨 ? -> css없어서, 코드블럭은 어케쓰는 거임?
이것도 4번 설치하니까 다된다.
4. tailwindcss typography 설치하니까 다된다. 짱..
h1~h6, 코드블럭 같은 것들 스타일링을 글로벌 css 쪽에 넣어줘야 하는지 고민했는데 안해도 된당..
https://tailwindcss.com/docs/typography-plugin
pose-sm , pose-lg 이런게 뷰포트에따라 크기를 설정해주는 건데,
lg 는 화면이 크더라도, 글씨가 너무너무 커져서 sm으로 통일해 버리고,
대신 글쓰는 칸 폭도 작게 줄어들어서, max-w-none 으로 max width 설정을 없애버렸다.
에디터를 감싸는 div에서 지정해줘도 될것 같다.
const editor = useEditor({
extensions: extensions,
content: content,
editorProps: {
attributes: {
class:
"prose prose-sm max-w-none mx-auto focus:outline-none",
},
},
5. 문제는 위 editorProps 이하 설정을
useEditor 예제만 있어서..
Provider 쪽에 넣어주는 법을 잘 모르겠어서, (쉬워보이는데 이해를 잘못했나.. -_- 또 내일보면 알지두..)
삽질을 조금 줄이고자, 빨리.. useEditor 방식으로 바꿔봤다..ㅠ.ㅠ
Provider가 나중에 필요하면 그때 알아보는 걸로..
일단 구현이 시급하므로...
6. 글자색 변경은 팔레트도 하나하나 만들어줘야하는 걸로 보여서.. 일단은 패스하기루^.^
7. 내일은(...새벽에) 데이터 넣기를 해봅시다.
- 커스텀 끝판왕 에디터다 TIPTAP -
초반 참고 블로구 : https://ryuhojin.tistory.com/14
프로젝트 진행 상황
✓ 전체적으로 다들 와이어 프레임에 맞춰 css 작업 완성 (몇몇 페이지 빼고? 수정 페이지 같은.. )
✓ 로그인도 되었고 ~ 트리거 어렵던디 해치웠나!
회고
오늘은 회의 줄이고 각자 집중하는 시간이 길어서 좋았다.
질문 주고받고 튜터님 도움도 적절히 잘 받고 있는듯 하다.
내 진행 상황
오늘 한일
1. 버튼 중에 안되던거 h1태그 같은 글자 스타일링 부분 추가!
2. 와이어프레임에 맞춰 css 작업
3. 와이어프렘에 없는 버튼 부분과 기타 스타일링 고민되는 부분 디자이너님께 공유.
오늘 나머지 공부 (21시~ 달려!)
1. 글쓴 데이터를 DB에 저장 해보세.. onchange 있는데에 왜 안되는가.