@lyfie/luthor-headless 2.2.0 → 2.3.1

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/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import * as lexical from 'lexical';
2
- import { TextFormatType, LexicalEditor, EditorThemeClasses, ParagraphNode, DecoratorNode, DOMConversionMap, NodeKey, EditorConfig as EditorConfig$1, DOMExportOutput, Spread, SerializedLexicalNode, LexicalNode, ElementNode, RangeSelection } from 'lexical';
3
- import React$1, { ReactNode, ComponentType, CSSProperties } from 'react';
4
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
- import { Transformer } from '@lexical/markdown';
6
- import { CodeNode } from '@lexical/code';
2
+ import { TextFormatType, LexicalEditor, KlassConstructor, LexicalNode, LexicalNodeReplacement, EditorThemeClasses, ParagraphNode, SerializedLexicalNode, EditorConfig as EditorConfig$1, DOMConversionMap, DOMExportOutput, ElementNode, DecoratorNode, RangeSelection } from 'lexical';
3
+ export { LexicalEditor } from 'lexical';
4
+ import * as React$1 from 'react';
5
+ import React__default, { ReactNode, ComponentType, CSSProperties } from 'react';
6
+ import { ListNode, ListItemNode } from '@lexical/list';
7
+ import { CodeNode, CodeHighlightNode } from '@lexical/code';
7
8
  import { HeadingTagType, HeadingNode, QuoteNode } from '@lexical/rich-text';
8
- import * as _lexical_table from '@lexical/table';
9
- import * as _lexical_react_LexicalHorizontalRuleNode from '@lexical/react/LexicalHorizontalRuleNode';
10
9
 
10
+ type LexicalNodeRegistration = KlassConstructor<typeof LexicalNode> | LexicalNodeReplacement;
11
11
  /** Extension category buckets */
