@collabchron/notiq 0.3.0 → 1.0.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.
Files changed (282) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -39
  3. package/dist/CodeActionMenuPlugin-EINOY4U4.mjs +15 -0
  4. package/dist/DynamicBlockComponent-NRQJ4WW4.mjs +161 -0
  5. package/dist/EquationComponent-CB6DFIHV.mjs +154 -0
  6. package/dist/ExcalidrawComponent-XW6646OH.mjs +528 -0
  7. package/dist/ExcalidrawPlugin-ZFHT62IF.mjs +14 -0
  8. package/dist/ExportPlugin-V2RLM63S.mjs +11 -0
  9. package/dist/FloatingLinkEditorPlugin-TRTCMSP4.mjs +12 -0
  10. package/dist/FloatingTextFormatToolbarPlugin-F2GY6LMI.mjs +30 -0
  11. package/dist/HintComponet-BRL6EAMS.mjs +217 -0
  12. package/dist/InlineImageComponent-UWIUWBHI.mjs +453 -0
  13. package/dist/MobileToolbar-BOOZAMQE.mjs +268 -0
  14. package/dist/SlashCommand-GMT5JI33.mjs +28 -0
  15. package/dist/StoryBuilderComponent-JGDBM5JU.mjs +562 -0
  16. package/{src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx → dist/TableCellActionMenuPlugin-PGK2K3VG.mjs} +667 -759
  17. package/{src/components/editor/plugins/TableHoverActionsPlugin/index.tsx → dist/TableHoverActionsPlugin-GJVE6VRW.mjs} +258 -314
  18. package/dist/TemplatePlugin-ZD3QEVTI.mjs +9 -0
  19. package/dist/ToolbarPlugin-YKYA4NB4.mjs +1547 -0
  20. package/dist/babel-JZ2EV6AX.mjs +7233 -0
  21. package/dist/background-color-XZTYLGO2.mjs +362 -0
  22. package/dist/block-format-YJCV2DIY.mjs +15 -0
  23. package/dist/chunk-2FNEAMSP.mjs +127 -0
  24. package/dist/chunk-3CPBODXA.mjs +84 -0
  25. package/dist/chunk-3G37YKTV.mjs +83 -0
  26. package/dist/chunk-3JVFG7ER.mjs +184 -0
  27. package/dist/chunk-456TN7IM.mjs +110 -0
  28. package/dist/chunk-4EXYCTGJ.mjs +27 -0
  29. package/{src/utils/getSelectedNode.ts → dist/chunk-4HBCVSE6.mjs} +26 -27
  30. package/dist/chunk-4MEDW3T6.mjs +125 -0
  31. package/dist/chunk-4VWFVWYP.mjs +36 -0
  32. package/dist/chunk-5BAKY5KN.mjs +84 -0
  33. package/dist/chunk-5QSNIVIG.mjs +333 -0
  34. package/dist/chunk-64Z3FI7T.mjs +37 -0
  35. package/{src/components/editor/nodes/Stepper/index.tsx → dist/chunk-6RNZQOH2.mjs} +214 -260
  36. package/dist/chunk-77KXU36M.mjs +64 -0
  37. package/dist/chunk-77UA6HYR.mjs +165 -0
  38. package/dist/chunk-7NZAPJ4G.mjs +102 -0
  39. package/dist/chunk-7VUMHWWL.mjs +152 -0
  40. package/dist/chunk-AMMKBSST.mjs +1256 -0
  41. package/dist/chunk-BIU7WTLX.mjs +95 -0
  42. package/dist/chunk-EGMI62PP.mjs +83 -0
  43. package/dist/chunk-EHNQD5KO.mjs +88 -0
  44. package/dist/chunk-FSM26655.mjs +37 -0
  45. package/{src/components/editor/nodes/Hint/index.tsx → dist/chunk-G53GLEAY.mjs} +158 -190
  46. package/dist/chunk-GK35L7UY.mjs +28 -0
  47. package/dist/chunk-GXYD4VZM.mjs +193 -0
  48. package/dist/chunk-GYIOYVCN.mjs +538 -0
  49. package/dist/chunk-GZPNVR7L.mjs +157 -0
  50. package/dist/chunk-JXDPPUJI.mjs +52 -0
  51. package/dist/chunk-K36V4SIW.mjs +141 -0
  52. package/dist/chunk-KJ6AJ44Q.mjs +128 -0
  53. package/dist/chunk-KJV3FAZ7.mjs +142 -0
  54. package/{src/components/editor/plugins/ImagesPlugin/index.tsx → dist/chunk-LGG4IUIA.mjs} +189 -222
  55. package/dist/chunk-LQN3CMKV.mjs +1906 -0
  56. package/dist/chunk-N3WN46VL.mjs +236 -0
  57. package/dist/chunk-PBD6LMLC.mjs +366 -0
  58. package/dist/chunk-POGRR73N.mjs +33 -0
  59. package/{src/components/editor/utils/editorFormatting.ts → dist/chunk-PZSUSXQG.mjs} +238 -282
  60. package/dist/chunk-QEIFVK5M.mjs +29 -0
  61. package/dist/chunk-QHIQKMVN.mjs +427 -0
  62. package/dist/chunk-TCYK7DM7.mjs +36 -0
  63. package/dist/chunk-TTHQCW5F.mjs +47 -0
  64. package/dist/chunk-U47ABU5Z.mjs +53 -0
  65. package/dist/chunk-WDG7J2DY.mjs +116 -0
  66. package/dist/chunk-WJRHXI2C.mjs +733 -0
  67. package/dist/chunk-XLER2DHM.mjs +357 -0
  68. package/dist/chunk-XWC4TK2N.mjs +315 -0
  69. package/dist/chunk-YHPNOWFH.mjs +15 -0
  70. package/dist/chunk-YKC3SO4Z.mjs +32 -0
  71. package/dist/chunk-YMBXLRW5.mjs +374 -0
  72. package/dist/chunk-YPHOEJ46.mjs +64 -0
  73. package/dist/chunk-YUDCJRJM.mjs +25 -0
  74. package/dist/chunk-Z4EWP7BI.mjs +65 -0
  75. package/dist/chunk-ZB5LZQKC.mjs +191 -0
  76. package/dist/chunk-ZJRKATOJ.mjs +65 -0
  77. package/dist/color-BPKOPQKN.mjs +12 -0
  78. package/dist/estree-XC56IUFX.mjs +4414 -0
  79. package/dist/font-FEZ3GKSF.mjs +13 -0
  80. package/dist/font-size-EK775WRH.mjs +15 -0
  81. package/dist/html-S3ACX7NI.mjs +2738 -0
  82. package/dist/image-2PJIAYAT.mjs +993 -0
  83. package/dist/index.d.mts +145 -0
  84. package/dist/index.d.ts +145 -0
  85. package/dist/index.js +57855 -0
  86. package/dist/index.mjs +1790 -0
  87. package/dist/insert-gif-SAIDYURE.mjs +100 -0
  88. package/dist/insert-image-U3RJN3OW.mjs +259 -0
  89. package/dist/insert-node-5P2CRJ7S.mjs +201 -0
  90. package/dist/insert-poll-HCPM7MO6.mjs +33 -0
  91. package/dist/insert-table-24XYUS2W.mjs +66 -0
  92. package/dist/markdown-SNVBOSRA.mjs +3487 -0
  93. package/dist/poll-component-2R4MDLHS.mjs +303 -0
  94. package/dist/postcss-ONF3VDIM.mjs +5051 -0
  95. package/dist/standalone-EOIALU3M.mjs +2373 -0
  96. package/dist/stepper-FSARL6X6.mjs +304 -0
  97. package/dist/styles/notiq.css +1149 -0
  98. package/dist/text-align-VLECWO4H.mjs +118 -0
  99. package/dist/text-format-BG5WOOPZ.mjs +16 -0
  100. package/dist/typescript-AMPI6OVS.mjs +13135 -0
  101. package/package.json +67 -11
  102. package/src/styles/notiq.css +1149 -0
  103. package/src/styles/tailwind-plugin.ts +134 -0
  104. package/components.json +0 -21
  105. package/eslint.config.mjs +0 -16
  106. package/next.config.ts +0 -12
  107. package/postcss.config.mjs +0 -5
  108. package/public/file.svg +0 -1
  109. package/public/globe.svg +0 -1
  110. package/public/images/icons/plus.svg +0 -10
  111. package/public/next.svg +0 -1
  112. package/public/vercel.svg +0 -1
  113. package/public/window.svg +0 -1
  114. package/src/app/actions.ts +0 -2
  115. package/src/app/api/ai/route.ts +0 -175
  116. package/src/app/api/edgestore/[...edgestore]/route.ts +0 -28
  117. package/src/app/favicon.ico +0 -0
  118. package/src/app/globals.css +0 -205
  119. package/src/app/layout.tsx +0 -38
  120. package/src/app/page.tsx +0 -12
  121. package/src/components/editor/Core.tsx +0 -220
  122. package/src/components/editor/hooks/instructions-messages.ts +0 -300
  123. package/src/components/editor/hooks/use-mobile.ts +0 -19
  124. package/src/components/editor/hooks/useReport.ts +0 -67
  125. package/src/components/editor/hooks/useResizeObservert.ts +0 -22
  126. package/src/components/editor/index.tsx +0 -39
  127. package/src/components/editor/lexical-on-change.tsx +0 -28
  128. package/src/components/editor/nodes/CollapsibleNode/CollapsibleContainerNode.ts +0 -92
  129. package/src/components/editor/nodes/CollapsibleNode/CollapsibleContentNode.ts +0 -65
  130. package/src/components/editor/nodes/CollapsibleNode/CollapsibleTitleNode.ts +0 -105
  131. package/src/components/editor/nodes/EquationNode/EquationComponent.tsx +0 -143
  132. package/src/components/editor/nodes/EquationNode/EquationNode.tsx +0 -170
  133. package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawComponent.tsx +0 -228
  134. package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawImage.tsx +0 -137
  135. package/src/components/editor/nodes/ExcalidrawNode/ImageResizer.tsx +0 -317
  136. package/src/components/editor/nodes/ExcalidrawNode/index.tsx +0 -204
  137. package/src/components/editor/nodes/FigmaNode/FigmaNode.tsx +0 -134
  138. package/src/components/editor/nodes/Hint/HintComponet.tsx +0 -221
  139. package/src/components/editor/nodes/ImageNode/index.tsx +0 -328
  140. package/src/components/editor/nodes/InlineImageNode/InlineImageComponent.tsx +0 -383
  141. package/src/components/editor/nodes/InlineImageNode/InlineImageNode.css +0 -94
  142. package/src/components/editor/nodes/InlineImageNode/InlineImageNode.tsx +0 -309
  143. package/src/components/editor/nodes/LayoutNode/LayoutContainerNode.ts +0 -146
  144. package/src/components/editor/nodes/LayoutNode/LayoutItemNode.ts +0 -79
  145. package/src/components/editor/nodes/PollNode/index.tsx +0 -204
  146. package/src/components/editor/nodes/TweetNode/index.tsx +0 -214
  147. package/src/components/editor/nodes/index.ts +0 -81
  148. package/src/components/editor/plugins/AutoEmbedPlugin/index.tsx +0 -350
  149. package/src/components/editor/plugins/AutoLinkPlugin/index.tsx +0 -56
  150. package/src/components/editor/plugins/CodeActionMenuPlugin/components/CopyButton.tsx +0 -70
  151. package/src/components/editor/plugins/CodeActionMenuPlugin/components/PrettierButton.tsx +0 -192
  152. package/src/components/editor/plugins/CodeActionMenuPlugin/index.tsx +0 -217
  153. package/src/components/editor/plugins/CodeActionMenuPlugin/utils.ts +0 -26
  154. package/src/components/editor/plugins/CodeHighlightPlugin/index.ts +0 -21
  155. package/src/components/editor/plugins/CollapsiblePlugin/Collapsible.css +0 -76
  156. package/src/components/editor/plugins/CollapsiblePlugin/index.ts +0 -228
  157. package/src/components/editor/plugins/DragDropPastePlugin/index.tsx +0 -44
  158. package/src/components/editor/plugins/DraggableBlockPlugin/index.tsx +0 -52
  159. package/src/components/editor/plugins/EquationsPlugin/index.tsx +0 -85
  160. package/src/components/editor/plugins/ExcalidrawPlugin/index.tsx +0 -98
  161. package/src/components/editor/plugins/FigmaPlugin/index.tsx +0 -42
  162. package/src/components/editor/plugins/FloatingLinkEditorPlugin/index.tsx +0 -445
  163. package/src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +0 -275
  164. package/src/components/editor/plugins/InlineImagePlugin/index.tsx +0 -351
  165. package/src/components/editor/plugins/LayoutPlugin/index.tsx +0 -238
  166. package/src/components/editor/plugins/LinkPlugin/index.tsx +0 -36
  167. package/src/components/editor/plugins/LinkWithMetaData/index.tsx +0 -271
  168. package/src/components/editor/plugins/MarkdownShortcutPlugin/index.tsx +0 -11
  169. package/src/components/editor/plugins/MarkdownTransformers/index.tsx +0 -304
  170. package/src/components/editor/plugins/PollPlugin/index.tsx +0 -49
  171. package/src/components/editor/plugins/ShortcutsPlugin/index.tsx +0 -180
  172. package/src/components/editor/plugins/ShortcutsPlugin/shortcuts.ts +0 -253
  173. package/src/components/editor/plugins/SlashCommand/index.tsx +0 -621
  174. package/src/components/editor/plugins/SpeechToTextPlugin/index.ts +0 -127
  175. package/src/components/editor/plugins/TabFocusPlugin/index.ts +0 -58
  176. package/src/components/editor/plugins/TableCellResizer/index.tsx +0 -438
  177. package/src/components/editor/plugins/TablePlugin/index.tsx +0 -99
  178. package/src/components/editor/plugins/ToolbarPlugin/index.tsx +0 -522
  179. package/src/components/editor/plugins/TwitterPlugin/index.ts +0 -35
  180. package/src/components/editor/plugins/YouTubeNode/index.tsx +0 -179
  181. package/src/components/editor/plugins/YouTubePlugin/index.ts +0 -41
  182. package/src/components/editor/themes/editor-theme.ts +0 -113
  183. package/src/components/editor/themes/theme.css +0 -377
  184. package/src/components/editor/utils/ai.ts +0 -291
  185. package/src/components/editor/utils/canUseDOM.ts +0 -12
  186. package/src/components/editor/utils/environment.ts +0 -50
  187. package/src/components/editor/utils/extract-data.ts +0 -166
  188. package/src/components/editor/utils/getAllLexicalChildren.ts +0 -13
  189. package/src/components/editor/utils/getDOMRangeRect.ts +0 -27
  190. package/src/components/editor/utils/getSelectedNode.ts +0 -27
  191. package/src/components/editor/utils/gif.ts +0 -29
  192. package/src/components/editor/utils/invariant.ts +0 -15
  193. package/src/components/editor/utils/setFloatingElemPosition.ts +0 -51
  194. package/src/components/editor/utils/setFloatingElemPositionForLinkEditor.ts +0 -40
  195. package/src/components/editor/utils/setNodePlaceholderFromSelection/getNodePlaceholder.ts +0 -51
  196. package/src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts +0 -15
  197. package/src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts +0 -114
  198. package/src/components/editor/utils/setNodePlaceholderFromSelection/styles.css +0 -6
  199. package/src/components/editor/utils/url.ts +0 -109
  200. package/src/components/editor/utils/useLayoutEffect.ts +0 -13
  201. package/src/components/providers/QueryProvider.tsx +0 -15
  202. package/src/components/providers/SharedHistoryContext.tsx +0 -28
  203. package/src/components/providers/ToolbarContext.tsx +0 -123
  204. package/src/components/providers/theme-provider.tsx +0 -11
  205. package/src/components/theme/ModeToggle.tsx +0 -40
  206. package/src/components/ui/FileInput.tsx +0 -40
  207. package/src/components/ui/Input.css +0 -32
  208. package/src/components/ui/Select.css +0 -42
  209. package/src/components/ui/Select.tsx +0 -36
  210. package/src/components/ui/TextInput.tsx +0 -48
  211. package/src/components/ui/ai/ai-button.tsx +0 -574
  212. package/src/components/ui/ai/border.tsx +0 -99
  213. package/src/components/ui/ai/placeholder-input-vanish.tsx +0 -282
  214. package/src/components/ui/button.tsx +0 -89
  215. package/src/components/ui/card.tsx +0 -76
  216. package/src/components/ui/checkbox.tsx +0 -30
  217. package/src/components/ui/command.tsx +0 -153
  218. package/src/components/ui/dialog/Dialog.css +0 -25
  219. package/src/components/ui/dialog/Dialog.tsx +0 -34
  220. package/src/components/ui/dialog.tsx +0 -122
  221. package/src/components/ui/drop-downs/background-color.tsx +0 -183
  222. package/src/components/ui/drop-downs/block-format.tsx +0 -159
  223. package/src/components/ui/drop-downs/code.tsx +0 -42
  224. package/src/components/ui/drop-downs/color.tsx +0 -177
  225. package/src/components/ui/drop-downs/font-size.tsx +0 -138
  226. package/src/components/ui/drop-downs/font.tsx +0 -155
  227. package/src/components/ui/drop-downs/index.tsx +0 -122
  228. package/src/components/ui/drop-downs/insert-node.tsx +0 -213
  229. package/src/components/ui/drop-downs/text-align.tsx +0 -123
  230. package/src/components/ui/drop-downs/text-format.tsx +0 -104
  231. package/src/components/ui/dropdown-menu.tsx +0 -201
  232. package/src/components/ui/equation/EquationEditor.css +0 -38
  233. package/src/components/ui/equation/EquationEditor.tsx +0 -56
  234. package/src/components/ui/equation/KatexEquationAlterer.css +0 -41
  235. package/src/components/ui/equation/KatexEquationAlterer.tsx +0 -83
  236. package/src/components/ui/equation/KatexRenderer.tsx +0 -66
  237. package/src/components/ui/excalidraw/ExcalidrawModal.css +0 -64
  238. package/src/components/ui/excalidraw/ExcalidrawModal.tsx +0 -234
  239. package/src/components/ui/excalidraw/Modal.css +0 -62
  240. package/src/components/ui/excalidraw/Modal.tsx +0 -110
  241. package/src/components/ui/hover-card.tsx +0 -29
  242. package/src/components/ui/image/error-image.tsx +0 -17
  243. package/src/components/ui/image/file-upload.tsx +0 -240
  244. package/src/components/ui/image/image-resizer.tsx +0 -297
  245. package/src/components/ui/image/image-toolbar.tsx +0 -264
  246. package/src/components/ui/image/index.tsx +0 -408
  247. package/src/components/ui/image/lazy-image.tsx +0 -68
  248. package/src/components/ui/image/lazy-video.tsx +0 -71
  249. package/src/components/ui/input.tsx +0 -22
  250. package/src/components/ui/models/custom-dialog.tsx +0 -320
  251. package/src/components/ui/models/insert-gif.tsx +0 -90
  252. package/src/components/ui/models/insert-image.tsx +0 -52
  253. package/src/components/ui/models/insert-poll.tsx +0 -29
  254. package/src/components/ui/models/insert-table.tsx +0 -62
  255. package/src/components/ui/models/use-model.tsx +0 -91
  256. package/src/components/ui/poll/poll-component.tsx +0 -304
  257. package/src/components/ui/popover.tsx +0 -33
  258. package/src/components/ui/progress.tsx +0 -28
  259. package/src/components/ui/scroll-area.tsx +0 -48
  260. package/src/components/ui/separator.tsx +0 -31
  261. package/src/components/ui/skeleton.tsx +0 -15
  262. package/src/components/ui/sonner.tsx +0 -31
  263. package/src/components/ui/stepper/step.tsx +0 -179
  264. package/src/components/ui/stepper/stepper.tsx +0 -89
  265. package/src/components/ui/textarea.tsx +0 -22
  266. package/src/components/ui/toggle.tsx +0 -71
  267. package/src/components/ui/tooltip.tsx +0 -32
  268. package/src/components/ui/write/text-format-floting-toolbar.tsx +0 -346
  269. package/src/lib/edgestore.ts +0 -9
  270. package/src/lib/pinecone-client.ts +0 -0
  271. package/src/lib/utils.ts +0 -6
  272. package/src/utils/docSerialization.ts +0 -77
  273. package/src/utils/emoji-list.ts +0 -16615
  274. package/src/utils/getDOMRangeRect.ts +0 -27
  275. package/src/utils/getThemeSelector.ts +0 -25
  276. package/src/utils/isMobileWidth.ts +0 -7
  277. package/src/utils/joinClasses.ts +0 -13
  278. package/src/utils/setFloatingElemPosition.ts +0 -74
  279. package/src/utils/setFloatingElemPositionForLinkEditor.ts +0 -46
  280. package/src/utils/swipe.ts +0 -127
  281. package/src/utils/url.ts +0 -38
  282. package/tsconfig.json +0 -27
