@thangph2146/lexical-editor 0.0.4 → 0.0.5

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.
Files changed (99) hide show
  1. package/dist/editor-x/editor.cjs +721 -432
  2. package/dist/editor-x/editor.cjs.map +1 -1
  3. package/dist/editor-x/editor.css +1418 -1120
  4. package/dist/editor-x/editor.css.map +1 -1
  5. package/dist/editor-x/editor.js +725 -436
  6. package/dist/editor-x/editor.js.map +1 -1
  7. package/dist/index.cjs +757 -469
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.css +1418 -1120
  10. package/dist/index.css.map +1 -1
  11. package/dist/index.js +760 -472
  12. package/dist/index.js.map +1 -1
  13. package/package.json +3 -3
  14. package/src/components/lexical-editor.tsx +138 -123
  15. package/src/editor-x/editor.tsx +16 -3
  16. package/src/editor-x/plugins.tsx +385 -380
  17. package/src/nodes/list-with-color-node.tsx +160 -160
  18. package/src/plugins/autocomplete-plugin.tsx +2574 -2574
  19. package/src/plugins/context-menu-plugin.tsx +239 -9
  20. package/src/plugins/floating-text-format-plugin.tsx +84 -92
  21. package/src/plugins/images-plugin.tsx +4 -4
  22. package/src/plugins/list-color-plugin.tsx +178 -178
  23. package/src/plugins/tab-focus-plugin.tsx +66 -66
  24. package/src/plugins/table-column-resizer-plugin.tsx +329 -190
  25. package/src/plugins/toolbar/block-format/block-format-data.tsx +4 -0
  26. package/src/plugins/toolbar/block-format/format-bulleted-list.tsx +40 -40
  27. package/src/plugins/toolbar/block-format/format-list-with-marker.tsx +74 -74
  28. package/src/plugins/toolbar/block-format/format-numbered-list.tsx +40 -40
  29. package/src/plugins/toolbar/block-format-toolbar-plugin.tsx +118 -117
  30. package/src/plugins/toolbar/element-format-toolbar-plugin.tsx +37 -53
  31. package/src/plugins/toolbar/font-format-toolbar-plugin.tsx +8 -15
  32. package/src/plugins/toolbar/font-size-toolbar-plugin.tsx +2 -3
  33. package/src/plugins/toolbar/history-toolbar-plugin.tsx +2 -5
  34. package/src/plugins/toolbar/subsuper-toolbar-plugin.tsx +15 -23
  35. package/src/themes/_mixins.scss +158 -10
  36. package/src/themes/_variables.scss +168 -0
  37. package/src/themes/core/_code.scss +59 -0
  38. package/src/themes/core/_images.scss +80 -0
  39. package/src/themes/core/_lists.scss +214 -0
  40. package/src/themes/core/_misc.scss +46 -0
  41. package/src/themes/core/_reset.scss +119 -0
  42. package/src/themes/core/_tables.scss +145 -0
  43. package/src/themes/core/_text.scss +35 -0
  44. package/src/themes/core/_typography.scss +73 -0
  45. package/src/themes/editor-theme copy.scss +763 -0
  46. package/src/themes/editor-theme.scss +9 -623
  47. package/src/themes/editor-theme.ts +118 -118
  48. package/src/themes/plugins/_auto-embed.scss +11 -0
  49. package/src/themes/plugins/_color-picker.scss +103 -0
  50. package/src/themes/plugins/_draggable-block.scss +32 -0
  51. package/src/themes/plugins/_floating-link-editor.scss +47 -0
  52. package/src/themes/plugins/_floating-toolbars.scss +61 -0
  53. package/src/themes/plugins/_image-resizer.scss +38 -0
  54. package/src/themes/plugins/_image.scss +57 -0
  55. package/src/themes/plugins/_layout.scss +39 -0
  56. package/src/themes/plugins/_list-color.scss +23 -0
  57. package/src/themes/plugins/_mentions.scss +21 -0
  58. package/src/themes/plugins/_menus-and-pickers.scss +153 -0
  59. package/src/themes/plugins/_table.scss +20 -0
  60. package/src/themes/plugins/_toolbar.scss +36 -0
  61. package/src/themes/plugins/_tree-view.scss +11 -0
  62. package/src/themes/plugins copy.scss +656 -0
  63. package/src/themes/plugins.scss +20 -1165
  64. package/src/themes/ui-components/_animations.scss +31 -0
  65. package/src/themes/ui-components/_backgrounds.scss +27 -0
  66. package/src/themes/ui-components/_borders.scss +20 -0
  67. package/src/themes/ui-components/_button.scss +176 -0
  68. package/src/themes/ui-components/_checkbox.scss +14 -0
  69. package/src/themes/ui-components/_cursors.scss +31 -0
  70. package/src/themes/ui-components/_dialog.scss +86 -0
  71. package/src/themes/ui-components/_display-sizing.scss +100 -0
  72. package/src/themes/ui-components/_flex.scss +124 -0
  73. package/src/themes/ui-components/_form-layout.scss +15 -0
  74. package/src/themes/ui-components/_icons.scss +23 -0
  75. package/src/themes/ui-components/_input.scss +86 -0
  76. package/src/themes/ui-components/_label.scss +19 -0
  77. package/src/themes/ui-components/_loader.scss +9 -0
  78. package/src/themes/ui-components/_margins-paddings.scss +45 -0
  79. package/src/themes/ui-components/_popover.scss +16 -0
  80. package/src/themes/ui-components/_positioning.scss +73 -0
  81. package/src/themes/ui-components/_rounded.scss +19 -0
  82. package/src/themes/ui-components/_scroll-area.scss +11 -0
  83. package/src/themes/ui-components/_select.scss +110 -0
  84. package/src/themes/ui-components/_separator.scss +19 -0
  85. package/src/themes/ui-components/_shadow.scss +15 -0
  86. package/src/themes/ui-components/_tabs.scss +46 -0
  87. package/src/themes/ui-components/_text-utilities.scss +48 -0
  88. package/src/themes/ui-components/_toggle-toolbar.scss +128 -0
  89. package/src/themes/ui-components/_toggle.scss +80 -0
  90. package/src/themes/ui-components/_typography.scss +22 -0
  91. package/src/themes/ui-components copy.scss +1335 -0
  92. package/src/themes/ui-components.scss +27 -937
  93. package/src/transformers/markdown-list-transformer.ts +51 -51
  94. package/src/ui/button.tsx +11 -2
  95. package/src/ui/collapsible.tsx +1 -1
  96. package/src/ui/dialog.tsx +2 -2
  97. package/src/ui/flex.tsx +4 -4
  98. package/src/ui/popover.tsx +1 -1
  99. package/src/ui/tooltip.tsx +2 -2
