@lyfie/luthor-headless 2.3.6 → 2.5.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/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/lyfie-app/luthor/main/apps/web/public/luthor-logo-horizontal.png" alt="Luthor" width="360" />
2
+ <img src="https://raw.githubusercontent.com/lyfie-org/luthor/main/apps/web/public/luthor-logo-horizontal.png" alt="Luthor" width="360" />
3
3
  <h1>@lyfie/luthor-headless</h1>
4
4
  <p><strong>Headless, extension-first rich text editor runtime for React on top of Lexical.</strong></p>
5
5
  </div>
6
6
 
7
7
  <div align="center">
8
8
 
9
- [![Project Status](https://img.shields.io/badge/status-active%20development-orange?style=flat-square)](https://github.com/lyfie-org/luthor)
9
+ [![Project Status](https://img.shields.io/badge/status-stable%20release%20%7C%20internal%20QA-yellowgreen?style=flat-square)](https://github.com/lyfie-org/luthor)
10
10
  [![Stability](https://img.shields.io/badge/stable%20release-expected%20soon-blue?style=flat-square)](https://github.com/lyfie-org/luthor/releases)
11
11
 
12
12
  [![npm version](https://img.shields.io/npm/v/@lyfie/luthor-headless?style=flat-square)](https://www.npmjs.com/package/@lyfie/luthor-headless)
@@ -14,7 +14,7 @@
14
14
  [![bundle size](https://img.shields.io/bundlephobia/minzip/@lyfie/luthor-headless?style=flat-square)](https://bundlephobia.com/package/@lyfie/luthor-headless)
15
15
  [![types](https://img.shields.io/npm/types/@lyfie/luthor-headless?style=flat-square)](https://www.npmjs.com/package/@lyfie/luthor-headless)
16
16
  [![license](https://img.shields.io/npm/l/@lyfie/luthor-headless?style=flat-square)](https://github.com/lyfie-org/luthor/blob/main/LICENSE)
17
- [![last commit](https://img.shields.io/github/last-commit/lyfie-app/luthor/main?style=flat-square)](https://github.com/lyfie-org/luthor/commits/main)
17
+ [![last commit](https://img.shields.io/github/last-commit/lyfie-org/luthor/main?style=flat-square)](https://github.com/lyfie-org/luthor/commits/main)
18
18
 
19
19
  </div>
20
20
 
package/dist/index.d.ts CHANGED
@@ -427,37 +427,41 @@ declare function isLuthorTheme(theme: any): theme is LuthorTheme;
427
427
  declare function clearLexicalSelection(editor: LexicalEditor): void;
428
428
  declare function resolveLinkNodeKeyFromAnchor(editor: LexicalEditor, anchorEl: HTMLAnchorElement): string | null;
429
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
- };
430
+ type JsonRecord = Record<string, unknown>;
455
431
  type JsonDocument = {
456
- root: JsonRootNode;
432
+ root: JsonRecord;
457
433
  };
434
+ type BridgeMode = "markdown" | "html";
435
+ type MetadataEnvelope = {
436
+ id: string;
437
+ type: string;
438
+ path: number[];
439
+ node: JsonRecord;
440
+ fallback: string;
441
+ };
442
+ type PreparedBridgeDocument = {
443
+ document: JsonDocument;
444
+ envelopes: MetadataEnvelope[];
445
+ };
446
+ type ExtractedMetadataEnvelopes = {
447
+ content: string;
448
+ envelopes: MetadataEnvelope[];
449
+ warnings: string[];
450
+ };
451
+ declare function prepareDocumentForBridge(input: unknown, options: {
452
+ mode: BridgeMode;
453
+ supportedNodeTypes: ReadonlySet<string>;
454
+ }): PreparedBridgeDocument;
455
+ declare function appendMetadataEnvelopes(content: string, envelopes: readonly MetadataEnvelope[]): string;
456
+ declare function extractMetadataEnvelopes(content: string): ExtractedMetadataEnvelopes;
457
+ declare function rehydrateDocumentFromEnvelopes(document: JsonDocument, envelopes: readonly MetadataEnvelope[]): JsonDocument;
458
+
458
459
  declare function markdownToJSON(markdown: string): JsonDocument;
459
460
  declare function jsonToMarkdown(input: unknown): string;
460
461
 
462
+ declare function htmlToJSON(html: string): JsonDocument;
463
+ declare function jsonToHTML(input: unknown): string;
464
+
461
465
  /**
462
466
  * Commands exposed by text format extensions.
463
467
  * Generates toggle commands for text formatting (e.g., toggleBold, toggleItalic).
@@ -1110,8 +1114,14 @@ declare class ContextMenuManager {
1110
1114
  y: number;
1111
1115
  };
1112
1116
  renderer?: ContextMenuRenderer;
1117
+ anchor?: {
1118
+ element: HTMLElement;
1119
+ offsetX: number;
1120
+ offsetY: number;
1121
+ };
1113
1122
  }): void;
1114
1123
  hideMenu(): void;
1124
+ repositionMenuFromAnchor(): void;
1115
1125
  getCurrentMenu(): {
1116
1126
  items: ContextMenuItem[];
1117
1127
  position: {
@@ -1119,9 +1129,16 @@ declare class ContextMenuManager {
1119
1129
  y: number;
1120
1130
  };
1121
1131
  renderer?: ContextMenuRenderer;
1132
+ anchor?: {
1133
+ element: HTMLElement;
1134
+ offsetX: number;
1135
+ offsetY: number;
1136
+ };
1122
1137
  } | null;
1138
+ getPortalContainer(): HTMLElement | null;
1123
1139
  subscribe(listener: (menu: typeof this.currentMenu) => void): () => void;
1124
1140
  private notifyListeners;
1141
+ private resolveAnchoredMenuConfig;
1125
1142
  }
1126
1143
  /**
1127
1144
  * Context menu extension - provides a clean, registry-based context menu system
@@ -1223,6 +1240,23 @@ declare class TableExtension extends BaseExtension<"table", TableConfig, TableCo
1223
1240
  */
1224
1241
  declare const tableExtension: TableExtension;
1225
1242
 
1243
+ declare const ORDERED_LIST_PATTERNS: {
1244
+ readonly "decimal-alpha-roman": readonly ["decimal", "lower-alpha", "lower-roman"];
1245
+ readonly "decimal-hierarchical": readonly ["decimal"];
1246
+ readonly "upper-roman-upper-alpha": readonly ["upper-roman", "upper-alpha", "decimal", "lower-alpha", "decimal", "lower-alpha", "lower-roman", "lower-alpha", "lower-roman"];
1247
+ readonly "upper-alpha-lower-alpha": readonly ["upper-alpha", "lower-alpha", "lower-roman", "decimal", "lower-alpha", "lower-roman", "decimal", "lower-alpha", "lower-roman"];
1248
+ readonly "decimal-leading-zero-alpha": readonly ["decimal-leading-zero", "lower-alpha", "lower-roman", "decimal", "lower-alpha", "lower-roman", "decimal", "lower-alpha", "lower-roman"];
1249
+ };
1250
+ declare const UNORDERED_LIST_PATTERNS: {
1251
+ readonly "disc-circle-square": readonly ["disc", "circle", "square"];
1252
+ readonly "arrow-diamond-disc": readonly ["\"▸\"", "\"◆\"", "disc"];
1253
+ readonly "square-square-square": readonly ["square", "square", "square"];
1254
+ readonly "arrow-circle-square": readonly ["\"▸\"", "circle", "square"];
1255
+ };
1256
+ type OrderedListPattern = keyof typeof ORDERED_LIST_PATTERNS;
1257
+ type UnorderedListPattern = keyof typeof UNORDERED_LIST_PATTERNS;
1258
+ type OrderedListSuffix = "dot" | "paren";
1259
+ type CheckListVariant = "strikethrough" | "plain";
1226
1260
  /**
1227
1261
  * Commands exposed by the list extension.
1228
1262
  */
@@ -1241,6 +1275,20 @@ type ListCommands = {
1241
1275
  insertNestedUnorderedList: () => void;
1242
1276
  /** Create a nested numbered list at the current selection */
1243
1277
  insertNestedOrderedList: () => void;
1278
+ /** Apply an ordered list pattern to the selected list tree */
1279
+ setOrderedListPattern: (pattern: OrderedListPattern) => void;
1280
+ /** Toggle ordered list marker suffix between "1." and "1)" */
1281
+ setOrderedListSuffix: (suffix: OrderedListSuffix) => void;
1282
+ /** Apply an unordered list marker pattern to the selected list tree */
1283
+ setUnorderedListPattern: (pattern: UnorderedListPattern) => void;
1284
+ /** Switch checklist behavior between strike and plain text */
1285
+ setCheckListVariant: (variant: CheckListVariant) => void;
1286
+ /** Rebuild list style tokens after state import/rehydration */
1287
+ rehydrateListStyles: () => void;
1288
+ };
1289
+ type ListExtensionConfig = {
1290
+ /** Maximum lexical list depth including the top-level list. */
1291
+ maxDepth?: number;
1244
1292
  };
1245
1293
  /**
1246
1294
  * List extension for managing ordered and unordered lists.
@@ -1276,7 +1324,7 @@ type ListCommands = {
1276
1324
  * }
1277
1325
  * ```
1278
1326
  */
1279
- declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1327
+ declare class ListExtension extends BaseExtension<"list", ListExtensionConfig, ListCommands, {
1280
1328
  unorderedList: () => Promise<boolean>;
1281
1329
  orderedList: () => Promise<boolean>;
1282
1330
  checkList: () => Promise<boolean>;
@@ -1284,7 +1332,8 @@ declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1284
1332
  /**
1285
1333
  * Creates a new list extension instance.
1286
1334
  */
1287
- constructor();
1335
+ constructor(config?: ListExtensionConfig);
1336
+ private getMaxListDepth;
1288
1337
  /**
1289
1338
  * Registers the extension with Lexical.
1290
1339
  * No special registration needed because Lexical handles list commands.
@@ -1312,6 +1361,13 @@ declare class ListExtension extends BaseExtension<"list", any, ListCommands, {
1312
1361
  * @returns Object containing list toggle commands
1313
1362
  */
1314
1363
  getCommands(editor: LexicalEditor): ListCommands;
1364
+ private applyOrderedPattern;
1365
+ private applyOrderedSuffix;
1366
+ private applyUnorderedPattern;
1367
+ private applyCheckListVariant;
1368
+ private syncListNodeStyles;
1369
+ private convertTopListType;
1370
+ private handleOrderedListShortcut;
1315
1371
  /**
1316
1372
  * Returns state query functions for list state.
1317
1373
  *
@@ -1388,6 +1444,7 @@ type CodeExtensionConfig = BaseExtensionConfig & CodeHighlightProviderConfig & {
1388
1444
  * ```
1389
1445
  */
1390
1446
  declare class CodeExtension extends BaseExtension<"code", CodeExtensionConfig, CodeCommands, CodeStateQueries, ReactNode[]> {
1447
+ private static readonly MAX_CODE_TAB_DEPTH;
1391
1448
  private codeHighlightProviderPromise;
1392
1449
  constructor();
1393
1450
  /**
@@ -1444,6 +1501,7 @@ declare class CodeExtension extends BaseExtension<"code", CodeExtensionConfig, C
1444
1501
  * @returns Current format or null
1445
1502
  */
1446
1503
  private getCurrentFormatSync;
1504
+ private hasReachedCodeTabLimit;
1447
1505
  }
1448
1506
  declare const codeExtension: CodeExtension;
1449
1507
 
@@ -1506,6 +1564,7 @@ declare const codeIntelligenceExtension: CodeIntelligenceExtension;
1506
1564
  */
1507
1565
  declare class CodeFormatExtension extends TextFormatExtension<"code"> {
1508
1566
  constructor();
1567
+ register(editor: LexicalEditor): () => void;
1509
1568
  }
1510
1569
  declare const codeFormatExtension: CodeFormatExtension;
1511
1570
 
@@ -2153,6 +2212,9 @@ declare const richTextExtension: RichTextExtension;
2153
2212
  type RichTextComponentProps = SharedRichTextProps;
2154
2213
  declare const RichText: React__default.FC<RichTextComponentProps>;
2155
2214
 
2215
+ type TabIndentConfig = {
2216
+ maxListDepth?: number;
2217
+ };
2156
2218
  /**
2157
2219
  * TabIndentExtension - Adds universal Tab/Shift+Tab indentation support
2158
2220
  *
@@ -2167,8 +2229,8 @@ declare const RichText: React__default.FC<RichTextComponentProps>;
2167
2229
  * const extensions = [tabIndentExtension];
2168
2230
  * ```
2169
2231
  */
2170
- declare class TabIndentExtension extends BaseExtension<"tabIndent", Record<string, never>, Record<string, never>, Record<string, never>, ReactNode[]> {
2171
- constructor();
2232
+ declare class TabIndentExtension extends BaseExtension<"tabIndent", TabIndentConfig, Record<string, never>, Record<string, never>, ReactNode[]> {
2233
+ constructor(config?: TabIndentConfig);
2172
2234
  /**
2173
2235
  * Register the extension with Lexical
2174
2236
  * @param editor - Lexical editor instance
@@ -2182,9 +2244,17 @@ declare class TabIndentExtension extends BaseExtension<"tabIndent", Record<strin
2182
2244
  */
2183
2245
  private isInCodeBlock;
2184
2246
  /**
2185
- * Check if a node is within a checklist list item.
2247
+ * Check whether current list depth reached the configured max depth.
2186
2248
  */
2187
- private isInCheckList;
2249
+ private isListAtMaxDepth;
2250
+ /**
2251
+ * Check whether current block indent reached the configured max depth.
2252
+ */
2253
+ private isBlockAtMaxIndent;
2254
+ private resolveTabContext;
2255
+ private findNearestListNode;
2256
+ private findNearestListItemNode;
2257
+ private hasReachedTextTabLimit;
2188
2258
  }
2189
2259
  declare const tabIndentExtension: TabIndentExtension;
2190
2260
 
@@ -2246,6 +2316,7 @@ declare class EmojiExtension extends BaseExtension<"emoji", EmojiConfig, EmojiCo
2246
2316
  private position;
2247
2317
  private suggestions;
2248
2318
  private activeMatch;
2319
+ private viewportRafId;
2249
2320
  private applyingAutoReplace;
2250
2321
  private catalogAdapter;
2251
2322
  private hasExplicitCatalogConfig;
@@ -2497,6 +2568,7 @@ declare class SlashCommandExtension extends BaseExtension<"slashCommand", SlashC
2497
2568
  private query;
2498
2569
  private position;
2499
2570
  private activeMatch;
2571
+ private viewportRafId;
2500
2572
  constructor(config?: SlashCommandConfig);
2501
2573
  register(editor: LexicalEditor): () => void;
2502
2574
  getCommands(editor: LexicalEditor): SlashCommandCommands;
@@ -2516,11 +2588,14 @@ declare class SlashCommandExtension extends BaseExtension<"slashCommand", SlashC
2516
2588
  }
2517
2589
  declare const slashCommandExtension: SlashCommandExtension;
2518
2590
 
2519
- type EnterKeyBehaviorCommands = Record<string, never>;
2591
+ type EnterKeyBehaviorCommands = {
2592
+ insertHardBreak: () => void;
2593
+ };
2520
2594
  type EnterKeyBehaviorStateQueries = Record<string, never>;
2521
2595
  declare class EnterKeyBehaviorExtension extends BaseExtension<"enterKeyBehavior", BaseExtensionConfig, EnterKeyBehaviorCommands, EnterKeyBehaviorStateQueries> {
2522
2596
  constructor();
2523
2597
  register(editor: LexicalEditor): () => void;
2598
+ getCommands(editor: LexicalEditor): EnterKeyBehaviorCommands;
2524
2599
  private findQuoteNode;
2525
2600
  private findCodeNode;
2526
2601
  private findDirectQuoteChild;
@@ -2528,4 +2603,4 @@ declare class EnterKeyBehaviorExtension extends BaseExtension<"enterKeyBehavior"
2528
2603
  }
2529
2604
  declare const enterKeyBehaviorExtension: EnterKeyBehaviorExtension;
2530
2605
 
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 JsonDocument, 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, jsonToMarkdown, lineHeightExtension, linkExtension, listExtension, markdownToJSON, mergeThemes, resolveLinkNodeKeyFromAnchor, richTextExtension, slashCommandExtension, strikethroughExtension, subscriptExtension, superscriptExtension, tabIndentExtension, tableExtension, textColorExtension, textHighlightExtension, underlineExtension, useBaseEditor, youTubeEmbedExtension };
2606
+ export { type Alignment, type BaseCommands, BaseExtension, type BaseExtensionConfig, BaseProvider, BlockFormatExtension, BoldExtension, type BridgeMode, 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 ExtractedMetadataEnvelopes, 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 JsonDocument, LIGHTWEIGHT_EMOJI_CATALOG, LUTHOR_EDITOR_THEME_TOKENS, type LexicalNodeRegistration, type LineHeightConfig, LineHeightExtension, type LineHeightOption, LinkExtension, ListExtension, type LuthorEditorThemeOverrides, type LuthorEditorThemeToken, type LuthorTheme, type MetadataEnvelope, type PreparedBridgeDocument, 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, appendMetadataEnvelopes, blockFormatExtension, boldExtension, clearLexicalSelection, codeExtension, codeFormatExtension, codeIntelligenceExtension, commandPaletteExtension, contextMenuExtension, createCustomNodeExtension, createEditorSystem, createEditorThemeStyleVars, createExtension, defaultLuthorTheme, draggableBlockExtension, emojiExtension, enterKeyBehaviorExtension, extractMetadataEnvelopes, floatingToolbarExtension, fontFamilyExtension, fontSizeExtension, historyExtension, horizontalRuleExtension, htmlToJSON, iframeEmbedExtension, imageExtension, isLuthorTheme, italicExtension, jsonToHTML, jsonToMarkdown, lineHeightExtension, linkExtension, listExtension, markdownToJSON, mergeThemes, prepareDocumentForBridge, rehydrateDocumentFromEnvelopes, resolveLinkNodeKeyFromAnchor, richTextExtension, slashCommandExtension, strikethroughExtension, subscriptExtension, superscriptExtension, tabIndentExtension, tableExtension, textColorExtension, textHighlightExtension, underlineExtension, useBaseEditor, youTubeEmbedExtension };