lexical 0.2.7 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Lexical.d.ts CHANGED
@@ -6,20 +6,23 @@
6
6
  *
7
7
  */
8
8
 
9
- import {Class, $ReadOnly} from 'utility-types';
9
+ import {Spread} from 'libdefs/globals';
10
+ import {Class} from 'utility-types';
10
11
 
11
12
  /**
12
13
  * LexicalCommands
13
14
  */
14
15
 
15
- export type LexicalCommand<P> = $ReadOnly<{}>;
16
+ export type LexicalCommand<P> = Readonly<{}>;
16
17
 
17
18
  export var SELECTION_CHANGE_COMMAND: LexicalCommand<void>;
18
19
  export var CLICK_COMMAND: LexicalCommand<MouseEvent>;
19
20
  export var DELETE_CHARACTER_COMMAND: LexicalCommand<boolean>;
20
21
  export var INSERT_LINE_BREAK_COMMAND: LexicalCommand<boolean>;
21
22
  export var INSERT_PARAGRAPH_COMMAND: LexicalCommand<void>;
22
- export var INSERT_TEXT_COMMAND: LexicalCommand<InputEvent | string>;
23
+ export var CONTROLLED_TEXT_INSERTION_COMMAND: LexicalCommand<
24
+ InputEvent | string
25
+ >;
23
26
  export var PASTE_COMMAND: LexicalCommand<ClipboardEvent>;
24
27
  export var REMOVE_TEXT_COMMAND: LexicalCommand<void>;
25
28
  export var DELETE_WORD_COMMAND: LexicalCommand<boolean>;
@@ -28,7 +31,9 @@ export var FORMAT_TEXT_COMMAND: LexicalCommand<TextFormatType>;
28
31
  export var UNDO_COMMAND: LexicalCommand<void>;
29
32
  export var REDO_COMMAND: LexicalCommand<void>;
30
33
  export var KEY_ARROW_RIGHT_COMMAND: LexicalCommand<KeyboardEvent>;
34
+ export var MOVE_TO_END: LexicalCommand<KeyboardEvent>;
31
35
  export var KEY_ARROW_LEFT_COMMAND: LexicalCommand<KeyboardEvent>;
36
+ export var MOVE_TO_START: LexicalCommand<KeyboardEvent>;
32
37
  export var KEY_ARROW_UP_COMMAND: LexicalCommand<KeyboardEvent>;
33
38
  export var KEY_ARROW_DOWN_COMMAND: LexicalCommand<KeyboardEvent>;
34
39
  export var KEY_ENTER_COMMAND: LexicalCommand<KeyboardEvent | null>;
@@ -43,6 +48,7 @@ export var OUTDENT_CONTENT_COMMAND: LexicalCommand<void>;
43
48
  export var DROP_COMMAND: LexicalCommand<DragEvent>;
44
49
  export var FORMAT_ELEMENT_COMMAND: LexicalCommand<ElementFormatType>;
45
50
  export var DRAGSTART_COMMAND: LexicalCommand<DragEvent>;
51
+ export var DRAGOVER_COMMAND: LexicalCommand<DragEvent>;
46
52
  export var DRAGEND_COMMAND: LexicalCommand<DragEvent>;
47
53
  export var COPY_COMMAND: LexicalCommand<ClipboardEvent>;
48
54
  export var CUT_COMMAND: LexicalCommand<ClipboardEvent>;
@@ -55,6 +61,7 @@ export var BLUR_COMMAND: LexicalCommand<FocusEvent>;
55
61
  export var INSERT_TABLE_COMMAND: LexicalCommand<{
56
62
  rows: string;
57
63
  columns: string;
64
+ includeHeaders?: boolean;
58
65
  }>;
59
66
 
60
67
  export declare function createCommand<T>(): LexicalCommand<T>;
@@ -89,7 +96,6 @@ type Listeners = {
89
96
  update: Set<UpdateListener>;
90
97
  };
91
98
  type CommandListener<P> = (payload: P, editor: LexicalEditor) => boolean;
92
- // $FlowFixMe[unclear-type]
93
99
  type Commands = Map<LexicalCommand<any>, Array<Set<CommandListener<any>>>>;
94
100
  type RegisteredNodes = Map<string, RegisteredNode>;