@@ -2990,8 +2990,8 @@ var init_button = __esm({
2990
2990
  "src/ui/button.tsx"() {
2991
2991
  init_utils();
2992
2992
  Button = React20__namespace.forwardRef(
2993
- ({ className, variant = "default", size = "default", type = "button", ...props }, ref) => {
2994
- return /* @__PURE__ */ jsxRuntime.jsx(
2993
+ ({ className, variant = "default", size = "default", type = "button", isLoading, disabled, children, ...props }, ref) => {
2994
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2995
2995
  "button",
2996
2996
  {
2997
2997
  type,
@@ -2999,10 +2999,16 @@ var init_button = __esm({
2999
2999
  "editor-btn",
3000
3000
  variant !== "default" && `editor-btn--${variant}`,
3001
3001
  size !== "default" && `editor-btn--size-${size}`,
3002
+ isLoading && "editor-btn--loading",
3002
3003
  className
3003
3004
  ),
3005
+ disabled: isLoading || disabled,
3004
3006
  ref,
3005
- ...props
3007
+ ...props,
3008
+ children: [
3009
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "editor-btn__loader editor-animate-spin", size: 16 }),
3010
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("editor-btn__content", isLoading && "editor-opacity-0"), children })
3011
+ ]
3006
3012
  }
3007
3013
  );
3008
3014
  }
@@ -4375,8 +4381,8 @@ function ImagePickerFolderTree({
4375
4381
  /* @__PURE__ */ jsxRuntime.jsx(TypographyP, { className: "editor-truncate", children: folder.name }),
4376
4382
  /* @__PURE__ */ jsxRuntime.jsx(TypographySpanSmallMuted, { className: "editor-ml-auto editor-shrink-0", children: `${folder.images.length} h\xECnh${folder.subfolders.length > 0 ? `, ${folder.subfolders.length} th\u01B0 m\u1EE5c` : ""}` })
4377
4383
  ] }),
4378
- /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleContent, { className: "editor-ml-4 editor-mt-1", children: [
4379
- folder.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-image-grid", children: folder.images.map((image) => /* @__PURE__ */ jsxRuntime.jsx(
4384
+ /* @__PURE__ */ jsxRuntime.jsxs(CollapsibleContent, { className: "editor-ml-4 editor-mt-1 editor-flex editor-flex-col editor-gap-1", children: [
4385
+ folder.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-image-grid editor-gap-2", children: folder.images.map((image) => /* @__PURE__ */ jsxRuntime.jsx(
4380
4386
  "button",
4381
4387
  {
4382
4388
  type: "button",
@@ -4463,10 +4469,10 @@ function InsertImageUploadsDialogBody({
4463
4469
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-form-grid", children: [
4464
4470
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-form-item", children: [
4465
4471
  /* @__PURE__ */ jsxRuntime.jsx(Label, { children: "Ch\u1ECDn h\xECnh \u1EA3nh t\u1EEB th\u01B0 vi\u1EC7n" }),
4466
- isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-flex-center-justify-py-8", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "editor-loader" }) }) : !folderTree || folderTree.subfolders.length === 0 && folderTree.images.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-empty-state", children: /* @__PURE__ */ jsxRuntime.jsx(TypographySpanSmallMuted, { children: "Ch\u01B0a c\xF3 h\xECnh \u1EA3nh n\xE0o \u0111\u01B0\u1EE3c upload" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-scroll-area", children: [
4472
+ isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-flex-center-justify-py-8", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "editor-loader" }) }) : !folderTree || folderTree.subfolders.length === 0 && folderTree.images.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-empty-state", children: /* @__PURE__ */ jsxRuntime.jsx(TypographySpanSmallMuted, { children: "Ch\u01B0a c\xF3 h\xECnh \u1EA3nh n\xE0o \u0111\u01B0\u1EE3c upload" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-scroll-area editor-flex editor-flex-col editor-gap-1", children: [
4467
4473
  folderTree.images.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-mb-3", children: [
4468
4474
  /* @__PURE__ */ jsxRuntime.jsx(TypographySpanSmallMuted, { className: "editor-mb-2 editor-px-1", children: "Root" }),
4469
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-image-grid", children: folderTree.images.map((image) => /* @__PURE__ */ jsxRuntime.jsx(
4475
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-image-grid editor-gap-2", children: folderTree.images.map((image) => /* @__PURE__ */ jsxRuntime.jsx(
4470
4476
  "button",
4471
4477
  {
4472
4478
  type: "button",
@@ -6507,10 +6513,10 @@ var init_flex = __esm({
6507
6513
  ref,
6508
6514
  className: cn(
6509
6515
  "editor-flex",
6510
- align && `editor-flex--items-${align}`,
6511
- justify && `editor-flex--justify-${justify}`,
6512
- direction && `editor-flex--flex-${direction}`,
6513
- wrap && `editor-flex--flex-${wrap}`,
6516
+ align && `editor-items-${align}`,
6517
+ justify && `editor-justify-${justify}`,
6518
+ direction && `editor-flex-${direction}`,
6519
+ wrap && `editor-flex-${wrap}`,
6514
6520
  className
6515
6521
  ),
6516
6522
  style: { ...gapStyle, ...style },
@@ -10188,6 +10194,9 @@ var init_list_color_plugin = __esm({
10188
10194
  });
10189
10195
  function ContextMenuPlugin() {
10190
10196
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
10197
+ const [contextTarget, setContextTarget] = React20.useState(null);
10198
+ const [showMarkerDialog, setShowMarkerDialog] = React20.useState(false);
10199
+ const [customMarker, setCustomMarker] = React20.useState("");
10191
10200
  const isInTable = (node) => utils.$findMatchingParent(node, table.$isTableCellNode) !== null;
10192
10201
  const isMergedCell = (node) => {
10193
10202
  const cell = utils.$findMatchingParent(node, table.$isTableCellNode);
@@ -10199,6 +10208,105 @@ function ContextMenuPlugin() {
10199
10208
  };
10200
10209
  const isInLayoutItem = (node) => utils.$findMatchingParent(node, $isLayoutItemNode) !== null;
10201
10210
  const isInList = (node) => utils.$findMatchingParent(node, list.$isListNode) !== null;
10211
+ const isInNumberList = (node) => {
10212
+ const listNode = utils.$findMatchingParent(node, list.$isListNode);
10213
+ return list.$isListNode(listNode) && listNode.getListType() === "number";
10214
+ };
10215
+ React20.useEffect(() => {
10216
+ const rootElement = editor.getRootElement();
10217
+ if (!rootElement) return;
10218
+ const onContextMenu = (event) => {
10219
+ const target = event.target;
10220
+ if (!(target instanceof HTMLElement)) return;
10221
+ setContextTarget(target);
10222
+ };
10223
+ rootElement.addEventListener("contextmenu", onContextMenu);
10224
+ return () => {
10225
+ rootElement.removeEventListener("contextmenu", onContextMenu);
10226
+ };
10227
+ }, [editor]);
10228
+ const getContextAnchorNode = React20.useCallback(() => {
10229
+ if (contextTarget) {
10230
+ const nearestNode = lexical.$getNearestNodeFromDOMNode(contextTarget);
10231
+ if (nearestNode) return nearestNode;
10232
+ }
10233
+ const selection = lexical.$getSelection();
10234
+ if (lexical.$isRangeSelection(selection)) {
10235
+ return selection.anchor.getNode();
10236
+ }
10237
+ return null;
10238
+ }, [contextTarget]);
10239
+ const updateNumberListMarkerType = React20.useCallback((markerType) => {
10240
+ editor.update(() => {
10241
+ const anchorNode = getContextAnchorNode();
10242
+ if (!anchorNode) return;
10243
+ const nearestListNode = utils.$findMatchingParent(
10244
+ anchorNode,
10245
+ (node) => list.$isListNode(node) && node.getListType() === "number"
10246
+ );
10247
+ if (!nearestListNode) return;
10248
+ let listNode = nearestListNode;
10249
+ let parent = listNode.getParent();
10250
+ while (parent) {
10251
+ if (list.$isListNode(parent) && parent.getListType() === "number") {
10252
+ listNode = parent;
10253
+ parent = parent.getParent();
10254
+ continue;
10255
+ }
10256
+ break;
10257
+ }
10258
+ if ($isListWithColorNode(listNode)) {
10259
+ listNode.setMarkerType(markerType);
10260
+ return;
10261
+ }
10262
+ const newList = createListWithColorNodeFromRegistry(
10263
+ editor,
10264
+ listNode.getListType(),
10265
+ listNode.getStart()
10266
+ );
10267
+ newList.setMarkerType(markerType);
10268
+ const children = listNode.getChildren();
10269
+ for (const child of children) newList.append(child);
10270
+ listNode.replace(newList);
10271
+ });
10272
+ }, [editor, getContextAnchorNode]);
10273
+ const syncMarkerToSameLevelLists = React20.useCallback((targetListNode, markerType) => {
10274
+ editor.update(() => {
10275
+ const parent = targetListNode.getParent();
10276
+ if (!parent) return;
10277
+ const siblings = parent.getChildren();
10278
+ for (const sibling of siblings) {
10279
+ if (list.$isListNode(sibling) && sibling.getListType() === "number" && sibling !== targetListNode) {
10280
+ if ($isListWithColorNode(sibling)) {
10281
+ sibling.setMarkerType(markerType);
10282
+ } else {
10283
+ const newList = $createListWithColorNode("number", sibling.getStart());
10284
+ newList.setMarkerType(markerType);
10285
+ const children = sibling.getChildren();
10286
+ for (const child of children) newList.append(child);
10287
+ sibling.replace(newList);
10288
+ }
10289
+ }
10290
+ }
10291
+ });
10292
+ }, [editor]);
10293
+ const handleCustomMarkerSubmit = () => {
10294
+ if (customMarker.trim()) {
10295
+ editor.update(() => {
10296
+ const anchorNode = getContextAnchorNode();
10297
+ if (!anchorNode) return;
10298
+ const nearestListNode = utils.$findMatchingParent(
10299
+ anchorNode,
10300
+ (node) => list.$isListNode(node) && node.getListType() === "number"
10301
+ );
10302
+ if (!nearestListNode) return;
10303
+ updateNumberListMarkerType(customMarker.trim());
10304
+ syncMarkerToSameLevelLists(nearestListNode, customMarker.trim());
10305
+ });
10306
+ setShowMarkerDialog(false);
10307
+ setCustomMarker("");
10308
+ }
10309
+ };
10202
10310
  const items = React20.useMemo(() => {
10203
10311
  return [
10204
10312
  new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`G\u1ED9p \xF4`, {
@@ -10324,6 +10432,41 @@ function ContextMenuPlugin() {
10324
10432
  new LexicalNodeContextMenuPlugin.NodeContextMenuSeparator({
10325
10433
  $showOn: isInList
10326
10434
  }),
10435
+ new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`\u0110\xE1nh s\u1ED1 1, 2, 3`, {
10436
+ $onSelect: () => {
10437
+ updateNumberListMarkerType(void 0);
10438
+ },
10439
+ $showOn: isInNumberList,
10440
+ disabled: false,
10441
+ icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrderedIcon, {}) })
10442
+ }),
10443
+ new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`\u0110\xE1nh s\u1ED1 \u0111a c\u1EA5p 1.1 / 1.1.1`, {
10444
+ $onSelect: () => {
10445
+ updateNumberListMarkerType("multi-level");
10446
+ },
10447
+ $showOn: isInNumberList,
10448
+ disabled: false,
10449
+ icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrderedIcon, {}) })
10450
+ }),
10451
+ new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`\u0110\xE1nh s\u1ED1 a, b, c`, {
10452
+ $onSelect: () => {
10453
+ updateNumberListMarkerType("alpha");
10454
+ },
10455
+ $showOn: isInNumberList,
10456
+ disabled: false,
10457
+ icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrderedIcon, {}) })
10458
+ }),
10459
+ new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`T\xF9y ch\u1EC9nh marker...`, {
10460
+ $onSelect: () => {
10461
+ setShowMarkerDialog(true);
10462
+ },
10463
+ $showOn: isInNumberList,
10464
+ disabled: false,
10465
+ icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hash, { className: "text-blue-600" }) })
10466
+ }),
10467
+ new LexicalNodeContextMenuPlugin.NodeContextMenuSeparator({
10468
+ $showOn: isInNumberList
10469
+ }),
10327
10470
  new LexicalNodeContextMenuPlugin.NodeContextMenuOption(`Remove Link`, {
10328
10471
  $onSelect: () => {
10329
10472
  editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, null);
@@ -10419,23 +10562,101 @@ function ContextMenuPlugin() {
10419
10562
  icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, {}) })
10420
10563
  })
10421
10564
  ];
10422
- }, [editor]);
10423
- return /* @__PURE__ */ jsxRuntime.jsx(
10424
- LexicalNodeContextMenuPlugin.NodeContextMenuPlugin,
10425
- {
10426
- className: "editor-context-menu",
10427
- itemClassName: "editor-context-menu-item",
10428
- separatorClassName: "editor-context-menu-separator",
10429
- items
10430
- }
10431
- );
10565
+ }, [editor, updateNumberListMarkerType]);
10566
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10567
+ /* @__PURE__ */ jsxRuntime.jsx(
10568
+ LexicalNodeContextMenuPlugin.NodeContextMenuPlugin,
10569
+ {
10570
+ className: "editor-context-menu",
10571
+ itemClassName: "editor-context-menu-item",
10572
+ separatorClassName: "editor-context-menu-separator",
10573
+ items
10574
+ }
10575
+ ),
10576
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: showMarkerDialog, onOpenChange: setShowMarkerDialog, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { style: { maxWidth: "400px" }, children: [
10577
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
10578
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "T\xF9y ch\u1EC9nh Marker" }),
10579
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "editor-text-sm editor-text-muted-foreground", children: "Nh\u1EADp ki\u1EC3u marker cho danh s\xE1ch c\u1EE7a b\u1EA1n" })
10580
+ ] }),
10581
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-flex-col editor-py-4 editor-gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-flex-col editor-gap-2", children: [
10582
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "marker-input", className: "editor-font-medium", children: "Ki\u1EC3u marker" }),
10583
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-relative editor-flex editor-items-center", children: [
10584
+ /* @__PURE__ */ jsxRuntime.jsx(
10585
+ lucideReact.Hash,
10586
+ {
10587
+ className: "editor-absolute editor-text-muted-foreground",
10588
+ style: { left: "0.75rem" },
10589
+ size: 16
10590
+ }
10591
+ ),
10592
+ /* @__PURE__ */ jsxRuntime.jsx(
10593
+ Input,
10594
+ {
10595
+ id: "marker-input",
10596
+ value: customMarker,
10597
+ onChange: (e) => setCustomMarker(e.target.value),
10598
+ placeholder: "V\xED d\u1EE5: multi-level, alpha, 4.1, ...",
10599
+ style: { paddingLeft: "2.25rem" },
10600
+ onKeyDown: (e) => {
10601
+ if (e.key === "Enter") {
10602
+ handleCustomMarkerSubmit();
10603
+ }
10604
+ }
10605
+ }
10606
+ )
10607
+ ] }),
10608
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-flex-col editor-gap-1 editor-text-sm editor-text-muted-foreground editor-mt-2", children: [
10609
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "editor-flex editor-items-center editor-gap-2", style: { margin: 0 }, children: [
10610
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "editor-font-medium", children: "multi-level" }),
10611
+ " - Hi\u1EC3n th\u1ECB d\u1EA1ng 4.1, 4.1.1"
10612
+ ] }),
10613
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "editor-flex editor-items-center editor-gap-2", style: { margin: 0 }, children: [
10614
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "editor-font-medium", children: "alpha" }),
10615
+ " - Hi\u1EC3n th\u1ECB d\u1EA1ng a, b, c"
10616
+ ] }),
10617
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "editor-flex editor-items-center editor-gap-2", style: { margin: 0 }, children: [
10618
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "editor-font-medium", children: "\u0110\u1EC3 tr\u1ED1ng" }),
10619
+ " - V\u1EC1 m\u1EB7c \u0111\u1ECBnh 1, 2, 3"
10620
+ ] })
10621
+ ] })
10622
+ ] }) }),
10623
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
10624
+ /* @__PURE__ */ jsxRuntime.jsx(
10625
+ Button,
10626
+ {
10627
+ variant: "outline",
10628
+ onClick: () => setShowMarkerDialog(false),
10629
+ children: "H\u1EE7y"
10630
+ }
10631
+ ),
10632
+ /* @__PURE__ */ jsxRuntime.jsxs(
10633
+ Button,
10634
+ {
10635
+ onClick: handleCustomMarkerSubmit,
10636
+ disabled: !customMarker.trim(),
10637
+ className: "editor-gap-2",
10638
+ children: [
10639
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListIcon, { size: 16 }),
10640
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\xC1p d\u1EE5ng" })
10641
+ ]
10642
+ }
10643
+ )
10644
+ ] })
10645
+ ] }) })
10646
+ ] });
10432
10647
  }