@@ -1,759 +1,667 @@
1
- import type { ElementNode, LexicalEditor } from "lexical";
2
- import { Compact } from '@uiw/react-color';
3
-
4
- import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
5
- import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
6
- import {
7
- $deleteTableColumn__EXPERIMENTAL,
8
- $deleteTableRow__EXPERIMENTAL,
9
- $getNodeTriplet,
10
- $getTableCellNodeFromLexicalNode,
11
- $getTableColumnIndexFromTableCellNode,
12
- $getTableNodeFromLexicalNodeOrThrow,
13
- $getTableRowIndexFromTableCellNode,
14
- $insertTableColumn__EXPERIMENTAL,
15
- $insertTableRow__EXPERIMENTAL,
16
- $isTableCellNode,
17
- $isTableRowNode,
18
- $isTableSelection,
19
- $unmergeCell,
20
- getTableElement,
21
- getTableObserverFromTableElement,
22
- TableCellHeaderStates,
23
- TableCellNode,
24
- TableObserver,
25
- TableRowNode,
26
- TableSelection,
27
- } from "@lexical/table";
28
- import { mergeRegister } from "@lexical/utils";
29
- import {
30
- $createParagraphNode,
31
- $getRoot,
32
- $getSelection,
33
- $isElementNode,
34
- $isParagraphNode,
35
- $isRangeSelection,
36
- $isTextNode,
37
- COMMAND_PRIORITY_CRITICAL,
38
- getDOMSelection,
39
- SELECTION_CHANGE_COMMAND,
40
- } from "lexical";
41
- import * as React from "react";
42
- import { ReactPortal, useCallback, useEffect, useRef, useState } from "react";
43
- import { createPortal } from "react-dom";
44
- import invariant from "../../utils/invariant";
45
- import {
46
- Menu,
47
- Merge,
48
- PaintBucket,
49
- Split,
50
- Table,
51
- TableColumnsSplit,
52
- TableRowsSplit,
53
- Trash,
54
- } from "lucide-react";
55
- import { DropDown } from "@/components/ui/drop-downs";
56
- import useModal from "@/components/ui/models/use-model";
57
-
58
- function computeSelectionCount(selection: TableSelection): {
59
- columns: number;
60
- rows: number;
61
- } {
62
- const selectionShape = selection.getShape();
63
- return {
64
- columns: selectionShape.toX - selectionShape.fromX + 1,
65
- rows: selectionShape.toY - selectionShape.fromY + 1,
66
- };
67
- }
68
-
69
- function $canUnmerge(): boolean {
70
- const selection = $getSelection();
71
- if (
72
- ($isRangeSelection(selection) && !selection.isCollapsed()) ||
73
- ($isTableSelection(selection) && !selection.anchor.is(selection.focus)) ||
74
- (!$isRangeSelection(selection) && !$isTableSelection(selection))
75
- ) {
76
- return false;
77
- }
78
- const [cell] = $getNodeTriplet(selection.anchor);
79
- return cell.__colSpan > 1 || cell.__rowSpan > 1;
80
- }
81
-
82
- function $cellContainsEmptyParagraph(cell: TableCellNode): boolean {
83
- if (cell.getChildrenSize() !== 1) {
84
- return false;
85
- }
86
- const firstChild = cell.getFirstChildOrThrow();
87
- if (!$isParagraphNode(firstChild) || !firstChild.isEmpty()) {
88
- return false;
89
- }
90
- return true;
91
- }
92
-
93
- function $selectLastDescendant(node: ElementNode): void {
94
- const lastDescendant = node.getLastDescendant();
95
- if ($isTextNode(lastDescendant)) {
96
- lastDescendant.select();
97
- } else if ($isElementNode(lastDescendant)) {
98
- lastDescendant.selectEnd();
99
- } else if (lastDescendant !== null) {
100
- lastDescendant.selectNext();
101
- }
102
- }
103
-
104
- function currentCellBackgroundColor(editor: LexicalEditor): null | string {
105
- return editor.getEditorState().read(() => {
106
- const selection = $getSelection();
107
- if ($isRangeSelection(selection) || $isTableSelection(selection)) {
108
- const [cell] = $getNodeTriplet(selection.anchor);
109
- if ($isTableCellNode(cell)) {
110
- return cell.getBackgroundColor();
111
- }
112
- }
113
- return null;
114
- });
115
- }
116
-
117
- type TableCellActionMenuProps = Readonly<{
118
- contextRef: { current: null | HTMLElement };
119
- tableCellNode: TableCellNode;
120
- cellMerge: boolean;
121
- }>;
122
-
123
- function TableActionMenu({
124
- tableCellNode: _tableCellNode,
125
- contextRef,
126
- cellMerge,
127
- }: TableCellActionMenuProps) {
128
- const [editor] = useLexicalComposerContext();
129
- const dropDownRef = useRef<HTMLDivElement | null>(null);
130
- const [tableCellNode, updateTableCellNode] = useState(_tableCellNode);
131
- const [selectionCounts, updateSelectionCounts] = useState({
132
- columns: 1,
133
- rows: 1,
134
- });
135
- const [canMergeCells, setCanMergeCells] = useState(false);
136
- const [canUnmergeCell, setCanUnmergeCell] = useState(false);
137
- const [backgroundColor, setBackgroundColor] = useState(
138
- () => currentCellBackgroundColor(editor) || ""
139
- );
140
- const [model, showModal] = useModal();
141
-
142
-
143
- useEffect(() => {
144
- return editor.registerMutationListener(
145
- TableCellNode,
146
- (nodeMutations) => {
147
- const nodeUpdated =
148
- nodeMutations.get(tableCellNode.getKey()) === "updated";
149
-
150
- if (nodeUpdated) {
151
- editor.getEditorState().read(() => {
152
- updateTableCellNode(tableCellNode.getLatest());
153
- });
154
- setBackgroundColor(currentCellBackgroundColor(editor) || "");
155
- }
156
- },
157
- { skipInitialization: true }
158
- );
159
- }, [editor, tableCellNode]);
160
-
161
- useEffect(() => {
162
- editor.getEditorState().read(() => {
163
- const selection = $getSelection();
164
- // Merge cells
165
- if ($isTableSelection(selection)) {
166
- const currentSelectionCounts = computeSelectionCount(selection);
167
- updateSelectionCounts(computeSelectionCount(selection));
168
- setCanMergeCells(
169
- currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1
170
- );
171
- }
172
- // Unmerge cell
173
- setCanUnmergeCell($canUnmerge());
174
- });
175
- }, [editor]);
176
-
177
- useEffect(() => {
178
- const menuButtonElement = contextRef.current;
179
- const dropDownElement = dropDownRef.current;
180
- const rootElement = editor.getRootElement();
181
-
182
- if (
183
- menuButtonElement != null &&
184
- dropDownElement != null &&
185
- rootElement != null
186
- ) {
187
- const rootEleRect = rootElement.getBoundingClientRect();
188
- const menuButtonRect = menuButtonElement.getBoundingClientRect();
189
- dropDownElement.style.opacity = "1";
190
- const dropDownElementRect = dropDownElement.getBoundingClientRect();
191
- const margin = 5;
192
- let leftPosition = menuButtonRect.right + margin;
193
- if (
194
- leftPosition + dropDownElementRect.width > window.innerWidth ||
195
- leftPosition + dropDownElementRect.width > rootEleRect.right
196
- ) {
197
- const position =
198
- menuButtonRect.left - dropDownElementRect.width - margin;
199
- leftPosition = (position < 0 ? margin : position) + window.pageXOffset;
200
- }
201
- dropDownElement.style.left = `${leftPosition + window.pageXOffset}px`;
202
-
203
- let topPosition = menuButtonRect.top;
204
- if (topPosition + dropDownElementRect.height > window.innerHeight) {
205
- const position = menuButtonRect.bottom - dropDownElementRect.height;
206
- topPosition = (position < 0 ? margin : position) + window.pageYOffset;
207
- }
208
- dropDownElement.style.top = `${topPosition + +window.pageYOffset}px`;
209
- }
210
- }, [contextRef, dropDownRef, editor]);
211
-
212
- const clearTableSelection = useCallback(() => {
213
- editor.update(() => {
214
- if (tableCellNode.isAttached()) {
215
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
216
- const tableElement = getTableElement(
217
- tableNode,
218
- editor.getElementByKey(tableNode.getKey())
219
- );
220
-
221
- invariant(
222
- tableElement !== null,
223
- "TableActionMenu: Expected to find tableElement in DOM"
224
- );
225
-
226
- const tableObserver = getTableObserverFromTableElement(tableElement);
227
- if (tableObserver !== null) {
228
- tableObserver.$clearHighlight();
229
- }
230
-
231
- tableNode.markDirty();
232
- updateTableCellNode(tableCellNode.getLatest());
233
- }
234
-
235
- const rootNode = $getRoot();
236
- rootNode.selectStart();
237
- });
238
- }, [editor, tableCellNode]);
239
-
240
- const mergeTableCellsAtSelection = () => {
241
- editor.update(() => {
242
- const selection = $getSelection();
243
- if ($isTableSelection(selection)) {
244
- const { columns, rows } = computeSelectionCount(selection);
245
- const nodes = selection.getNodes();
246
- let firstCell: null | TableCellNode = null;
247
- for (let i = 0; i < nodes.length; i++) {
248
- const node = nodes[i];
249
- if ($isTableCellNode(node)) {
250
- if (firstCell === null) {
251
- node.setColSpan(columns).setRowSpan(rows);
252
- firstCell = node;
253
- const isEmpty = $cellContainsEmptyParagraph(node);
254
- let firstChild;
255
- if (
256
- isEmpty &&
257
- $isParagraphNode((firstChild = node.getFirstChild()))
258
- ) {
259
- firstChild.remove();
260
- }
261
- } else if ($isTableCellNode(firstCell)) {
262
- const isEmpty = $cellContainsEmptyParagraph(node);
263
- if (!isEmpty) {
264
- firstCell.append(...node.getChildren());
265
- }
266
- node.remove();
267
- }
268
- }
269
- }
270
- if (firstCell !== null) {
271
- if (firstCell.getChildrenSize() === 0) {
272
- firstCell.append($createParagraphNode());
273
- }
274
- $selectLastDescendant(firstCell);
275
- }
276
- }
277
- });
278
- };
279
-
280
- const unmergeTableCellsAtSelection = () => {
281
- editor.update(() => {
282
- $unmergeCell();
283
- });
284
- };
285
-
286
- const insertTableRowAtSelection = useCallback(
287
- (shouldInsertAfter: boolean) => {
288
- editor.update(() => {
289
- for (let i = 0; i < selectionCounts.rows; i++) {
290
- $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
291
- }
292
- });
293
- },
294
- [editor, selectionCounts.rows]
295
- );
296
-
297
- const insertTableColumnAtSelection = useCallback(
298
- (shouldInsertAfter: boolean) => {
299
- editor.update(() => {
300
- for (let i = 0; i < selectionCounts.columns; i++) {
301
- $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
302
- }
303
- });
304
- },
305
- [editor, selectionCounts.columns]
306
- );
307
-
308
- const deleteTableRowAtSelection = useCallback(() => {
309
- editor.update(() => {
310
- $deleteTableRow__EXPERIMENTAL();
311
- });
312
- }, [editor]);
313
-
314
- const deleteTableAtSelection = useCallback(() => {
315
- editor.update(() => {
316
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
317
- tableNode.remove();
318
-
319
- clearTableSelection();
320
- });
321
- }, [editor, tableCellNode, clearTableSelection]);
322
-
323
- const deleteTableColumnAtSelection = useCallback(() => {
324
- editor.update(() => {
325
- $deleteTableColumn__EXPERIMENTAL();
326
- });
327
- }, [editor]);
328
-
329
- const toggleTableRowIsHeader = useCallback(() => {
330
- editor.update(() => {
331
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
332
-
333
- const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
334
-
335
- const tableRows = tableNode.getChildren();
336
-
337
- if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
338
- throw new Error("Expected table cell to be inside of table row.");
339
- }
340
-
341
- const tableRow = tableRows[tableRowIndex];
342
-
343
- if (!$isTableRowNode(tableRow)) {
344
- throw new Error("Expected table row");
345
- }
346
-
347
- const newStyle =
348
- tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.ROW;
349
- tableRow.getChildren().forEach((tableCell) => {
350
- if (!$isTableCellNode(tableCell)) {
351
- throw new Error("Expected table cell");
352
- }
353
-
354
- tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.ROW);
355
- });
356
-
357
- clearTableSelection();
358
- });
359
- }, [editor, tableCellNode, clearTableSelection]);
360
-
361
- const toggleTableColumnIsHeader = useCallback(() => {
362
- editor.update(() => {
363
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
364
-
365
- const tableColumnIndex =
366
- $getTableColumnIndexFromTableCellNode(tableCellNode);
367
-
368
- const tableRows = tableNode.getChildren<TableRowNode>();
369
- const maxRowsLength = Math.max(
370
- ...tableRows.map((row) => row.getChildren().length)
371
- );
372
-
373
- if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
374
- throw new Error("Expected table cell to be inside of table row.");
375
- }
376
-
377
- const newStyle =
378
- tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.COLUMN;
379
- for (let r = 0; r < tableRows.length; r++) {
380
- const tableRow = tableRows[r];
381
-
382
- if (!$isTableRowNode(tableRow)) {
383
- throw new Error("Expected table row");
384
- }
385
-
386
- const tableCells = tableRow.getChildren();
387
- if (tableColumnIndex >= tableCells.length) {
388
- // if cell is outside of bounds for the current row (for example various merge cell cases) we shouldn't highlight it
389
- continue;
390
- }
391
-
392
- const tableCell = tableCells[tableColumnIndex];
393
-
394
- if (!$isTableCellNode(tableCell)) {
395
- throw new Error("Expected table cell");
396
- }
397
-
398
- tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.COLUMN);
399
- }
400
- clearTableSelection();
401
- });
402
- }, [editor, tableCellNode, clearTableSelection]);
403
-
404
- const toggleRowStriping = useCallback(() => {
405
- editor.update(() => {
406
- if (tableCellNode.isAttached()) {
407
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
408
- if (tableNode) {
409
- tableNode.setRowStriping(!tableNode.getRowStriping());
410
- }
411
- }
412
- clearTableSelection();
413
- });
414
- }, [editor, tableCellNode, clearTableSelection]);
415
-
416
- const handleCellBackgroundColor = useCallback(
417
- (value: string) => {
418
- editor.update(() => {
419
- const selection = $getSelection();
420
- if ($isRangeSelection(selection) || $isTableSelection(selection)) {
421
- const [cell] = $getNodeTriplet(selection.anchor);
422
- if ($isTableCellNode(cell)) {
423
- cell.setBackgroundColor(value);
424
- }
425
-
426
- if ($isTableSelection(selection)) {
427
- const nodes = selection.getNodes();
428
-
429
- for (let i = 0; i < nodes.length; i++) {
430
- const node = nodes[i];
431
- if ($isTableCellNode(node)) {
432
- node.setBackgroundColor(value);
433
- }
434
- }
435
- }
436
- }
437
- });
438
- },
439
- [editor]
440
- );
441
-
442
- const commands = React.useMemo(
443
- () => [
444
- {
445
- label: "Background",
446
- func: () => {
447
- showModal(
448
- "Background",
449
- "Select color",
450
- (onClose) => (
451
- <Compact
452
- style={{background:"transparent",width:"100%" }}
453
- color={backgroundColor}
454
- onChange={(color) => {
455
- handleCellBackgroundColor(color.hex)
456
- onClose()
457
- }}
458
- />
459
- ),
460
- true
461
- );
462
- },
463
- icon: <PaintBucket />,
464
- style: { backgroundColor: `${currentCellBackgroundColor(editor)}` },
465
- },
466
- {
467
- label: "Insert Row Above",
468
- func: () => insertTableRowAtSelection(false),
469
- icon: <TableRowsSplit />,
470
- },
471
- {
472
- label: "Insert Row Below",
473
- func: () => insertTableRowAtSelection(true),
474
- icon: <TableRowsSplit />,
475
- },
476
- {
477
- label: "Insert Column Left",
478
- func: () => insertTableColumnAtSelection(false),
479
- icon: <TableColumnsSplit />,
480
- },
481
- {
482
- label: "Insert Column Right",
483
- func: () => insertTableColumnAtSelection(true),
484
- icon: <TableColumnsSplit />,
485
- },
486
- { label: "Delete Row", func: deleteTableRowAtSelection, icon: <Trash /> },
487
- {
488
- label: "Delete Column",
489
- func: deleteTableColumnAtSelection,
490
- icon: <Trash />,
491
- },
492
- { label: "Delete Table", func: deleteTableAtSelection, icon: <Trash /> },
493
- {
494
- label: "Toggle Row Header",
495
- func: toggleTableRowIsHeader,
496
- icon: <Table />,
497
- },
498
- {
499
- label: "Toggle Column Header",
500
- func: toggleTableColumnIsHeader,
501
- icon: <Table />,
502
- },
503
- { label: "Toggle Striping", func: toggleRowStriping, icon: <Table /> },
504
- ],
505
- [
506
- currentCellBackgroundColor(editor),
507
- canMergeCells,
508
- canUnmergeCell,
509
- insertTableRowAtSelection,
510
- insertTableColumnAtSelection,
511
- deleteTableRowAtSelection,
512
- deleteTableColumnAtSelection,
513
- deleteTableAtSelection,
514
- toggleTableRowIsHeader,
515
- toggleTableColumnIsHeader,
516
- toggleRowStriping,
517
- backgroundColor,
518
- editor,
519
- tableCellNode,
520
- cellMerge,
521
- selectionCounts,
522
-
523
- ]
524
- );
525
- if (cellMerge) {
526
- if (canMergeCells) {
527
- commands.push({
528
- label: "Merge Cells",
529
- func: mergeTableCellsAtSelection,
530
- icon: <Merge />,
531
- });
532
- } else if (canUnmergeCell) {
533
- commands.push({
534
- label: "Unmerge Cells",
535
- func: unmergeTableCellsAtSelection,
536
- icon: <Split />,
537
- });
538
- }
539
- }
540
-
541
- return (
542
- <>
543
- <DropDown
544
- values={commands}
545
- TriggerLabel={<Menu className="w-4 h-4 " />}
546
- TriggerClassName={{
547
- height: "24px",
548
- padding: "0px 4px",
549
- position: "absolute",
550
- top: 0,
551
- right: "10px",
552
- }}
553
- ShowChevronsUpDown={false}
554
- triggerVariants={"ghost"}
555
- disabled={false}
556
- />
557
- {model}
558
- </>
559
- );
560
- }
561
-
562
- function TableCellActionMenuContainer({
563
- anchorElem,
564
- cellMerge,
565
- }: {
566
- anchorElem: HTMLElement;
567
- cellMerge: boolean;
568
- }): React.JSX.Element {
569
- const [editor] = useLexicalComposerContext();
570
-
571
- const menuButtonRef = useRef<HTMLDivElement | null>(null);
572
- const menuRootRef = useRef<HTMLButtonElement | null>(null);
573
-
574
- const [tableCellNode, setTableMenuCellNode] = useState<TableCellNode | null>(
575
- null
576
- );
577
-
578
- const $moveMenu = useCallback(() => {
579
- const menu = menuButtonRef.current;
580
- const selection = $getSelection();
581
- const nativeSelection = getDOMSelection(editor._window);
582
- let activeElement;
583
- if (typeof window !== "undefined") {
584
- activeElement = document?.activeElement;
585
- }
586
- function disable() {
587
- if (menu) {
588
- menu.classList.remove("table-cell-action-button-container--active");
589
- menu.classList.add("table-cell-action-button-container--inactive");
590
- }
591
- setTableMenuCellNode(null);
592
- }
593
-
594
- if (selection == null || menu == null) {
595
- return disable();
596
- }
597
-
598
- const rootElement = editor.getRootElement();
599
- let tableObserver: TableObserver | null = null;
600
- let tableCellParentNodeDOM: HTMLElement | null = null;
601
-
602
- if (
603
- $isRangeSelection(selection) &&
604
- rootElement !== null &&
605
- nativeSelection !== null &&
606
- rootElement.contains(nativeSelection.anchorNode)
607
- ) {
608
- const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(
609
- selection.anchor.getNode()
610
- );
611
-
612
- if (tableCellNodeFromSelection == null) {
613
- return disable();
614
- }
615
-
616
- tableCellParentNodeDOM = editor.getElementByKey(
617
- tableCellNodeFromSelection.getKey()
618
- );
619
-
620
- if (
621
- tableCellParentNodeDOM == null ||
622
- !tableCellNodeFromSelection.isAttached()
623
- ) {
624
- return disable();
625
- }
626
-
627
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(
628
- tableCellNodeFromSelection
629
- );
630
- const tableElement = getTableElement(
631
- tableNode,
632
- editor.getElementByKey(tableNode.getKey())
633
- );
634
-
635
- invariant(
636
- tableElement !== null,
637
- "TableActionMenu: Expected to find tableElement in DOM"
638
- );
639
-
640
- tableObserver = getTableObserverFromTableElement(tableElement);
641
- setTableMenuCellNode(tableCellNodeFromSelection);
642
- } else if ($isTableSelection(selection)) {
643
- const anchorNode = $getTableCellNodeFromLexicalNode(
644
- selection.anchor.getNode()
645
- );
646
- invariant(
647
- $isTableCellNode(anchorNode),
648
- "TableSelection anchorNode must be a TableCellNode"
649
- );
650
- const tableNode = $getTableNodeFromLexicalNodeOrThrow(anchorNode);
651
- const tableElement = getTableElement(
652
- tableNode,
653
- editor.getElementByKey(tableNode.getKey())
654
- );
655
- invariant(
656
- tableElement !== null,
657
- "TableActionMenu: Expected to find tableElement in DOM"
658
- );
659
- tableObserver = getTableObserverFromTableElement(tableElement);
660
- tableCellParentNodeDOM = editor.getElementByKey(anchorNode.getKey());
661
- } else if (!activeElement) {
662
- return disable();
663
- }
664
- if (tableObserver === null || tableCellParentNodeDOM === null) {
665
- return disable();
666
- }
667
- const enabled = !tableObserver || !tableObserver.isSelecting;
668
- menu.classList.toggle(
669
- "table-cell-action-button-container--active",
670
- enabled
671
- );
672
- menu.classList.toggle(
673
- "table-cell-action-button-container--inactive",
674
- !enabled
675
- );
676
- if (enabled) {
677
- const tableCellRect = tableCellParentNodeDOM.getBoundingClientRect();
678
- const anchorRect = anchorElem.getBoundingClientRect();
679
- const top = tableCellRect.top - anchorRect.top;
680
- const left = tableCellRect.right - anchorRect.left;
681
- menu.style.transform = `translate(${left}px, ${top}px)`;
682
- }
683
- }, [editor, anchorElem]);
684
-
685
- useEffect(() => {
686
- // We call the $moveMenu callback every time the selection changes,
687
- // once up front, and once after each mouseUp
688
- let timeoutId: ReturnType<typeof setTimeout> | undefined = undefined;
689
- const callback = () => {
690
- timeoutId = undefined;
691
- editor.getEditorState().read($moveMenu);
692
- };
693
- const delayedCallback = () => {
694
- if (timeoutId === undefined) {
695
- timeoutId = setTimeout(callback, 0);
696
- }
697
- return false;
698
- };
699
- return mergeRegister(
700
- editor.registerUpdateListener(delayedCallback),
701
- editor.registerCommand(
702
- SELECTION_CHANGE_COMMAND,
703
- delayedCallback,
704
- COMMAND_PRIORITY_CRITICAL
705
- ),
706
- editor.registerRootListener((rootElement, prevRootElement) => {
707
- if (prevRootElement) {
708
- prevRootElement.removeEventListener("mouseup", delayedCallback);
709
- }
710
- if (rootElement) {
711
- rootElement.addEventListener("mouseup", delayedCallback);
712
- delayedCallback();
713
- }
714
- }),
715
- () => clearTimeout(timeoutId)
716
- );
717
- });
718
-
719
- const prevTableCellDOM = useRef(tableCellNode);
720
-
721
- useEffect(() => {
722
- prevTableCellDOM.current = tableCellNode;
723
- }, [prevTableCellDOM, tableCellNode]);
724
-
725
- return (
726
- <div
727
- className=" absolute top-1 left-1 will-change-transform"
728
- ref={menuButtonRef}
729
- >
730
- {tableCellNode != null && (
731
- <TableActionMenu
732
- contextRef={menuRootRef}
733
- tableCellNode={tableCellNode}
734
- cellMerge={cellMerge}
735
- />
736
- )}
737
- </div>
738
- );
739
- }
740
-
741
- export default function TableActionMenuPlugin({
742
- anchorElem = document.body,
743
- cellMerge = false,
744
- }: {
745
- anchorElem?: HTMLElement;
746
- cellMerge?: boolean;
747
- }): null | ReactPortal {
748
- const isEditable = useLexicalEditable();
749
-
750
- return createPortal(
751
- isEditable ? (
752
- <TableCellActionMenuContainer
753
- anchorElem={anchorElem}
754
- cellMerge={cellMerge}
755
- />
756
- ) : null,
757
- anchorElem
758
- );
759
- }
1
+ import {
2
+ DropDown
3
+ } from "./chunk-EGMI62PP.mjs";
4
+ import "./chunk-KJ6AJ44Q.mjs";
5
+ import "./chunk-64Z3FI7T.mjs";
6
+ import {
7
+ useModal
8
+ } from "./chunk-5QSNIVIG.mjs";
9
+ import "./chunk-WDG7J2DY.mjs";
10
+ import "./chunk-BIU7WTLX.mjs";
11
+ import "./chunk-YHPNOWFH.mjs";
12
+ import {
13
+ init_react_shim
14
+ } from "./chunk-77KXU36M.mjs";
15
+
16
+ // src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx
17
+ init_react_shim();
18
+ import { Compact } from "@uiw/react-color";
19
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
20
+ import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
21
+ import {
22
+ $deleteTableColumn__EXPERIMENTAL,
23
+ $deleteTableRow__EXPERIMENTAL,
24
+ $getNodeTriplet,
25
+ $getTableCellNodeFromLexicalNode,
26
+ $getTableColumnIndexFromTableCellNode,
27
+ $getTableNodeFromLexicalNodeOrThrow,
28
+ $getTableRowIndexFromTableCellNode,
29
+ $insertTableColumn__EXPERIMENTAL,
30
+ $insertTableRow__EXPERIMENTAL,
31
+ $isTableCellNode,
32
+ $isTableRowNode,
33
+ $isTableSelection,
34
+ $unmergeCell,
35
+ getTableElement,
36
+ getTableObserverFromTableElement,
37
+ TableCellHeaderStates,
38
+ TableCellNode
39
+ } from "@lexical/table";
40
+ import { mergeRegister } from "@lexical/utils";
41
+ import {
42
+ $createParagraphNode,
43
+ $getRoot,
44
+ $getSelection,
45
+ $isElementNode,
46
+ $isParagraphNode,
47
+ $isRangeSelection,
48
+ $isTextNode,
49
+ COMMAND_PRIORITY_CRITICAL,
50
+ getDOMSelection,
51
+ SELECTION_CHANGE_COMMAND
52
+ } from "lexical";
53
+ import * as React2 from "react";
54
+ import { useCallback, useEffect, useRef, useState } from "react";
55
+ import { createPortal } from "react-dom";
56
+
57
+ // src/components/editor/utils/invariant.ts
58
+ init_react_shim();
59
+ function invariant(cond, message) {
60
+ if (cond) {
61
+ return;
62
+ }
63
+ throw new Error(
64
+ "Internal Lexical error: invariant() is meant to be replaced at compile time. There is no runtime version. Error: " + message
65
+ );
66
+ }
67
+
68
+ // src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx
69
+ import {
70
+ Menu,
71
+ Merge,
72
+ PaintBucket,
73
+ Split,
74
+ Table,
75
+ TableColumnsSplit,
76
+ TableRowsSplit,
77
+ Trash
78
+ } from "lucide-react";
79
+ function computeSelectionCount(selection) {
80
+ const selectionShape = selection.getShape();
81
+ return {
82
+ columns: selectionShape.toX - selectionShape.fromX + 1,
83
+ rows: selectionShape.toY - selectionShape.fromY + 1
84
+ };
85
+ }
86
+ function $canUnmerge() {
87
+ const selection = $getSelection();
88
+ if ($isRangeSelection(selection) && !selection.isCollapsed() || $isTableSelection(selection) && !selection.anchor.is(selection.focus) || !$isRangeSelection(selection) && !$isTableSelection(selection)) {
89
+ return false;
90
+ }
91
+ const [cell] = $getNodeTriplet(selection.anchor);
92
+ return cell.__colSpan > 1 || cell.__rowSpan > 1;
93
+ }
94
+ function $cellContainsEmptyParagraph(cell) {
95
+ if (cell.getChildrenSize() !== 1) {
96
+ return false;
97
+ }
98
+ const firstChild = cell.getFirstChildOrThrow();
99
+ if (!$isParagraphNode(firstChild) || !firstChild.isEmpty()) {
100
+ return false;
101
+ }
102
+ return true;
103
+ }
104
+ function $selectLastDescendant(node) {
105
+ const lastDescendant = node.getLastDescendant();
106
+ if ($isTextNode(lastDescendant)) {
107
+ lastDescendant.select();
108
+ } else if ($isElementNode(lastDescendant)) {
109
+ lastDescendant.selectEnd();
110
+ } else if (lastDescendant !== null) {
111
+ lastDescendant.selectNext();
112
+ }
113
+ }
114
+ function currentCellBackgroundColor(editor) {
115
+ return editor.getEditorState().read(() => {
116
+ const selection = $getSelection();
117
+ if ($isRangeSelection(selection) || $isTableSelection(selection)) {
118
+ const [cell] = $getNodeTriplet(selection.anchor);
119
+ if ($isTableCellNode(cell)) {
120
+ return cell.getBackgroundColor();
121
+ }
122
+ }
123
+ return null;
124
+ });
125
+ }
126
+ function TableActionMenu({
127
+ tableCellNode: _tableCellNode,
128
+ contextRef,
129
+ cellMerge
130
+ }) {
131
+ const [editor] = useLexicalComposerContext();
132
+ const dropDownRef = useRef(null);
133
+ const [tableCellNode, updateTableCellNode] = useState(_tableCellNode);
134
+ const [selectionCounts, updateSelectionCounts] = useState({
135
+ columns: 1,
136
+ rows: 1
137
+ });
138
+ const [canMergeCells, setCanMergeCells] = useState(false);
139
+ const [canUnmergeCell, setCanUnmergeCell] = useState(false);
140
+ const [backgroundColor, setBackgroundColor] = useState(
141
+ () => currentCellBackgroundColor(editor) || ""
142
+ );
143
+ const [model, showModal] = useModal();
144
+ useEffect(() => {
145
+ return editor.registerMutationListener(
146
+ TableCellNode,
147
+ (nodeMutations) => {
148
+ const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === "updated";
149
+ if (nodeUpdated) {
150
+ editor.getEditorState().read(() => {
151
+ updateTableCellNode(tableCellNode.getLatest());
152
+ });
153
+ setBackgroundColor(currentCellBackgroundColor(editor) || "");
154
+ }
155
+ },
156
+ { skipInitialization: true }
157
+ );
158
+ }, [editor, tableCellNode]);
159
+ useEffect(() => {
160
+ editor.getEditorState().read(() => {
161
+ const selection = $getSelection();
162
+ if ($isTableSelection(selection)) {
163
+ const currentSelectionCounts = computeSelectionCount(selection);
164
+ updateSelectionCounts(computeSelectionCount(selection));
165
+ setCanMergeCells(
166
+ currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1
167
+ );
168
+ }
169
+ setCanUnmergeCell($canUnmerge());
170
+ });
171
+ }, [editor]);
172
+ useEffect(() => {
173
+ const menuButtonElement = contextRef.current;
174
+ const dropDownElement = dropDownRef.current;
175
+ const rootElement = editor.getRootElement();
176
+ if (menuButtonElement != null && dropDownElement != null && rootElement != null) {
177
+ const rootEleRect = rootElement.getBoundingClientRect();
178
+ const menuButtonRect = menuButtonElement.getBoundingClientRect();
179
+ dropDownElement.style.opacity = "1";
180
+ const dropDownElementRect = dropDownElement.getBoundingClientRect();
181
+ const margin = 5;
182
+ let leftPosition = menuButtonRect.right + margin;
183
+ if (leftPosition + dropDownElementRect.width > window.innerWidth || leftPosition + dropDownElementRect.width > rootEleRect.right) {
184
+ const position = menuButtonRect.left - dropDownElementRect.width - margin;
185
+ leftPosition = (position < 0 ? margin : position) + window.pageXOffset;
186
+ }
187
+ dropDownElement.style.left = `${leftPosition + window.pageXOffset}px`;
188
+ let topPosition = menuButtonRect.top;
189
+ if (topPosition + dropDownElementRect.height > window.innerHeight) {
190
+ const position = menuButtonRect.bottom - dropDownElementRect.height;
191
+ topPosition = (position < 0 ? margin : position) + window.pageYOffset;
192
+ }
193
+ dropDownElement.style.top = `${topPosition + +window.pageYOffset}px`;
194
+ }
195
+ }, [contextRef, dropDownRef, editor]);
196
+ const clearTableSelection = useCallback(() => {
197
+ editor.update(() => {
198
+ if (tableCellNode.isAttached()) {
199
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
200
+ const tableElement = getTableElement(
201
+ tableNode,
202
+ editor.getElementByKey(tableNode.getKey())
203
+ );
204
+ invariant(
205
+ tableElement !== null,
206
+ "TableActionMenu: Expected to find tableElement in DOM"
207
+ );
208
+ const tableObserver = getTableObserverFromTableElement(tableElement);
209
+ if (tableObserver !== null) {
210
+ tableObserver.$clearHighlight();
211
+ }
212
+ tableNode.markDirty();
213
+ updateTableCellNode(tableCellNode.getLatest());
214
+ }
215
+ const rootNode = $getRoot();
216
+ rootNode.selectStart();
217
+ });
218
+ }, [editor, tableCellNode]);
219
+ const mergeTableCellsAtSelection = () => {
220
+ editor.update(() => {
221
+ const selection = $getSelection();
222
+ if ($isTableSelection(selection)) {
223
+ const { columns, rows } = computeSelectionCount(selection);
224
+ const nodes = selection.getNodes();
225
+ let firstCell = null;
226
+ for (let i = 0; i < nodes.length; i++) {
227
+ const node = nodes[i];
228
+ if ($isTableCellNode(node)) {
229
+ if (firstCell === null) {
230
+ node.setColSpan(columns).setRowSpan(rows);
231
+ firstCell = node;
232
+ const isEmpty = $cellContainsEmptyParagraph(node);
233
+ let firstChild;
234
+ if (isEmpty && $isParagraphNode(firstChild = node.getFirstChild())) {
235
+ firstChild.remove();
236
+ }
237
+ } else if ($isTableCellNode(firstCell)) {
238
+ const isEmpty = $cellContainsEmptyParagraph(node);
239
+ if (!isEmpty) {
240
+ firstCell.append(...node.getChildren());
241
+ }
242
+ node.remove();
243
+ }
244
+ }
245
+ }
246
+ if (firstCell !== null) {
247
+ if (firstCell.getChildrenSize() === 0) {
248
+ firstCell.append($createParagraphNode());
249
+ }
250
+ $selectLastDescendant(firstCell);
251
+ }
252
+ }
253
+ });
254
+ };
255
+ const unmergeTableCellsAtSelection = () => {
256
+ editor.update(() => {
257
+ $unmergeCell();
258
+ });
259
+ };
260
+ const insertTableRowAtSelection = useCallback(
261
+ (shouldInsertAfter) => {
262
+ editor.update(() => {
263
+ for (let i = 0; i < selectionCounts.rows; i++) {
264
+ $insertTableRow__EXPERIMENTAL(shouldInsertAfter);
265
+ }
266
+ });
267
+ },
268
+ [editor, selectionCounts.rows]
269
+ );
270
+ const insertTableColumnAtSelection = useCallback(
271
+ (shouldInsertAfter) => {
272
+ editor.update(() => {
273
+ for (let i = 0; i < selectionCounts.columns; i++) {
274
+ $insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
275
+ }
276
+ });
277
+ },
278
+ [editor, selectionCounts.columns]
279
+ );
280
+ const deleteTableRowAtSelection = useCallback(() => {
281
+ editor.update(() => {
282
+ $deleteTableRow__EXPERIMENTAL();
283
+ });
284
+ }, [editor]);
285
+ const deleteTableAtSelection = useCallback(() => {
286
+ editor.update(() => {
287
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
288
+ tableNode.remove();
289
+ clearTableSelection();
290
+ });
291
+ }, [editor, tableCellNode, clearTableSelection]);
292
+ const deleteTableColumnAtSelection = useCallback(() => {
293
+ editor.update(() => {
294
+ $deleteTableColumn__EXPERIMENTAL();
295
+ });
296
+ }, [editor]);
297
+ const toggleTableRowIsHeader = useCallback(() => {
298
+ editor.update(() => {
299
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
300
+ const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
301
+ const tableRows = tableNode.getChildren();
302
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
303
+ throw new Error("Expected table cell to be inside of table row.");
304
+ }
305
+ const tableRow = tableRows[tableRowIndex];
306
+ if (!$isTableRowNode(tableRow)) {
307
+ throw new Error("Expected table row");
308
+ }
309
+ const newStyle = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.ROW;
310
+ tableRow.getChildren().forEach((tableCell) => {
311
+ if (!$isTableCellNode(tableCell)) {
312
+ throw new Error("Expected table cell");
313
+ }
314
+ tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.ROW);
315
+ });
316
+ clearTableSelection();
317
+ });
318
+ }, [editor, tableCellNode, clearTableSelection]);
319
+ const toggleTableColumnIsHeader = useCallback(() => {
320
+ editor.update(() => {
321
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
322
+ const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
323
+ const tableRows = tableNode.getChildren();
324
+ const maxRowsLength = Math.max(
325
+ ...tableRows.map((row) => row.getChildren().length)
326
+ );
327
+ if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {
328
+ throw new Error("Expected table cell to be inside of table row.");
329
+ }
330
+ const newStyle = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.COLUMN;
331
+ for (let r = 0; r < tableRows.length; r++) {
332
+ const tableRow = tableRows[r];
333
+ if (!$isTableRowNode(tableRow)) {
334
+ throw new Error("Expected table row");
335
+ }
336
+ const tableCells = tableRow.getChildren();
337
+ if (tableColumnIndex >= tableCells.length) {
338
+ continue;
339
+ }
340
+ const tableCell = tableCells[tableColumnIndex];
341
+ if (!$isTableCellNode(tableCell)) {
342
+ throw new Error("Expected table cell");
343
+ }
344
+ tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.COLUMN);
345
+ }
346
+ clearTableSelection();
347
+ });
348
+ }, [editor, tableCellNode, clearTableSelection]);
349
+ const toggleRowStriping = useCallback(() => {
350
+ editor.update(() => {
351
+ if (tableCellNode.isAttached()) {
352
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
353
+ if (tableNode) {
354
+ tableNode.setRowStriping(!tableNode.getRowStriping());
355
+ }
356
+ }
357
+ clearTableSelection();
358
+ });
359
+ }, [editor, tableCellNode, clearTableSelection]);
360
+ const handleCellBackgroundColor = useCallback(
361
+ (value) => {
362
+ editor.update(() => {
363
+ const selection = $getSelection();
364
+ if ($isRangeSelection(selection) || $isTableSelection(selection)) {
365
+ const [cell] = $getNodeTriplet(selection.anchor);
366
+ if ($isTableCellNode(cell)) {
367
+ cell.setBackgroundColor(value);
368
+ }
369
+ if ($isTableSelection(selection)) {
370
+ const nodes = selection.getNodes();
371
+ for (let i = 0; i < nodes.length; i++) {
372
+ const node = nodes[i];
373
+ if ($isTableCellNode(node)) {
374
+ node.setBackgroundColor(value);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ });
380
+ },
381
+ [editor]
382
+ );
383
+ const commands = React2.useMemo(
384
+ () => [
385
+ {
386
+ label: "Background",
387
+ func: () => {
388
+ showModal(
389
+ "Background",
390
+ "Select color",
391
+ (onClose) => /* @__PURE__ */ React2.createElement(
392
+ Compact,
393
+ {
394
+ style: { background: "transparent", width: "100%" },
395
+ color: backgroundColor,
396
+ onChange: (color) => {
397
+ handleCellBackgroundColor(color.hex);
398
+ onClose();
399
+ }
400
+ }
401
+ ),
402
+ true
403
+ );
404
+ },
405
+ icon: /* @__PURE__ */ React2.createElement(PaintBucket, null),
406
+ style: { backgroundColor: `${currentCellBackgroundColor(editor)}` }
407
+ },
408
+ {
409
+ label: "Insert Row Above",
410
+ func: () => insertTableRowAtSelection(false),
411
+ icon: /* @__PURE__ */ React2.createElement(TableRowsSplit, null)
412
+ },
413
+ {
414
+ label: "Insert Row Below",
415
+ func: () => insertTableRowAtSelection(true),
416
+ icon: /* @__PURE__ */ React2.createElement(TableRowsSplit, null)
417
+ },
418
+ {
419
+ label: "Insert Column Left",
420
+ func: () => insertTableColumnAtSelection(false),
421
+ icon: /* @__PURE__ */ React2.createElement(TableColumnsSplit, null)
422
+ },
423
+ {
424
+ label: "Insert Column Right",
425
+ func: () => insertTableColumnAtSelection(true),
426
+ icon: /* @__PURE__ */ React2.createElement(TableColumnsSplit, null)
427
+ },
428
+ { label: "Delete Row", func: deleteTableRowAtSelection, icon: /* @__PURE__ */ React2.createElement(Trash, null) },
429
+ {
430
+ label: "Delete Column",
431
+ func: deleteTableColumnAtSelection,
432
+ icon: /* @__PURE__ */ React2.createElement(Trash, null)
433
+ },
434
+ { label: "Delete Table", func: deleteTableAtSelection, icon: /* @__PURE__ */ React2.createElement(Trash, null) },
435
+ {
436
+ label: "Toggle Row Header",
437
+ func: toggleTableRowIsHeader,
438
+ icon: /* @__PURE__ */ React2.createElement(Table, null)
439
+ },
440
+ {
441
+ label: "Toggle Column Header",
442
+ func: toggleTableColumnIsHeader,
443
+ icon: /* @__PURE__ */ React2.createElement(Table, null)
444
+ },
445
+ { label: "Toggle Striping", func: toggleRowStriping, icon: /* @__PURE__ */ React2.createElement(Table, null) }
446
+ ],
447
+ [
448
+ currentCellBackgroundColor(editor),
449
+ canMergeCells,
450
+ canUnmergeCell,
451
+ insertTableRowAtSelection,
452
+ insertTableColumnAtSelection,
453
+ deleteTableRowAtSelection,
454
+ deleteTableColumnAtSelection,
455
+ deleteTableAtSelection,
456
+ toggleTableRowIsHeader,
457
+ toggleTableColumnIsHeader,
458
+ toggleRowStriping,
459
+ backgroundColor,
460
+ editor,
461
+ tableCellNode,
462
+ cellMerge,
463
+ selectionCounts
464
+ ]
465
+ );
466
+ if (cellMerge) {
467
+ if (canMergeCells) {
468
+ commands.push({
469
+ label: "Merge Cells",
470
+ func: mergeTableCellsAtSelection,
471
+ icon: /* @__PURE__ */ React2.createElement(Merge, null)
472
+ });
473
+ } else if (canUnmergeCell) {
474
+ commands.push({
475
+ label: "Unmerge Cells",
476
+ func: unmergeTableCellsAtSelection,
477
+ icon: /* @__PURE__ */ React2.createElement(Split, null)
478
+ });
479
+ }
480
+ }
481
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
482
+ DropDown,
483
+ {
484
+ values: commands,
485
+ TriggerLabel: /* @__PURE__ */ React2.createElement(Menu, { className: "w-4 h-4 " }),
486
+ TriggerClassName: {
487
+ height: "24px",
488
+ padding: "0px 4px",
489
+ position: "absolute",
490
+ top: 0,
491
+ right: "10px"
492
+ },
493
+ ShowChevronsUpDown: false,
494
+ triggerVariants: "ghost",
495
+ disabled: false
496
+ }
497
+ ), model);
498
+ }
499
+ function TableCellActionMenuContainer({
500
+ anchorElem,
501
+ cellMerge
502
+ }) {
503
+ const [editor] = useLexicalComposerContext();
504
+ const menuButtonRef = useRef(null);
505
+ const menuRootRef = useRef(null);
506
+ const [tableCellNode, setTableMenuCellNode] = useState(
507
+ null
508
+ );
509
+ const $moveMenu = useCallback(() => {
510
+ const menu = menuButtonRef.current;
511
+ const selection = $getSelection();
512
+ const nativeSelection = getDOMSelection(editor._window);
513
+ let activeElement;
514
+ if (typeof window !== "undefined") {
515
+ activeElement = document == null ? void 0 : document.activeElement;
516
+ }
517
+ function disable() {
518
+ if (menu) {
519
+ menu.classList.remove("table-cell-action-button-container--active");
520
+ menu.classList.add("table-cell-action-button-container--inactive");
521
+ }
522
+ setTableMenuCellNode(null);
523
+ }
524
+ if (selection == null || menu == null) {
525
+ return disable();
526
+ }
527
+ const rootElement = editor.getRootElement();
528
+ let tableObserver = null;
529
+ let tableCellParentNodeDOM = null;
530
+ if ($isRangeSelection(selection) && rootElement !== null && nativeSelection !== null && rootElement.contains(nativeSelection.anchorNode)) {
531
+ const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(
532
+ selection.anchor.getNode()
533
+ );
534
+ if (tableCellNodeFromSelection == null) {
535
+ return disable();
536
+ }
537
+ tableCellParentNodeDOM = editor.getElementByKey(
538
+ tableCellNodeFromSelection.getKey()
539
+ );
540
+ if (tableCellParentNodeDOM == null || !tableCellNodeFromSelection.isAttached()) {
541
+ return disable();
542
+ }
543
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(
544
+ tableCellNodeFromSelection
545
+ );
546
+ const tableElement = getTableElement(
547
+ tableNode,
548
+ editor.getElementByKey(tableNode.getKey())
549
+ );
550
+ invariant(
551
+ tableElement !== null,
552
+ "TableActionMenu: Expected to find tableElement in DOM"
553
+ );
554
+ tableObserver = getTableObserverFromTableElement(tableElement);
555
+ setTableMenuCellNode(tableCellNodeFromSelection);
556
+ } else if ($isTableSelection(selection)) {
557
+ const anchorNode = $getTableCellNodeFromLexicalNode(
558
+ selection.anchor.getNode()
559
+ );
560
+ invariant(
561
+ $isTableCellNode(anchorNode),
562
+ "TableSelection anchorNode must be a TableCellNode"
563
+ );
564
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(anchorNode);
565
+ const tableElement = getTableElement(
566
+ tableNode,
567
+ editor.getElementByKey(tableNode.getKey())
568
+ );
569
+ invariant(
570
+ tableElement !== null,
571
+ "TableActionMenu: Expected to find tableElement in DOM"
572
+ );
573
+ tableObserver = getTableObserverFromTableElement(tableElement);
574
+ tableCellParentNodeDOM = editor.getElementByKey(anchorNode.getKey());
575
+ } else if (!activeElement) {
576
+ return disable();
577
+ }
578
+ if (tableObserver === null || tableCellParentNodeDOM === null) {
579
+ return disable();
580
+ }
581
+ const enabled = !tableObserver || !tableObserver.isSelecting;
582
+ menu.classList.toggle(
583
+ "table-cell-action-button-container--active",
584
+ enabled
585
+ );
586
+ menu.classList.toggle(
587
+ "table-cell-action-button-container--inactive",
588
+ !enabled
589
+ );
590
+ if (enabled) {
591
+ const tableCellRect = tableCellParentNodeDOM.getBoundingClientRect();
592
+ const anchorRect = anchorElem.getBoundingClientRect();
593
+ const top = tableCellRect.top - anchorRect.top;
594
+ const left = tableCellRect.right - anchorRect.left;
595
+ menu.style.transform = `translate(${left}px, ${top}px)`;
596
+ }
597
+ }, [editor, anchorElem]);
598
+ useEffect(() => {
599
+ let timeoutId = void 0;
600
+ const callback = () => {
601
+ timeoutId = void 0;
602
+ editor.getEditorState().read($moveMenu);
603
+ };
604
+ const delayedCallback = () => {
605
+ if (timeoutId === void 0) {
606
+ timeoutId = setTimeout(callback, 0);
607
+ }
608
+ return false;
609
+ };
610
+ return mergeRegister(
611
+ editor.registerUpdateListener(delayedCallback),
612
+ editor.registerCommand(
613
+ SELECTION_CHANGE_COMMAND,
614
+ delayedCallback,
615
+ COMMAND_PRIORITY_CRITICAL
616
+ ),
617
+ editor.registerRootListener((rootElement, prevRootElement) => {
618
+ if (prevRootElement) {
619
+ prevRootElement.removeEventListener("mouseup", delayedCallback);
620
+ }
621
+ if (rootElement) {
622
+ rootElement.addEventListener("mouseup", delayedCallback);
623
+ delayedCallback();
624
+ }
625
+ }),
626
+ () => clearTimeout(timeoutId)
627
+ );
628
+ });
629
+ const prevTableCellDOM = useRef(tableCellNode);
630
+ useEffect(() => {
631
+ prevTableCellDOM.current = tableCellNode;
632
+ }, [prevTableCellDOM, tableCellNode]);
633
+ return /* @__PURE__ */ React2.createElement(
634
+ "div",
635
+ {
636
+ className: " absolute top-1 left-1 will-change-transform",
637
+ ref: menuButtonRef
638
+ },
639
+ tableCellNode != null && /* @__PURE__ */ React2.createElement(
640
+ TableActionMenu,
641
+ {
642
+ contextRef: menuRootRef,
643
+ tableCellNode,
644
+ cellMerge
645
+ }
646
+ )
647
+ );
648
+ }
649
+ function TableActionMenuPlugin({
650
+ anchorElem = document.body,
651
+ cellMerge = false
652
+ }) {
653
+ const isEditable = useLexicalEditable();
654
+ return createPortal(
655
+ isEditable ? /* @__PURE__ */ React2.createElement(
656
+ TableCellActionMenuContainer,
657
+ {
658
+ anchorElem,
659
+ cellMerge
660
+ }
661
+ ) : null,
662
+ anchorElem
663
+ );
664
+ }
665
+ export {
666
+ TableActionMenuPlugin as default
667
+ };