0
# Lexical
1
2
Lexical is an extensible JavaScript text editor framework with an emphasis on reliability, accessibility, and performance. It provides a dependency-free editor engine that allows for powerful text editing implementations with immutable state management, plugin architecture, and advanced features like collaborative editing support.
3
4
## Package Information
5
6
- **Package Name**: lexical
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install lexical`
10
11
## Core Imports
12
13
```typescript
14
import { createEditor, $getRoot, $getSelection } from "lexical";
15
import { $createTextNode, $createParagraphNode } from "lexical";
16
```
17
18
For CommonJS:
19
20
```javascript
21
const { createEditor, $getRoot, $getSelection } = require("lexical");
22
```
23
24
## Basic Usage
25
26
```typescript
27
import { createEditor, $getRoot, $createParagraphNode, $createTextNode } from "lexical";
28
29
// Create an editor instance
30
const config = {
31
namespace: 'MyEditor',
32
theme: {
33
// Optional theming
34
},
35
onError: (error) => {
36
console.error(error);
37
},
38
};
39
40
const editor = createEditor(config);
41
42
// Associate with a DOM element
43
const contentEditable = document.getElementById('editor');
44
editor.setRootElement(contentEditable);
45
46
// Update editor content
47
editor.update(() => {
48
const root = $getRoot();
49
const paragraph = $createParagraphNode();
50
const text = $createTextNode('Hello, Lexical!');
51
52
paragraph.append(text);
53
root.append(paragraph);
54
});
55
56
// Listen for updates
57
editor.registerUpdateListener(({ editorState }) => {
58
editorState.read(() => {
59
// Read the current editor state
60
const root = $getRoot();
61
console.log(root.getTextContent());
62
});
63
});
64
```
65
66
## Architecture
67
68
Lexical is built around several key components:
69
70
- **Editor Instance**: Core editor that manages state, DOM binding, and operations
71
- **Editor State**: Immutable state container representing the current document state
72
- **Node System**: Tree-based node structure for representing content (Text, Element, Paragraph, etc.)
73
- **Selection System**: Sophisticated selection handling with Range and Node selections
74
- **Command System**: Event-driven architecture for handling user interactions and programmatic changes
75
- **Caret System**: Advanced caret positioning and navigation for precise text manipulation
76
- **DOM Reconciler**: Efficient DOM updates through state diffing and reconciliation
77
78
## Capabilities
79
80
### Editor Management
81
82
Core editor functionality for creating, configuring, and managing Lexical editor instances.
83
84
```typescript { .api }
85
function createEditor(config?: CreateEditorArgs): LexicalEditor;
86
87
interface CreateEditorArgs {
88
namespace?: string;
89
theme?: EditorThemeClasses;
90
onError?: (error: Error) => void;
91
nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;
92
editorState?: EditorState;
93
html?: HTMLConfig;
94
editable?: boolean;
95
}
96
97
interface LexicalEditor {
98
setRootElement(rootElement: null | HTMLElement): void;
99
getEditorState(): EditorState;
100
setEditorState(editorState: EditorState, options?: EditorSetOptions): void;
101
update(updateFn: () => void, options?: EditorUpdateOptions): void;
102
read(readFn: () => T): T;
103
focus(callbackFn?: () => void): void;
104
blur(): void;
105
isEditable(): boolean;
106
setEditable(editable: boolean): void;
107
}
108
```
109
110
[Editor Management](./editor-management.md)
111
112
### Node System
113
114
Comprehensive node types and utilities for representing and manipulating document content.
115
116
```typescript { .api }
117
abstract class LexicalNode {
118
getKey(): NodeKey;
119
getType(): string;
120
clone(): LexicalNode;
121
createDOM(config: EditorConfig): HTMLElement;
122
updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean;
123
exportJSON(): SerializedLexicalNode;
124
exportDOM(editor: LexicalEditor): DOMExportOutput;
125
}
126
127
class TextNode extends LexicalNode {
128
constructor(text: string, key?: NodeKey);
129
getTextContent(): string;
130
setTextContent(text: string): this;
131
hasFormat(type: TextFormatType): boolean;
132
toggleFormat(type: TextFormatType): this;
133
}
134
135
class ElementNode extends LexicalNode {
136
getChildren(): Array<LexicalNode>;
137
getChildrenSize(): number;
138
append(...nodesToAppend: LexicalNode[]): this;
139
select(anchorOffset?: number, focusOffset?: number): RangeSelection;
140
}
141
```
142
143
[Node System](./node-system.md)
144
145
### Selection System
146
147
Advanced selection management with Range and Node selections, providing precise control over user selection and programmatic selection manipulation.
148
149
```typescript { .api }
150
function $getSelection(): BaseSelection | null;
151
function $setSelection(selection: BaseSelection): void;
152
function $createRangeSelection(): RangeSelection;
153
function $createNodeSelection(): NodeSelection;
154
155
interface RangeSelection extends BaseSelection {
156
anchor: Point;
157
focus: Point;
158
getTextContent(): string;
159
insertText(text: string): void;
160
insertNodes(nodes: LexicalNode[]): void;
161
removeText(): void;
162
}
163
164
interface NodeSelection extends BaseSelection {
165
getNodes(): LexicalNode[];
166
add(key: NodeKey): void;
167
delete(key: NodeKey): void;
168
clear(): void;
169
}
170
```
171
172
[Selection System](./selection-system.md)
173
174
### Command System
175
176
Comprehensive command system for handling user interactions, keyboard events, and programmatic editor operations.
177
178
```typescript { .api }
179
function createCommand<T>(type?: string): LexicalCommand<T>;
180
181
interface LexicalEditor {
182
registerCommand<P>(
183
command: LexicalCommand<P>,
184
listener: CommandListener<P>,
185
priority: CommandListenerPriority
186
): () => void;
187
188
dispatchCommand<P>(command: LexicalCommand<P>, payload: P): boolean;
189
}
190
191
// Built-in Commands
192
const FORMAT_TEXT_COMMAND: LexicalCommand<TextFormatType>;
193
const INSERT_PARAGRAPH_COMMAND: LexicalCommand<void>;
194
const DELETE_CHARACTER_COMMAND: LexicalCommand<boolean>;
195
const UNDO_COMMAND: LexicalCommand<void>;
196
const REDO_COMMAND: LexicalCommand<void>;
197
```
198
199
[Command System](./command-system.md)
200
201
### State Management
202
203
Immutable editor state management with node state capabilities for advanced use cases.
204
205
```typescript { .api }
206
interface EditorState {
207
read<T>(callbackFn: () => T): T;
208
clone(selection?: BaseSelection): EditorState;
209
toJSON(): SerializedEditorState;
210
}
211
212
// Node State Management
213
function createState<T>(config: StateValueConfig<T>): StateConfig<T>;
214
function $getState<T>(node: LexicalNode, stateConfig: StateConfig<T>): T;
215
function $setState<T>(node: LexicalNode, stateConfig: StateConfig<T>, value: T): void;
216
```
217
218
[State Management](./state-management.md)
219
220
### Utilities and Helpers
221
222
Essential utility functions for DOM operations, node manipulation, and editor interaction.
223
224
```typescript { .api }
225
function $getRoot(): RootNode;
226
function $getNodeByKey(key: NodeKey): LexicalNode | null;
227
function $createTextNode(text?: string): TextNode;
228
function $createParagraphNode(): ParagraphNode;
229
230
// DOM Utilities
231
function isLexicalEditor(editor: unknown): editor is LexicalEditor;
232
function getNearestEditorFromDOMNode(node: Node): LexicalEditor | null;
233
function $getNearestNodeFromDOMNode(node: Node): LexicalNode | null;
234
```
235
236
[Utilities and Helpers](./utilities-helpers.md)
237
238
### Caret System
239
240
Advanced caret positioning and navigation system for precise text manipulation and cursor movement.
241
242
```typescript { .api }
243
interface TextPointCaret {
244
type: 'text-point';
245
node: TextNode;
246
offset: number;
247
}
248
249
interface SiblingCaret {
250
type: 'sibling';
251
node: LexicalNode;
252
direction: 'next' | 'previous';
253
}
254
255
function $getTextPointCaret(node: TextNode, offset: number): TextPointCaret;
256
function $getSiblingCaret(node: LexicalNode, direction: CaretDirection): SiblingCaret;
257
function $setSelectionFromCaretRange(range: CaretRange): void;
258
```
259
260
[Caret System](./caret-system.md)
261
262
## Constants
263
264
```typescript { .api }
265
/** Text formatting constants */
266
const IS_BOLD: number;
267
const IS_ITALIC: number;
268
const IS_STRIKETHROUGH: number;
269
const IS_UNDERLINE: number;
270
const IS_CODE: number;
271
const IS_SUBSCRIPT: number;
272
const IS_SUPERSCRIPT: number;
273
const IS_HIGHLIGHT: number;
274
const IS_ALL_FORMATTING: number;
275
276
/** Node state key for internal state management */
277
const NODE_STATE_KEY: string;
278
279
/** Mapping of text format types to numeric values */
280
const TEXT_TYPE_TO_FORMAT: Record<string, number>;
281
282
/** Update tags for categorizing editor updates */
283
const HISTORIC_TAG: string;
284
const HISTORY_PUSH_TAG: string;
285
const HISTORY_MERGE_TAG: string;
286
const PASTE_TAG: string;
287
const COLLABORATION_TAG: string;
288
const SKIP_COLLAB_TAG: string;
289
const SKIP_SCROLL_INTO_VIEW_TAG: string;
290
const SKIP_DOM_SELECTION_TAG: string;
291
const FOCUS_TAG: string;
292
```
293
294
## Types
295
296
```typescript { .api }
297
type NodeKey = string;
298
type TextFormatType = 'bold' | 'italic' | 'strikethrough' | 'underline' | 'code' | 'subscript' | 'superscript' | 'highlight';
299
type ElementFormatType = 'left' | 'center' | 'right' | 'justify' | 'start' | 'end';
300
type CommandListenerPriority = 0 | 1 | 2 | 3 | 4;
301
type UpdateTag = string;
302
303
interface EditorThemeClasses {
304
paragraph?: string;
305
text?: {
306
bold?: string;
307
italic?: string;
308
underline?: string;
309
strikethrough?: string;
310
underlineStrikethrough?: string;
311
code?: string;
312
highlight?: string;
313
subscript?: string;
314
superscript?: string;
315
};
316
}
317
318
interface SerializedLexicalNode {
319
type: string;
320
version: number;
321
}
322
323
interface SerializedEditorState {
324
root: SerializedRootNode;
325
}
326
```