10433
10648
  var init_context_menu_plugin = __esm({
10434
10649
  "src/plugins/context-menu-plugin.tsx"() {
10435
10650
  init_layout_item_node();
10651
+ init_nodes();
10652
+ init_list_with_color_node();
10436
10653
  init_layout_plugin();
10437
10654
  init_list_color_plugin();
10438
10655
  init_typography();
10656
+ init_dialog();
10657
+ init_input();
10658
+ init_button();
10659
+ init_label();
10439
10660
  }
10440
10661
  });
10441
10662
  function DragDropPastePlugin() {
@@ -28687,99 +28908,90 @@ function FloatingTextFormat({
28687
28908
  ref: popupCharStylesEditorRef,
28688
28909
  className: "editor-floating-text-format",
28689
28910
  children: editor.isEditable() && /* @__PURE__ */ jsxRuntime.jsxs(Flex, { align: "center", gap: 1, className: "editor-flex-nowrap", children: [
28690
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-floating-group editor-flex editor-items-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
28691
- ToggleGroup,
28692
- {
28693
- type: "multiple",
28694
- className: "editor-flex editor-items-center",
28695
- value: [
28696
- isBold ? "bold" : "",
28697
- isItalic ? "italic" : "",
28698
- isUnderline ? "underline" : "",
28699
- isStrikethrough ? "strikethrough" : "",
28700
- isCode ? "code" : "",
28701
- isLink ? "link" : ""
28702
- ].filter(Boolean),
28703
- children: [
28704
- /* @__PURE__ */ jsxRuntime.jsx(
28705
- ToggleGroupItem,
28706
- {
28707
- value: "bold",
28708
- "aria-label": "Toggle bold",
28709
- className: "editor-toolbar-item",
28710
- onClick: () => {
28711
- editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "bold");
28712
- },
28713
- size: "sm",
28714
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BoldIcon, {}) })
28715
- }
28716
- ),
28717
- /* @__PURE__ */ jsxRuntime.jsx(
28718
- ToggleGroupItem,
28719
- {
28720
- value: "italic",
28721
- "aria-label": "Toggle italic",
28722
- className: "editor-toolbar-item",
28723
- onClick: () => {
28724
- editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "italic");
28725
- },
28726
- size: "sm",
28727
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ItalicIcon, {}) })
28728
- }
28729
- ),
28730
- /* @__PURE__ */ jsxRuntime.jsx(
28731
- ToggleGroupItem,
28732
- {
28733
- value: "underline",
28734
- "aria-label": "Toggle underline",
28735
- className: "editor-toolbar-item",
28736
- onClick: () => {
28737
- editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "underline");
28738
- },
28739
- size: "sm",
28740
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UnderlineIcon, {}) })
28741
- }
28742
- ),
28743
- /* @__PURE__ */ jsxRuntime.jsx(
28744
- ToggleGroupItem,
28745
- {
28746
- value: "strikethrough",
28747
- "aria-label": "Toggle strikethrough",
28748
- className: "editor-toolbar-item",
28749
- onClick: () => {
28750
- editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "strikethrough");
28751
- },
28752
- size: "sm",
28753
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.StrikethroughIcon, {}) })
28754
- }
28755
- ),
28756
- /* @__PURE__ */ jsxRuntime.jsx(
28757
- ToggleGroupItem,
28758
- {
28759
- value: "code",
28760
- "aria-label": "Toggle code",
28761
- className: "editor-toolbar-item",
28762
- onClick: () => {
28763
- editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "code");
28764
- },
28765
- size: "sm",
28766
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CodeIcon, {}) })
28767
- }
28768
- ),
28769
- /* @__PURE__ */ jsxRuntime.jsx(
28770
- ToggleGroupItem,
28771
- {
28772
- value: "link",
28773
- "aria-label": "Toggle link",
28774
- className: "editor-toolbar-item",
28775
- onClick: insertLink,
28776
- size: "sm",
28777
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LinkIcon, {}) })
28778
- }
28779
- )
28780
- ]
28781
- }
28782
- ) }),
28911
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-floating-group editor-flex editor-items-center", children: [
28912
+ /* @__PURE__ */ jsxRuntime.jsx(
28913
+ Button,
28914
+ {
28915
+ variant: "ghost",
28916
+ size: "sm",
28917
+ className: "editor-toolbar-item",
28918
+ "data-state": isBold ? "on" : "off",
28919
+ onClick: () => {
28920
+ editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "bold");
28921
+ },
28922
+ "aria-label": "Toggle bold",
28923
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BoldIcon, {}) })
28924
+ }
28925
+ ),
28926
+ /* @__PURE__ */ jsxRuntime.jsx(
28927
+ Button,
28928
+ {
28929
+ variant: "ghost",
28930
+ size: "sm",
28931
+ className: "editor-toolbar-item",
28932
+ "data-state": isItalic ? "on" : "off",
28933
+ onClick: () => {
28934
+ editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "italic");
28935
+ },
28936
+ "aria-label": "Toggle italic",
28937
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ItalicIcon, {}) })
28938
+ }
28939
+ ),
28940
+ /* @__PURE__ */ jsxRuntime.jsx(
28941
+ Button,
28942
+ {
28943
+ variant: "ghost",
28944
+ size: "sm",
28945
+ className: "editor-toolbar-item",
28946
+ "data-state": isUnderline ? "on" : "off",
28947
+ onClick: () => {
28948
+ editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "underline");
28949
+ },
28950
+ "aria-label": "Toggle underline",
28951
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UnderlineIcon, {}) })
28952
+ }
28953
+ ),
28954
+ /* @__PURE__ */ jsxRuntime.jsx(
28955
+ Button,
28956
+ {
28957
+ variant: "ghost",
28958
+ size: "sm",
28959
+ className: "editor-toolbar-item",
28960
+ "data-state": isStrikethrough ? "on" : "off",
28961
+ onClick: () => {
28962
+ editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "strikethrough");
28963
+ },
28964
+ "aria-label": "Toggle strikethrough",
28965
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.StrikethroughIcon, {}) })
28966
+ }
28967
+ ),
28968
+ /* @__PURE__ */ jsxRuntime.jsx(
28969
+ Button,
28970
+ {
28971
+ variant: "ghost",
28972
+ size: "sm",
28973
+ className: "editor-toolbar-item",
28974
+ "data-state": isCode ? "on" : "off",
28975
+ onClick: () => {
28976
+ editor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "code");
28977
+ },
28978
+ "aria-label": "Toggle code",
28979
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CodeIcon, {}) })
28980
+ }
28981
+ ),
28982
+ /* @__PURE__ */ jsxRuntime.jsx(
28983
+ Button,
28984
+ {
28985
+ variant: "ghost",
28986
+ size: "sm",
28987
+ className: "editor-toolbar-item",
28988
+ "data-state": isLink ? "on" : "off",
28989
+ onClick: insertLink,
28990
+ "aria-label": "Toggle link",
28991
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LinkIcon, {}) })
28992
+ }
28993
+ )
28994
+ ] }),
28783
28995
  /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-separator--vertical" }),