12
12
  declare enum ExtensionCategory {
13
13
  Toolbar = "toolbar",
@@ -22,14 +22,14 @@ interface BaseExtensionConfig {
22
22
  position?: "before" | "after";
23
23
  /** Initialization priority; higher registers first (default: 0) */
24
24
  initPriority?: number;
25
- [key: string]: any;
25
+ [key: string]: unknown;
26
26
  }
27
27
  /** Toolbar item configuration */
28
28
  interface ToolbarItem {
29
29
  label: string;
30
30
  onClick: () => void;
31
31
  isActive?: () => boolean;
32
- component?: React.ComponentType<any>;
32
+ component?: React.ComponentType<Record<string, unknown>>;
33
33
  }
34
34
  /**
35
35
  * Core extension contract implemented by all extensions.
@@ -41,7 +41,7 @@ interface ToolbarItem {
41
41
  * @template StateQueries - State query function map
42
42
  * @template Plugins - React plugins exposed by the extension
43
43
  */
44
- interface Extension<Name extends string = string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, any> = {}, StateQueries extends Record<string, () => Promise<boolean>> = {}, Plugins extends ReactNode[] = ReactNode[]> {
44
+ interface Extension<Name extends string = string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, unknown> = Record<string, never>, StateQueries extends Record<string, () => Promise<boolean>> = Record<string, never>, Plugins extends ReactNode[] = ReactNode[]> {
45
45
  /** Unique identifier for this extension */
46
46
  name: Name;
47
47
  /** Category groups for this extension */
@@ -59,15 +59,15 @@ interface Extension<Name extends string = string, Config extends BaseExtensionCo
59
59
  selected?: boolean;
60
60
  className?: string;
61
61
  style?: CSSProperties;
62
- [key: string]: any;
62
+ [key: string]: unknown;
63
63
  }>) => Extension<Name, Config, Commands, StateQueries, Plugins>;
64
64
  /** Override node rendering logic */
65
65
  overrideNodeRender?: (overrides: {
66
- createDOM?: (config: any) => HTMLElement;
67
- updateDOM?: (prev: any, next: any, dom: HTMLElement) => boolean;
66
+ createDOM?: (config: unknown) => HTMLElement;
67
+ updateDOM?: (prev: unknown, next: unknown, dom: HTMLElement) => boolean;
68
68
  }) => Extension<Name, Config, Commands, StateQueries, Plugins>;
69
69
  /** Return custom Lexical nodes */
70
- getNodes?: () => any[];
70
+ getNodes?: () => LexicalNodeRegistration[];
71
71
  /** Return React plugins */
72
72
  getPlugins: () => Plugins;
73
73
  /** Provide commands exposed by the extension */
@@ -109,23 +109,19 @@ interface EditorContextType<Exts extends readonly Extension[]> {
109
109
  /** Current state for all extensions */
110
110
  activeStates: ExtractStateQueries<Exts>;
111
111
  /** State query functions from extensions */
112
- stateQueries: Record<string, () => Promise<any>>;
112
+ stateQueries: Record<string, () => Promise<unknown>>;
113
113
  /** Event listener registration */
114
114
  listeners: {
115
- registerUpdate: (listener: (state: any) => void) => (() => void) | undefined;
115
+ registerUpdate: (listener: (state: unknown) => void) => (() => void) | undefined;
116
116
  registerPaste: (listener: (event: ClipboardEvent) => boolean) => (() => void) | undefined;
117
117
  };
118
118
  /** Export helpers for formats */
119
119
  export: {
120
- toHTML: () => Promise<string>;
121
- toMarkdown: () => Promise<string>;
122
- toJSON: () => any;
120
+ toJSON: () => unknown;
123
121
  };
124
122
  /** Import helpers for formats */
125
123
  import: {
126
- fromHTML: (html: string) => Promise<void>;
127
- fromMarkdown: (md: string) => Promise<void>;
128
- fromJSON: (json: any) => void;
124
+ fromJSON: (json: unknown) => void;
129
125
  };
130
126
  /** Alias of the raw Lexical editor */
131
127
  lexical: LexicalEditor | null;
@@ -142,7 +138,7 @@ interface EditorContextType<Exts extends readonly Extension[]> {
142
138
  }
143
139
  interface EditorConfig {
144
140
  theme?: EditorThemeClasses;
145
- [key: string]: any;
141
+ [key: string]: unknown;
146
142
  }
147
143
 
148
144
  interface ProviderProps<Exts extends readonly Extension[]> {
@@ -168,8 +164,8 @@ declare function createEditorSystem<Exts extends readonly Extension[]>(): {
168
164
  Provider: (props: ProviderProps<Exts>) => react_jsx_runtime.JSX.Element;
169
165
  useEditor: () => EditorContextType<Exts>;
170
166
  };
171
- declare const BaseProvider: (props: ProviderProps<readonly Extension<string, BaseExtensionConfig, {}, {}, React$1.ReactNode[]>[]>) => react_jsx_runtime.JSX.Element;
172
- declare const useBaseEditor: () => EditorContextType<any>;
167
+ declare const BaseProvider: (props: ProviderProps<readonly Extension<string, BaseExtensionConfig, Record<string, never>, Record<string, never>, React__default.ReactNode[]>[]>) => react_jsx_runtime.JSX.Element;
168
+ declare const useBaseEditor: () => EditorContextType<readonly Extension<string, BaseExtensionConfig, Record<string, never>, Record<string, never>, React__default.ReactNode[]>[]>;
173
169
 
174
170
  /**
175
171
  * Abstract base class for all Luthor extensions.
@@ -181,7 +177,7 @@ declare const useBaseEditor: () => EditorContextType<any>;
181
177
  * @template StateQueries - State query functions exposed by this extension
182
178
  * @template Plugins - React plugins/components exposed by this extension
183
179
  */
184
- declare abstract class BaseExtension<Name extends string = string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, any> = {}, StateQueries extends Record<string, () => Promise<boolean>> = {}, Plugins extends ReactNode[] = ReactNode[]> implements Extension<Name, Config, Commands, StateQueries, Plugins> {
180
+ declare abstract class BaseExtension<Name extends string = string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, unknown> = Record<string, never>, StateQueries extends Record<string, () => Promise<boolean>> = Record<string, never>, Plugins extends ReactNode[] = ReactNode[]> implements Extension<Name, Config, Commands, StateQueries, Plugins> {
185
181
  /** Unique name identifier for this extension */
186
182
  name: Name;
187
183
  /** Categories this extension belongs to (toolbar, sidebar, etc.) */
@@ -192,8 +188,8 @@ declare abstract class BaseExtension<Name extends string = string, Config extend
192
188
  supportedFormats: readonly TextFormatType[];
193
189
  /** Node rendering overrides */
194
190
  nodeOverrides: {
195
- createDOM?: (config: any) => HTMLElement;
196
- updateDOM?: (prev: any, next: any, dom: HTMLElement) => boolean;
191
+ createDOM?: (config: unknown) => HTMLElement;
192
+ updateDOM?: (prev: unknown, next: unknown, dom: HTMLElement) => boolean;
197
193
  };
198
194
  /**
199
195
  * Creates a new extension instance.
@@ -223,7 +219,7 @@ declare abstract class BaseExtension<Name extends string = string, Config extend
223
219
  *
224
220
  * @returns Array of Lexical node classes
225
221
  */
226
- getNodes(): any[];
222
+ getNodes(): LexicalNodeRegistration[];
227
223
  /**
228
224
  * Allows overriding the UI component used for this extension.
229
225
  *
@@ -234,7 +230,7 @@ declare abstract class BaseExtension<Name extends string = string, Config extend
234
230
  selected?: boolean;
235
231
  className?: string;
236
232
  style?: CSSProperties;
237
- [key: string]: any;
233
+ [key: string]: unknown;
238
234
  }>): Extension<Name, Config, Commands, StateQueries, Plugins>;
239
235
  /**
240
236
  * Overrides node rendering behavior.
@@ -243,8 +239,8 @@ declare abstract class BaseExtension<Name extends string = string, Config extend
243
239
  * @returns Extension instance for chaining
244
240
  */
245
241
  overrideNodeRender(overrides: {
246
- createDOM?: (config: any) => HTMLElement;
247
- updateDOM?: (prev: any, next: any, dom: HTMLElement) => boolean;
242
+ createDOM?: (config: unknown) => HTMLElement;
243
+ updateDOM?: (prev: unknown, next: unknown, dom: HTMLElement) => boolean;
248
244
  }): Extension<Name, Config, Commands, StateQueries, Plugins>;
249
245
  /**
250
246
  * Returns React plugins/components exposed by this extension.
@@ -272,13 +268,13 @@ declare abstract class BaseExtension<Name extends string = string, Config extend
272
268
  * @param commands - Available commands from all extensions
273
269
  * @returns Array of toolbar item configurations
274
270
  */
275
- getToolbarItems(commands: any): ToolbarItem[];
271
+ getToolbarItems(commands: Record<string, unknown>): ToolbarItem[];
276
272
  }
277
273
 
278
274
  /**
279
275
  * Configuration options for creating a custom extension
280
276
  */
281
- interface CreateExtensionConfig<Name extends string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, any> = {}, StateQueries extends Record<string, () => Promise<boolean>> = {}, Plugins extends ReactNode[] = ReactNode[]> {
277
+ interface CreateExtensionConfig<Name extends string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, unknown> = Record<string, never>, StateQueries extends Record<string, () => Promise<boolean>> = Record<string, never>, Plugins extends ReactNode[] = ReactNode[]> {
282
278
  /** Unique name for the extension */
283
279
  name: Name;
284
280
  /** Categories this extension belongs to */
@@ -294,9 +290,9 @@ interface CreateExtensionConfig<Name extends string, Config extends BaseExtensio
294
290
  /** Initialization function called when extension is registered */
295
291
  initialize?: (editor: LexicalEditor) => (() => void) | void;
296
292
  /** Custom Lexical nodes */
297
- nodes?: any[];
293
+ nodes?: LexicalNodeRegistration[];
298
294
  /** Text formats supported by this extension */
299
- supportedFormats?: readonly any[];
295
+ supportedFormats?: readonly TextFormatType[];
300
296
  }
301
297
  /**
302
298
  * Factory function to create a type-safe extension that extends BaseExtension.
@@ -330,8 +326,12 @@ interface CreateExtensionConfig<Name extends string, Config extends BaseExtensio
330
326
  * });
331
327
  * ```
332
328
  */
333
- declare function createExtension<Name extends string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, any> = {}, StateQueries extends Record<string, () => Promise<boolean>> = {}, Plugins extends ReactNode[] = ReactNode[]>(config: CreateExtensionConfig<Name, Config, Commands, StateQueries, Plugins>): BaseExtension<Name, Config, Commands, StateQueries, Plugins>;
329
+ declare function createExtension<Name extends string, Config extends BaseExtensionConfig = BaseExtensionConfig, Commands extends Record<string, unknown> = Record<string, never>, StateQueries extends Record<string, () => Promise<boolean>> = Record<string, never>, Plugins extends ReactNode[] = ReactNode[]>(config: CreateExtensionConfig<Name, Config, Commands, StateQueries, Plugins>): BaseExtension<Name, Config, Commands, StateQueries, Plugins>;
334
330
 
331
+ declare const LUTHOR_EDITOR_THEME_TOKENS: readonly ["--luthor-bg", "--luthor-fg", "--luthor-border", "--luthor-border-hover", "--luthor-border-active", "--luthor-accent", "--luthor-accent-hover", "--luthor-shadow", "--luthor-muted", "--luthor-muted-fg", "--luthor-theme-transition", "--luthor-drag-gutter-width", "--luthor-line-height-ratio", "--luthor-toolbar-bg", "--luthor-toolbar-section-border", "--luthor-toolbar-button-fg", "--luthor-toolbar-button-hover-bg", "--luthor-toolbar-button-hover-border", "--luthor-toolbar-button-hover-shadow", "--luthor-toolbar-button-press-shadow", "--luthor-toolbar-button-active-bg", "--luthor-toolbar-button-active-border", "--luthor-toolbar-button-active-fg", "--luthor-toolbar-button-active-shadow", "--luthor-toolbar-button-overlay", "--luthor-toolbar-button-active-overlay", "--luthor-toolbar-color-indicator-border", "--luthor-toolbar-highlight-bg", "--luthor-quote-bg", "--luthor-quote-fg", "--luthor-quote-border", "--luthor-text-bold-color", "--luthor-link-color", "--luthor-list-marker-color", "--luthor-list-checkbox-color", "--luthor-table-border-color", "--luthor-table-header-bg", "--luthor-hr-color", "--luthor-placeholder-color", "--luthor-codeblock-bg", "--luthor-syntax-comment", "--luthor-syntax-keyword", "--luthor-syntax-string", "--luthor-syntax-number", "--luthor-syntax-function", "--luthor-syntax-variable", "--luthor-floating-bg", "--luthor-floating-fg", "--luthor-floating-border", "--luthor-floating-shadow", "--luthor-floating-muted", "--luthor-floating-border-hover", "--luthor-floating-border-active", "--luthor-floating-accent", "--luthor-floating-accent-fg", "--luthor-preset-bg", "--luthor-preset-fg", "--luthor-preset-border", "--luthor-preset-muted", "--luthor-preset-muted-fg", "--luthor-preset-accent", "--luthor-preset-radius", "--luthor-preset-shadow", "--luthor-preset-content-padding", "--luthor-preset-content-min-height"];
332
+ type LuthorEditorThemeToken = (typeof LUTHOR_EDITOR_THEME_TOKENS)[number];
333
+ type LuthorEditorThemeOverrides = Partial<Record<LuthorEditorThemeToken, string>>;
334
+ declare function createEditorThemeStyleVars(overrides?: LuthorEditorThemeOverrides): React__default.CSSProperties | undefined;
335
335
  /**
336
336
  * Enhanced theme type that extends Lexical's EditorThemeClasses
337
337
  * with better TypeScript support and additional properties
@@ -362,16 +362,16 @@ interface LuthorTheme extends EditorThemeClasses {
362
362
  blockIsDragging?: string;
363
363
  buttonStack?: string;
364
364
  styles?: {
365
- handle?: React$1.CSSProperties;
366
- handleActive?: React$1.CSSProperties;
367
- handleHover?: React$1.CSSProperties;
368
- handleDragging?: React$1.CSSProperties;
369
- blockDragging?: React$1.CSSProperties;
370
- dropIndicator?: React$1.CSSProperties;
371
- upButton?: React$1.CSSProperties;
372
- downButton?: React$1.CSSProperties;
373
- blockIsDragging?: React$1.CSSProperties;
374
- buttonStack?: React$1.CSSProperties;
365
+ handle?: React__default.CSSProperties;
366
+ handleActive?: React__default.CSSProperties;
367
+ handleHover?: React__default.CSSProperties;
368
+ handleDragging?: React__default.CSSProperties;
369
+ blockDragging?: React__default.CSSProperties;
370
+ dropIndicator?: React__default.CSSProperties;
371
+ upButton?: React__default.CSSProperties;
372
+ downButton?: React__default.CSSProperties;
373
+ blockIsDragging?: React__default.CSSProperties;
374
+ buttonStack?: React__default.CSSProperties;
375
375
  };
376
376
  };
377
377
  floatingToolbar?: {
@@ -379,59 +379,35 @@ interface LuthorTheme extends EditorThemeClasses {
379
379
  button?: string;
380
380
  buttonActive?: string;
381
381
  styles?: {
382
- container?: React$1.CSSProperties;
383
- button?: React$1.CSSProperties;
384
- buttonActive?: React$1.CSSProperties;
385
- };
386
- };
387
- htmlEmbed?: {
388
- container?: string;
389
- preview?: string;
390
- editor?: string;
391
- textarea?: string;
392
- toggle?: string;
393
- content?: string;
394
- styles?: {
395
- container?: React$1.CSSProperties;
396
- preview?: React$1.CSSProperties;
397
- editor?: React$1.CSSProperties;
398
- textarea?: React$1.CSSProperties;
399
- toggle?: React$1.CSSProperties;
400
- content?: React$1.CSSProperties;
382
+ container?: React__default.CSSProperties;
383
+ button?: React__default.CSSProperties;
384
+ buttonActive?: React__default.CSSProperties;
401
385
  };
402
386
  };
403
387
  styles?: {
404
388
  toolbar?: {
405
- button?: React$1.CSSProperties;
406
- buttonActive?: React$1.CSSProperties;
407
- buttonDisabled?: React$1.CSSProperties;
408
- group?: React$1.CSSProperties;
389
+ button?: React__default.CSSProperties;
390
+ buttonActive?: React__default.CSSProperties;
391
+ buttonDisabled?: React__default.CSSProperties;
392
+ group?: React__default.CSSProperties;
409
393
  };
410
- container?: React$1.CSSProperties;
411
- wrapper?: React$1.CSSProperties;
394
+ container?: React__default.CSSProperties;
395
+ wrapper?: React__default.CSSProperties;
412
396
  draggable?: {
413
- handle?: React$1.CSSProperties;
414
- handleHover?: React$1.CSSProperties;
415
- handleDragging?: React$1.CSSProperties;
416
- blockDragging?: React$1.CSSProperties;
417
- dropIndicator?: React$1.CSSProperties;
418
- upButton?: React$1.CSSProperties;
419
- downButton?: React$1.CSSProperties;
420
- blockIsDragging?: React$1.CSSProperties;
421
- buttonStack?: React$1.CSSProperties;
397
+ handle?: React__default.CSSProperties;
398
+ handleHover?: React__default.CSSProperties;
399
+ handleDragging?: React__default.CSSProperties;
400
+ blockDragging?: React__default.CSSProperties;
401
+ dropIndicator?: React__default.CSSProperties;
402
+ upButton?: React__default.CSSProperties;
403
+ downButton?: React__default.CSSProperties;
404
+ blockIsDragging?: React__default.CSSProperties;
405
+ buttonStack?: React__default.CSSProperties;
422
406
  };
423
407
  floatingToolbar?: {
424
- container?: React$1.CSSProperties;
425
- button?: React$1.CSSProperties;
426
- buttonActive?: React$1.CSSProperties;
427
- };
428
- htmlEmbed?: {
429
- container?: React$1.CSSProperties;
430
- preview?: React$1.CSSProperties;
431
- editor?: React$1.CSSProperties;
432
- textarea?: React$1.CSSProperties;
433
- toggle?: React$1.CSSProperties;
434
- content?: React$1.CSSProperties;
408
+ container?: React__default.CSSProperties;
409
+ button?: React__default.CSSProperties;
410
+ buttonActive?: React__default.CSSProperties;
435
411
  };
436
412
  };
437
413
  }
@@ -448,6 +424,40 @@ declare function mergeThemes(baseTheme: LuthorTheme, overrideTheme: Partial<Luth
448
424
  */
449
425
  declare function isLuthorTheme(theme: any): theme is LuthorTheme;
450
426
 
427
+ declare function clearLexicalSelection(editor: LexicalEditor): void;
428
+ declare function resolveLinkNodeKeyFromAnchor(editor: LexicalEditor, anchorEl: HTMLAnchorElement): string | null;
429
+
430
+ type JsonTextNode = {
431
+ type: "text";
432
+ version: 1;
433
+ text: string;
434
+ detail: 0;
435
+ format: 0;
436
+ mode: "normal";
437
+ style: "";
438
+ };
439
+ type JsonParagraphNode = {
440
+ type: "paragraph";
441
+ version: 1;
442
+ format: "";
443
+ indent: 0;
444
+ direction: null;
445
+ children: JsonTextNode[];
446
+ };
447
+ type JsonRootNode = {
448
+ type: "root";
449
+ version: 1;
450
+ format: "";
451
+ indent: 0;
452
+ direction: null;
453
+ children: JsonParagraphNode[];
454
+ };
455
+ type JsonbDocument = {
456
+ root: JsonRootNode;
457
+ };
458
+ declare function markdownToJSONB(markdown: string): JsonbDocument;
459
+ declare function jsonbToMarkdown(input: unknown): string;
460
+
451
461
  /**
452
462
  * Commands exposed by text format extensions.
453
463
  * Generates toggle commands for text formatting (e.g., toggleBold, toggleItalic).
@@ -543,6 +553,15 @@ declare class ItalicExtension extends TextFormatExtension<"italic"> {
543
553
  */
544
554
  declare const italicExtension: ItalicExtension;
545
555
 
556
+ /**
557
+ * Custom underline transformer for Markdown
558
+ * Uses ++underline++ syntax (common in extended Markdown)
559
+ */
560
+ declare const UNDERLINE_TRANSFORMER: {
561
+ format: readonly ["underline"];
562
+ tag: string;
563
+ type: "text-format";
564
+ };
546
565
  /**
547
566
  * UnderlineExtension - Adds underline text formatting
548
567
  *
@@ -567,7 +586,7 @@ declare class UnderlineExtension extends TextFormatExtension<"underline"> {
567
586
  *
568
587
  * @returns An array containing the underline transformer
569
588
  */
570
- getMarkdownTransformers(): any[];
589
+ getMarkdownTransformers(): readonly typeof UNDERLINE_TRANSFORMER[];
571
590
  }
572
591
  declare const underlineExtension: UnderlineExtension;
573
592
 
@@ -613,13 +632,30 @@ interface LinkConfig extends BaseExtensionConfig {
613
632
  linkSelectedTextOnPaste?: boolean;
614
633
  /** URL validation function (default: basic URL regex) */
615
634
  validateUrl?: (url: string) => boolean;
635
+ /** Enable click navigation on links rendered inside the editor. Default: true */
636
+ clickableLinks?: boolean;
637
+ /** Open clicked links in a new tab when click navigation is enabled. Default: true */
638
+ openLinksInNewTab?: boolean;
616
639
  }
617
640
  /**
618
641
  * Commands exposed by the link extension.
619
642
  */
620
643
  type LinkCommands = {
621
644
  insertLink: (url?: string, text?: string) => void;
645
+ updateLink: (url: string, rel?: string, target?: string) => boolean;
622
646
  removeLink: () => void;
647
+ getCurrentLink: () => Promise<{
648
+ url: string;
649
+ rel: string | null;
650
+ target: string | null;
651
+ } | null>;
652
+ getLinkByKey: (linkNodeKey: string) => Promise<{
653
+ url: string;
654
+ rel: string | null;
655
+ target: string | null;
656
+ } | null>;
657
+ updateLinkByKey: (linkNodeKey: string, url: string, rel?: string, target?: string) => boolean;
658
+ removeLinkByKey: (linkNodeKey: string) => boolean;
623
659
  };
624
660
  /**
625
661
  * State queries exposed by the link extension.
@@ -665,7 +701,8 @@ type LinkStateQueries = {
665
701
  * }
666
702
  * ```
667
703
  */
668
- declare class LinkExtension extends BaseExtension<"link", LinkConfig, LinkCommands, LinkStateQueries, React$1.ReactElement[]> {
704
+ declare class LinkExtension extends BaseExtension<"link", LinkConfig, LinkCommands, LinkStateQueries, React__default.ReactElement[]> {
705
+ private lastSelectedLinkNodeKey;
669
706
  /**
670
707
  * Creates a new link extension instance.
671
708
  */
@@ -682,11 +719,16 @@ declare class LinkExtension extends BaseExtension<"link", LinkConfig, LinkComman
682
719
  /**
683
720
  * Returns React plugins exposed by this extension.
684
721
  */
685
- getPlugins(): React$1.ReactElement[];
722
+ getPlugins(): React__default.ReactElement[];
686
723
  /**
687
724
  * Returns command handlers exposed by this extension.
688
725
  */
689
726
  getCommands(editor: LexicalEditor): LinkCommands;
727
+ private serializeLinkNode;
728
+ private removeLinkNode;
729
+ private getLinkNodeByKey;
730
+ private getSelectedLinkNode;
731
+ private getCachedLinkNode;
690
732
  /**
691
733
  * Returns state query functions exposed by this extension.
692
734
  */
@@ -729,7 +771,7 @@ type HorizontalRuleStateQueries = {
729
771
  * }
730
772
  * ```
731
773
  */
732
- declare class HorizontalRuleExtension extends BaseExtension<"horizontalRule", any, HorizontalRuleCommands, HorizontalRuleStateQueries, React$1.ReactElement[]> {
774
+ declare class HorizontalRuleExtension extends BaseExtension<"horizontalRule", any, HorizontalRuleCommands, HorizontalRuleStateQueries, React__default.ReactElement[]> {
733
775
  /**
734
776
  * Creates a new horizontal rule extension.
735
777
  */
@@ -753,7 +795,7 @@ declare class HorizontalRuleExtension extends BaseExtension<"horizontalRule", an
753
795
  *
754
796
  * @returns Array containing the HorizontalRulePlugin
755
797
  */
756
- getPlugins(): React$1.ReactElement[];
798
+ getPlugins(): React__default.ReactElement[];
757
799
  /**
758
800
  * Returns commands exposed by this extension.
759
801
  *
@@ -775,37 +817,189 @@ declare class HorizontalRuleExtension extends BaseExtension<"horizontalRule", an
775
817
  */
776
818
  declare const horizontalRuleExtension: HorizontalRuleExtension;
777
819
 
778
- type MarkdownConfig = BaseExtensionConfig & {
779
- /** Optional debounce (ms) for programmatic markdown imports */
780
- importDebounce?: number;
781
- /** Pre-registered transformers */
782
- transformers?: Transformer[];
783
- /** Transformer alias for backward compatibility */
784
- customTransformers?: Transformer[];
785
- };
786
- type MarkdownCommands = {
787
- exportToMarkdown: () => string;
788
- importFromMarkdown: (markdown: string, opts?: {
789
- immediate?: boolean;
790
- preventFocus?: boolean;
791
- }) => Promise<void>;
792
- registerMarkdownTransformer: (transformer: Transformer) => void;
793
- };
794
- type MarkdownStateQueries = {};
795
- declare class MarkdownExtension extends BaseExtension<'markdown', MarkdownConfig, MarkdownCommands, MarkdownStateQueries, [
796
- ]> {
797
- private manager;
798
- private pendingTransformers;
799
- private importTimer;
820
+ type FontFamilyOption = {
821
+ value: string;
822
+ label: string;
823
+ fontFamily: string;
824
+ cssImportUrl?: string;
825
+ };
826
+ type FontCssLoadStrategy = "none" | "preload-all" | "on-demand";
827
+ interface FontFamilyConfig extends BaseExtensionConfig {
828
+ options: readonly FontFamilyOption[];
829
+ cssLoadStrategy: FontCssLoadStrategy;
830
+ }
831
+ type FontFamilyCommands = {
832
+ setFontFamily: (fontValue: string) => void;
833
+ clearFontFamily: () => void;
834
+ getCurrentFontFamily: () => Promise<string | null>;
835
+ getFontFamilyOptions: () => readonly FontFamilyOption[];
836
+ };
837
+ type FontFamilyStateQueries = {
838
+ hasCustomFontFamily: () => Promise<boolean>;
839
+ };
840
+ /**
841
+ * FontFamilyExtension provides controlled font-family styling for text selections.
842
+ *
843
+ * Fonts are only applied from a configured whitelist (`config.options`).
844
+ * Optional CSS font loading can be configured via `cssLoadStrategy`:
845
+ * - "none": do not load external CSS
846
+ * - "preload-all": load all option `cssImportUrl` values on register
847
+ * - "on-demand": load a font's `cssImportUrl` when it is first selected
848
+ */
849
+ declare class FontFamilyExtension extends BaseExtension<"fontFamily", FontFamilyConfig, FontFamilyCommands, FontFamilyStateQueries> {
850
+ private readonly loadedFontUrls;
800
851
  constructor();
801
- configure(config: Partial<MarkdownConfig>): this;
802
- /** Allow other extensions to register transformers before or after editor registration */
803
- registerTransformer: (transformer: Transformer) => void;
804
- register(editor: LexicalEditor): () => void;
805
- getCommands(editor: LexicalEditor): MarkdownCommands;
806
- getStateQueries(editor: LexicalEditor): MarkdownStateQueries;
852
+ register(): () => void;
853
+ configure(config: Partial<FontFamilyConfig>): Extension<"fontFamily", FontFamilyConfig, FontFamilyCommands, FontFamilyStateQueries, React$1.ReactNode[]>;
854
+ getCommands(editor: LexicalEditor): FontFamilyCommands;
855
+ getStateQueries(editor: LexicalEditor): FontFamilyStateQueries;
856
+ private applyFontFamily;
857
+ private hasCustomFontFamily;
858
+ private getCurrentFontFamilyValue;
859
+ private findOption;
860
+ private normalizeFontValue;
861
+ private ensureFontCssLoaded;
862
+ }
863
+ declare const fontFamilyExtension: FontFamilyExtension;
864
+
865
+ type FontSizeOption = {
866
+ value: string;
867
+ label: string;
868
+ fontSize: string;
869
+ };
870
+ interface FontSizeConfig extends BaseExtensionConfig {
871
+ options: readonly FontSizeOption[];
872
+ }
873
+ type FontSizeCommands = {
874
+ setFontSize: (fontSizeValue: string) => void;
875
+ clearFontSize: () => void;
876
+ getCurrentFontSize: () => Promise<string | null>;
877
+ getFontSizeOptions: () => readonly FontSizeOption[];
878
+ };
879
+ type FontSizeStateQueries = {
880
+ hasCustomFontSize: () => Promise<boolean>;
881
+ };
882
+ declare class FontSizeExtension extends BaseExtension<"fontSize", FontSizeConfig, FontSizeCommands, FontSizeStateQueries> {
883
+ constructor();
884
+ register(): () => void;
885
+ configure(config: Partial<FontSizeConfig>): Extension<"fontSize", FontSizeConfig, FontSizeCommands, FontSizeStateQueries, React$1.ReactNode[]>;
886
+ getCommands(editor: LexicalEditor): FontSizeCommands;
887
+ getStateQueries(editor: LexicalEditor): FontSizeStateQueries;
888
+ private applyFontSize;
889
+ private hasCustomFontSize;
890
+ private getCurrentFontSizeValue;
891
+ private findOption;
892
+ private normalizeValue;
893
+ }
894
+ declare const fontSizeExtension: FontSizeExtension;
895
+
896
+ type LineHeightOption = {
897
+ value: string;
898
+ label: string;
899
+ lineHeight: string;
900
+ };
901
+ interface LineHeightConfig extends BaseExtensionConfig {
902
+ options: readonly LineHeightOption[];
903
+ defaultLineHeight: string;
807
904
  }
808
- declare const markdownExtension: MarkdownExtension;
905
+ type LineHeightCommands = {
906
+ setLineHeight: (lineHeightValue: string) => void;
907
+ clearLineHeight: () => void;
908
+ getCurrentLineHeight: () => Promise<string | null>;
909
+ getLineHeightOptions: () => readonly LineHeightOption[];
910
+ };
911
+ type LineHeightStateQueries = {
912
+ hasCustomLineHeight: () => Promise<boolean>;
913
+ };
914
+ declare class LineHeightExtension extends BaseExtension<"lineHeight", LineHeightConfig, LineHeightCommands, LineHeightStateQueries> {
915
+ constructor();
916
+ register(): () => void;
917
+ configure(config: Partial<LineHeightConfig>): Extension<"lineHeight", LineHeightConfig, LineHeightCommands, LineHeightStateQueries, React$1.ReactNode[]>;
918
+ getCommands(editor: LexicalEditor): LineHeightCommands;
919
+ getStateQueries(editor: LexicalEditor): LineHeightStateQueries;
920
+ private applyLineHeight;
921
+ private getSelectedTopLevelBlocks;
922
+ private withStyleProperty;
923
+ private hasCustomLineHeight;
924
+ private getCurrentLineHeightValue;
925
+ private getSelectedBlocksLineHeight;
926
+ private findOption;
927
+ private normalizeValue;
928
+ private readStyleProperty;
929
+ }
930
+ declare const lineHeightExtension: LineHeightExtension;
931
+
932
+ type TextColorOption = {
933
+ value: string;
934
+ label: string;
935
+ color: string;
936
+ };
937
+ interface TextColorConfig extends BaseExtensionConfig {
938
+ options: readonly TextColorOption[];
939
+ }
940
+ type TextColorCommands = {
941
+ setTextColor: (colorValue: string) => void;
942
+ clearTextColor: () => void;
943
+ getCurrentTextColor: () => Promise<string | null>;
944
+ getTextColorOptions: () => readonly TextColorOption[];
945
+ };
946
+ type TextColorStateQueries = {
947
+ hasCustomTextColor: () => Promise<boolean>;
948
+ };
949
+ declare class TextColorExtension extends BaseExtension<"textColor", TextColorConfig, TextColorCommands, TextColorStateQueries> {
950
+ constructor();
951
+ register(): () => void;
952
+ getCommands(editor: LexicalEditor): TextColorCommands;
953
+ getStateQueries(editor: LexicalEditor): TextColorStateQueries;
954
+ private applyColor;
955
+ private hasCustomTextColor;
956
+ private getCurrentTextColorValue;
957
+ private findOption;
958
+ private normalizeValue;
959
+ private isValidCssColor;
960
+ }
961
+ declare const textColorExtension: TextColorExtension;
962
+
963
+ type TextHighlightOption = {
964
+ value: string;
965
+ label: string;
966
+ backgroundColor: string;
967
+ };
968
+ interface TextHighlightConfig extends BaseExtensionConfig {
969
+ options: readonly TextHighlightOption[];
970
+ }
971
+ type TextHighlightCommands = {
972
+ setTextHighlight: (highlightValue: string) => void;
973
+ clearTextHighlight: () => void;
974
+ getCurrentTextHighlight: () => Promise<string | null>;
975
+ getTextHighlightOptions: () => readonly TextHighlightOption[];
976
+ };
977
+ type TextHighlightStateQueries = {
978
+ hasTextHighlight: () => Promise<boolean>;
979
+ };
980
+ declare class TextHighlightExtension extends BaseExtension<"textHighlight", TextHighlightConfig, TextHighlightCommands, TextHighlightStateQueries> {
981
+ constructor();
982
+ register(): () => void;
983
+ getCommands(editor: LexicalEditor): TextHighlightCommands;
984
+ getStateQueries(editor: LexicalEditor): TextHighlightStateQueries;
985
+ private applyHighlight;
986
+ private hasTextHighlight;
987
+ private getCurrentTextHighlightValue;
988
+ private findOption;
989
+ private normalizeValue;
990
+ private isValidCssColor;
991
+ }
992
+ declare const textHighlightExtension: TextHighlightExtension;
993
+
994
+ declare class SubscriptExtension extends TextFormatExtension<"subscript"> {
995
+ constructor();
996
+ }
997
+ declare const subscriptExtension: SubscriptExtension;
998
+
999
+ declare class SuperscriptExtension extends TextFormatExtension<"superscript"> {
1000
+ constructor();
1001
+ }
1002
+ declare const superscriptExtension: SuperscriptExtension;
809
1003
 
810
1004
  /**
811
1005
  * Context menu item definition
@@ -813,7 +1007,7 @@ declare const markdownExtension: MarkdownExtension;
813
1007
  type ContextMenuItem = {
814
1008
  label: string;
815
1009
  action: () => void;
816
- icon?: React$1.ComponentType<{
1010
+ icon?: React__default.ComponentType<{
817
1011
  size?: number;
818
1012
  className?: string;
819
1013
  }>;
@@ -851,12 +1045,12 @@ type ContextMenuRenderer = (props: {
851
1045
  };
852
1046
  onClose: () => void;
853
1047
  className: string;
854
- style?: React$1.CSSProperties;
1048
+ style?: React__default.CSSProperties;
855
1049
  itemClassName: string;
856
- itemStyle?: React$1.CSSProperties;
1050
+ itemStyle?: React__default.CSSProperties;
857
1051
  disabledItemClassName: string;
858
- disabledItemStyle?: React$1.CSSProperties;
859
- }) => React$1.ReactElement;
1052
+ disabledItemStyle?: React__default.CSSProperties;
1053
+ }) => React__default.ReactElement;
860
1054
  /**
861
1055
  * Context menu configuration
862
1056
  */
@@ -869,9 +1063,9 @@ interface ContextMenuConfig extends BaseExtensionConfig {
869
1063
  itemDisabled?: string;
870
1064
  };
871
1065
  styles?: {
872
- container?: React$1.CSSProperties;
873
- item?: React$1.CSSProperties;
874
- itemDisabled?: React$1.CSSProperties;
1066
+ container?: React__default.CSSProperties;
1067
+ item?: React__default.CSSProperties;
1068
+ itemDisabled?: React__default.CSSProperties;
875
1069
  };
876
1070
  }
877
1071
  /**
@@ -932,7 +1126,7 @@ declare class ContextMenuManager {
932
1126
  /**
933
1127
  * Context menu extension - provides a clean, registry-based context menu system
934
1128
  */
935
- declare class ContextMenuExtension extends BaseExtension<"contextMenu", ContextMenuConfig, ContextMenuCommands, ContextMenuStateQueries, React$1.ReactElement[]> {
1129
+ declare class ContextMenuExtension extends BaseExtension<"contextMenu", ContextMenuConfig, ContextMenuCommands, ContextMenuStateQueries, React__default.ReactElement[]> {
936
1130
  manager: ContextMenuManager | null;
937
1131
  private pendingListeners;
938
1132
  constructor(config?: ContextMenuConfig);
@@ -940,7 +1134,7 @@ declare class ContextMenuExtension extends BaseExtension<"contextMenu", ContextM
940
1134
  register(editor: LexicalEditor): () => void;
941
1135
  getCommands(editor: LexicalEditor): ContextMenuCommands;
942
1136
  getStateQueries(editor: LexicalEditor): ContextMenuStateQueries;
943
- getPlugins(): React$1.ReactElement[];
1137
+ getPlugins(): React__default.ReactElement[];
944
1138
  subscribe(listener: (menu: any) => void): () => void;
945
1139
  }
946
1140
  declare const contextMenuExtension: ContextMenuExtension;
@@ -960,8 +1154,21 @@ type TableConfig = BaseExtensionConfig & {
960
1154
  contextMenuRenderer?: ContextMenuRenderer;
961
1155
  /** Context menu extension used to register providers */
962
1156
  contextMenuExtension?: typeof contextMenuExtension;
963
- /** Markdown extension used to register transformers */
964
- markdownExtension?: typeof markdownExtension;
1157
+ /** Custom table bubble menu renderer */
1158
+ tableBubbleRenderer?: (props: TableBubbleRenderProps) => ReactNode;
1159
+ };
1160
+ type TableBubbleRenderProps = {
1161
+ headersEnabled: boolean;
1162
+ setHeadersEnabled: (enabled: boolean) => void;
1163
+ actions: {
1164
+ insertRowAbove: () => void;
1165
+ insertRowBelow: () => void;
1166
+ insertColumnLeft: () => void;
1167
+ insertColumnRight: () => void;
1168
+ deleteSelectedColumn: () => void;
1169
+ deleteSelectedRow: () => void;
1170
+ deleteTable: () => void;
1171
+ };
965
1172
  };
966
1173
  /**
967
1174
  * Commands exposed by the Table extension.
@@ -976,6 +1183,10 @@ type TableCommands = {
976
1183
  insertRowBelow: () => void;
977
1184
  insertColumnLeft: () => void;
978
1185
  insertColumnRight: () => void;
1186
+ toggleRowHeader: () => void;
1187
+ toggleColumnHeader: () => void;
1188
+ mergeSelectedCells: () => void;
1189
+ unmergeSelectedCell: () => void;
979
1190
  deleteRow: () => void;
980
1191
  deleteColumn: () => void;
981
1192
  deleteTable: () => void;
@@ -1020,6 +1231,8 @@ type ListCommands = {
1020
1231
  toggleUnorderedList: () => void;
1021
1232
  /** Toggle a numbered list for the current selection */
1022
1233
  toggleOrderedList: () => void;
1234
+ /** Toggle a checklist for the current selection */
1235
+ toggleCheckList: () => void;
1023
1236
  /** Indent the current list item (nest deeper) */
1024
1237
  indentList: () => void;
1025
1238
  /** Outdent the current list item (unnest) */
@@ -1066,6 +1279,7 @@ type ListCommands = {
1066
1279
  declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1067
1280
  unorderedList: () => Promise<boolean>;
1068
1281
  orderedList: () => Promise<boolean>;
1282
+ checkList: () => Promise<boolean>;
1069
1283
  }, ReactNode[]> {
1070
1284
  /**
1071
1285
  * Creates a new list extension instance.
@@ -1084,13 +1298,13 @@ declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1084
1298
  *
1085
1299
  * @returns Array containing ListNode and ListItemNode
1086
1300
  */
1087
- getNodes(): any[];
1301
+ getNodes(): (typeof ListNode | typeof ListItemNode)[];
1088
1302
  /**
1089
1303
  * Returns React plugins needed for list functionality.
1090
1304
  *
1091
1305
  * @returns Array containing the ListPlugin component
1092
1306
  */
1093
- getPlugins(): React$1.ReactNode[];
1307
+ getPlugins(): ReactNode[];
1094
1308
  /**
1095
1309
  * Returns command handlers exposed by this extension.
1096
1310
  *
@@ -1107,6 +1321,7 @@ declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1107
1321
  getStateQueries(editor: LexicalEditor): {
1108
1322
  unorderedList: () => Promise<boolean>;
1109
1323
  orderedList: () => Promise<boolean>;
1324
+ checkList: () => Promise<boolean>;
1110
1325
  };
1111
1326
  }
1112
1327
  /**
@@ -1115,6 +1330,23 @@ declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1115
1330
  */
1116
1331
  declare const listExtension: ListExtension;
1117
1332
 
1333
+ type CodeTokenizer = {
1334
+ defaultLanguage: string;
1335
+ tokenize: (code: string, language?: string) => unknown[];
1336
+ };
1337
+ type CodeHighlightResult = {
1338
+ language?: string | null;
1339
+ };
1340
+ type CodeHighlightProvider = {
1341
+ highlightAuto?: (code: string, languageSubset?: string[]) => CodeHighlightResult | Promise<CodeHighlightResult>;
1342
+ tokenizer?: CodeTokenizer | null;
1343
+ getTokenizer?: () => CodeTokenizer | null | Promise<CodeTokenizer | null>;
1344
+ };
1345
+ type CodeHighlightProviderConfig = {
1346
+ provider?: CodeHighlightProvider | null;
1347
+ loadProvider?: () => Promise<CodeHighlightProvider | null>;
1348
+ };
1349
+
1118
1350
  /**
1119
1351
  * Commands exposed by the CodeExtension for toggling code blocks
1120
1352
  */
@@ -1129,6 +1361,10 @@ type CodeStateQueries = {
1129
1361
  /** Check whether the current selection is within a code block */
1130
1362
  isInCodeBlock: () => Promise<boolean>;
1131
1363
  };
1364
+ type CodeExtensionConfig = BaseExtensionConfig & CodeHighlightProviderConfig & {
1365
+ syntaxHighlighting?: "auto" | "disabled";
1366
+ tokenizer?: CodeTokenizer | null;
1367
+ };
1132
1368
  /**
1133
1369
  * CodeExtension - Adds code block support for the Lexical editor
1134
1370
  *
@@ -1151,7 +1387,8 @@ type CodeStateQueries = {
1151
1387
  * commands.toggleCodeBlock(); // Toggle code block on or off
1152
1388
  * ```
1153
1389
  */
1154
- declare class CodeExtension extends BaseExtension<"code", {}, CodeCommands, CodeStateQueries, ReactNode[]> {
1390
+ declare class CodeExtension extends BaseExtension<"code", CodeExtensionConfig, CodeCommands, CodeStateQueries, ReactNode[]> {
1391
+ private codeHighlightProviderPromise;
1155
1392
  constructor();
1156
1393
  /**
1157
1394
  * Register the extension with Lexical
@@ -1163,7 +1400,7 @@ declare class CodeExtension extends BaseExtension<"code", {}, CodeCommands, Code
1163
1400
  * Get Lexical nodes required by this extension
1164
1401
  * @returns Array of node classes
1165
1402
  */
1166
- getNodes(): (typeof CodeNode)[];
1403
+ getNodes(): (typeof CodeNode | typeof CodeHighlightNode)[];
1167
1404
  /**
1168
1405
  * Get commands exposed by this extension
1169
1406
  * @param editor - Lexical editor instance
@@ -1175,6 +1412,8 @@ declare class CodeExtension extends BaseExtension<"code", {}, CodeCommands, Code
1175
1412
  * @param editor - Lexical editor instance
1176
1413
  */
1177
1414
  private toggleCodeBlock;
1415
+ private resolveConfiguredTokenizer;
1416
+ private loadCodeHighlightProvider;
1178
1417
  /**
1179
1418
  * Get state queries exposed by this extension
1180
1419
  * @param editor - Lexical editor instance
@@ -1208,6 +1447,48 @@ declare class CodeExtension extends BaseExtension<"code", {}, CodeCommands, Code
1208
1447
  }
1209
1448
  declare const codeExtension: CodeExtension;
1210
1449
 
1450
+ type CodeIntelligenceCommands = {
1451
+ setCodeLanguage: (language: string) => void;
1452
+ autoDetectCodeLanguage: () => Promise<string | null>;
1453
+ getCurrentCodeLanguage: () => Promise<string | null>;
1454
+ getCodeLanguageOptions: () => string[];
1455
+ copySelectedCodeBlock: () => Promise<boolean>;
1456
+ };
1457
+ type CodeLanguageOptionsMode = "append" | "replace";
1458
+ type CodeLanguageOptionsConfig = {
1459
+ mode?: CodeLanguageOptionsMode;
1460
+ values: readonly string[];
1461
+ };
1462
+ type CodeIntelligenceConfig = CodeHighlightProviderConfig & {
1463
+ maxAutoDetectLength?: number;
1464
+ isCopyAllowed?: boolean;
1465
+ languageOptions?: readonly string[] | CodeLanguageOptionsConfig;
1466
+ };
1467
+ declare class CodeIntelligenceExtension extends BaseExtension<"codeIntelligence", CodeIntelligenceConfig, CodeIntelligenceCommands, Record<string, never>, ReactNode[]> {
1468
+ private languageOptions;
1469
+ constructor();
1470
+ register(editor: LexicalEditor): () => void;
1471
+ getPlugins(): ReactNode[];
1472
+ getCommands(editor: LexicalEditor): CodeIntelligenceCommands;
1473
+ isCopyAllowed(): boolean;
1474
+ getLanguageOptionsSnapshot(): string[];
1475
+ getCodeBlocksSnapshot(editor: LexicalEditor): CodeBlockSnapshot[];
1476
+ setCodeBlockLanguage(editor: LexicalEditor, nodeKey: string, selectedLanguage: string): void;
1477
+ getCodeBlockText(editor: LexicalEditor, nodeKey: string): string;
1478
+ private getThemeForLanguage;
1479
+ private ensureCodeBlockThemes;
1480
+ private getSelectionCodeNodes;
1481
+ private getNearestCodeNode;
1482
+ private getLanguageOptions;
1483
+ private getPrimaryCodeBlockText;
1484
+ }
1485
+ type CodeBlockSnapshot = {
1486
+ key: string;
1487
+ language: string;
1488
+ text: string;
1489
+ };
1490
+ declare const codeIntelligenceExtension: CodeIntelligenceExtension;
1491
+
1211
1492
  /**
1212
1493
  * CodeFormatExtension - Provides inline code text formatting functionality
1213
1494
  *
@@ -1244,6 +1525,8 @@ type BlockFormatCommands = {
1244
1525
  toggleHeading: (tag: HeadingTagType) => void;
1245
1526
  /** Switch to quote format */
1246
1527
  toggleQuote: () => void;
1528
+ /** Set text alignment for selected blocks */
1529
+ setTextAlignment: (alignment: "left" | "center" | "right" | "justify") => void;
1247
1530
  /** Return the current block type as a string ('p', 'h1', 'h2', etc.) */
1248
1531
  getCurrentBlockType: () => BlockFormat;
1249
1532
  };
@@ -1267,6 +1550,14 @@ type BlockFormatStateQueries = {
1267
1550
  isH6: () => Promise<boolean>;
1268
1551
  /** Check whether the selection is in a quote block */
1269
1552
  isQuote: () => Promise<boolean>;
1553
+ /** Check whether selected blocks are left-aligned */
1554
+ isTextAlignedLeft: () => Promise<boolean>;
1555
+ /** Check whether selected blocks are center-aligned */
1556
+ isTextAlignedCenter: () => Promise<boolean>;
1557
+ /** Check whether selected blocks are right-aligned */
1558
+ isTextAlignedRight: () => Promise<boolean>;
1559
+ /** Check whether selected blocks are justified */
1560
+ isTextAlignedJustify: () => Promise<boolean>;
1270
1561
  };
1271
1562
  /**
1272
1563
  * BlockFormatExtension - Provides block-level formatting
@@ -1292,8 +1583,7 @@ type BlockFormatStateQueries = {
1292
1583
  * commands.toggleQuote(); // Convert selection to a quote block
1293
1584
  * ```
1294
1585
  */
1295
- declare class BlockFormatExtension extends BaseExtension<"blockFormat", {}, // No extra config needed
1296
- BlockFormatCommands, BlockFormatStateQueries> {
1586
+ declare class BlockFormatExtension extends BaseExtension<"blockFormat", Record<string, never>, BlockFormatCommands, BlockFormatStateQueries> {
1297
1587
  constructor();
1298
1588
  /**
1299
1589
  * Register the extension with Lexical
@@ -1312,6 +1602,12 @@ BlockFormatCommands, BlockFormatStateQueries> {
1312
1602
  * @returns Object containing available commands
1313
1603
  */
1314
1604
  getCommands(editor: LexicalEditor): BlockFormatCommands;
1605
+ /**
1606
+ * Set element alignment for selected blocks
1607
+ * @param editor - Lexical editor instance
1608
+ * @param alignment - Target text alignment
1609
+ */
1610
+ private setTextAlignment;
1315
1611
  /**
1316
1612
  * Toggle the block format for the current selection
1317
1613
  * @param editor - Lexical editor instance
@@ -1324,6 +1620,14 @@ BlockFormatCommands, BlockFormatStateQueries> {
1324
1620
  * @returns Object containing available state queries
1325
1621
  */
1326
1622
  getStateQueries(editor: LexicalEditor): BlockFormatStateQueries;
1623
+ /**
1624
+ * Check whether all selected blocks match the specified alignment
1625
+ * @param alignment - Alignment to check
1626
+ * @param editor - Lexical editor instance
1627
+ * @returns True if all selected blocks match the alignment
1628
+ */
1629
+ private isAlignment;
1630
+ private normalizeAlignment;
1327
1631
  /**
1328
1632
  * Get the nearest block node starting from the given node
1329
1633
  * @param node - Starting node
@@ -1453,12 +1757,8 @@ declare const historyExtension: HistoryExtension;
1453
1757
  interface DraggableConfig extends BaseExtensionConfig {
1454
1758
  /** Portal anchor element (default: document.body) */
1455
1759
  anchorElem?: HTMLElement;
1456
- /** Show move buttons */
1457
- showMoveButtons?: boolean;
1458
- /** Show the up button */
1459
- showUpButton?: boolean;
1460
- /** Show the down button */
1461
- showDownButton?: boolean;
1760
+ /** Show the add button near the drag handle */
1761
+ showAddButton?: boolean;
1462
1762
  /** Button stack position relative to blocks */
1463
1763
  buttonStackPosition?: "left" | "right";
1464
1764
  /** Allow drag via text selection (default: true) */
@@ -1473,25 +1773,23 @@ interface DraggableConfig extends BaseExtensionConfig {
1473
1773
  handleActive?: string;
1474
1774
  blockDragging?: string;
1475
1775
  dropIndicator?: string;
1476
- upButton?: string;
1477
- downButton?: string;
1776
+ addButton?: string;
1478
1777
  buttonStack?: string;
1479
1778
  };
1480
1779
  /** Custom styles for UI elements */
1481
1780
  styles?: {
1482
- handle?: React$1.CSSProperties;
1483
- handleActive?: React$1.CSSProperties;
1484
- blockDragging?: React$1.CSSProperties;
1485
- dropIndicator?: React$1.CSSProperties;
1486
- upButton?: React$1.CSSProperties;
1487
- downButton?: React$1.CSSProperties;
1488
- buttonStack?: React$1.CSSProperties;
1781
+ handle?: React__default.CSSProperties;
1782
+ handleActive?: React__default.CSSProperties;
1783
+ blockDragging?: React__default.CSSProperties;
1784
+ dropIndicator?: React__default.CSSProperties;
1785
+ addButton?: React__default.CSSProperties;
1786
+ buttonStack?: React__default.CSSProperties;
1489
1787
  };
1490
1788
  /** Custom handle renderer for full headless control */
1491
1789
  handleRenderer?: (props: {
1492
1790
  rect: DOMRect;
1493
1791
  isDragging: boolean;
1494
- onDragStart: (e: React$1.DragEvent) => void;
1792
+ onDragStart: (e: React__default.DragEvent) => void;
1495
1793
  className: string;
1496
1794
  }) => ReactNode;
1497
1795
  /** Custom up/down button renderer */
@@ -1545,89 +1843,6 @@ declare class DraggableBlockExtension extends BaseExtension<"draggableBlock", Dr
1545
1843
  */
1546
1844
  declare const draggableBlockExtension: DraggableBlockExtension;
1547
1845
 
1548
- /**
1549
- * Commands exposed by the HTML extension.
1550
- */
1551
- type HTMLCommands = {
1552
- /** Export current editor content as an HTML string */
1553
- exportToHTML: () => string;
1554
- /** Import HTML into the editor, replacing current content */
1555
- importFromHTML: (html: string, opts?: {
1556
- preventFocus?: boolean;
1557
- }) => Promise<void>;
1558
- };
1559
- /**
1560
- * State queries exposed by the HTML extension.
1561
- */
1562
- type HTMLStateQueries = {
1563
- /** Check whether HTML export is available (always true) */
1564
- canExportHTML: () => Promise<boolean>;
1565
- };
1566
- /**
1567
- * HTML extension for import/export of HTML content.
1568
- * Converts between Lexical editor state and HTML strings.
1569
- *
1570
- * @example
1571
- * ```tsx
1572
- * const extensions = [htmlExtension] as const;
1573
- * const { Provider, useEditor } = createEditorSystem<typeof extensions>();
1574
- *
1575
- * function MyEditor() {
1576
- * const { commands } = useEditor();
1577
- *
1578
- * const handleExport = () => {
1579
- * const html = commands.exportToHTML();
1580
- * console.log('Exported HTML:', html);
1581
- * };
1582
- *
1583
- * const handleImport = () => {
1584
- * const html = '<p>Hello <strong>world</strong>!</p>';
1585
- * commands.importFromHTML(html);
1586
- * };
1587
- *
1588
- * return (
1589
- * <div>
1590
- * <button onClick={handleExport}>Export HTML</button>
1591
- * <button onClick={handleImport}>Import HTML</button>
1592
- * </div>
1593
- * );
1594
- * }
1595
- * ```
1596
- */
1597
- declare class HTMLExtension extends BaseExtension<"html", {}, HTMLCommands, HTMLStateQueries, ReactNode[]> {
1598
- /**
1599
- * Creates a new HTML extension.
1600
- */
1601
- constructor();
1602
- /**
1603
- * Registers the extension with the Lexical editor.
1604
- * No special registration needed for HTML functionality.
1605
- *
1606
- * @param editor - Lexical editor instance
1607
- * @returns Cleanup function
1608
- */
1609
- register(editor: LexicalEditor): () => void;
1610
- /**
1611
- * Returns commands exposed by this extension.
1612
- *
1613
- * @param editor - Lexical editor instance
1614
- * @returns Object containing HTML import/export commands
1615
- */
1616
- getCommands(editor: LexicalEditor): HTMLCommands;
1617
- /**
1618
- * Returns state query functions for this extension.
1619
- *
1620
- * @param editor - Lexical editor instance
1621
- * @returns Object containing state query functions
1622
- */
1623
- getStateQueries(editor: LexicalEditor): HTMLStateQueries;
1624
- }
1625
- /**
1626
- * Preconfigured HTML extension instance.
1627
- * Ready for use in extension arrays.
1628
- */
1629
- declare const htmlExtension: HTMLExtension;
1630
-
1631
1846
  /**
1632
1847
  * Supported alignment options for media items
1633
1848
  */
@@ -1663,6 +1878,8 @@ interface ImageComponentProps extends ImagePayload {
1663
1878
  nodeKey?: string;
1664
1879
  /** Whether the image is resizable */
1665
1880
  resizable?: boolean;
1881
+ /** Whether resize keeps aspect ratio by default */
1882
+ scaleByRatio?: boolean;
1666
1883
  /** Whether the image is uploading */
1667
1884
  uploading?: boolean;
1668
1885
  }
@@ -1707,6 +1924,8 @@ interface ImageExtensionConfig extends BaseExtensionConfig {
1707
1924
  customRenderer?: ComponentType<ImageComponentProps>;
1708
1925
  /** Enable image resizing (default: true) */
1709
1926
  resizable?: boolean;
1927
+ /** Keep aspect ratio while resizing by default (Shift toggles) */
1928
+ scaleByRatio?: boolean;
1710
1929
  /** Paste behavior configuration */
1711
1930
  pasteListener?: {
1712
1931
  /** Insert a new image on paste when none is selected */
@@ -1729,6 +1948,8 @@ type ImageCommands = {
1729
1948
  setImageAlignment: (alignment: Alignment) => void;
1730
1949
  /** Set caption for the selected image */
1731
1950
  setImageCaption: (caption: string) => void;
1951
+ /** Read caption for the selected image */
1952
+ getImageCaption: () => Promise<string>;
1732
1953
  /** Set the CSS class name on the selected image */
1733
1954
  setImageClassName: (className: string) => void;
1734
1955
  /** Set inline styles on the selected image */
@@ -1750,51 +1971,11 @@ type ImageStateQueries = {
1750
1971
  isImageAlignedNone: () => Promise<boolean>;
1751
1972
  };
1752
1973
 
1753
- declare class ImageNode extends DecoratorNode<ReactNode> {
1754
- /** Source URL for the image */
1755
- __src: string;
1756
- /** Accessible alt text */
1757
- __alt: string;
1758
- /** Optional caption */
1759
- __caption?: string;
1760
- /** Alignment */
1761
- __alignment: Alignment;
1762
- /** CSS class name */
1763
- __className?: string;
1764
- /** Inline style overrides */
1765
- __style?: CSSProperties;
1766
- /** Width in pixels */
1767
- __width?: number;
1768
- /** Height in pixels */
1769
- __height?: number;
1770
- /** Whether the image is uploading */
1771
- __uploading?: boolean;
1772
- static getType(): string;
1773
- static clone(node: ImageNode): ImageNode;
1774
- static importDOM(): DOMConversionMap | null;
1775
- static importJSON(serializedNode: SerializedImageNode): ImageNode;
1776
- constructor(src?: string, alt?: string, caption?: string, alignment?: Alignment, className?: string, style?: CSSProperties, width?: number, height?: number, uploading?: boolean, key?: NodeKey);
1777
- createDOM(config: EditorConfig$1): HTMLElement;
1778
- updateDOM(prevNode: ImageNode, dom: HTMLElement, config: EditorConfig$1): boolean;
1779
- exportDOM(): DOMExportOutput;
1780
- exportJSON(): SerializedImageNode;
1781
- setSrc(src: string): void;
1782
- setAlt(alt: string): void;
1783
- setCaption(caption?: string): void;
1784
- setAlignment(alignment: Alignment): void;
1785
- setClassName(className?: string): void;
1786
- setStyle(style?: CSSProperties): void;
1787
- getWidth(): number | undefined;
1788
- getHeight(): number | undefined;
1789
- setWidthAndHeight(width: number, height: number): void;
1790
- isInline(): boolean;
1791
- isBlockElement(): boolean;
1792
- canBeEmpty(): boolean;
1793
- decorate(): ReactNode;
1794
- }
1795
1974
  declare class ImageExtension extends BaseExtension<"image", ImageExtensionConfig, ImageCommands, ImageStateQueries, ReactNode[]> {
1796
1975
  /** Track recent image sources to avoid duplicate inserts */
1797
1976
  private recentImages;
1977
+ /** Last selected image key for toolbar edits while focus moves to external inputs */
1978
+ private lastSelectedImageNodeKey;
1798
1979
  constructor();
1799
1980
  configure(config: Partial<ImageExtensionConfig>): this;
1800
1981
  register(editor: LexicalEditor): () => void;
@@ -1804,183 +1985,72 @@ declare class ImageExtension extends BaseExtension<"image", ImageExtensionConfig
1804
1985
  }
1805
1986
  declare const imageExtension: ImageExtension;
1806
1987
 
1807
- /**
1808
- * Payload for HTML embed content
1809
- */
1810
- type HTMLEmbedPayload = {
1811
- /** HTML content to embed */
1812
- html: string;
1813
- /** Whether to show preview or edit mode */
1814
- preview: boolean;
1988
+ type EmbedAlignment = "left" | "center" | "right";
1989
+ interface IframeEmbedConfig extends BaseExtensionConfig {
1990
+ defaultWidth?: number;
1991
+ defaultHeight?: number;
1992
+ defaultAlignment?: EmbedAlignment;
1993
+ }
1994
+ type IframeEmbedCommands = {
1995
+ insertIframeEmbed: (inputUrl: string, width?: number, height?: number, title?: string) => void;
1996
+ setIframeEmbedAlignment: (alignment: EmbedAlignment) => void;
1997
+ resizeIframeEmbed: (width: number, height: number) => void;
1998
+ setIframeEmbedCaption: (caption: string) => void;
1999
+ getIframeEmbedCaption: () => Promise<string>;
2000
+ updateIframeEmbedUrl: (inputUrl: string) => boolean;
2001
+ getIframeEmbedUrl: () => Promise<string>;
1815
2002
  };
1816
- /**
1817
- * HTMLEmbedExtension configuration
1818
- */
1819
- interface HTMLEmbedConfig extends BaseExtensionConfig {
1820
- /** Default HTML for new embeds */
1821
- defaultHtml?: string;
1822
- /** Default to preview mode */
1823
- defaultPreview?: boolean;
1824
- /** Theme class names */
1825
- theme?: {
1826
- container?: string;
1827
- preview?: string;
1828
- editor?: string;
1829
- textarea?: string;
1830
- toggle?: string;
1831
- content?: string;
1832
- };
1833
- /** Custom styles for UI elements */
1834
- styles?: {
1835
- container?: React$1.CSSProperties;
1836
- preview?: React$1.CSSProperties;
1837
- editor?: React$1.CSSProperties;
1838
- textarea?: React$1.CSSProperties;
1839
- toggle?: React$1.CSSProperties;
1840
- content?: React$1.CSSProperties;
1841
- };
1842
- /** Custom container renderer for full headless control */
1843
- containerRenderer?: (props: {
1844
- children: ReactNode;
1845
- className: string;
1846
- style?: React$1.CSSProperties;
1847
- }) => ReactNode;
1848
- /** Custom preview renderer component */
1849
- previewRenderer?: (props: {
1850
- html: string;
1851
- onToggleEdit: () => void;
1852
- className: string;
1853
- style?: React$1.CSSProperties;
1854
- toggleClassName: string;
1855
- toggleStyle?: React$1.CSSProperties;
1856
- }) => ReactNode;
1857
- /** Custom editor renderer component */
1858
- editorRenderer?: (props: {
1859
- html: string;
1860
- onTogglePreview: () => void;
1861
- onSave: () => void;
1862
- className: string;
1863
- style?: React$1.CSSProperties;
1864
- textareaClassName: string;
1865
- textareaStyle?: React$1.CSSProperties;
1866
- toggleClassName: string;
1867
- toggleStyle?: React$1.CSSProperties;
1868
- }) => ReactNode;
1869
- /** Custom toggle button renderer component */
1870
- toggleRenderer?: (props: {
1871
- isPreview: boolean;
1872
- onClick: () => void;
1873
- className: string;
1874
- style?: React$1.CSSProperties;
1875
- }) => ReactNode;
1876
- /** Markdown extension instance used to register transformers */
1877
- markdownExtension?: typeof markdownExtension;
2003
+ type IframeEmbedQueries = {
2004
+ isIframeEmbedSelected: () => Promise<boolean>;
2005
+ isIframeEmbedAlignedLeft: () => Promise<boolean>;
2006
+ isIframeEmbedAlignedCenter: () => Promise<boolean>;
2007
+ isIframeEmbedAlignedRight: () => Promise<boolean>;
2008
+ };
2009
+ declare class IframeEmbedExtension extends BaseExtension<"iframeEmbed", IframeEmbedConfig, IframeEmbedCommands, IframeEmbedQueries, ReactNode[]> {
2010
+ constructor(config?: Partial<IframeEmbedConfig>);
2011
+ register(editor: LexicalEditor): () => void;
2012
+ getNodes(): any[];
2013
+ getPlugins(): ReactNode[];
2014
+ getCommands(editor: LexicalEditor): IframeEmbedCommands;
2015
+ getStateQueries(editor: LexicalEditor): IframeEmbedQueries;
1878
2016
  }
1879
- /**
1880
- * Commands exposed by the HTMLEmbedExtension
1881
- */
1882
- type HTMLEmbedCommands = {
1883
- /** Insert an HTML embed with optional initial HTML */
1884
- insertHTMLEmbed: (html?: string) => void;
1885
- /** Toggle between preview and edit modes */
1886
- toggleHTMLPreview: () => void;
2017
+ declare const iframeEmbedExtension: IframeEmbedExtension;
2018
+
2019
+ interface YouTubeEmbedConfig extends BaseExtensionConfig {
2020
+ defaultWidth?: number;
2021
+ defaultHeight?: number;
2022
+ defaultAlignment?: EmbedAlignment;
2023
+ allowFullscreen?: boolean;
2024
+ autoplay?: boolean;
2025
+ controls?: boolean;
2026
+ nocookie?: boolean;
2027
+ rel?: number;
2028
+ }
2029
+ type YouTubeEmbedCommands = {
2030
+ insertYouTubeEmbed: (inputUrl: string, width?: number, height?: number, start?: number) => void;
2031
+ setYouTubeEmbedAlignment: (alignment: EmbedAlignment) => void;
2032
+ resizeYouTubeEmbed: (width: number, height: number) => void;
2033
+ setYouTubeEmbedCaption: (caption: string) => void;
2034
+ getYouTubeEmbedCaption: () => Promise<string>;
2035
+ updateYouTubeEmbedUrl: (inputUrl: string) => boolean;
2036
+ getYouTubeEmbedUrl: () => Promise<string>;
1887
2037
  };
1888
- /**
1889
- * State queries exposed by the HTMLEmbedExtension
1890
- */
1891
- type HTMLEmbedQueries = {
1892
- /** Check whether an HTML embed is selected */
1893
- isHTMLEmbedSelected: () => Promise<boolean>;
1894
- /** Check whether HTML preview mode is active */
1895
- isHTMLPreviewMode: () => Promise<boolean>;
2038
+ type YouTubeEmbedQueries = {
2039
+ isYouTubeEmbedSelected: () => Promise<boolean>;
2040
+ isYouTubeEmbedAlignedLeft: () => Promise<boolean>;
2041
+ isYouTubeEmbedAlignedCenter: () => Promise<boolean>;
2042
+ isYouTubeEmbedAlignedRight: () => Promise<boolean>;
1896
2043
  };
1897
- /**
1898
- * Serialized representation of an HTMLEmbedNode
1899
- */
1900
- type SerializedHTMLEmbedNode = Spread<{
1901
- /** HTML content */
1902
- html: string;
1903
- /** Preview mode state */
1904
- preview: boolean;
1905
- /** Node type ID */
1906
- type: "html-embed";
1907
- /** Version for migrations */
1908
- version: 1;
1909
- }, SerializedLexicalNode>;
1910
- /**
1911
- * HTMLEmbedNode - A Lexical DecoratorNode for custom HTML embeds
1912
- *
1913
- * Allows users to embed custom HTML content in the editor.
1914
- * Supports preview mode (rendered HTML) and edit mode
1915
- * (editable HTML source).
1916
- *
1917
- * @example
1918
- * ```typescript
1919
- * const node = new HTMLEmbedNode({
1920
- * html: '<div>Hello World</div>',
1921
- * preview: true
1922
- * });
1923
- * ```
1924
- */
1925
- declare class HTMLEmbedNode extends DecoratorNode<ReactNode> {
1926
- __payload: HTMLEmbedPayload;
1927
- /**
1928
- * Get the node type identifier
1929
- * @returns Node type string
1930
- */
1931
- static getType(): string;
1932
- /**
1933
- * Clone the node
1934
- * @param node - Node to clone
1935
- * @returns New cloned node instance
1936
- */
1937
- static clone(node: HTMLEmbedNode): HTMLEmbedNode;
1938
- /**
1939
- * Constructor for HTMLEmbedNode
1940
- * @param payload - HTML embed payload
1941
- * @param key - Optional node key
1942
- */
1943
- constructor(payload: HTMLEmbedPayload, key?: NodeKey);
1944
- /**
1945
- * Create the DOM element for this node
1946
- * @returns DOM element
1947
- */
1948
- createDOM(): HTMLElement;
1949
- /**
1950
- * Update the DOM element (unused with React rendering)
1951
- * @returns Always false to let React handle updates
1952
- */
1953
- updateDOM(): boolean;
1954
- /**
1955
- * Import node from JSON serialization
1956
- * @param serialized - Serialized node data
1957
- * @returns New HTMLEmbedNode instance
1958
- */
1959
- static importJSON(serialized: SerializedHTMLEmbedNode): HTMLEmbedNode;
1960
- /**
1961
- * Export node to JSON serialization
1962
- * @returns Serialized node data
1963
- */
1964
- exportJSON(): SerializedHTMLEmbedNode;
1965
- static importDOM(): DOMConversionMap | null;
1966
- exportDOM(): {
1967
- element: HTMLElement;
1968
- };
1969
- getPayload(): HTMLEmbedPayload;
1970
- setPayload(payload: Partial<HTMLEmbedPayload>): void;
1971
- decorate(editor: LexicalEditor): ReactNode;
1972
- isInline(): false;
1973
- isKeyboardSelectable(): boolean;
1974
- }
1975
- declare class HTMLEmbedExtension extends BaseExtension<"htmlEmbed", HTMLEmbedConfig, HTMLEmbedCommands, HTMLEmbedQueries, ReactNode[]> {
1976
- constructor(config?: Partial<HTMLEmbedConfig>);
2044
+ declare class YouTubeEmbedExtension extends BaseExtension<"youtubeEmbed", YouTubeEmbedConfig, YouTubeEmbedCommands, YouTubeEmbedQueries, ReactNode[]> {
2045
+ private lastSelectedYouTubeNodeKey;
2046
+ constructor(config?: Partial<YouTubeEmbedConfig>);
1977
2047
  register(editor: LexicalEditor): () => void;
1978
2048
  getNodes(): any[];
1979
2049
  getPlugins(): ReactNode[];
1980
- getCommands(editor: LexicalEditor): HTMLEmbedCommands;
1981
- getStateQueries(editor: LexicalEditor): HTMLEmbedQueries;
2050
+ getCommands(editor: LexicalEditor): YouTubeEmbedCommands;
2051
+ getStateQueries(editor: LexicalEditor): YouTubeEmbedQueries;
1982
2052
  }
1983
- declare const htmlEmbedExtension: HTMLEmbedExtension;
2053
+ declare const youTubeEmbedExtension: YouTubeEmbedExtension;
1984
2054
 
1985
2055
  type CustomPayload = Record<string, any>;
1986
2056
  interface CustomNodeConfig<CustomCommands, CustomStateQueries> {
@@ -2042,15 +2112,15 @@ interface CustomNodeConfig<CustomCommands, CustomStateQueries> {
2042
2112
  * });
2043
2113
  * ```
2044
2114
  */
2045
- declare function createCustomNodeExtension<Name extends string, Commands extends Record<string, any> = {}, StateQueries extends Record<string, () => Promise<boolean>> = {}>(userConfig: CustomNodeConfig<Commands, StateQueries>): {
2115
+ declare function createCustomNodeExtension<Name extends string, Commands extends Record<string, any> = Record<string, never>, StateQueries extends Record<string, () => Promise<boolean>> = Record<string, never>>(userConfig: CustomNodeConfig<Commands, StateQueries>): {
2046
2116
  extension: BaseExtension<Name, BaseExtensionConfig, Commands, StateQueries>;
2047
2117
  $createCustomNode: (payload?: CustomPayload) => ElementNode | DecoratorNode<ReactNode>;
2048
2118
  jsxToDOM: (jsxElement: React.ReactElement) => HTMLElement;
2049
2119
  };
2050
2120
 
2051
2121
  interface BaseRichTextProps {
2052
- contentEditable?: React$1.ReactElement;
2053
- placeholder?: React$1.ReactElement | string;
2122
+ contentEditable?: React__default.ReactElement;
2123
+ placeholder?: React__default.ReactElement | string;
2054
2124
  className?: string;
2055
2125
  classNames?: {
2056
2126
  container?: string;
@@ -2058,36 +2128,153 @@ interface BaseRichTextProps {
2058
2128
  placeholder?: string;
2059
2129
  };
2060
2130
  styles?: {
2061
- container?: React$1.CSSProperties;
2062
- contentEditable?: React$1.CSSProperties;
2063
- placeholder?: React$1.CSSProperties;
2131
+ container?: React__default.CSSProperties;
2132
+ contentEditable?: React__default.CSSProperties;
2133
+ placeholder?: React__default.CSSProperties;
2064
2134
  };
2065
- errorBoundary?: React$1.ComponentType<{
2066
- children: React$1.JSX.Element;
2135
+ errorBoundary?: React__default.ComponentType<{
2136
+ children: React__default.JSX.Element;
2067
2137
  onError: (error: Error) => void;
2068
2138
  }>;
2069
2139
  }
2070
- interface SharedRichTextProps extends BaseRichTextProps {
2071
- }
2072
- interface RichTextConfig extends BaseExtensionConfig, BaseRichTextProps {
2073
- }
2074
2140
  interface RichTextConfig extends BaseExtensionConfig, BaseRichTextProps {
2075
2141
  }
2142
+ type SharedRichTextProps = BaseRichTextProps;
2076
2143
  /**
2077
2144
  * RichTextExtension - Provides core rich text editing functionality
2078
2145
  * Extends BaseExtension to stay consistent with other extensions
2079
2146
  */
2080
- declare class RichTextExtension extends BaseExtension<"richText", RichTextConfig, {}, // No commands
2081
- {}, // No state queries
2082
- ReactNode[]> {
2147
+ declare class RichTextExtension extends BaseExtension<"richText", RichTextConfig, Record<string, never>, Record<string, never>, ReactNode[]> {
2083
2148
  constructor(config?: RichTextConfig);
2084
2149
  register(editor: LexicalEditor): () => void;
2085
2150
  getPlugins(): ReactNode[];
2086
2151
  }
2087
2152
  declare const richTextExtension: RichTextExtension;
2088
- interface RichTextComponentProps extends SharedRichTextProps {
2153
+ type RichTextComponentProps = SharedRichTextProps;
2154
+ declare const RichText: React__default.FC<RichTextComponentProps>;
2155
+
2156
+ /**
2157
+ * TabIndentExtension - Adds universal Tab/Shift+Tab indentation support
2158
+ *
2159
+ * Enables Tab key to indent and Shift+Tab to outdent content throughout
2160
+ * the editor, not just in code blocks. This provides a consistent
2161
+ * indentation experience across all content types.
2162
+ *
2163
+ * @example
2164
+ * ```tsx
2165
+ * import { tabIndentExtension } from '@lyfie/luthor-headless';
2166
+ *
2167
+ * const extensions = [tabIndentExtension];
2168
+ * ```
2169
+ */
2170
+ declare class TabIndentExtension extends BaseExtension<"tabIndent", Record<string, never>, Record<string, never>, Record<string, never>, ReactNode[]> {
2171
+ constructor();
2172
+ /**
2173
+ * Register the extension with Lexical
2174
+ * @param editor - Lexical editor instance
2175
+ * @returns Cleanup function
2176
+ */
2177
+ register(editor: LexicalEditor): () => void;
2178
+ /**
2179
+ * Check if a node is within a code block
2180
+ * @param node - Node to check
2181
+ * @returns True if node is in a code block
2182
+ */
2183
+ private isInCodeBlock;
2184
+ /**
2185
+ * Check if a node is within a checklist list item.
2186
+ */
2187
+ private isInCheckList;
2089
2188
  }
2090
- declare const RichText: React$1.FC<RichTextComponentProps>;
2189
+ declare const tabIndentExtension: TabIndentExtension;
2190
+
2191
+ type EmojiCatalogItem = {
2192
+ emoji: string;
2193
+ label: string;
2194
+ shortcodes: string[];
2195
+ keywords?: string[];
2196
+ };
2197
+ type EmojiCatalogAdapter = {
2198
+ search: (query: string, options?: {
2199
+ limit?: number;
2200
+ }) => EmojiCatalogItem[];
2201
+ resolveShortcode: (shortcode: string) => EmojiCatalogItem | null;
2202
+ getAll: () => EmojiCatalogItem[];
2203
+ };
2204
+ type EmojiSuggestionState = {
2205
+ isOpen: boolean;
2206
+ query: string;
2207
+ position: {
2208
+ x: number;
2209
+ y: number;
2210
+ } | null;
2211
+ suggestions: EmojiCatalogItem[];
2212
+ };
2213
+ interface EmojiConfig extends BaseExtensionConfig {
2214
+ trigger?: string;
2215
+ maxSuggestions?: number;
2216
+ maxQueryLength?: number;
2217
+ autoReplaceSymbols?: boolean;
2218
+ symbolReplacements?: Record<string, string>;
2219
+ catalog?: EmojiCatalogItem[];
2220
+ catalogAdapter?: EmojiCatalogAdapter;
2221
+ autoDetectExternalCatalog?: boolean;
2222
+ offset?: {
2223
+ x: number;
2224
+ y: number;
2225
+ };
2226
+ }
2227
+ type EmojiCommands = {
2228
+ insertEmoji: (emoji: string) => void;
2229
+ executeEmojiSuggestion: (emoji: string) => boolean;
2230
+ closeEmojiSuggestions: () => void;
2231
+ getEmojiSuggestions: (query?: string) => EmojiCatalogItem[];
2232
+ getEmojiCatalog: () => EmojiCatalogItem[];
2233
+ resolveEmojiShortcode: (shortcode: string) => EmojiCatalogItem | null;
2234
+ setEmojiCatalog: (catalog: EmojiCatalogItem[]) => void;
2235
+ setEmojiCatalogAdapter: (adapter: EmojiCatalogAdapter) => void;
2236
+ getEmojiCatalogAdapter: () => EmojiCatalogAdapter;
2237
+ };
2238
+ type EmojiStateQueries = {
2239
+ isEmojiSuggestionOpen: () => Promise<boolean>;
2240
+ };
2241
+ declare const LIGHTWEIGHT_EMOJI_CATALOG: EmojiCatalogItem[];
2242
+ declare class EmojiExtension extends BaseExtension<"emoji", EmojiConfig, EmojiCommands, EmojiStateQueries, React__default.ReactElement[]> {
2243
+ private listeners;
2244
+ private isOpen;
2245
+ private query;
2246
+ private position;
2247
+ private suggestions;
2248
+ private activeMatch;
2249
+ private applyingAutoReplace;
2250
+ private catalogAdapter;
2251
+ private hasExplicitCatalogConfig;
2252
+ private hasExplicitAdapterConfig;
2253
+ private externalCatalogDetectionStarted;
2254
+ constructor(config?: EmojiConfig);
2255
+ configure(config: Partial<EmojiConfig>): this;
2256
+ register(editor: LexicalEditor): () => void;
2257
+ getCommands(editor: LexicalEditor): EmojiCommands;
2258
+ getStateQueries(editor: LexicalEditor): EmojiStateQueries;
2259
+ subscribe(listener: (state: EmojiSuggestionState) => void): () => void;
2260
+ private getCatalog;
2261
+ private getSuggestions;
2262
+ private resolveShortcode;
2263
+ private resolveCatalogAdapter;
2264
+ private tryEnableExternalCatalog;
2265
+ private refreshSuggestionsIfOpen;
2266
+ private updateFromSelection;
2267
+ private isSelectionInsideCodeBlock;
2268
+ private detectSymbolReplacement;
2269
+ private replaceSymbolsInText;
2270
+ private executeEmojiSuggestion;
2271
+ private closeEmojiSuggestions;
2272
+ private closeIfNeeded;
2273
+ private getCaretPosition;
2274
+ private getState;
2275
+ private notifyListeners;
2276
+ }
2277
+ declare const emojiExtension: EmojiExtension;
2091
2278
 
2092
2279
  /**
2093
2280
  * Selection rectangle with position data.
@@ -2182,7 +2369,7 @@ interface FloatingConfig<TCommands = any, TStates = any> extends BaseExtensionCo
2182
2369
  /**
2183
2370
  * Commands exposed by the floating toolbar extension (none by default).
2184
2371
  */
2185
- type FloatingCommands = {};
2372
+ type FloatingCommands = Record<string, never>;
2186
2373
  /**
2187
2374
  * State queries exposed by the floating toolbar extension.
2188
2375
  */
@@ -2221,7 +2408,7 @@ type CommandPaletteItem = {
2221
2408
  action: () => void;
2222
2409
  keywords?: string[];
2223
2410
  category?: string;
2224
- icon?: React$1.ReactNode;
2411
+ icon?: React__default.ReactNode;
2225
2412
  shortcut?: string;
2226
2413
  };
2227
2414
  /**
@@ -2243,7 +2430,7 @@ type CommandPaletteStateQueries = {
2243
2430
  * Command palette extension for quick access to editor commands.
2244
2431
  * Provides a searchable command palette similar to VS Code.
2245
2432
  */
2246
- declare class CommandPaletteExtension extends BaseExtension<"commandPalette", any, CommandPaletteCommands, CommandPaletteStateQueries, React$1.ReactElement[]> {
2433
+ declare class CommandPaletteExtension extends BaseExtension<"commandPalette", any, CommandPaletteCommands, CommandPaletteStateQueries, React__default.ReactElement[]> {
2247
2434
  private isOpen;
2248
2435
  private commands;
2249
2436
  private listeners;
@@ -2266,46 +2453,79 @@ declare class CommandPaletteExtension extends BaseExtension<"commandPalette", an
2266
2453
  }
2267
2454
  declare const commandPaletteExtension: CommandPaletteExtension;
2268
2455
 
2269
- /**
2270
- * All Markdown transformers collected in one place
2271
- * Import this array to get all available transformers
2272
- */
2273
- declare const ALL_MARKDOWN_TRANSFORMERS: ({
2274
- format: readonly ["underline"];
2275
- tag: string;
2276
- type: "text-format";
2277
- } | {
2278
- dependencies: typeof _lexical_react_LexicalHorizontalRuleNode.HorizontalRuleNode[];
2279
- export: (node: lexical.LexicalNode) => "---" | null;
2280
- regExp: RegExp;
2281
- replace: (parentNode: lexical.ElementNode, children: lexical.LexicalNode[], match: string[]) => void;
2282
- type: "element";
2283
- } | {
2284
- dependencies: (typeof _lexical_table.TableNode | typeof _lexical_table.TableRowNode | typeof _lexical_table.TableCellNode)[];
2285
- export: (node: any) => string | null;
2286
- regExpStart: RegExp;
2287
- regExpEnd: {
2288
- optional: true;
2289
- regExp: RegExp;
2290
- };
2291
- replace: (rootNode: any, children: any, startMatch: any, endMatch: any, linesInBetween: any, isImport: boolean) => void;
2292
- type: "multiline-element";
2293
- } | {
2294
- dependencies: typeof HTMLEmbedNode[];
2295
- export: (node: any) => string | null;
2296
- regExpStart: RegExp;
2297
- regExpEnd: {
2298
- optional: true;
2299
- regExp: RegExp;
2456
+ type SlashCommandItem = {
2457
+ id: string;
2458
+ label: string;
2459
+ description?: string;
2460
+ action: () => void;
2461
+ keywords?: string[];
2462
+ category?: string;
2463
+ icon?: React__default.ReactNode;
2464
+ shortcut?: string;
2465
+ };
2466
+ type SlashCommandMenuState = {
2467
+ isOpen: boolean;
2468
+ query: string;
2469
+ position: {
2470
+ x: number;
2471
+ y: number;
2472
+ } | null;
2473
+ commands: SlashCommandItem[];
2474
+ };
2475
+ interface SlashCommandConfig extends BaseExtensionConfig {
2476
+ trigger?: string;
2477
+ offset?: {
2478
+ x: number;
2479
+ y: number;
2300
2480
  };
2301
- replace: (rootNode: any, children: any, startMatch: any, endMatch: any, linesInBetween: any, isImport: boolean) => void;
2302
- type: "multiline-element";
2303
- } | {
2304
- dependencies: typeof ImageNode[];
2305
- export: (node: lexical.LexicalNode) => string | null;
2306
- regExp: RegExp;
2307
- replace: (parentNode: lexical.ElementNode, _children: lexical.LexicalNode[], match: string[], isImport: boolean) => void;
2308
- type: "element";
2309
- })[];
2481
+ items?: readonly SlashCommandItem[];
2482
+ }
2483
+ type SlashCommandCommands = {
2484
+ registerSlashCommand: (item: SlashCommandItem) => void;
2485
+ unregisterSlashCommand: (id: string) => void;
2486
+ setSlashCommands: (items: readonly SlashCommandItem[]) => void;
2487
+ closeSlashMenu: () => void;
2488
+ executeSlashCommand: (id: string) => boolean;
2489
+ };
2490
+ type SlashCommandStateQueries = {
2491
+ isSlashMenuOpen: () => Promise<boolean>;
2492
+ };
2493
+ declare class SlashCommandExtension extends BaseExtension<"slashCommand", SlashCommandConfig, SlashCommandCommands, SlashCommandStateQueries, React__default.ReactElement[]> {
2494
+ private commands;
2495
+ private listeners;
2496
+ private isOpen;
2497
+ private query;
2498
+ private position;
2499
+ private activeMatch;
2500
+ constructor(config?: SlashCommandConfig);
2501
+ register(editor: LexicalEditor): () => void;
2502
+ getCommands(editor: LexicalEditor): SlashCommandCommands;
2503
+ getStateQueries(_editor: LexicalEditor): SlashCommandStateQueries;
2504
+ subscribe(listener: (state: SlashCommandMenuState) => void): () => void;
2505
+ getAllCommands(): SlashCommandItem[];
2506
+ private registerSlashCommand;
2507
+ private unregisterSlashCommand;
2508
+ private setSlashCommands;
2509
+ private closeSlashMenu;
2510
+ private executeSlashCommand;
2511
+ private updateMatchFromSelection;
2512
+ private closeIfNeeded;
2513
+ private getCaretPosition;
2514
+ private getState;
2515
+ private notifyListeners;
2516
+ }
2517
+ declare const slashCommandExtension: SlashCommandExtension;
2518
+
2519
+ type EnterKeyBehaviorCommands = Record<string, never>;
2520
+ type EnterKeyBehaviorStateQueries = Record<string, never>;
2521
+ declare class EnterKeyBehaviorExtension extends BaseExtension<"enterKeyBehavior", BaseExtensionConfig, EnterKeyBehaviorCommands, EnterKeyBehaviorStateQueries> {
2522
+ constructor();
2523
+ register(editor: LexicalEditor): () => void;
2524
+ private findQuoteNode;
2525
+ private findCodeNode;
2526
+ private findDirectQuoteChild;
2527
+ private isEmptyQuoteLine;
2528
+ }
2529
+ declare const enterKeyBehaviorExtension: EnterKeyBehaviorExtension;
2310
2530
 
2311
- export { ALL_MARKDOWN_TRANSFORMERS, type Alignment, type BaseCommands, BaseExtension, type BaseExtensionConfig, BaseProvider, BlockFormatExtension, BoldExtension, CodeExtension, CodeFormatExtension, type CommandPaletteCommands, CommandPaletteExtension, type CommandPaletteItem, type CommandPaletteStateQueries, type ContextMenuCommands, type ContextMenuConfig, ContextMenuExtension, type ContextMenuItem, type ContextMenuStateQueries, DraggableBlockExtension, type DraggableCommands, type DraggableConfig, type DraggableStateQueries, type EditorConfig, type EditorContextType, type Extension, ExtensionCategory, type ExtractCommands, type ExtractNames, type ExtractPlugins, type ExtractStateQueries, type FloatingCommands, type FloatingConfig, type FloatingStateQueries, FloatingToolbarExtension, HTMLEmbedExtension, HTMLExtension, HistoryExtension, HorizontalRuleExtension, type ImageCommands, type ImageComponentProps, ImageExtension, type ImageExtensionConfig, type ImagePayload, type ImageStateQueries, ItalicExtension, LinkExtension, ListExtension, type LuthorTheme, MarkdownExtension, RichText, type RichTextComponentProps, type RichTextConfig, type SerializedImageNode, StrikethroughExtension, type TableConfig, TableExtension, TextFormatExtension, type ToolbarItem, UnderlineExtension, blockFormatExtension, boldExtension, codeExtension, codeFormatExtension, commandPaletteExtension, contextMenuExtension, createCustomNodeExtension, createEditorSystem, createExtension, defaultLuthorTheme, draggableBlockExtension, floatingToolbarExtension, historyExtension, horizontalRuleExtension, htmlEmbedExtension, htmlExtension, imageExtension, isLuthorTheme, italicExtension, linkExtension, listExtension, markdownExtension, mergeThemes, richTextExtension, strikethroughExtension, tableExtension, underlineExtension, useBaseEditor };
2531
+ export { type Alignment, type BaseCommands, BaseExtension, type BaseExtensionConfig, BaseProvider, BlockFormatExtension, BoldExtension, CodeExtension, type CodeExtensionConfig, CodeFormatExtension, type CodeHighlightProvider, type CodeHighlightProviderConfig, type CodeIntelligenceCommands, type CodeIntelligenceConfig, CodeIntelligenceExtension, type CodeLanguageOptionsConfig, type CodeLanguageOptionsMode, type CommandPaletteCommands, CommandPaletteExtension, type CommandPaletteItem, type CommandPaletteStateQueries, type ContextMenuCommands, type ContextMenuConfig, ContextMenuExtension, type ContextMenuItem, type ContextMenuStateQueries, DraggableBlockExtension, type DraggableCommands, type DraggableConfig, type DraggableStateQueries, type EditorConfig, type EditorContextType, type EmojiCatalogAdapter, type EmojiCatalogItem, type EmojiCommands, type EmojiConfig, EmojiExtension, type EmojiStateQueries, type EmojiSuggestionState, EnterKeyBehaviorExtension, type Extension, ExtensionCategory, type ExtractCommands, type ExtractNames, type ExtractPlugins, type ExtractStateQueries, type FloatingCommands, type FloatingConfig, type FloatingStateQueries, FloatingToolbarExtension, type FontCssLoadStrategy, type FontFamilyConfig, FontFamilyExtension, type FontFamilyOption, type FontSizeConfig, FontSizeExtension, type FontSizeOption, HistoryExtension, HorizontalRuleExtension, IframeEmbedExtension, type ImageCommands, type ImageComponentProps, ImageExtension, type ImageExtensionConfig, type ImagePayload, type ImageStateQueries, ItalicExtension, type JsonbDocument, LIGHTWEIGHT_EMOJI_CATALOG, LUTHOR_EDITOR_THEME_TOKENS, type LexicalNodeRegistration, type LineHeightConfig, LineHeightExtension, type LineHeightOption, LinkExtension, ListExtension, type LuthorEditorThemeOverrides, type LuthorEditorThemeToken, type LuthorTheme, RichText, type RichTextComponentProps, type RichTextConfig, type SerializedImageNode, type SlashCommandCommands, type SlashCommandConfig, SlashCommandExtension, type SlashCommandItem, type SlashCommandMenuState, type SlashCommandStateQueries, StrikethroughExtension, SubscriptExtension, SuperscriptExtension, TabIndentExtension, type TableConfig, TableExtension, type TextColorConfig, TextColorExtension, type TextColorOption, TextFormatExtension, type TextHighlightConfig, TextHighlightExtension, type TextHighlightOption, type ToolbarItem, UnderlineExtension, YouTubeEmbedExtension, blockFormatExtension, boldExtension, clearLexicalSelection, codeExtension, codeFormatExtension, codeIntelligenceExtension, commandPaletteExtension, contextMenuExtension, createCustomNodeExtension, createEditorSystem, createEditorThemeStyleVars, createExtension, defaultLuthorTheme, draggableBlockExtension, emojiExtension, enterKeyBehaviorExtension, floatingToolbarExtension, fontFamilyExtension, fontSizeExtension, historyExtension, horizontalRuleExtension, iframeEmbedExtension, imageExtension, isLuthorTheme, italicExtension, jsonbToMarkdown, lineHeightExtension, linkExtension, listExtension, markdownToJSONB, mergeThemes, resolveLinkNodeKeyFromAnchor, richTextExtension, slashCommandExtension, strikethroughExtension, subscriptExtension, superscriptExtension, tabIndentExtension, tableExtension, textColorExtension, textHighlightExtension, underlineExtension, useBaseEditor, youTubeEmbedExtension };