0
# Utilities and Helpers
1
2
Essential utility functions for DOM operations, node manipulation, and editor interaction. These utilities provide the building blocks for working with Lexical's editor system and integrating with the DOM.
3
4
## Capabilities
5
6
### Node Access and Manipulation
7
8
Core functions for accessing and manipulating nodes within the editor.
9
10
```typescript { .api }
11
/**
12
* Get the root node of the editor
13
* @returns Root node of the current editor
14
*/
15
function $getRoot(): RootNode;
16
17
/**
18
* Get a node by its unique key
19
* @param key - Node key to lookup
20
* @returns Node instance or null if not found
21
*/
22
function $getNodeByKey(key: NodeKey): LexicalNode | null;
23
24
/**
25
* Get a node by key or throw if not found
26
* @param key - Node key to lookup
27
* @returns Node instance
28
* @throws Error if node not found
29
*/
30
function $getNodeByKeyOrThrow<T extends LexicalNode>(key: NodeKey): T;
31
32
/**
33
* Get the active editor instance
34
* @returns Current editor instance
35
*/
36
function $getEditor(): LexicalEditor;
37
38
/**
39
* Create a node using its constructor
40
* @param klass - Node constructor class
41
* @param args - Constructor arguments
42
* @returns New node instance
43
*/
44
function $create<T extends LexicalNode>(
45
klass: Klass<T>,
46
...args: any[]
47
): T;
48
49
/**
50
* Copy a node with all its properties
51
* @param node - Node to copy
52
* @returns Copied node instance
53
*/
54
function $copyNode<T extends LexicalNode>(node: T): T;
55
56
/**
57
* Clone node with specific properties
58
* @param node - Node to clone
59
* @param options - Cloning options
60
* @returns Cloned node
61
*/
62
function $cloneWithProperties<T extends LexicalNode>(node: T): T;
63
64
/**
65
* Apply node replacement transformations
66
* @param node - Node to transform
67
* @returns Transformed node
68
*/
69
function $applyNodeReplacement<T extends LexicalNode>(node: T): T;
70
```
71
72
### Node Factory Functions
73
74
Convenient factory functions for creating common node types.
75
76
```typescript { .api }
77
/**
78
* Create a new TextNode
79
* @param text - Initial text content
80
* @returns New TextNode instance
81
*/
82
function $createTextNode(text?: string): TextNode;
83
84
/**
85
* Create a new ParagraphNode
86
* @returns New ParagraphNode instance
87
*/
88
function $createParagraphNode(): ParagraphNode;
89
90
/**
91
* Create a new LineBreakNode
92
* @returns New LineBreakNode instance
93
*/
94
function $createLineBreakNode(): LineBreakNode;
95
96
/**
97
* Create a new TabNode
98
* @returns New TabNode instance
99
*/
100
function $createTabNode(): TabNode;
101
```
102
103
### Node Queries and Traversal
104
105
Functions for querying and traversing the node tree.
106
107
```typescript { .api }
108
/**
109
* Get all nodes of a specific type
110
* @param klass - Node class to search for
111
* @returns Array of nodes of the specified type
112
*/
113
function $nodesOfType<T extends LexicalNode>(klass: Klass<T>): Array<T>;
114
115
/**
116
* Get adjacent node in specified direction
117
* @param node - Starting node
118
* @param isBackward - Direction to search
119
* @returns Adjacent node or null
120
*/
121
function $getAdjacentNode(node: LexicalNode, isBackward: boolean): LexicalNode | null;
122
123
/**
124
* Check if node has a specific ancestor
125
* @param node - Node to check
126
* @param targetNode - Potential ancestor node
127
* @returns True if targetNode is an ancestor
128
*/
129
function $hasAncestor(node: LexicalNode, targetNode: LexicalNode): boolean;
130
131
/**
132
* Get nearest root or shadow root
133
* @param node - Starting node
134
* @returns Root or shadow root node
135
*/
136
function $getNearestRootOrShadowRoot(node: LexicalNode): ElementNode;
137
138
/**
139
* Check if node is root or shadow root
140
* @param node - Node to check
141
* @returns True if node is root or shadow root
142
*/
143
function $isRootOrShadowRoot(node: LexicalNode | null | undefined): boolean;
144
145
/**
146
* Check if node is a leaf node (no children)
147
* @param node - Node to check
148
* @returns True if node is leaf
149
*/
150
function $isLeafNode(node: LexicalNode): boolean;
151
152
/**
153
* Check if node is inline element or decorator
154
* @param node - Node to check
155
* @returns True if inline element or decorator
156
*/
157
function $isInlineElementOrDecoratorNode(node: LexicalNode): boolean;
158
```
159
160
### Node Type Checking
161
162
Utility functions for checking node types and characteristics.
163
164
```typescript { .api }
165
/**
166
* Check if text node is token or segmented
167
* @param node - Node to check
168
* @returns True if token or segmented
169
*/
170
function $isTokenOrSegmented(node: LexicalNode): boolean;
171
172
/**
173
* Check if text node is token or tab
174
* @param node - Node to check
175
* @returns True if token or tab
176
*/
177
function $isTokenOrTab(node: LexicalNode): boolean;
178
179
/**
180
* Internal function to check if node is block
181
* @param node - Node to check
182
* @returns True if block node
183
*/
184
function INTERNAL_$isBlock(node: ElementNode): boolean;
185
```
186
187
### Selection and Editor Operations
188
189
Functions for working with selections and performing editor operations.
190
191
```typescript { .api }
192
/**
193
* Select all content in the editor
194
* @returns RangeSelection covering all content
195
*/
196
function $selectAll(): RangeSelection;
197
198
/**
199
* Split a node at a specific position
200
* @param node - Node to split
201
* @param offset - Position to split at
202
* @returns Array of resulting nodes
203
*/
204
function $splitNode(node: LexicalNode, offset: number): [LexicalNode, LexicalNode];
205
206
/**
207
* Remove node from its parent
208
* @param node - Node to remove
209
*/
210
function removeFromParent(node: LexicalNode): void;
211
212
/**
213
* Set composition key for IME input
214
* @param compositionKey - Composition key string
215
*/
216
function $setCompositionKey(compositionKey: string | null): void;
217
```
218
219
### DOM Integration
220
221
Functions for integrating with DOM elements and browser APIs.
222
223
```typescript { .api }
224
/**
225
* Get nearest Lexical node from DOM node
226
* @param domNode - DOM node to start from
227
* @returns Nearest Lexical node or null
228
*/
229
function $getNearestNodeFromDOMNode(domNode: Node): LexicalNode | null;
230
231
/**
232
* Get nearest editor from DOM node
233
* @param domNode - DOM node to start from
234
* @returns Nearest editor instance or null
235
*/
236
function getNearestEditorFromDOMNode(domNode: Node): LexicalEditor | null;
237
238
/**
239
* Get editor property from DOM node
240
* @param domNode - DOM node to check
241
* @param editorPropertyName - Property name to retrieve
242
* @returns Property value or null
243
*/
244
function getEditorPropertyFromDOMNode(
245
domNode: Node,
246
editorPropertyName: string
247
): unknown;
248
249
/**
250
* Get DOM owner document
251
* @param node - Node to get document from
252
* @returns Document object
253
*/
254
function getDOMOwnerDocument(node: Node): Document;
255
256
/**
257
* Get DOM selection
258
* @param targetWindow - Window object to get selection from
259
* @returns Selection object or null
260
*/
261
function getDOMSelection(targetWindow?: Window): Selection | null;
262
263
/**
264
* Get DOM selection from target element
265
* @param target - Target element
266
* @returns Selection object or null
267
*/
268
function getDOMSelectionFromTarget(target: Node): Selection | null;
269
270
/**
271
* Get DOM text node
272
* @param node - Node to get text node from
273
* @returns Text node or null
274
*/
275
function getDOMTextNode(node: Node): Text | null;
276
```
277
278
### DOM Type Checking
279
280
Functions for checking DOM node types and characteristics.
281
282
```typescript { .api }
283
/**
284
* Check if object is a DOM node
285
* @param node - Object to check
286
* @returns True if DOM node
287
*/
288
function isDOMNode(node: unknown): node is Node;
289
290
/**
291
* Check if node is DOM text node
292
* @param node - Node to check
293
* @returns True if DOM text node
294
*/
295
function isDOMTextNode(node: Node): node is Text;
296
297
/**
298
* Check if node is DOM document
299
* @param node - Node to check
300
* @returns True if DOM document
301
*/
302
function isDOMDocumentNode(node: Node): node is Document;
303
304
/**
305
* Check if node is document fragment
306
* @param node - Node to check
307
* @returns True if document fragment
308
*/
309
function isDocumentFragment(node: Node): node is DocumentFragment;
310
311
/**
312
* Check if element is HTML element
313
* @param node - Node to check
314
* @returns True if HTML element
315
*/
316
function isHTMLElement(node: Node): node is HTMLElement;
317
318
/**
319
* Check if element is HTML anchor element
320
* @param node - Node to check
321
* @returns True if HTML anchor element
322
*/
323
function isHTMLAnchorElement(node: Node): node is HTMLAnchorElement;
324
325
/**
326
* Check if DOM node is block element
327
* @param node - Node to check
328
* @returns True if block element
329
*/
330
function isBlockDomNode(node: Node): boolean;
331
332
/**
333
* Check if DOM node is inline element
334
* @param node - Node to check
335
* @returns True if inline element
336
*/
337
function isInlineDomNode(node: Node): boolean;
338
339
/**
340
* Check if object is Lexical editor
341
* @param editor - Object to check
342
* @returns True if Lexical editor
343
*/
344
function isLexicalEditor(editor: unknown): editor is LexicalEditor;
345
346
/**
347
* Check if DOM node is unmanaged by Lexical
348
* @param node - Node to check
349
* @returns True if unmanaged
350
*/
351
function isDOMUnmanaged(node: Node): boolean;
352
353
/**
354
* Mark DOM node as unmanaged by Lexical
355
* @param node - Node to mark
356
* @param unmanaged - Whether to mark as unmanaged
357
*/
358
function setDOMUnmanaged(node: Node, unmanaged: boolean): void;
359
```
360
361
### Event and Input Handling
362
363
Utilities for handling keyboard events and user input.
364
365
```typescript { .api }
366
/**
367
* Check if keyboard event matches exact shortcut
368
* @param event - Keyboard event
369
* @param shortcut - Shortcut string
370
* @returns True if exact match
371
*/
372
function isExactShortcutMatch(event: KeyboardEvent, shortcut: string): boolean;
373
374
/**
375
* Check if modifier keys match
376
* @param event - Keyboard event
377
* @param modifier - Modifier combination
378
* @returns True if modifiers match
379
*/
380
function isModifierMatch(event: KeyboardEvent, modifier: string): boolean;
381
382
/**
383
* Check if selection is captured in decorator input
384
* @param selection - Selection to check
385
* @returns True if in decorator input
386
*/
387
function isSelectionCapturedInDecoratorInput(selection: BaseSelection): boolean;
388
389
/**
390
* Check if selection is within editor
391
* @param editor - Editor instance
392
* @param selection - Selection to check
393
* @returns True if selection is within editor
394
*/
395
function isSelectionWithinEditor(
396
editor: LexicalEditor,
397
selection: BaseSelection
398
): boolean;
399
```
400
401
### Node Registration and Configuration
402
403
Functions for working with registered nodes and node configuration.
404
405
```typescript { .api }
406
/**
407
* Get registered node class by type
408
* @param type - Node type string
409
* @returns Node class or null
410
*/
411
function getRegisteredNode(type: string): Klass<LexicalNode> | null;
412
413
/**
414
* Get registered node class or throw
415
* @param type - Node type string
416
* @returns Node class
417
* @throws Error if node type not registered
418
*/
419
function getRegisteredNodeOrThrow<T extends LexicalNode>(type: string): Klass<T>;
420
421
/**
422
* Set node indent from DOM element
423
* @param node - Node to set indent on
424
* @param element - DOM element to read indent from
425
*/
426
function setNodeIndentFromDOM(node: ElementNode, element: HTMLElement): void;
427
428
/**
429
* Build import map for node deserialization
430
* @param importMap - Mapping of node types to constructor functions
431
* @returns Normalized import map
432
*/
433
function buildImportMap<K extends string>(importMap: {
434
[key in K]: Klass<LexicalNode> | LexicalNodeReplacement;
435
}): Map<string, Klass<LexicalNode>>;
436
437
/**
438
* Experimental function to normalize selection
439
* @param selection - Selection to normalize
440
* @returns Normalized selection
441
*/
442
function $normalizeSelection__EXPERIMENTAL(selection: BaseSelection): BaseSelection;
443
```
444
445
### Update Tags and Lifecycle
446
447
Functions for working with update tags and editor lifecycle.
448
449
```typescript { .api }
450
/**
451
* Add update tag to current update
452
* @param tag - Tag to add
453
*/
454
function $addUpdateTag(tag: string): void;
455
456
/**
457
* Check if current update has tag
458
* @param tag - Tag to check for
459
* @returns True if update has tag
460
*/
461
function $hasUpdateTag(tag: string): boolean;
462
463
/**
464
* Register callback for update events
465
* @param callback - Function to call on update
466
* @returns Function to remove listener
467
*/
468
function $onUpdate(callback: () => void): () => void;
469
470
/**
471
* Reset random key generator
472
*/
473
function resetRandomKey(): void;
474
```
475
476
**Usage Examples:**
477
478
```typescript
479
import {
480
$getRoot,
481
$getNodeByKey,
482
$createTextNode,
483
$nodesOfType,
484
$selectAll,
485
getNearestEditorFromDOMNode,
486
isLexicalEditor
487
} from "lexical";
488
489
// Working with nodes
490
editor.update(() => {
491
const root = $getRoot();
492
const textNode = $createTextNode('Hello, world!');
493
494
// Query nodes
495
const allTextNodes = $nodesOfType(TextNode);
496
console.log('Found', allTextNodes.length, 'text nodes');
497
498
// Node manipulation
499
const nodeKey = textNode.getKey();
500
const retrievedNode = $getNodeByKey(nodeKey);
501
502
if (retrievedNode && $isTextNode(retrievedNode)) {
503
retrievedNode.setTextContent('Updated text');
504
}
505
506
// Select all content
507
const selection = $selectAll();
508
console.log('Selected text:', selection.getTextContent());
509
});
510
511
// DOM integration
512
const domElement = document.getElementById('editor-content');
513
if (domElement) {
514
const nearestEditor = getNearestEditorFromDOMNode(domElement);
515
516
if (isLexicalEditor(nearestEditor)) {
517
console.log('Found editor from DOM element');
518
}
519
}
520
521
// Working with update tags
522
editor.update(() => {
523
$addUpdateTag('user-action');
524
525
if ($hasUpdateTag('user-action')) {
526
console.log('This is a user-initiated update');
527
}
528
}, { tag: 'custom-update' });
529
530
// Type checking utilities
531
const someNode = $getNodeByKey('some-key');
532
if ($isTextNode(someNode)) {
533
console.log('Text content:', someNode.getTextContent());
534
} else if ($isParagraphNode(someNode)) {
535
console.log('Paragraph children:', someNode.getChildrenSize());
536
}
537
```
538
539
These utilities form the foundation of Lexical's functionality, providing essential building blocks for editor operations, DOM integration, and node manipulation. They are designed to work seamlessly with Lexical's immutable state model and update system.