28784
28996
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-floating-group--lg editor-flex editor-items-center", children: [
28785
28997
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -28976,8 +29188,8 @@ var init_floating_text_format_plugin = __esm({
28976
29188
  init_dialog();
28977
29189
  init_flex();
28978
29190
  init_separator();
28979
- init_toggle_group();
28980
29191
  init_typography();
29192
+ init_toggle_group();
28981
29193
  }
28982
29194
  });
28983
29195
  function KeywordsPlugin() {
@@ -30172,7 +30384,7 @@ function getResizeEdge(clientX, rect) {
30172
30384
  if (nearLeft && nearRight) return "right";
30173
30385
  return nearLeft ? "left" : "right";
30174
30386
  }
30175
- function getColumnIndexFromTableMap(tableNode, tableCellNode) {
30387
+ function $getColumnIndexFromTableMap(tableNode, tableCellNode) {
30176
30388
  if (!table.$isTableCellNode(tableCellNode)) return null;
30177
30389
  const [tableMap] = table.$computeTableMapSkipCellCheck(tableNode, null, null);
30178
30390
  for (let row = 0; row < tableMap.length; row++) {
@@ -30187,183 +30399,290 @@ function getColumnIndexFromTableMap(tableNode, tableCellNode) {
30187
30399
  }
30188
30400
  return null;
30189
30401
  }
30190
- function TableColumnResizerPlugin() {
30402
+ function TableColumnResizerPlugin({
30403
+ anchorElem = document.body
30404
+ }) {
30191
30405
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
30192
30406
  const isEditable = useLexicalEditable.useLexicalEditable();
30193
30407
  const dragRef = React20.useRef(null);
30408
+ const [hoverState, setHoverState] = React20.useState(null);
30409
+ const resizerRef = React20.useRef(null);
30410
+ const onPointerDownImpl = React20.useCallback((event, cell, edge) => {
30411
+ if (event.button !== 0) return;
30412
+ event.preventDefault();
30413
+ const target = event.target;
30414
+ if (target) {
30415
+ target.setPointerCapture(event.pointerId);
30416
+ }
30417
+ let nextDragState = null;
30418
+ editor.update(() => {
30419
+ const tableCellNode = lexical.$getNearestNodeFromDOMNode(cell);
30420
+ if (!table.$isTableCellNode(tableCellNode)) return;
30421
+ const tableNode = table.$getTableNodeFromLexicalNodeOrThrow(tableCellNode);
30422
+ const tableElement = editor.getElementByKey(tableNode.getKey());
30423
+ if (!tableElement) return;
30424
+ const tableMap = table.$computeTableMapSkipCellCheck(tableNode, null, null)[0];
30425
+ const colCount = tableMap[0]?.length ?? 0;
30426
+ const columnIndexFromMap = $getColumnIndexFromTableMap(tableNode, tableCellNode);
30427
+ if (columnIndexFromMap === null) return;
30428
+ const colSpan = tableCellNode.getColSpan();
30429
+ const resizeColumnIndex = edge === "left" ? columnIndexFromMap - 1 : columnIndexFromMap + colSpan - 1;
30430
+ if (resizeColumnIndex < 0 || resizeColumnIndex >= colCount - 1) return;
30431
+ let currentWidths = tableNode.getColWidths();
30432
+ if (!currentWidths) {
30433
+ const columns = tableElement.querySelectorAll("col");
30434
+ const widths = [];
30435
+ if (columns.length === colCount) {
30436
+ columns.forEach((col) => {
30437
+ const styleWidth = col.style.width;
30438
+ if (styleWidth && styleWidth.endsWith("px")) {
30439
+ widths.push(parseFloat(styleWidth));
30440
+ } else {
30441
+ const rect = col.getBoundingClientRect();
30442
+ widths.push(rect.width || 0);
30443
+ }
30444
+ });
30445
+ }
30446
+ if (widths.length !== colCount) {
30447
+ const firstRow = tableElement.querySelector("tr");
30448
+ if (firstRow) {
30449
+ const cells = firstRow.querySelectorAll("th, td");
30450
+ if (cells.length === colCount) {
30451
+ cells.forEach((cell2) => {
30452
+ widths.push(cell2.getBoundingClientRect().width);
30453
+ });
30454
+ }
30455
+ }
30456
+ }
30457
+ if (widths.length !== colCount) {
30458
+ const tableRect = tableElement.getBoundingClientRect();
30459
+ const avgWidth = tableRect.width / (colCount || 1);
30460
+ for (let i = 0; i < colCount; i++) {
30461
+ widths.push(avgWidth);
30462
+ }
30463
+ }
30464
+ currentWidths = widths;
30465
+ }
30466
+ if (currentWidths[resizeColumnIndex] === void 0 || currentWidths[resizeColumnIndex + 1] === void 0) {
30467
+ return;
30468
+ }
30469
+ nextDragState = {
30470
+ columnIndex: resizeColumnIndex,
30471
+ initialColWidths: currentWidths,
30472
+ startX: event.clientX,
30473
+ startWidth: currentWidths[resizeColumnIndex],
30474
+ tableKey: tableNode.getKey()
30475
+ };
30476
+ });
30477
+ if (!nextDragState) return;
30478
+ dragRef.current = nextDragState;
30479
+ const rootElement = editor.getRootElement();
30480
+ if (rootElement) {
30481
+ rootElement.style.userSelect = "none";
30482
+ rootElement.style.cursor = "col-resize";
30483
+ }
30484
+ const onPointerMoveDocument = (event2) => {
30485
+ const drag = dragRef.current;
30486
+ if (!drag) return;
30487
+ event2.preventDefault();
30488
+ const deltaX = event2.clientX - drag.startX;
30489
+ const { tableKey, columnIndex, initialColWidths } = drag;
30490
+ editor.update(() => {
30491
+ const tableNode = lexical.$getNodeByKey(tableKey);
30492
+ if (!(tableNode instanceof table.TableNode)) return;
30493
+ const currentWidths = tableNode.getColWidths() || initialColWidths;
30494
+ const colCount = tableNode.getColumnCount();
30495
+ const nextColumnIndex = columnIndex + 1;
30496
+ if (nextColumnIndex >= colCount) return;
30497
+ const currentLeftWidth = initialColWidths[columnIndex];
30498
+ const currentRightWidth = initialColWidths[nextColumnIndex];
30499
+ if (currentLeftWidth === void 0 || currentRightWidth === void 0) return;
30500
+ const maxShrinkLeft = currentLeftWidth - MIN_COLUMN_WIDTH_PX;
30501
+ const maxGrowLeft = currentRightWidth - MIN_COLUMN_WIDTH_PX;
30502
+ const constrainedDelta = Math.min(Math.max(deltaX, -maxShrinkLeft), maxGrowLeft);
30503
+ const newLeftWidth = currentLeftWidth + constrainedDelta;
30504
+ const newRightWidth = currentRightWidth - constrainedDelta;
30505
+ const nextColWidths = Array.from({ length: colCount }, (_, i) => {
30506
+ if (i === columnIndex) return newLeftWidth;
30507
+ if (i === nextColumnIndex) return newRightWidth;
30508
+ return currentWidths[i] ?? initialColWidths[i] ?? 0;
30509
+ });
30510
+ if (typeof tableNode.setColWidths === "function") {
30511
+ tableNode.setColWidths(nextColWidths);
30512
+ } else {
30513
+ tableNode.__colWidths = nextColWidths;
30514
+ tableNode.__widths = nextColWidths;
30515
+ tableNode.markDirty();
30516
+ }
30517
+ });
30518
+ };
30519
+ const onPointerUpDocument = (event2) => {
30520
+ const drag = dragRef.current;
30521
+ if (!drag) return;
30522
+ const target2 = event2.target;
30523
+ if (target2 && target2.hasPointerCapture(event2.pointerId)) {
30524
+ target2.releasePointerCapture(event2.pointerId);
30525
+ }
30526
+ dragRef.current = null;
30527
+ const rootElement2 = editor.getRootElement();
30528
+ if (rootElement2) {
30529
+ rootElement2.style.userSelect = "";
30530
+ rootElement2.style.cursor = "";
30531
+ }
30532
+ document.removeEventListener("pointermove", onPointerMoveDocument);
30533
+ document.removeEventListener("pointerup", onPointerUpDocument);
30534
+ };
30535
+ document.addEventListener("pointermove", onPointerMoveDocument);
30536
+ document.addEventListener("pointerup", onPointerUpDocument);
30537
+ }, [editor]);
30538
+ const updateResizerPosition = React20.useCallback(() => {
30539
+ const state = hoverState;
30540
+ if (state === null || !resizerRef.current) return;
30541
+ const { cellKey, edge } = state;
30542
+ const cell = editor.getElementByKey(cellKey);
30543
+ if (!cell) return;
30544
+ const cellRect = cell.getBoundingClientRect();
30545
+ const anchorRect = anchorElem.getBoundingClientRect();
30546
+ const resizerElem = resizerRef.current;
30547
+ const tableElement = cell.closest("table");
30548
+ let top = cellRect.top - anchorRect.top;
30549
+ let height = cellRect.height;
30550
+ if (tableElement) {
30551
+ const tableRect = tableElement.getBoundingClientRect();
30552
+ top = tableRect.top - anchorRect.top;
30553
+ height = tableRect.height;
30554
+ }
30555
+ const left = (edge === "left" ? cellRect.left : cellRect.right) - anchorRect.left - 8;
30556
+ resizerElem.style.transform = `translate(${left}px, ${top}px)`;
30557
+ resizerElem.style.height = `${height}px`;
30558
+ resizerElem.style.opacity = "1";
30559
+ }, [editor, hoverState, anchorElem]);
30560
+ React20.useLayoutEffect(() => {
30561
+ updateResizerPosition();
30562
+ window.addEventListener("resize", updateResizerPosition);
30563
+ window.addEventListener("scroll", updateResizerPosition, true);
30564
+ const updateListener = editor.registerUpdateListener(() => {
30565
+ editor.read(() => {
30566
+ const state = hoverState;
30567
+ if (state !== null) {
30568
+ const cell = editor.getElementByKey(state.cellKey);
30569
+ if (!cell) {
30570
+ setHoverState(null);
30571
+ } else {
30572
+ updateResizerPosition();
30573
+ }
30574
+ }
30575
+ });
30576
+ });
30577
+ return () => {
30578
+ window.removeEventListener("resize", updateResizerPosition);
30579
+ window.removeEventListener("scroll", updateResizerPosition, true);
30580
+ updateListener();
30581
+ };
30582
+ }, [editor, hoverState, updateResizerPosition]);
30194
30583
  React20.useEffect(() => {
30195
30584
  if (!isEditable) return;
30196
30585
  const rootElement = editor.getRootElement();
30197
30586
  if (!rootElement) return;
30198
30587
  const setCursor = (cursor) => {
30199
- rootElement.style.cursor = cursor;
30588
+ if (rootElement) {
30589
+ rootElement.style.cursor = cursor;
30590
+ }
30200
30591
  };
30201
30592
  const clearCursor = () => {
30202
30593
  setCursor("");
30203
30594
  };
30204
30595
  const onPointerMove = (event) => {
30205
30596
  if (dragRef.current) return;
30206
- const cell = getCellTarget(event.target);
30207
- if (!cell) {
30208
- clearCursor();
30597
+ if (event.buttons !== 0) return;
30598
+ if (resizerRef.current && (event.target === resizerRef.current || resizerRef.current.contains(event.target))) {
30209
30599
  return;
30210
30600
  }
30211
- const edge = getResizeEdge(event.clientX, cell.getBoundingClientRect());
30212
- if (edge === "left") {
30213
- const table = cell.closest("table");
30214
- if (table) {
30215
- const tableRect = table.getBoundingClientRect();
30216
- const cellRect = cell.getBoundingClientRect();
30217
- if (Math.abs(cellRect.left - tableRect.left) < 5) {
30218
- clearCursor();
30219
- return;
30220
- }
30221
- }
30222
- }
30223
- setCursor(edge ? "col-resize" : "");
30224
- };
30225
- const onPointerDown = (event) => {
30226
- if (event.button !== 0) return;
30227
30601
  const cell = getCellTarget(event.target);
30228
- if (!cell) return;
30229
- const edge = getResizeEdge(event.clientX, cell.getBoundingClientRect());
30230
- if (!edge) return;
30231
- event.preventDefault();
30232
- let nextDragState = null;
30233
- editor.read(() => {
30234
- const tableCellNode = lexical.$getNearestNodeFromDOMNode(cell);
30235
- if (!table.$isTableCellNode(tableCellNode)) return;
30236
- const tableNode = table.$getTableNodeFromLexicalNodeOrThrow(tableCellNode);
30237
- const columnIndexFromMap = getColumnIndexFromTableMap(tableNode, tableCellNode);
30238
- if (columnIndexFromMap == null) return;
30239
- if (edge === "left" && columnIndexFromMap === 0) return;
30240
- const colSpan = tableCellNode.getColSpan();
30241
- const resizeColumnIndex = edge === "left" ? columnIndexFromMap - 1 : columnIndexFromMap + colSpan - 1;
30242
- let currentWidths = tableNode.getColWidths();
30243
- if (!currentWidths) {
30244
- const tableElement = editor.getElementByKey(tableNode.getKey());
30245
- if (tableElement instanceof HTMLTableElement) {
30246
- const [tableMap] = table.$computeTableMapSkipCellCheck(tableNode, null, null);
30247
- const colCount = tableNode.getColumnCount();
30248
- const widths = new Array(colCount).fill(void 0);
30249
- for (let r = 0; r < tableMap.length; r++) {
30250
- const row = tableMap[r];
30251
- if (!row) continue;
30252
- for (let c = 0; c < row.length; c++) {
30253
- if (widths[c] !== void 0) continue;
30254
- const tableMapCell = row[c];
30255
- if (!tableMapCell) continue;
30256
- const { cell: cell2 } = tableMapCell;
30257
- if (cell2.getColSpan() === 1) {
30258
- const cellElem = editor.getElementByKey(cell2.getKey());
30259
- if (cellElem) {
30260
- widths[c] = Math.round(cellElem.getBoundingClientRect().width);
30261
- }
30262
- }
30263
- }
30264
- if (widths.every((w) => w !== void 0)) break;
30265
- }
30266
- if (widths.some((w) => w === void 0)) {
30267
- if (tableElement.rows.length > 0) {
30268
- const row = tableElement.rows[0];
30269
- if (row && row.cells.length === colCount) {
30270
- const rowWidths = Array.from(row.cells).map((c) => Math.round(c.getBoundingClientRect().width));
30271
- for (let i = 0; i < colCount; i++) {
30272
- if (widths[i] === void 0) widths[i] = rowWidths[i];
30273
- }
30274
- }
30602
+ let nextHoverState = null;
30603
+ if (cell) {
30604
+ editor.read(() => {
30605
+ const cellNode = lexical.$getNearestNodeFromDOMNode(cell);
30606
+ if (table.$isTableCellNode(cellNode)) {
30607
+ const tableNode = table.$getTableNodeFromLexicalNodeOrThrow(cellNode);
30608
+ const cellKey = cellNode.getKey();
30609
+ const tableKey = tableNode.getKey();
30610
+ const edge = getResizeEdge(event.clientX, cell.getBoundingClientRect());
30611
+ if (edge) {
30612
+ const colCount = tableNode.getColumnCount();
30613
+ const colSpan = cellNode.getColSpan();
30614
+ const columnIndexFromMap = $getColumnIndexFromTableMap(tableNode, cellNode);
30615
+ if (columnIndexFromMap !== null && !(edge === "left" && columnIndexFromMap === 0 || edge === "right" && columnIndexFromMap + colSpan === colCount)) {
30616
+ nextHoverState = { cellKey, tableKey, edge };
30275
30617
  }
30276
30618
  }
30277
- if (widths.some((w) => w === void 0)) {
30278
- const tableWidth = tableElement.getBoundingClientRect().width;
30279
- const defaultWidth = tableWidth / colCount;
30280
- for (let i = 0; i < colCount; i++) {
30281
- if (widths[i] === void 0) widths[i] = defaultWidth;
30282
- }
30283
- }
30284
- currentWidths = widths;
30285
30619
  }
30620
+ });
30621
+ }
30622
+ if (!nextHoverState) {
30623
+ if (hoverState !== null) {
30624
+ clearCursor();
30625
+ setHoverState(null);
30286
30626
  }
30287
- if (!currentWidths) {
30288
- currentWidths = Array(tableNode.getColumnCount()).fill(MIN_COLUMN_WIDTH_PX);
30289
- }
30290
- const startWidth = currentWidths[resizeColumnIndex] ?? Math.max(Math.round(cell.getBoundingClientRect().width), MIN_COLUMN_WIDTH_PX);
30291
- nextDragState = {
30292
- tableKey: tableNode.getKey(),
30293
- columnIndex: resizeColumnIndex,
30294
- startX: event.clientX,
30295
- startWidth,
30296
- initialColWidths: [...currentWidths]
30297
- };
30298
- });
30299
- if (!nextDragState) return;
30300
- event.preventDefault();
30301
- event.stopPropagation();
30302
- dragRef.current = nextDragState;
30303
- setCursor("col-resize");
30304
- };
30305
- const onPointerMoveDocument = (event) => {
30306
- const drag = dragRef.current;
30307
- if (!drag) return;
30308
- const { initialColWidths, startX, columnIndex } = drag;
30309
- const deltaX = event.clientX - startX;
30310
- editor.update(() => {
30311
- const tableNode = lexical.$getNodeByKey(drag.tableKey);
30312
- if (!(tableNode instanceof table.TableNode)) return;
30313
- const colWidths = tableNode.getColWidths() ?? initialColWidths;
30314
- const nextColumnIndex = columnIndex + 1;
30315
- const hasNeighbor = nextColumnIndex < initialColWidths.length;
30316
- if (hasNeighbor) {
30317
- const currentLeftWidth = initialColWidths[columnIndex];
30318
- const currentRightWidth = initialColWidths[nextColumnIndex];
30319
- if (currentLeftWidth === void 0 || currentRightWidth === void 0) return;
30320
- const maxShrinkLeft = currentLeftWidth - MIN_COLUMN_WIDTH_PX;
30321
- const maxGrowLeft = currentRightWidth - MIN_COLUMN_WIDTH_PX;
30322
- const constrainedDelta = Math.min(Math.max(deltaX, -maxShrinkLeft), maxGrowLeft);
30323
- const newLeftWidth = currentLeftWidth + constrainedDelta;
30324
- const newRightWidth = currentRightWidth - constrainedDelta;
30325
- if (colWidths[columnIndex] === newLeftWidth && colWidths[nextColumnIndex] === newRightWidth)
30326
- return;
30327
- const nextColWidths = [...colWidths];
30328
- nextColWidths[columnIndex] = newLeftWidth;
30329
- nextColWidths[nextColumnIndex] = newRightWidth;
30330
- tableNode.setColWidths(nextColWidths);
30331
- } else {
30332
- const currentWidth = initialColWidths[columnIndex];
30333
- if (currentWidth === void 0) return;
30334
- const newWidth = Math.max(MIN_COLUMN_WIDTH_PX, Math.round(currentWidth + deltaX));
30335
- if (colWidths[columnIndex] === newWidth) return;
30336
- const nextColWidths = [...colWidths];
30337
- nextColWidths[columnIndex] = newWidth;
30338
- tableNode.setColWidths(nextColWidths);
30627
+ } else {
30628
+ setCursor("col-resize");
30629
+ if (!hoverState || hoverState.cellKey !== nextHoverState.cellKey || hoverState.edge !== nextHoverState.edge) {
30630
+ setHoverState(nextHoverState);
30339
30631
  }
30340
- });
30341
- };
30342
- const onPointerUpDocument = () => {
30343
- if (!dragRef.current) return;
30344
- dragRef.current = null;
30345
- clearCursor();
30632
+ }
30346
30633
  };
30347
- rootElement.addEventListener("pointermove", onPointerMove);
30348
- rootElement.addEventListener("pointerdown", onPointerDown);
30349
- document.addEventListener("pointermove", onPointerMoveDocument);
30350
- document.addEventListener("pointerup", onPointerUpDocument);
30634
+ anchorElem.addEventListener("pointermove", onPointerMove);
30351
30635
  return () => {
30352
- rootElement.removeEventListener("pointermove", onPointerMove);
30353
- rootElement.removeEventListener("pointerdown", onPointerDown);
30354
- document.removeEventListener("pointermove", onPointerMoveDocument);
30355
- document.removeEventListener("pointerup", onPointerUpDocument);
30636
+ anchorElem.removeEventListener("pointermove", onPointerMove);
30356
30637
  clearCursor();
30357
- dragRef.current = null;
30358
30638
  };
30359
- }, [editor, isEditable]);
30360
- return null;
30639
+ }, [editor, isEditable, hoverState, anchorElem]);
30640
+ const resizer = React20.useMemo(() => {
30641
+ const state = hoverState;
30642
+ if (state === null) return null;
30643
+ const { cellKey, edge } = state;
30644
+ return reactDom.createPortal(
30645
+ /* @__PURE__ */ jsxRuntime.jsx(
30646
+ "div",
30647
+ {
30648
+ ref: resizerRef,
30649
+ className: "editor-table-cell-resizer",
30650
+ style: {
30651
+ position: "absolute",
30652
+ top: 0,
30653
+ left: 0,
30654
+ width: "16px",
30655
+ opacity: 1,
30656
+ willChange: "transform",
30657
+ userSelect: "none"
30658
+ },
30659
+ onPointerDown: (event) => {
30660
+ event.stopPropagation();
30661
+ event.preventDefault();
30662
+ const cell = editor.getElementByKey(cellKey);
30663
+ if (cell instanceof HTMLTableCellElement) {
30664
+ onPointerDownImpl(event.nativeEvent, cell, edge);
30665
+ }
30666
+ },
30667
+ children: /* @__PURE__ */ jsxRuntime.jsx(
30668
+ "div",
30669
+ {
30670
+ className: "editor-table-cell-resize-ruler",
30671
+ style: { pointerEvents: "none" }
30672
+ }
30673
+ )
30674
+ }
30675
+ ),
30676
+ anchorElem
30677
+ );
30678
+ }, [hoverState, anchorElem, editor, onPointerDownImpl]);
30679
+ return resizer;
30361
30680
  }
30362
30681
  var EDGE_HITBOX_PX, MIN_COLUMN_WIDTH_PX;
30363
30682
  var init_table_column_resizer_plugin = __esm({
30364
30683
  "src/plugins/table-column-resizer-plugin.tsx"() {
30365
30684
  "use client";
30366
- EDGE_HITBOX_PX = 12;
30685
+ EDGE_HITBOX_PX = 8;
30367
30686
  MIN_COLUMN_WIDTH_PX = 15;
30368
30687
  }
30369
30688
  });
@@ -30467,6 +30786,10 @@ var init_block_format_data = __esm({
30467
30786
  label: "Alpha List (a, b, c)",
30468
30787
  icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CaseSensitiveIcon, {}) })
30469
30788
  },
30789
+ "number-multi-level": {
30790
+ label: "Multi-level List (1.1 / 1.1.1)",
30791
+ icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListOrderedIcon, {}) })
30792
+ },
30470
30793
  bullet: {
30471
30794
  label: "Bulleted List",
30472
30795
  icon: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListIcon, {}) })
@@ -30528,6 +30851,7 @@ function BlockFormatDropDown({
30528
30851
  else if (markerType === "+") type = "bullet-plus";
30529
30852
  } else if (type === "number") {
30530
30853
  if (markerType === "alpha") type = "number-alpha";
30854
+ else if (markerType === "multi-level") type = "number-multi-level";
30531
30855
  }
30532
30856
  }
30533
30857
  setBlockType(type);
@@ -31245,61 +31569,40 @@ function ElementFormatToolbarPlugin({
31245
31569
  }
31246
31570
  };
31247
31571
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
31248
- /* @__PURE__ */ jsxRuntime.jsx(
31249
- ToggleGroup,
31572
+ Object.entries(ELEMENT_FORMAT_OPTIONS).map(([value, option]) => /* @__PURE__ */ jsxRuntime.jsx(
31573
+ Button,
31250
31574
  {
31251
- type: "single",
31252
- value: elementFormat,
31253
- onValueChange: handleValueChange,
31575
+ variant: "outline",
31254
31576
  size: "sm",
31577
+ "aria-label": option.name,
31578
+ "data-state": elementFormat === value ? "on" : "off",
31579
+ onClick: () => handleValueChange(value),
31580
+ className: "editor-toolbar-item",
31581
+ children: option.icon
31582
+ },
31583
+ value
31584
+ )),
31585
+ separator && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" }),
31586
+ /* @__PURE__ */ jsxRuntime.jsx(
31587
+ Button,
31588
+ {
31255
31589
  variant: "outline",
31256
- children: Object.entries(ELEMENT_FORMAT_OPTIONS).map(([value, option]) => /* @__PURE__ */ jsxRuntime.jsx(
31257
- ToggleGroupItem,
31258
- {
31259
- value,
31260
- variant: "outline",
31261
- size: "sm",
31262
- "aria-label": option.name,
31263
- className: "editor-toolbar-item",
31264
- children: option.icon
31265
- },
31266
- value
31267
- ))
31590
+ size: "sm",
31591
+ "aria-label": "Outdent",
31592
+ onClick: () => handleValueChange("outdent"),
31593
+ className: "editor-toolbar-item",
31594
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.IndentDecreaseIcon, {}) })
31268
31595
  }
