Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
© 2025 Wantedly, Inc. 目次機能実装から理解するLexical Editor Wantedly Tech Night #9 2025-03-19 Kyuhwan Lee
Slide 2
Slide 2 text
© 2025 Wantedly, Inc. 自己紹介 李 圭煥 (Kyuhwan Lee) @wtdlee Wantedly, Inc. (2023/10~) Visit User Growth フロントエンドエンジニア
Slide 3
Slide 3 text
© 2025 Wantedly, Inc. 目次 ● Lexicalについて ● Lexicalの基本概念 ○ Editor ○ EditorState ○ Lexical Nodes ○ Commands ○ Editor Plugins ● 実際の実装:目次
Slide 4
Slide 4 text
© 2025 Wantedly, Inc. Lexicalについて
Slide 5
Slide 5 text
© 2025 Wantedly, Inc. Lexicalについて ● 安定性、アクセシビリティ、性能にフォーカスした拡張可能な JavaScript Webテキスト編集フレームワーク ○ WYSIWYG(What You See Is What You Get) エディターフレームワーク イメージ:https://lexical.dev/
Slide 6
Slide 6 text
© 2025 Wantedly, Inc. Lexicalについて ● 安定性 ○ 必要な機能をプラグインとして追加 ○ カスタムレンダリングエンジン ● アクセシビリティ ○ Screen Reader ○ ARIA属性管理 ● 性能 ○ カスタムレンダリングエンジン ○ JSON基盤の状態管理
Slide 7
Slide 7 text
© 2025 Wantedly, Inc. Lexicalの基本概念
Slide 8
Slide 8 text
© 2025 Wantedly, Inc. Lexicalの設計 ● Editor ○ Lexicalのエンジン ○ Lexicalの全体的な動作の処理やイベントを管理 ● EditorState ○ Editor内部の状態(JSON)が記録されているオブジェクト ○ editor.update()で変更可能
Slide 9
Slide 9 text
© 2025 Wantedly, Inc. Lexicalの設計 ● Lexical Nodes ○ LexicalのドキュメントはNode基盤 ○ 基本Node ■ TextNode ■ ParagraphNode ■ HeadingNode ■ ListNode, ListItemNode ○ カスタムNodeの追加でEditor内部の要素として利用可能
Slide 10
Slide 10 text
© 2025 Wantedly, Inc. Lexicalの設計 ● Commands ○ Editorの特定機能を実行する ○ editor.registerCommand()で登録、editor.dispatchCommand()で実行 ○ createCommandでカスタムコマンドも生成可能 User Action EditorState Command Registry 入力 Command実行 (Editorの状態変更) アップデート View
Slide 11
Slide 11 text
© 2025 Wantedly, Inc. Lexicalの設計 ● Editor Plugins ○ 特定機能を追加する際に利用可能 ○ ex) ■ RichTextPlugin:Bold, Italicなど基本的な書式 ■ HistoryPlugin:Undo/Redo ■ MarkdownShortcutPlugin:Markdown入力 ○ 目次実装では「TableOfContentsPlugin」を利用
Slide 12
Slide 12 text
© 2025 Wantedly, Inc. 実際の実装:目次 - Wantedly 開発の場合
Slide 13
Slide 13 text
© 2025 Wantedly, Inc. https://playground.lexical.dev/?showTableOfContents=true Lexical Playgroundでは固定箇所に表示されている が、ウォンテッドリーストーリーでは Nodeとして好きな 箇所に挿入できるようにしたい。 また、コンテンツに含まれていて詳細画面描画にも使 えるようになる必要があった。
Slide 14
Slide 14 text
© 2025 Wantedly, Inc. 各種機能の挿入ボタン。 Inserterと呼ばれている
Slide 15
Slide 15 text
© 2025 Wantedly, Inc. Inserterをクリックすると 目次が挿入できるボタンが表示
Slide 16
Slide 16 text
© 2025 Wantedly, Inc. 目次ボタンをクリックすると Lexical Custom Nodeが追加
Slide 17
Slide 17 text
© 2025 Wantedly, Inc. まず、クリックした際のイベント( Command)を登録 する必要がある
Slide 18
Slide 18 text
© 2025 Wantedly, Inc. Node.tsx ● Command 定義 ○ createCommandで識別できるToken(Key)を生成する ○
Slide 19
Slide 19 text
© 2025 Wantedly, Inc. TableofcontentsPlugin.tsx ● Plugin 定義 ○ 生成したTokenがどんな挙動を起こすのかを定義する このCommandは 目次Nodeを生成して 一番近い要素に追加する
Slide 20
Slide 20 text
© 2025 Wantedly, Inc. InserterPlugin.tsx ● Command 実行 ○ 目次ボタンをクリックした際に、定義した Commandが実行されるようにする
Slide 21
Slide 21 text
© 2025 Wantedly, Inc. Node.tsx ● Serialized Type 定義 ○ NodeはClass基盤だが、EditorStateがJSON形式なので NodeもSerializeできる必要がある
Slide 22
Slide 22 text
© 2025 Wantedly, Inc. Node.tsx ● Node 定義
Slide 23
Slide 23 text
© 2025 Wantedly, Inc. Editor.tsx ● Pluginを挿入