-
Notifications
You must be signed in to change notification settings - Fork 5
Novel이란?
Novel은 Tiptab
에 노션의 command
, bubble
기능을 추가한 라이브러리이다.
Novel 패키지에는 스타일이 포함되어 있지 않다. Tiptap의 사용자 지정 구성 및 컴포넌트 모음일 뿐이다.
Tiptab
: Wysiwyg기반 에디터인ProseMirror
에 에디터 내부 컨텐츠 조작 기능을 제공해주는 라이브러리이다.
Wysiwyg(위즈윅, what you see is what you get) : 사용자가 보는 것이 그대로 최종 산물에 나타나도록 하는 유저 인터페이스 Wysiwyg 에디터: 편집 상태인데 최종 산물이 보이는 에디터
살펴보면 좋은 링크
Novel의 extensions인 StarterKit
에서 설정하고, EditorContent의 extension 프로퍼티에 추가하면 된다.
import { cx } from "class-variance-authority";
const starterKit = StarterKit.configure({
bulletList: {
HTMLAttributes: {
class: cx("list-disc list-outside leading-3 -mt-2"),
},
},
orderedList: {
HTMLAttributes: {
class: cx("list-decimal list-outside leading-3 -mt-2"),
},
},
listItem: {
HTMLAttributes: {
class: cx("leading-normal -mb-2"),
},
},
blockquote: {
HTMLAttributes: {
class: cx("border-l-4 border-primary"),
},
}
...
});
드래그한 텍스트를 커스텀할 수 있는 툴바이다.
// https://github.com/steven-tey/novel/blob/ecdb5d2ff5d3e6ab5f5af95b5a81de3ab4e8a0e9/examples/novel-tailwind/src/components/editor/advanced-editor.tsx#L84-L103
import { NodeSelector } from "./selectors/node-selector";
import { LinkSelector } from "./selectors/link-selector";
import { ColorSelector } from "./selectors/color-selector";
<EditorBubble
tippyOptions={{
placement: "top",
}}
className="flex w-fit max-w-[90vw] overflow-hidden rounded-md border border-muted bg-background shadow-xl"
>
<Separator orientation="vertical" />
<NodeSelector open={openNode} onOpenChange={setOpenNode} />
<Separator orientation="vertical" />
<LinkSelector open={openLink} onOpenChange={setOpenLink} />
<Separator orientation="vertical" />
<TextButtons />
<Separator orientation="vertical" />
<ColorSelector open={openColor} onOpenChange={setOpenColor} />
</EditorBubble>
노션에서 /
를 입력하면 나오는 단축키 기능이다.
// https://github.com/steven-tey/novel/blob/main/examples/novel-tailwind/src/components/editor/slash-command.tsx
export const suggestionItems = createSuggestionItems([
{
title: "Send Feedback",
description: "Let us know how we can improve.",
icon: <MessageSquarePlus size={18} />,
command: ({ editor, range }) => {
editor.chain().focus().deleteRange(range).run();
window.open("/feedback", "_blank");
},
},
{
title: "Text",
description: "Just start typing with plain text.",
searchTerms: ["p", "paragraph"],
icon: <Text size={18} />,
command: ({ editor, range }) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleNode("paragraph", "paragraph")
.run();
},
},
...
)
// https://github.com/steven-tey/novel/blob/ecdb5d2ff5d3e6ab5f5af95b5a81de3ab4e8a0e9/examples/novel-tailwind/src/components/editor/advanced-editor.tsx#L62C9-L81C31
<EditorCommandList>
{suggestionItems.map((item) => (
<EditorCommandItem
value={item.title}
onCommand={(val) => item.command?.(val)}
className={`flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-accent aria-selected:bg-accent `}
key={item.title}
>
<div className="flex h-10 w-10 items-center justify-center rounded-md border border-muted bg-background">
{item.icon}
</div>
<div>
<p className="font-medium">{item.title}</p>
<p className="text-xs text-muted-foreground">{item.description}</p>
</div>
</EditorCommandItem>
))}
</EditorCommandList>;
- Block 단위의 DND가 잘 안된다.
네모 박스와 같은 drag-handler를 따로 추가해야할듯
⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
✏️ 에디터
Novel이란?
Novel 스타일링 문제
에디터 저장 및 고려 사항들
📠 실시간 협업, 통신
Yorkie와 Novel editor 연동
YJS, Websocket, React-Flow
YJS, Socket.io
WebSocket과 Socket.io에 대해 간단히 알아보기
YJS 가이드 근데 이제 Socket.io를 곁들인
🏗️ 인프라와 CI/CD
NCloud CI CD 구축
BE 개발 스택과 기술적 고민
private key로 원격 서버 접근
nCloud 서버, VPC 만들고 설정
monorepo로 변경
⌛ 캐시, 최적화
rabbit mq 사용법
🔑 인증, 인가, 보안
passport로 oAuth 로그인 회원가입 구현
FE 로그인 기능 구현
JWT로 인증 인가 구현
JWT 쿠키로 사용하기
refresh token 보완하기
🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략
🌤️ 데일리 스크럼
📑 회의록
1️⃣ 1주차
킥오프(10/25)
2일차(10/29)
3일차(10/30)
4일차(10/31)
2️⃣ 2주차
8일차(11/04)
9일차(11/05)
11일차(11/07)
13일차(11/09)
3️⃣ 3주차
3주차 주간계획(11/11)
16일차(11/12)
18일차(11/14)
4️⃣ 4주차
4주차 주간계획(11/18)
23일차(11/19)
24일차(11/20)
25일차(11/21)
5️⃣ 5주차
5주차 주간계획(11/25)
29일차(11/25)
32일차(11/28)
34일차(11/30)
6️⃣ 6주차
6주차 주간계획(12/2)
37일차(12/3)