31269
31596
  ),
31270
- separator && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" }),
31271
- /* @__PURE__ */ jsxRuntime.jsxs(
31272
- ToggleGroup,
31597
+ /* @__PURE__ */ jsxRuntime.jsx(
31598
+ Button,
31273
31599
  {
31274
- type: "single",
31275
- value: elementFormat,
31276
- onValueChange: handleValueChange,
31277
- size: "sm",
31278
31600
  variant: "outline",
31279
- children: [
31280
- /* @__PURE__ */ jsxRuntime.jsx(
31281
- ToggleGroupItem,
31282
- {
31283
- value: "outdent",
31284
- "aria-label": "Outdent",
31285
- variant: "outline",
31286
- size: "sm",
31287
- className: "editor-toolbar-item",
31288
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.IndentDecreaseIcon, {}) })
31289
- }
31290
- ),
31291
- /* @__PURE__ */ jsxRuntime.jsx(
31292
- ToggleGroupItem,
31293
- {
31294
- value: "indent",
31295
- variant: "outline",
31296
- "aria-label": "Indent",
31297
- size: "sm",
31298
- className: "editor-toolbar-item",
31299
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.IndentIncreaseIcon, {}) })
31300
- }
31301
- )
31302
- ]
31601
+ size: "sm",
31602
+ "aria-label": "Indent",
31603
+ onClick: () => handleValueChange("indent"),
31604
+ className: "editor-toolbar-item",
31605
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.IndentIncreaseIcon, {}) })
31303
31606
  }
