はじめに
早稲田大学4年のkouta222です!
Lexicalエディタをインターンで使う機会があるので、学習も兼ねて記事を書きます。
Lexicalエディタとは
Lexicalエディタは、Mataが開発したテキストエディタを作成するためのフレームワークです。一般的な<textarea>
よりも高度な機能を備えた、プレーンテキストエディタ、ブログやソーシャルメディア、メッセージングアプリなどで使用されるリッチテキストエディタ、CMSで使用されるWYSIWYGエディタ、リアルタイムコラボレーション機能を持つエディタなどを実装するのに適しています。
他のリッチテキストエディターライブラリと異なり、Lexicalはテキストエディタの核となる機能を提供するフレームワークです。ツールバーやスタイリングなどの機能は、プラグインとして別途実装する必要があります。これにより、最小限の設定で使用できますが、開発者が柔軟にカスタマイズできるようになっています。
Lexicalの特徴
Lexicalのライフサイクルには大きく分けて3つの概念が登場します。
- EditorState: エディターの状態を保持する不変のモデル
- Editor: LexicalのコアAPIで本体を指す
- DOM(contentEditable): ユーザーが入力するテキストを反映するDOMエレメント
ユーザーがDOMを操作するとEditorStateが更新され、Editorがその変更をDOMに反映させる、といった単方向のデータフローになっています。
EditorStateの構造
EditorStateには以下の2つのデータが含まれています:
-
Node
- 編集中のデータをツリー状に管理
- ユーザーがHeadingブロックを追加すると
HeadingNode
が、その中にテキストを表すTextNode
が追加される
-
Selection
- エディター上の選択状態を表現
- テキストの選択範囲や、キャレットの位置を管理
Commands
ユーザーによるすべての操作は Commandのディスパッチ に変換されます。特定のCommandに対して予め実行する処理をEditorに登録しておき、EditorがCommandを受け取ったらその処理(多くはEditorStateの更新)を行います。
Editorにあらかじめ用意したCommandを登録し、dispatchで呼び出すことができます。以下のようなAPIが用意されています。
-
createCommand()
: 新しいCommandの作成 -
LexicalEditor.registerCommand()
: 対象のEditorにCommandを登録 -
LexicalEditor.dispatchCommand()
: 対象のCommandをEditor内で実行
レキシカルエディタの処理の流れ
Lexicalの使い方
Lexicalを使ったリッチテキストエディターを実装する例を示します。
jsxCopy code// LexicalComposer
import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { RichTextPlugin } from '@lexical/react/RichTextPlugin';
import { OnChangePlugin } from '@lexical/react/OnChangePlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { HistoryPlugin } from '@lexical/react/HistoryPlugin';
const initialConfig = {
namespace: 'my-rich-text-editor',
onError: (error) => console.error(error),
};
function App() {
return (
<LexicalComposer initialConfig={initialConfig}>
<RichTextPlugin
contentEditable={<ContentEditable />}
placeholder={<div>Enter some rich text...</div>}
/>
<OnChangePlugin onChange={handleChange} />
<HistoryPlugin />
{/* Add custom plugins and toolbar here */}
</LexicalComposer>
);
}
function handleChange(editorState) {
console.log('Editor state changed:', editorState);
}
- LexicalComposer: エディターの初期設定を行うProviderコンポーネント
- RichTextPlugin: リッチテキスト機能を提供するプラグイン
- OnChangePlugin: エディターの変更を検知するコールバック関数を設定するプラグイン
- HistoryPlugin: 編集履歴の管理を行うプラグイン
LexicalComposerでは、名前空間の設定やエラー処理の関数を指定しています。RichTextPluginではcontentEditable
コンポーネントとプレースホルダーを設定し、OnChangePluginでは変更検知のコールバック関数を指定しています。