95
101
  type RegisteredNode = {
@@ -128,6 +134,7 @@ export declare class LexicalEditor {
128
134
  _observer: null | MutationObserver;
129
135
  _key: string;
130
136
  _readOnly: boolean;
137
+ _headless: boolean;
131
138
  isComposing(): boolean;
132
139
  registerUpdateListener(listener: UpdateListener): () => void;
133
140
  registerRootListener(listener: RootListener): () => void;
@@ -149,6 +156,7 @@ export declare class LexicalEditor {
149
156
  ): () => void;
150
157
  dispatchCommand<P>(type: LexicalCommand<P>, payload: P): boolean;
151
158
  hasNodes(nodes: Array<Class<LexicalNode>>): boolean;
159
+ getKey(): string;
152
160
  getDecorators<X>(): Record<NodeKey, X>;
153
161
  getRootElement(): null | HTMLElement;
154
162
  setRootElement(rootElement: null | HTMLElement): void;
@@ -156,13 +164,15 @@ export declare class LexicalEditor {
156
164
  getEditorState(): EditorState;
157
165
  setEditorState(editorState: EditorState, options?: EditorSetOptions): void;
158
166
  parseEditorState(
159
- maybeStringifiedEditorState: string | ParsedEditorState,
167
+ maybeStringifiedEditorState: string | SerializedEditorState,
168
+ updateFn?: () => void,
160
169
  ): EditorState;
161
170
  update(updateFn: () => void, options?: EditorUpdateOptions): boolean;
162
171
  focus(callbackFn?: () => void): void;
163
172
  blur(): void;
164
173
  isReadOnly(): boolean;
165
174
  setReadOnly(readOnly: boolean): void;
175
+ toJSON(): SerializedEditor;
166
176
  }
167
177
  type EditorUpdateOptions = {
168
178
  onUpdate?: () => void;
@@ -184,12 +194,14 @@ type TextNodeThemeClasses = {
184
194
  subscript?: EditorThemeClassName;
185
195
  superscript?: EditorThemeClassName;
186
196
  };
197
+
187
198
  export type EditorThemeClasses = {
188
199
  ltr?: EditorThemeClassName;
189
200
  rtl?: EditorThemeClassName;
190
201
  text?: TextNodeThemeClasses;
191
202
  paragraph?: EditorThemeClassName;
192
203
  image?: EditorThemeClassName;
204
+ characterLimit?: EditorThemeClassName;
193
205
  list?: {
194
206
  ul?: EditorThemeClassName;
195
207
  ulDepth?: Array<EditorThemeClassName>;
@@ -224,18 +236,23 @@ export type EditorThemeClasses = {
224
236
  // Handle other generic values
225
237
  [key: string]:
226
238
  | EditorThemeClassName
227
- | Record<
228
- string,
229
- | EditorThemeClassName
230
- | Array<EditorThemeClassName>
231
- | Record<string, EditorThemeClassName>
232
- >;
239
+ | TextNodeThemeClasses
240
+ | {
241
+ [key: string]:
242
+ | Array<EditorThemeClassName>
243
+ | EditorThemeClassName
244
+ | TextNodeThemeClasses
245
+ | {
246
+ [key: string]: EditorThemeClassName;
247
+ };
248
+ };
233
249
  };
250
+
234
251
  export type EditorConfig = {
235
- namespace: string;
236
252
  theme: EditorThemeClasses;
237
253
  disableEvents?: boolean;
238
254
  };
255
+
239
256
  export type CommandListenerPriority = 0 | 1 | 2 | 3 | 4;
240
257
  export const COMMAND_PRIORITY_EDITOR = 0;
241
258
  export const COMMAND_PRIORITY_LOW = 1;
@@ -244,11 +261,10 @@ export const COMMAND_PRIORITY_HIGH = 3;
244
261
  export const COMMAND_PRIORITY_CRITICAL = 4;
245
262
  export type IntentionallyMarkedAsDirtyElement = boolean;
246
263
  export function createEditor(editorConfig?: {
247
- namespace?: string;
248
264
  editorState?: EditorState;
249
265
  theme?: EditorThemeClasses;
250
266
  parentEditor?: LexicalEditor;
251
- nodes?: Array<Class<LexicalNode>>;
267
+ nodes?: ReadonlyArray<Class<LexicalNode>>;
252
268
  onError: (error: Error) => void;
253
269
  disableEvents?: boolean;
254
270
  readOnly?: boolean;
@@ -257,25 +273,7 @@ export function createEditor(editorConfig?: {
257
273
  /**
258
274
  * LexicalEditorState
259
275
  */
260
- export type ParsedEditorState = {
261
- _selection: null | {
262
- anchor: {
263
- key: string;
264
- offset: number;
265
- type: 'text' | 'element';
266
- };
267
- focus: {
268
- key: string;
269
- offset: number;
270
- type: 'text' | 'element';
271
- };
272
- };
273
- _nodeMap: Array<[NodeKey, ParsedNode]>;
274
- };
275
- type JSONEditorState = {
276
- _nodeMap: Array<[NodeKey, LexicalNode]>;
277
- _selection: null | ParsedSelection;
278
- };
276
+
279
277
  export interface EditorState {
280
278
  _nodeMap: NodeMap;
281
279
  _selection: null | RangeSelection | NodeSelection | GridSelection;
@@ -287,7 +285,7 @@ export interface EditorState {
287
285
  );
288
286
  isEmpty(): boolean;
289
287
  read<V>(callbackFn: () => V): V;
290
- toJSON(space?: string | number): JSONEditorState;
288
+ toJSON(): SerializedEditorState;
291
289
  clone(
292
290
  selection?: RangeSelection | NodeSelection | GridSelection | null,
293
291
  ): EditorState;
@@ -327,8 +325,10 @@ export declare class LexicalNode {
327
325
  __type: string;
328
326
  __key: NodeKey;
329
327
  __parent: null | NodeKey;
328
+ static getType: () => string;
330
329
  getType(): string;
331
330
  clone(data: any): LexicalNode;
331
+ exportJSON(): SerializedLexicalNode;
332
332
  importDOM(): DOMConversionMap | null;
333
333
  constructor(key?: NodeKey);
334
334
  getType(): string;
@@ -336,26 +336,24 @@ export declare class LexicalNode {
336
336
  isSelected(): boolean;
337
337
  getKey(): NodeKey;
338
338
  getIndexWithinParent(): number;
339
- getParent(): ElementNode | null;
340
- getParentOrThrow(): ElementNode;
341
- getTopLevelElement(): null | ElementNode;
342
- getTopLevelElementOrThrow(): ElementNode;
343
- getParents(): Array<ElementNode>;
339
+ getParent<T extends ElementNode>(): T | null;
340
+ getParentOrThrow<T extends ElementNode>(): T;
341
+ getTopLevelElement(): ElementNode | this | null;
342
+ getTopLevelElementOrThrow(): ElementNode | this;
343
+ getParents<T extends ElementNode>(): Array<T>;
344
344
  getParentKeys(): Array<NodeKey>;
345
- getPreviousSibling(): LexicalNode | null;
346
- getPreviousSiblings(): Array<LexicalNode>;
347
- getNextSibling(): LexicalNode | null;
348
- getNextSiblings(): Array<LexicalNode>;
349
- getCommonAncestor(node: LexicalNode): ElementNode | null;
345
+ getPreviousSibling<T extends LexicalNode>(): T | null;
346
+ getPreviousSiblings<T extends LexicalNode>(): Array<T>;
347
+ getNextSibling<T extends LexicalNode>(): T | null;
348
+ getNextSiblings<T extends LexicalNode>(): Array<T>;
349
+ getCommonAncestor<T extends ElementNode>(node: LexicalNode): T | null;
350
350
  is(object: LexicalNode | null | undefined): boolean;
351
351
  isBefore(targetNode: LexicalNode): boolean;
352
352
  isParentOf(targetNode: LexicalNode): boolean;
353
353
  getNodesBetween(targetNode: LexicalNode): Array<LexicalNode>;
354
354
  isDirty(): boolean;
355
- // $FlowFixMe
356
- getLatest<T extends LexicalNode>(): T;
357
- // $FlowFixMe
358
- getWritable<T extends LexicalNode>(): T;
355
+ getLatest(): this;
356
+ getWritable(): this;
359
357
  getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
360
358
  getTextContentSize(
361
359
  includeInert?: boolean,
@@ -363,43 +361,17 @@ export declare class LexicalNode {
363
361
  ): number;
364
362
  exportDOM(editor: LexicalEditor): DOMExportOutput;
365
363
  createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement;
366
- updateDOM(prevNode: any, dom: HTMLElement, config: EditorConfig): boolean;
364
+ updateDOM(prevNode: unknown, dom: HTMLElement, config: EditorConfig): boolean;
367
365
  remove(preserveEmptyParent?: boolean): void;
368
366
  replace<N extends LexicalNode>(replaceWith: N): N;
369
367
  insertAfter(nodeToInsert: LexicalNode): LexicalNode;
370
368
  insertBefore(nodeToInsert: LexicalNode): LexicalNode;
371
- selectPrevious(anchorOffset?: number, focusOffset?: number): Selection;
372
- selectNext(anchorOffset?: number, focusOffset?: number): Selection;
369
+ selectPrevious(anchorOffset?: number, focusOffset?: number): RangeSelection;
370
+ selectNext(anchorOffset?: number, focusOffset?: number): RangeSelection;
373
371
  markDirty(): void;
374
372
  }
375
373
  export type NodeMap = Map<NodeKey, LexicalNode>;
376
374
 
377
- /**
378
- * LexicalParsing
379
- */
380
- export type ParsedNode = {
381
- __key: NodeKey;
382
- __type: string;
383
- __parent: null | NodeKey;
384
- };
385
- export type ParsedNodeMap = Map<NodeKey, ParsedNode>;
386
- export function $createNodeFromParse(
387
- parsedNode: ParsedNode,
388
- parsedNodeMap: ParsedNodeMap,
389
- ): LexicalNode;
390
- type ParsedSelection = {
391
- anchor: {
392
- key: NodeKey;
393
- offset: number;
394
- type: 'text' | 'element';
395
- };
396
- focus: {
397
- key: NodeKey;
398
- offset: number;
399
- type: 'text' | 'element';
400
- };
401
- };
402
-
403
375
  /**
404
376
  * LexicalSelection
405
377
  */
@@ -476,7 +448,6 @@ export declare class RangeSelection {
476
448
  focusOffset: number,
477
449
  ): void;
478
450
  getTextContent(): string;
479
- // $FlowFixMe DOM API
480
451
  applyDOMRange(range: StaticRange): void;
481
452
  clone(): RangeSelection;
482
453
  toggleFormat(format: TextFormatType): void;
@@ -535,7 +506,6 @@ declare class _Point {
535
506
  getNode(): LexicalNode;
536
507
  set(key: NodeKey, offset: number, type: 'text' | 'element'): void;
537
508
  }
538
-
539
509
  export function $createRangeSelection(): RangeSelection;
540
510
  export function $createNodeSelection(): NodeSelection;
541
511
  export function $createGridSelection(): GridSelection;
@@ -587,9 +557,7 @@ export declare class TextNode extends LexicalNode {
587
557
  isSimpleText(): boolean;
588
558
  getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
589
559
  getFormatFlags(type: TextFormatType, alignWithFormat: null | number): number;
590
- // $FlowFixMe
591
560
  createDOM(config: EditorConfig): HTMLElement;
592
- // $FlowFixMe
593
561
  updateDOM(
594
562
  prevNode: TextNode,
595
563
  dom: HTMLElement,
@@ -604,7 +572,10 @@ export declare class TextNode extends LexicalNode {
604
572
  toggleFormat(type: TextFormatType): TextNode;
605
573
  toggleDirectionless(): TextNode;
606
574
  toggleUnmergeable(): TextNode;
607
- setMode(type: TextModeType): TextNode;
575
+ setMode(type: TextModeType): this;
576
+ setDetail(detail: number): TextNode;
577
+ getDetail(): number;
578
+ getMode(): TextModeType;
608
579
  setTextContent(text: string): TextNode;
609
580
  select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
610
581
  spliceText(
@@ -617,6 +588,9 @@ export declare class TextNode extends LexicalNode {
617
588
  canInsertTextAfter(): boolean;
618
589
  splitText(...splitOffsets: Array<number>): Array<TextNode>;
619
590
  mergeWithSibling(target: TextNode): TextNode;
591
+ isTextEntity(): boolean;
592
+ static importJSON(serializedTextNode: SerializedTextNode): TextNode;
593
+ exportJSON(): SerializedTextNode;
620
594
  }
621
595
  export function $createTextNode(text?: string): TextNode;
622
596
  export function $isTextNode(
@@ -633,6 +607,10 @@ export declare class LineBreakNode extends LexicalNode {
633
607
  getTextContent(): '\n';
634
608
  createDOM(): HTMLElement;
635
609
  updateDOM(): false;
610
+ static importJSON(
611
+ serializedLineBreakNode: SerializedLexicalNode,
612
+ ): LineBreakNode;
613
+ exportJSON(): SerializedLexicalNode;
636
614
  }
637
615
  export function $createLineBreakNode(): LineBreakNode;
638
616
  export function $isLineBreakNode(
@@ -651,11 +629,13 @@ export declare class RootNode extends ElementNode {
651
629
  select(): RangeSelection;
652
630
  remove(): void;
653
631
  replace<N extends LexicalNode>(node: N): N;
654
- insertBefore(): LexicalNode;
655
- insertAfter(node: LexicalNode): LexicalNode;
632
+ insertBefore<T extends LexicalNode>(nodeToInsert: T): T;
633
+ insertAfter<T extends LexicalNode>(nodeToInsert: T): T;
656
634
  updateDOM(prevNode: RootNode, dom: HTMLElement): false;
657
- append(...nodesToAppend: Array<LexicalNode>): ElementNode;
635
+ append(...nodesToAppend: Array<LexicalNode>): this;
658
636
  canBeEmpty(): false;
637
+ static importJSON(serializedRootNode: SerializedRootNode): RootNode;
638
+ exportJSON(): SerializedElementNode;
659
639
  }
660
640
  export function $isRootNode(
661
641
  node: LexicalNode | null | undefined,
@@ -664,7 +644,7 @@ export function $isRootNode(
664
644
  /**
665
645
  * LexicalElementNode
666
646
  */
667
- export type ElementFormatType = 'left' | 'center' | 'right' | 'justify';
647
+ export type ElementFormatType = 'left' | 'center' | 'right' | 'justify' | '';
668
648
  export declare class ElementNode extends LexicalNode {
669
649
  __children: Array<NodeKey>;
670
650
  __format: number;
@@ -672,28 +652,30 @@ export declare class ElementNode extends LexicalNode {
672
652
  __dir: 'ltr' | 'rtl' | null;
673
653
  constructor(key?: NodeKey);
674
654
  getFormat(): number;
655
+ getFormatType(): ElementFormatType;
675
656
  getIndent(): number;
676
- getChildren(): Array<LexicalNode>;
657
+ getChildren<T extends LexicalNode>(): Array<T>;
658
+ getChildren<T extends Array<LexicalNode>>(): T;
677
659
  getChildrenKeys(): Array<NodeKey>;
678
660
  getChildrenSize(): number;
679
661
  isEmpty(): boolean;
680
662
  isDirty(): boolean;
681
663
  getAllTextNodes(includeInert?: boolean): Array<TextNode>;
682
- getFirstDescendant(): null | LexicalNode;
683
- getLastDescendant(): null | LexicalNode;
684
- getDescendantByIndex(index: number): LexicalNode;
664
+ getFirstDescendant<T extends LexicalNode>(): null | T;
665
+ getLastDescendant<T extends LexicalNode>(): null | T;
666
+ getDescendantByIndex<T extends LexicalNode>(index: number): null | T;
685
667
  getFirstChild<T extends LexicalNode>(): null | T;
686
668
  getFirstChildOrThrow<T extends LexicalNode>(): T;
687
- getLastChild(): null | LexicalNode;
688
- getChildAtIndex(index: number): null | LexicalNode;
669
+ getLastChild<T extends LexicalNode>(): null | T;
670
+ getChildAtIndex<T extends LexicalNode>(index: number): null | T;
689
671
  getTextContent(includeInert?: boolean, includeDirectionless?: false): string;
690
672
  getDirection(): 'ltr' | 'rtl' | null;
691
673
  hasFormat(type: ElementFormatType): boolean;
692
674
  select(_anchorOffset?: number, _focusOffset?: number): RangeSelection;
693
675
  selectStart(): RangeSelection;
694
676
  selectEnd(): RangeSelection;
695
- clear(): ElementNode;
696
- append(...nodesToAppend: Array<LexicalNode>): ElementNode;
677
+ clear(): this;
678
+ append(...nodesToAppend: Array<LexicalNode>): this;
697
679
  setDirection(direction: 'ltr' | 'rtl' | null): ElementNode;
698
680
  setFormat(type: ElementFormatType): ElementNode;
699
681
  setIndent(indentLevel: number): ElementNode;
@@ -719,7 +701,8 @@ export declare class ElementNode extends LexicalNode {
719
701
  start: number,
720
702
  deleteCount: number,
721
703
  nodesToInsert: Array<LexicalNode>,
722
- ): ElementNode;
704
+ ): this;
705
+ exportJSON(): SerializedElementNode;
723
706
  }
724
707
  export function $isElementNode(
725
708
  node: LexicalNode | null | undefined,
@@ -728,7 +711,7 @@ export function $isElementNode(
728
711
  /**
729
712
  * LexicalDecoratorNode
730
713
  */
731
- export declare class DecoratorNode<X> extends LexicalNode {
714
+ export declare class DecoratorNode<X = unknown> extends LexicalNode {
732
715
  constructor(key?: NodeKey);
733
716
  decorate(editor: LexicalEditor): X;
734
717
  isIsolated(): boolean;
@@ -749,6 +732,10 @@ export declare class ParagraphNode extends ElementNode {
749
732
  updateDOM(prevNode: ParagraphNode, dom: HTMLElement): boolean;
750
733
  insertNewAfter(): ParagraphNode;
751
734
  collapseAtStart(): boolean;
735
+ static importJSON(
736
+ serializedParagraphNode: SerializedElementNode,
737
+ ): ParagraphNode;
738
+ exportJSON(): SerializedElementNode;
752
739
  }
753
740
  export function $createParagraphNode(): ParagraphNode;
754
741
  export function $isParagraphNode(
@@ -773,6 +760,8 @@ export function $isGridCellNode(
773
760
  /**
774
761
  * LexicalUtils
775
762
  */
763
+ export function $hasUpdateTag(tag: string): boolean;
764
+ export function $addUpdateTag(tag: string): void;
776
765
  export function $getNearestNodeFromDOMNode(
777
766
  startingDOM: Node,
778
767
  ): LexicalNode | null;
@@ -791,7 +780,70 @@ export function $getDecoratorNode(
791
780
  isBackward: boolean,
792
781
  ): null | LexicalNode;
793
782
 
783
+ export type EventHandler = (event: Event, editor: LexicalEditor) => void;
784
+
794
785
  /**
795
786
  * LexicalVersion
796
787
  */
797
788
  export declare var VERSION: string;
789
+
790
+ /**
791
+ * Serialization/Deserialization
792
+ * */
793
+ interface InternalSerializedNode {
794
+ children?: Array<InternalSerializedNode>;
795
+ type: string;
796
+ version: number;
797
+ }
798
+
799
+ export function $parseSerializedNode<
800
+ SerializedNode extends InternalSerializedNode,
801
+ >(serializedNode: SerializedNode): LexicalNode;
802
+
803
+ export type SerializedLexicalNode = {
804
+ type: string;
805
+ version: number;
806
+ };
807
+
808
+ export type SerializedEditor = {
809
+ editorState: SerializedEditorState;
810
+ };
811
+
812
+ export type SerializedTextNode = Spread<
813
+ {
814
+ detail: number;
815
+ format: number;
816
+ mode: TextModeType;
817
+ style: string;
818
+ text: string;
819
+ },
820
+ SerializedLexicalNode
821
+ >;
822
+
823
+ export type SerializedElementNode = Spread<
824
+ {
825
+ children: Array<SerializedLexicalNode>;
826
+ direction: 'ltr' | 'rtl' | null;
827
+ format: ElementFormatType;
828
+ indent: number;
829
+ },
830
+ SerializedLexicalNode
831
+ >;
832
+
833
+ export type SerializedRootNode = Spread<
834
+ {
835
+ type: 'root';
836
+ },
837
+ SerializedElementNode
838
+ >;
839
+
840
+ export type SerializedGridCellNode = Spread<
841
+ {
842
+ colSpan: number;
843
+ },
844
+ SerializedElementNode
845
+ >;
846
+
847
+ export interface SerializedEditorState {
848
+ root: SerializedRootNode;
849
+ }