31304
31607
  )
31305
31608
  ] });
@@ -31312,8 +31615,8 @@ var init_element_format_toolbar_plugin = __esm({
31312
31615
  init_layout_item_node();
31313
31616
  init_use_update_toolbar();
31314
31617
  init_get_selected_node();
31618
+ init_button();
31315
31619
  init_separator();
31316
- init_toggle_group();
31317
31620
  init_typography();
31318
31621
  ELEMENT_FORMAT_OPTIONS = {
31319
31622
  left: {
@@ -31643,32 +31946,24 @@ function FontFormatToolbarPlugin() {
31643
31946
  }
31644
31947
  }, []);
31645
31948
  useUpdateToolbarHandler($updateToolbar);
31646
- return /* @__PURE__ */ jsxRuntime.jsx(
31647
- ToggleGroup,
31949
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: FORMATS.map(({ format, icon: Icon, label }) => /* @__PURE__ */ jsxRuntime.jsx(
31950
+ Button,
31648
31951
  {
31649
- type: "multiple",
31650
- value: activeFormats,
31651
- onValueChange: setActiveFormats,
31652
- variant: "default",
31952
+ variant: "ghost",
31653
31953
  size: "sm",
31654
- children: FORMATS.map(({ format, icon: Icon, label }) => /* @__PURE__ */ jsxRuntime.jsx(
31655
- ToggleGroupItem,
31656
- {
31657
- value: format,
31658
- "aria-label": label,
31659
- className: "editor-toolbar-item",
31660
- onClick: () => {
31661
- activeEditor.dispatchCommand(
31662
- lexical.FORMAT_TEXT_COMMAND,
31663
- format
31664
- );
31665
- },
31666
- children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "editor-icon-sm" })
31667
- },
31668
- format
31669
- ))
31670
- }
31671
- );
31954
+ "aria-label": label,
31955
+ "data-state": activeFormats.includes(format) ? "on" : "off",
31956
+ className: "editor-toolbar-item",
31957
+ onClick: () => {
31958
+ activeEditor.dispatchCommand(
31959
+ lexical.FORMAT_TEXT_COMMAND,
31960
+ format
31961
+ );
31962
+ },
31963
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "editor-icon-sm" })
31964
+ },
31965
+ format
31966
+ )) });
31672
31967
  }
31673
31968
  var FORMATS;
31674
31969
  var init_font_format_toolbar_plugin = __esm({
@@ -31676,7 +31971,7 @@ var init_font_format_toolbar_plugin = __esm({
31676
31971
  "use client";
31677
31972
  init_toolbar_context();
31678
31973
  init_use_update_toolbar();
31679
- init_toggle_group();
31974
+ init_button();
31680
31975
  FORMATS = [
31681
31976
  { format: "bold", icon: lucideReact.BoldIcon, label: "Bold" },
31682
31977
  { format: "italic", icon: lucideReact.ItalicIcon, label: "Italic" },
@@ -31685,14 +31980,6 @@ var init_font_format_toolbar_plugin = __esm({
31685
31980
  ];
31686
31981
  }
31687
31982
  });
31688
- function ButtonGroup({ className, children, ...props }) {
31689
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("editor-button-group", className), ...props, children });
31690
- }
31691
- var init_button_group = __esm({
31692
- "src/ui/button-group.tsx"() {
31693
- init_utils();
31694
- }
31695
- });
31696
31983
  function FontSizeToolbarPlugin() {
31697
31984
  const style = "font-size";
31698
31985
  const [fontSize, setFontSize] = React20.useState(DEFAULT_FONT_SIZE);
@@ -31782,7 +32069,7 @@ function FontSizeToolbarPlugin() {
31782
32069
  React20.useEffect(() => {
31783
32070
  return () => stopTimer();
31784
32071
  }, [stopTimer]);
31785
- return /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { children: [
32072
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
31786
32073
  /* @__PURE__ */ jsxRuntime.jsx(
31787
32074
  Button,
31788
32075
  {
@@ -31839,7 +32126,6 @@ var init_font_size_toolbar_plugin = __esm({
31839
32126
  init_toolbar_context();
31840
32127
  init_use_update_toolbar();
31841
32128
  init_button();
31842
- init_button_group();
31843
32129
  init_input();
31844
32130
  init_typography();
31845
32131
  DEFAULT_FONT_SIZE = 16;
@@ -31883,7 +32169,7 @@ function HistoryToolbarPlugin() {
31883
32169
  )
31884
32170
  );
31885
32171
  }, [$updateToolbar, activeEditor, editor]);
31886
- return /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { children: [
32172
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
31887
32173
  /* @__PURE__ */ jsxRuntime.jsx(
31888
32174
  Button,
31889
32175
  {
@@ -31894,7 +32180,6 @@ function HistoryToolbarPlugin() {
31894
32180
  title: utils.IS_APPLE ? "Undo (\u2318Z)" : "Undo (Ctrl+Z)",
31895
32181
  type: "button",
31896
32182
  "aria-label": "Undo",
31897
- size: "sm",
31898
32183
  variant: "ghost",
31899
32184
  className: "editor-toolbar-item",
31900
32185
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UndoIcon, { className: "editor-icon-sm" })
@@ -31910,7 +32195,6 @@ function HistoryToolbarPlugin() {
31910
32195
  title: utils.IS_APPLE ? "Redo (\u21E7\u2318Z)" : "Redo (Ctrl+Y)",
31911
32196
  type: "button",
31912
32197
  "aria-label": "Redo",
31913
- size: "sm",
31914
32198
  variant: "ghost",
31915
32199
  className: "editor-toolbar-item",
31916
32200
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RedoIcon, { className: "editor-icon-sm" })
@@ -31923,7 +32207,6 @@ var init_history_toolbar_plugin = __esm({
31923
32207
  "use client";
31924
32208
  init_toolbar_context();
31925
32209
  init_button();
31926
- init_button_group();
31927
32210
  }
31928
32211
  });
31929
32212
  var Toggle;
@@ -32033,50 +32316,43 @@ function SubSuperToolbarPlugin() {
32033
32316
  }
32034
32317
  };
32035
32318
  useUpdateToolbarHandler($updateToolbar);
32036
- return /* @__PURE__ */ jsxRuntime.jsxs(
32037
- ToggleGroup,
32038
- {
32039
- type: "single",
32040
- value: isSubscript ? "subscript" : isSuperscript ? "superscript" : "",
32041
- size: "default",
32042
- variant: "outline",
32043
- children: [
32044
- /* @__PURE__ */ jsxRuntime.jsx(
32045
- ToggleGroupItem,
32046
- {
32047
- value: "subscript",
32048
- size: "default",
32049
- "aria-label": "Toggle subscript",
32050
- onClick: () => {
32051
- activeEditor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "subscript");
32052
- },
32053
- variant: "outline",
32054
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SubscriptIcon, {}) })
32055
- }
32056
- ),
32057
- /* @__PURE__ */ jsxRuntime.jsx(
32058
- ToggleGroupItem,
32059
- {
32060
- value: "superscript",
32061
- size: "default",
32062
- "aria-label": "Toggle superscript",
32063
- onClick: () => {
32064
- activeEditor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "superscript");
32065
- },
32066
- variant: "outline",
32067
- children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SuperscriptIcon, {}) })
32068
- }
32069
- )
32070
- ]
32071
- }
32072
- );
32319
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32320
+ /* @__PURE__ */ jsxRuntime.jsx(
32321
+ Button,
32322
+ {
32323
+ variant: "outline",
32324
+ size: "icon",
32325
+ "aria-label": "Toggle subscript",
32326
+ "data-state": isSubscript ? "on" : "off",
32327
+ onClick: () => {
32328
+ activeEditor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "subscript");
32329
+ },
32330
+ className: "editor-toolbar-item",
32331
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SubscriptIcon, {}) })
32332
+ }
32333
+ ),
32334
+ /* @__PURE__ */ jsxRuntime.jsx(
32335
+ Button,
32336
+ {
32337
+ variant: "outline",
32338
+ size: "icon",
32339
+ "aria-label": "Toggle superscript",
32340
+ "data-state": isSuperscript ? "on" : "off",
32341
+ onClick: () => {
32342
+ activeEditor.dispatchCommand(lexical.FORMAT_TEXT_COMMAND, "superscript");
32343
+ },
32344
+ className: "editor-toolbar-item",
32345
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconSize, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SuperscriptIcon, {}) })
32346
+ }
32347
+ )
32348
+ ] });
32073
32349
  }
32074
32350
  var init_subsuper_toolbar_plugin = __esm({
32075
32351
  "src/plugins/toolbar/subsuper-toolbar-plugin.tsx"() {
32076
32352
  "use client";
32077
32353
  init_toolbar_context();
32078
32354
  init_use_update_toolbar();
32079
- init_toggle_group();
32355
+ init_button();
32080
32356
  init_typography();
32081
32357
  }
32082
32358
  });
@@ -32606,47 +32882,50 @@ function Plugins({
32606
32882
  children: ({ blockType }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32607
32883
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsx(HistoryToolbarPlugin, {}) }),
32608
32884
  /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" }),
32609
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsxs(BlockInsertPlugin, { children: [
32610
- /* @__PURE__ */ jsxRuntime.jsx(InsertHorizontalRule, {}),
32611
- /* @__PURE__ */ jsxRuntime.jsx(InsertImage, {}),
32612
- /* @__PURE__ */ jsxRuntime.jsx(InsertTable, {}),
32613
- /* @__PURE__ */ jsxRuntime.jsx(InsertColumnsLayout, {}),
32614
- /* @__PURE__ */ jsxRuntime.jsx(InsertEmbeds, {})
32615
- ] }) }),
32616
- /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" }),
32617
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsxs(BlockFormatDropDown, { children: [
32618
- /* @__PURE__ */ jsxRuntime.jsx(FormatParagraph, {}),
32619
- /* @__PURE__ */ jsxRuntime.jsx(FormatHeading, { levels: ["h1", "h2", "h3"] }),
32620
- /* @__PURE__ */ jsxRuntime.jsx(FormatNumberedList, {}),
32621
- /* @__PURE__ */ jsxRuntime.jsx(
32622
- FormatListWithMarker,
32623
- {
32624
- blockFormatValue: "number-alpha",
32625
- listType: "number",
32626
- markerType: "alpha"
32627
- }
32628
- ),
32629
- /* @__PURE__ */ jsxRuntime.jsx(FormatBulletedList, {}),
32630
- /* @__PURE__ */ jsxRuntime.jsx(
32631
- FormatListWithMarker,
32632
- {
32633
- blockFormatValue: "bullet-dash",
32634
- listType: "bullet",
32635
- markerType: "-"
32636
- }
32637
- ),
32638
- /* @__PURE__ */ jsxRuntime.jsx(
32639
- FormatListWithMarker,
32640
- {
32641
- blockFormatValue: "bullet-plus",
32642
- listType: "bullet",
32643
- markerType: "+"
32644
- }
32645
- ),
32646
- /* @__PURE__ */ jsxRuntime.jsx(FormatCheckList, {}),
32647
- /* @__PURE__ */ jsxRuntime.jsx(FormatCodeBlock, {}),
32648
- /* @__PURE__ */ jsxRuntime.jsx(FormatQuote, {})
32649
- ] }) }),
32885
+ blockType !== "code" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32886
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsxs(BlockInsertPlugin, { children: [
32887
+ /* @__PURE__ */ jsxRuntime.jsx(InsertHorizontalRule, {}),
32888
+ /* @__PURE__ */ jsxRuntime.jsx(InsertImage, {}),
32889
+ /* @__PURE__ */ jsxRuntime.jsx(InsertTable, {}),
32890
+ /* @__PURE__ */ jsxRuntime.jsx(InsertColumnsLayout, {}),
32891
+ /* @__PURE__ */ jsxRuntime.jsx(InsertEmbeds, {})
32892
+ ] }) }),
32893
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" }),
32894
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsxs(BlockFormatDropDown, { children: [
32895
+ /* @__PURE__ */ jsxRuntime.jsx(FormatParagraph, {}),
32896
+ /* @__PURE__ */ jsxRuntime.jsx(FormatHeading, { levels: ["h1", "h2", "h3"] }),
32897
+ /* @__PURE__ */ jsxRuntime.jsx(FormatNumberedList, {}),
32898
+ /* @__PURE__ */ jsxRuntime.jsx(
32899
+ FormatListWithMarker,
32900
+ {
32901
+ blockFormatValue: "number-alpha",
32902
+ listType: "number",
32903
+ markerType: "alpha"
32904
+ }
32905
+ ),
32906
+ /* @__PURE__ */ jsxRuntime.jsx(FormatBulletedList, {}),
32907
+ /* @__PURE__ */ jsxRuntime.jsx(
32908
+ FormatListWithMarker,
32909
+ {
32910
+ blockFormatValue: "bullet-dash",
32911
+ listType: "bullet",
32912
+ markerType: "-"
32913
+ }
32914
+ ),
32915
+ /* @__PURE__ */ jsxRuntime.jsx(
32916
+ FormatListWithMarker,
32917
+ {
32918
+ blockFormatValue: "bullet-plus",
32919
+ listType: "bullet",
32920
+ markerType: "+"
32921
+ }
32922
+ ),
32923
+ /* @__PURE__ */ jsxRuntime.jsx(FormatCheckList, {}),
32924
+ /* @__PURE__ */ jsxRuntime.jsx(FormatCodeBlock, {}),
32925
+ /* @__PURE__ */ jsxRuntime.jsx(FormatQuote, {})
32926
+ ] }) }),
32927
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "editor-toolbar-separator" })
32928
+ ] }),
32650
32929
  blockType === "code" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "editor-toolbar-group", children: /* @__PURE__ */ jsxRuntime.jsx(CodeLanguageToolbarPlugin, {}) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32651
32930
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "editor-toolbar-group", children: [
32652
32931
  /* @__PURE__ */ jsxRuntime.jsx(FontFamilyToolbarPlugin, {}),
@@ -32697,7 +32976,7 @@ function Plugins({
32697
32976
  /* @__PURE__ */ jsxRuntime.jsx(LexicalHorizontalRulePlugin.HorizontalRulePlugin, {}),
32698
32977
  /* @__PURE__ */ jsxRuntime.jsx(LexicalTablePlugin.TablePlugin, { hasHorizontalScroll: true }),
32699
32978
  /* @__PURE__ */ jsxRuntime.jsx(InsertTableCommandPlugin, {}),
32700
- /* @__PURE__ */ jsxRuntime.jsx(TableColumnResizerPlugin, {}),
32979
+ /* @__PURE__ */ jsxRuntime.jsx(TableColumnResizerPlugin, { anchorElem: floatingAnchorElem ?? document.body }),
32701
32980
  /* @__PURE__ */ jsxRuntime.jsx(LexicalListPlugin.ListPlugin, {}),
32702
32981
  /* @__PURE__ */ jsxRuntime.jsx(LexicalTabIndentationPlugin.TabIndentationPlugin, {}),
32703
32982
  /* @__PURE__ */ jsxRuntime.jsx(LexicalHistoryPlugin.HistoryPlugin, {})
@@ -33070,7 +33349,18 @@ function Editor({
33070
33349
  Promise.resolve().then(() => (init_plugins(), plugins_exports)).then((m) => ({ Plugins: m.Plugins }))
33071
33350
  ]).then(([nodes2, { Plugins: Plugins3 }]) => setConfig({ nodes: nodes2, Plugins: Plugins3 }));
33072
33351
  }, []);
33073
- if (!config) {
33352
+ const editorConfig = React20.useMemo(() => {
33353
+ if (!config || !config.nodes) return null;
33354
+ const validNodes = config.nodes.filter((node) => {
33355
+ if (node === void 0) {
33356
+ console.error("[Editor] Found undefined node in config.nodes");
33357
+ return false;
33358
+ }
33359
+ return true;
33360
+ });
33361
+ return createEditorConfig(validNodes);
33362
+ }, [config]);
33363
+ if (!config || !editorConfig) {
33074
33364
  return /* @__PURE__ */ jsxRuntime.jsx(
33075
33365
  "div",
33076
33366
  {
@@ -33082,7 +33372,6 @@ function Editor({
33082
33372
  }
33083
33373
  );
33084
33374
  }
33085
- const editorConfig = createEditorConfig(config.nodes);
33086
33375
  const { Plugins: Plugins2 } = config;
33087
33376
  return /* @__PURE__ */ jsxRuntime.jsx(
33088
33377
  "div",