@payloadcms/richtext-lexical 3.0.0-beta.57 → 3.0.0-beta.59

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 (78) hide show
  1. package/dist/cell/index.d.ts.map +1 -1
  2. package/dist/cell/index.js +2 -2
  3. package/dist/cell/index.js.map +1 -1
  4. package/dist/exports/client/Field-5TCNFYE2.js +2 -0
  5. package/dist/exports/client/Field-5TCNFYE2.js.map +7 -0
  6. package/dist/exports/client/bundled.css +1 -1
  7. package/dist/exports/client/chunk-CUMDYP5E.js +2 -0
  8. package/dist/exports/client/chunk-CUMDYP5E.js.map +7 -0
  9. package/dist/exports/client/component-7J2IXLN3.js +2 -0
  10. package/dist/exports/client/component-7J2IXLN3.js.map +7 -0
  11. package/dist/exports/client/{component-V5QZ7EVZ.js → component-RV346GAA.js} +2 -2
  12. package/dist/exports/client/index.d.ts +1 -0
  13. package/dist/exports/client/index.d.ts.map +1 -1
  14. package/dist/exports/client/index.js +7 -7
  15. package/dist/exports/client/index.js.map +4 -4
  16. package/dist/features/blocks/component/index.js +3 -3
  17. package/dist/features/blocks/component/index.js.map +1 -1
  18. package/dist/features/createFeaturePropComponent.js +1 -1
  19. package/dist/features/createFeaturePropComponent.js.map +1 -1
  20. package/dist/features/experimental_table/feature.client.d.ts +2 -0
  21. package/dist/features/experimental_table/feature.client.d.ts.map +1 -0
  22. package/dist/features/experimental_table/feature.client.js +66 -0
  23. package/dist/features/experimental_table/feature.client.js.map +1 -0
  24. package/dist/features/experimental_table/feature.server.d.ts +2 -0
  25. package/dist/features/experimental_table/feature.server.d.ts.map +1 -0
  26. package/dist/features/experimental_table/feature.server.js +52 -0
  27. package/dist/features/experimental_table/feature.server.js.map +1 -0
  28. package/dist/features/experimental_table/plugins/TableActionMenuPlugin/index.d.ts +4 -0
  29. package/dist/features/experimental_table/plugins/TableActionMenuPlugin/index.d.ts.map +1 -0
  30. package/dist/features/experimental_table/plugins/TableActionMenuPlugin/index.js +602 -0
  31. package/dist/features/experimental_table/plugins/TableActionMenuPlugin/index.js.map +1 -0
  32. package/dist/features/experimental_table/plugins/TableCellResizerPlugin/index.d.ts +4 -0
  33. package/dist/features/experimental_table/plugins/TableCellResizerPlugin/index.d.ts.map +1 -0
  34. package/dist/features/experimental_table/plugins/TableCellResizerPlugin/index.js +322 -0
  35. package/dist/features/experimental_table/plugins/TableCellResizerPlugin/index.js.map +1 -0
  36. package/dist/features/experimental_table/plugins/TablePlugin/index.d.ts +24 -0
  37. package/dist/features/experimental_table/plugins/TablePlugin/index.d.ts.map +1 -0
  38. package/dist/features/experimental_table/plugins/TablePlugin/index.js +99 -0
  39. package/dist/features/experimental_table/plugins/TablePlugin/index.js.map +1 -0
  40. package/dist/features/typesClient.d.ts +5 -1
  41. package/dist/features/typesClient.d.ts.map +1 -1
  42. package/dist/features/typesClient.js.map +1 -1
  43. package/dist/field/index.d.ts.map +1 -1
  44. package/dist/field/index.js +8 -8
  45. package/dist/field/index.js.map +1 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/lexical/LexicalProvider.d.ts.map +1 -1
  51. package/dist/lexical/LexicalProvider.js +24 -4
  52. package/dist/lexical/LexicalProvider.js.map +1 -1
  53. package/dist/lexical/config/client/sanitize.d.ts.map +1 -1
  54. package/dist/lexical/config/client/sanitize.js +4 -0
  55. package/dist/lexical/config/client/sanitize.js.map +1 -1
  56. package/dist/lexical/ui/icons/Meatballs/index.d.ts +3 -0
  57. package/dist/lexical/ui/icons/Meatballs/index.d.ts.map +1 -0
  58. package/dist/lexical/ui/icons/Meatballs/index.js +25 -0
  59. package/dist/lexical/ui/icons/Meatballs/index.js.map +1 -0
  60. package/dist/lexical/ui/icons/Table/index.d.ts +3 -0
  61. package/dist/lexical/ui/icons/Table/index.d.ts.map +1 -0
  62. package/dist/lexical/ui/icons/Table/index.js +19 -0
  63. package/dist/lexical/ui/icons/Table/index.js.map +1 -0
  64. package/dist/utilities/fieldsDrawer/DrawerContent.js +2 -2
  65. package/dist/utilities/fieldsDrawer/DrawerContent.js.map +1 -1
  66. package/dist/utilities/generateComponentMap.d.ts.map +1 -1
  67. package/dist/utilities/generateComponentMap.js +3 -3
  68. package/dist/utilities/generateComponentMap.js.map +1 -1
  69. package/dist/utilities/generateSchemaMap.js +1 -1
  70. package/dist/utilities/generateSchemaMap.js.map +1 -1
  71. package/package.json +12 -11
  72. package/dist/exports/client/Field-XBUN6QOM.js +0 -2
  73. package/dist/exports/client/Field-XBUN6QOM.js.map +0 -7
  74. package/dist/exports/client/chunk-OAQL5GDK.js +0 -2
  75. package/dist/exports/client/chunk-OAQL5GDK.js.map +0 -7
  76. package/dist/exports/client/component-YNZTTMBY.js +0 -2
  77. package/dist/exports/client/component-YNZTTMBY.js.map +0 -7
  78. /package/dist/exports/client/{component-V5QZ7EVZ.js.map → component-RV346GAA.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/features/experimental_table/plugins/TableActionMenuPlugin/index.tsx"],"sourcesContent":["'use client'\n\nimport type {\n HTMLTableElementWithWithTableSelectionState,\n TableRowNode,\n TableSelection,\n} from '@lexical/table'\nimport type { ElementNode } from 'lexical'\nimport type { JSX } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport {\n $deleteTableColumn__EXPERIMENTAL,\n $deleteTableRow__EXPERIMENTAL,\n $getNodeTriplet,\n $getTableCellNodeFromLexicalNode,\n $getTableColumnIndexFromTableCellNode,\n $getTableNodeFromLexicalNodeOrThrow,\n $getTableRowIndexFromTableCellNode,\n $insertTableColumn__EXPERIMENTAL,\n $insertTableRow__EXPERIMENTAL,\n $isTableCellNode,\n $isTableRowNode,\n $isTableSelection,\n $unmergeCell,\n TableCellHeaderStates,\n TableCellNode,\n getTableObserverFromTableElement,\n} from '@lexical/table'\nimport { useScrollInfo } from '@payloadcms/ui'\nimport {\n $createParagraphNode,\n $getRoot,\n $getSelection,\n $isElementNode,\n $isParagraphNode,\n $isRangeSelection,\n $isTextNode,\n} from 'lexical'\nimport * as React from 'react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { PluginComponentWithAnchor } from '../../../typesClient.js'\n\nimport { MeatballsIcon } from '../../../../lexical/ui/icons/Meatballs/index.js'\nimport { invariant } from '../../../../lexical/utils/invariant.js'\nimport './index.scss'\n\nfunction computeSelectionCount(selection: TableSelection): {\n columns: number\n rows: number\n} {\n const selectionShape = selection.getShape()\n return {\n columns: selectionShape.toX - selectionShape.fromX + 1,\n rows: selectionShape.toY - selectionShape.fromY + 1,\n }\n}\n\n// This is important when merging cells as there is no good way to re-merge weird shapes (a result\n// of selecting merged cells and non-merged)\nfunction isTableSelectionRectangular(selection: TableSelection): boolean {\n const nodes = selection.getNodes()\n const currentRows: Array<number> = []\n let currentRow = null\n let expectedColumns = null\n let currentColumns = 0\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]\n if ($isTableCellNode(node)) {\n const row = node.getParentOrThrow()\n invariant($isTableRowNode(row), 'Expected CellNode to have a RowNode parent')\n if (currentRow !== row) {\n if (expectedColumns !== null && currentColumns !== expectedColumns) {\n return false\n }\n if (currentRow !== null) {\n expectedColumns = currentColumns\n }\n currentRow = row\n currentColumns = 0\n }\n const colSpan = node.__colSpan\n for (let j = 0; j < colSpan; j++) {\n if (currentRows[currentColumns + j] === undefined) {\n currentRows[currentColumns + j] = 0\n }\n currentRows[currentColumns + j] += node.__rowSpan\n }\n currentColumns += colSpan\n }\n }\n return (\n (expectedColumns === null || currentColumns === expectedColumns) &&\n currentRows.every((v) => v === currentRows[0])\n )\n}\n\nfunction $canUnmerge(): boolean {\n const selection = $getSelection()\n if (\n ($isRangeSelection(selection) && !selection.isCollapsed()) ||\n ($isTableSelection(selection) && !selection.anchor.is(selection.focus)) ||\n (!$isRangeSelection(selection) && !$isTableSelection(selection))\n ) {\n return false\n }\n const [cell] = $getNodeTriplet(selection.anchor)\n return cell.__colSpan > 1 || cell.__rowSpan > 1\n}\n\nfunction $cellContainsEmptyParagraph(cell: TableCellNode): boolean {\n if (cell.getChildrenSize() !== 1) {\n return false\n }\n const firstChild = cell.getFirstChildOrThrow()\n if (!$isParagraphNode(firstChild) || !firstChild.isEmpty()) {\n return false\n }\n return true\n}\n\nfunction $selectLastDescendant(node: ElementNode): void {\n const lastDescendant = node.getLastDescendant()\n if ($isTextNode(lastDescendant)) {\n lastDescendant.select()\n } else if ($isElementNode(lastDescendant)) {\n lastDescendant.selectEnd()\n } else if (lastDescendant !== null) {\n lastDescendant.selectNext()\n }\n}\n\ntype TableCellActionMenuProps = Readonly<{\n cellMerge: boolean\n contextRef: { current: HTMLElement | null }\n onClose: () => void\n setIsMenuOpen: (isOpen: boolean) => void\n tableCellNode: TableCellNode\n}>\n\nfunction TableActionMenu({\n cellMerge,\n contextRef,\n onClose,\n setIsMenuOpen,\n tableCellNode: _tableCellNode,\n}: TableCellActionMenuProps) {\n const [editor] = useLexicalComposerContext()\n const dropDownRef = useRef<HTMLDivElement | null>(null)\n const [tableCellNode, updateTableCellNode] = useState(_tableCellNode)\n const [selectionCounts, updateSelectionCounts] = useState({\n columns: 1,\n rows: 1,\n })\n const [canMergeCells, setCanMergeCells] = useState(false)\n const [canUnmergeCell, setCanUnmergeCell] = useState(false)\n const { y } = useScrollInfo()\n\n useEffect(() => {\n return editor.registerMutationListener(TableCellNode, (nodeMutations) => {\n const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === 'updated'\n\n if (nodeUpdated) {\n editor.getEditorState().read(() => {\n updateTableCellNode(tableCellNode.getLatest())\n })\n }\n })\n }, [editor, tableCellNode])\n\n useEffect(() => {\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n // Merge cells\n if ($isTableSelection(selection)) {\n const currentSelectionCounts = computeSelectionCount(selection)\n updateSelectionCounts(computeSelectionCount(selection))\n setCanMergeCells(\n isTableSelectionRectangular(selection) &&\n (currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1),\n )\n }\n // Unmerge cell\n setCanUnmergeCell($canUnmerge())\n })\n }, [editor])\n\n useEffect(() => {\n const menuButtonElement = contextRef.current\n const dropDownElement = dropDownRef.current\n const rootElement = editor.getRootElement()\n\n if (menuButtonElement != null && dropDownElement != null && rootElement != null) {\n const rootEleRect = rootElement.getBoundingClientRect()\n const menuButtonRect = menuButtonElement.getBoundingClientRect()\n dropDownElement.style.opacity = '1'\n const dropDownElementRect = dropDownElement.getBoundingClientRect()\n const margin = 5\n let leftPosition = menuButtonRect.right + margin\n if (\n leftPosition + dropDownElementRect.width > window.innerWidth ||\n leftPosition + dropDownElementRect.width > rootEleRect.right\n ) {\n const position = menuButtonRect.left - dropDownElementRect.width - margin\n leftPosition = (position < 0 ? margin : position) + window.pageXOffset\n }\n dropDownElement.style.left = `${leftPosition + window.pageXOffset}px`\n\n let topPosition = menuButtonRect.top\n if (topPosition + dropDownElementRect.height > window.innerHeight) {\n const position = menuButtonRect.bottom - dropDownElementRect.height\n topPosition = (position < 0 ? margin : position) + window.pageYOffset\n }\n dropDownElement.style.top = `${topPosition}px`\n }\n }, [contextRef, dropDownRef, editor, y])\n\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (\n dropDownRef.current != null &&\n contextRef.current != null &&\n !dropDownRef.current.contains(event.target as Node) &&\n !contextRef.current.contains(event.target as Node)\n ) {\n setIsMenuOpen(false)\n }\n }\n\n window.addEventListener('click', handleClickOutside)\n\n return () => window.removeEventListener('click', handleClickOutside)\n }, [setIsMenuOpen, contextRef])\n\n const clearTableSelection = useCallback(() => {\n editor.update(() => {\n if (tableCellNode.isAttached()) {\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n const tableElement = editor.getElementByKey(\n tableNode.getKey(),\n ) as HTMLTableElementWithWithTableSelectionState\n\n if (!tableElement) {\n throw new Error('Expected to find tableElement in DOM')\n }\n\n const tableSelection = getTableObserverFromTableElement(tableElement)\n if (tableSelection !== null) {\n tableSelection.clearHighlight()\n }\n\n tableNode.markDirty()\n updateTableCellNode(tableCellNode.getLatest())\n }\n\n const rootNode = $getRoot()\n rootNode.selectStart()\n })\n }, [editor, tableCellNode])\n\n const mergeTableCellsAtSelection = () => {\n editor.update(() => {\n const selection = $getSelection()\n if ($isTableSelection(selection)) {\n const { columns, rows } = computeSelectionCount(selection)\n const nodes = selection.getNodes()\n let firstCell: TableCellNode | null = null\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]\n if ($isTableCellNode(node)) {\n if (firstCell === null) {\n node.setColSpan(columns).setRowSpan(rows)\n firstCell = node\n const isEmpty = $cellContainsEmptyParagraph(node)\n let firstChild\n if (isEmpty && $isParagraphNode((firstChild = node.getFirstChild()))) {\n firstChild.remove()\n }\n } else if ($isTableCellNode(firstCell)) {\n const isEmpty = $cellContainsEmptyParagraph(node)\n if (!isEmpty) {\n firstCell.append(...node.getChildren())\n }\n node.remove()\n }\n }\n }\n if (firstCell !== null) {\n if (firstCell.getChildrenSize() === 0) {\n firstCell.append($createParagraphNode())\n }\n $selectLastDescendant(firstCell)\n }\n onClose()\n }\n })\n }\n\n const unmergeTableCellsAtSelection = () => {\n editor.update(() => {\n $unmergeCell()\n })\n }\n\n const insertTableRowAtSelection = useCallback(\n (shouldInsertAfter: boolean) => {\n editor.update(() => {\n $insertTableRow__EXPERIMENTAL(shouldInsertAfter)\n onClose()\n })\n },\n [editor, onClose],\n )\n\n const insertTableColumnAtSelection = useCallback(\n (shouldInsertAfter: boolean) => {\n editor.update(() => {\n for (let i = 0; i < selectionCounts.columns; i++) {\n $insertTableColumn__EXPERIMENTAL(shouldInsertAfter)\n }\n onClose()\n })\n },\n [editor, onClose, selectionCounts.columns],\n )\n\n const deleteTableRowAtSelection = useCallback(() => {\n editor.update(() => {\n $deleteTableRow__EXPERIMENTAL()\n onClose()\n })\n }, [editor, onClose])\n\n const deleteTableAtSelection = useCallback(() => {\n editor.update(() => {\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n tableNode.remove()\n\n clearTableSelection()\n onClose()\n })\n }, [editor, tableCellNode, clearTableSelection, onClose])\n\n const deleteTableColumnAtSelection = useCallback(() => {\n editor.update(() => {\n $deleteTableColumn__EXPERIMENTAL()\n onClose()\n })\n }, [editor, onClose])\n\n const toggleTableRowIsHeader = useCallback(() => {\n editor.update(() => {\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n\n const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode)\n\n const tableRows = tableNode.getChildren()\n\n if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {\n throw new Error('Expected table cell to be inside of table row.')\n }\n\n const tableRow = tableRows[tableRowIndex]\n\n if (!$isTableRowNode(tableRow)) {\n throw new Error('Expected table row')\n }\n\n tableRow.getChildren().forEach((tableCell) => {\n if (!$isTableCellNode(tableCell)) {\n throw new Error('Expected table cell')\n }\n\n tableCell.toggleHeaderStyle(TableCellHeaderStates.ROW)\n })\n\n clearTableSelection()\n onClose()\n })\n }, [editor, tableCellNode, clearTableSelection, onClose])\n\n const toggleTableColumnIsHeader = useCallback(() => {\n editor.update(() => {\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n\n const tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode)\n\n const tableRows = tableNode.getChildren<TableRowNode>()\n const maxRowsLength = Math.max(...tableRows.map((row) => row.getChildren().length))\n\n if (tableColumnIndex >= maxRowsLength || tableColumnIndex < 0) {\n throw new Error('Expected table cell to be inside of table row.')\n }\n\n for (let r = 0; r < tableRows.length; r++) {\n const tableRow = tableRows[r]\n\n if (!$isTableRowNode(tableRow)) {\n throw new Error('Expected table row')\n }\n\n const tableCells = tableRow.getChildren()\n if (tableColumnIndex >= tableCells.length) {\n // if cell is outside of bounds for the current row (for example various merge cell cases) we shouldn't highlight it\n continue\n }\n\n const tableCell = tableCells[tableColumnIndex]\n\n if (!$isTableCellNode(tableCell)) {\n throw new Error('Expected table cell')\n }\n\n tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN)\n }\n\n clearTableSelection()\n onClose()\n })\n }, [editor, tableCellNode, clearTableSelection, onClose])\n\n let mergeCellButton: JSX.Element | null = null\n if (cellMerge) {\n if (canMergeCells) {\n mergeCellButton = (\n <button\n className=\"item\"\n data-test-id=\"table-merge-cells\"\n onClick={() => mergeTableCellsAtSelection()}\n type=\"button\"\n >\n Merge cells\n </button>\n )\n } else if (canUnmergeCell) {\n mergeCellButton = (\n <button\n className=\"item\"\n data-test-id=\"table-unmerge-cells\"\n onClick={() => unmergeTableCellsAtSelection()}\n type=\"button\"\n >\n Unmerge cells\n </button>\n )\n }\n }\n\n return createPortal(\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions,jsx-a11y/click-events-have-key-events\n <div\n className=\"table-action-menu-dropdown\"\n onClick={(e) => {\n e.stopPropagation()\n }}\n ref={dropDownRef}\n >\n {mergeCellButton ? (\n <React.Fragment>\n {mergeCellButton}\n <hr />\n </React.Fragment>\n ) : null}\n\n <button\n className=\"item\"\n data-test-id=\"table-insert-row-above\"\n onClick={() => insertTableRowAtSelection(false)}\n type=\"button\"\n >\n <span className=\"text\">\n Insert {selectionCounts.rows === 1 ? 'row' : `${selectionCounts.rows} rows`} above\n </span>\n </button>\n <button\n className=\"item\"\n data-test-id=\"table-insert-row-below\"\n onClick={() => insertTableRowAtSelection(true)}\n type=\"button\"\n >\n <span className=\"text\">\n Insert {selectionCounts.rows === 1 ? 'row' : `${selectionCounts.rows} rows`} below\n </span>\n </button>\n <hr />\n <button\n className=\"item\"\n data-test-id=\"table-insert-column-before\"\n onClick={() => insertTableColumnAtSelection(false)}\n type=\"button\"\n >\n <span className=\"text\">\n Insert {selectionCounts.columns === 1 ? 'column' : `${selectionCounts.columns} columns`}{' '}\n left\n </span>\n </button>\n <button\n className=\"item\"\n data-test-id=\"table-insert-column-after\"\n onClick={() => insertTableColumnAtSelection(true)}\n type=\"button\"\n >\n <span className=\"text\">\n Insert {selectionCounts.columns === 1 ? 'column' : `${selectionCounts.columns} columns`}{' '}\n right\n </span>\n </button>\n <hr />\n <button\n className=\"item\"\n data-test-id=\"table-delete-columns\"\n onClick={() => deleteTableColumnAtSelection()}\n type=\"button\"\n >\n <span className=\"text\">Delete column</span>\n </button>\n <button\n className=\"item\"\n data-test-id=\"table-delete-rows\"\n onClick={() => deleteTableRowAtSelection()}\n type=\"button\"\n >\n <span className=\"text\">Delete row</span>\n </button>\n <button\n className=\"item\"\n data-test-id=\"table-delete\"\n onClick={() => deleteTableAtSelection()}\n type=\"button\"\n >\n <span className=\"text\">Delete table</span>\n </button>\n <hr />\n <button className=\"item\" onClick={() => toggleTableRowIsHeader()} type=\"button\">\n <span className=\"text\">\n {(tableCellNode.__headerState & TableCellHeaderStates.ROW) === TableCellHeaderStates.ROW\n ? 'Remove'\n : 'Add'}{' '}\n row header\n </span>\n </button>\n <button\n className=\"item\"\n data-test-id=\"table-column-header\"\n onClick={() => toggleTableColumnIsHeader()}\n type=\"button\"\n >\n <span className=\"text\">\n {(tableCellNode.__headerState & TableCellHeaderStates.COLUMN) ===\n TableCellHeaderStates.COLUMN\n ? 'Remove'\n : 'Add'}{' '}\n column header\n </span>\n </button>\n </div>,\n document.body,\n )\n}\n\nfunction TableCellActionMenuContainer({\n anchorElem,\n cellMerge,\n}: {\n anchorElem: HTMLElement\n cellMerge: boolean\n}): JSX.Element {\n const [editor] = useLexicalComposerContext()\n\n const menuButtonRef = useRef(null)\n const menuRootRef = useRef(null)\n const [isMenuOpen, setIsMenuOpen] = useState(false)\n\n const [tableCellNode, setTableMenuCellNode] = useState<TableCellNode | null>(null)\n\n const $moveMenu = useCallback(() => {\n const menu = menuButtonRef.current\n const selection = $getSelection()\n const nativeSelection = window.getSelection()\n const activeElement = document.activeElement\n\n if (selection == null || menu == null) {\n setTableMenuCellNode(null)\n return\n }\n\n const rootElement = editor.getRootElement()\n\n if (\n $isRangeSelection(selection) &&\n rootElement !== null &&\n nativeSelection !== null &&\n rootElement.contains(nativeSelection.anchorNode)\n ) {\n const tableCellNodeFromSelection = $getTableCellNodeFromLexicalNode(\n selection.anchor.getNode(),\n )\n\n if (tableCellNodeFromSelection == null) {\n setTableMenuCellNode(null)\n return\n }\n\n const tableCellParentNodeDOM = editor.getElementByKey(tableCellNodeFromSelection.getKey())\n\n if (tableCellParentNodeDOM == null) {\n setTableMenuCellNode(null)\n return\n }\n\n setTableMenuCellNode(tableCellNodeFromSelection)\n } else if (!activeElement) {\n setTableMenuCellNode(null)\n }\n }, [editor])\n\n useEffect(() => {\n return editor.registerUpdateListener(() => {\n editor.getEditorState().read(() => {\n $moveMenu()\n })\n })\n })\n\n useEffect(() => {\n const menuButtonDOM = menuButtonRef.current as HTMLButtonElement | null\n\n if (menuButtonDOM != null && tableCellNode != null) {\n const tableCellNodeDOM = editor.getElementByKey(tableCellNode.getKey())\n\n if (tableCellNodeDOM != null) {\n const tableCellRect = tableCellNodeDOM.getBoundingClientRect()\n const menuRect = menuButtonDOM.getBoundingClientRect()\n const anchorRect = anchorElem.getBoundingClientRect()\n\n const top = tableCellRect.top - anchorRect.top + 4\n const left = tableCellRect.right - menuRect.width - 10 - anchorRect.left\n\n menuButtonDOM.style.opacity = '1'\n menuButtonDOM.style.transform = `translate(${left}px, ${top}px)`\n } else {\n menuButtonDOM.style.opacity = '0'\n menuButtonDOM.style.transform = 'translate(-10000px, -10000px)'\n }\n }\n }, [menuButtonRef, tableCellNode, editor, anchorElem])\n\n const prevTableCellDOM = useRef(tableCellNode)\n\n useEffect(() => {\n if (prevTableCellDOM.current !== tableCellNode) {\n setIsMenuOpen(false)\n }\n\n prevTableCellDOM.current = tableCellNode\n }, [prevTableCellDOM, tableCellNode])\n\n return (\n <div className=\"table-cell-action-button-container\" ref={menuButtonRef}>\n {tableCellNode != null && (\n <React.Fragment>\n <button\n className=\"table-cell-action-button\"\n onClick={(e) => {\n e.stopPropagation()\n setIsMenuOpen(!isMenuOpen)\n }}\n ref={menuRootRef}\n type=\"button\"\n >\n <MeatballsIcon />\n </button>\n {isMenuOpen && (\n <TableActionMenu\n cellMerge={cellMerge}\n contextRef={menuRootRef}\n onClose={() => setIsMenuOpen(false)}\n setIsMenuOpen={setIsMenuOpen}\n tableCellNode={tableCellNode}\n />\n )}\n </React.Fragment>\n )}\n </div>\n )\n}\n\nexport const TableActionMenuPlugin: PluginComponentWithAnchor = ({ anchorElem }) => {\n const isEditable = useLexicalEditable()\n return createPortal(\n isEditable ? (\n <TableCellActionMenuContainer anchorElem={anchorElem ?? document.body} cellMerge />\n ) : null,\n anchorElem ?? document.body,\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","$deleteTableColumn__EXPERIMENTAL","$deleteTableRow__EXPERIMENTAL","$getNodeTriplet","$getTableCellNodeFromLexicalNode","$getTableColumnIndexFromTableCellNode","$getTableNodeFromLexicalNodeOrThrow","$getTableRowIndexFromTableCellNode","$insertTableColumn__EXPERIMENTAL","$insertTableRow__EXPERIMENTAL","$isTableCellNode","$isTableRowNode","$isTableSelection","$unmergeCell","TableCellHeaderStates","TableCellNode","getTableObserverFromTableElement","useScrollInfo","$createParagraphNode","$getRoot","$getSelection","$isElementNode","$isParagraphNode","$isRangeSelection","$isTextNode","React","useCallback","useEffect","useRef","useState","createPortal","MeatballsIcon","invariant","computeSelectionCount","selection","selectionShape","getShape","columns","toX","fromX","rows","toY","fromY","isTableSelectionRectangular","nodes","getNodes","currentRows","currentRow","expectedColumns","currentColumns","i","length","node","row","getParentOrThrow","colSpan","__colSpan","j","undefined","__rowSpan","every","v","$canUnmerge","isCollapsed","anchor","is","focus","cell","$cellContainsEmptyParagraph","getChildrenSize","firstChild","getFirstChildOrThrow","isEmpty","$selectLastDescendant","lastDescendant","getLastDescendant","select","selectEnd","selectNext","TableActionMenu","cellMerge","contextRef","onClose","setIsMenuOpen","tableCellNode","_tableCellNode","editor","dropDownRef","updateTableCellNode","selectionCounts","updateSelectionCounts","canMergeCells","setCanMergeCells","canUnmergeCell","setCanUnmergeCell","y","registerMutationListener","nodeMutations","nodeUpdated","get","getKey","getEditorState","read","getLatest","currentSelectionCounts","menuButtonElement","current","dropDownElement","rootElement","getRootElement","rootEleRect","getBoundingClientRect","menuButtonRect","style","opacity","dropDownElementRect","margin","leftPosition","right","width","window","innerWidth","position","left","pageXOffset","topPosition","top","height","innerHeight","bottom","pageYOffset","handleClickOutside","event","contains","target","addEventListener","removeEventListener","clearTableSelection","update","isAttached","tableNode","tableElement","getElementByKey","Error","tableSelection","clearHighlight","markDirty","rootNode","selectStart","mergeTableCellsAtSelection","firstCell","setColSpan","setRowSpan","getFirstChild","remove","append","getChildren","unmergeTableCellsAtSelection","insertTableRowAtSelection","shouldInsertAfter","insertTableColumnAtSelection","deleteTableRowAtSelection","deleteTableAtSelection","deleteTableColumnAtSelection","toggleTableRowIsHeader","tableRowIndex","tableRows","tableRow","forEach","tableCell","toggleHeaderStyle","ROW","toggleTableColumnIsHeader","tableColumnIndex","maxRowsLength","Math","max","map","r","tableCells","COLUMN","mergeCellButton","button","className","data-test-id","onClick","type","div","e","stopPropagation","ref","Fragment","hr","span","__headerState","document","body","TableCellActionMenuContainer","anchorElem","menuButtonRef","menuRootRef","isMenuOpen","setTableMenuCellNode","$moveMenu","menu","nativeSelection","getSelection","activeElement","anchorNode","tableCellNodeFromSelection","getNode","tableCellParentNodeDOM","registerUpdateListener","menuButtonDOM","tableCellNodeDOM","tableCellRect","menuRect","anchorRect","transform","prevTableCellDOM","TableActionMenuPlugin","isEditable"],"mappings":"AAAA;;AAUA,SAASA,yBAAyB,QAAQ,wCAAuC;AACjF,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SACEC,gCAAgC,EAChCC,6BAA6B,EAC7BC,eAAe,EACfC,gCAAgC,EAChCC,qCAAqC,EACrCC,mCAAmC,EACnCC,kCAAkC,EAClCC,gCAAgC,EAChCC,6BAA6B,EAC7BC,gBAAgB,EAChBC,eAAe,EACfC,iBAAiB,EACjBC,YAAY,EACZC,qBAAqB,EACrBC,aAAa,EACbC,gCAAgC,QAC3B,iBAAgB;AACvB,SAASC,aAAa,QAAQ,iBAAgB;AAC9C,SACEC,oBAAoB,EACpBC,QAAQ,EACRC,aAAa,EACbC,cAAc,EACdC,gBAAgB,EAChBC,iBAAiB,EACjBC,WAAW,QACN,UAAS;AAChB,YAAYC,WAAW,QAAO;AAC9B,SAASC,WAAW,EAAEC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChE,SAASC,YAAY,QAAQ,YAAW;AAIxC,SAASC,aAAa,QAAQ,kDAAiD;AAC/E,SAASC,SAAS,QAAQ,yCAAwC;AAGlE,SAASC,sBAAsBC,SAAyB;IAItD,MAAMC,iBAAiBD,UAAUE,QAAQ;IACzC,OAAO;QACLC,SAASF,eAAeG,GAAG,GAAGH,eAAeI,KAAK,GAAG;QACrDC,MAAML,eAAeM,GAAG,GAAGN,eAAeO,KAAK,GAAG;IACpD;AACF;AAEA,kGAAkG;AAClG,4CAA4C;AAC5C,SAASC,4BAA4BT,SAAyB;IAC5D,MAAMU,QAAQV,UAAUW,QAAQ;IAChC,MAAMC,cAA6B,EAAE;IACrC,IAAIC,aAAa;IACjB,IAAIC,kBAAkB;IACtB,IAAIC,iBAAiB;IACrB,IAAK,IAAIC,IAAI,GAAGA,IAAIN,MAAMO,MAAM,EAAED,IAAK;QACrC,MAAME,OAAOR,KAAK,CAACM,EAAE;QACrB,IAAIxC,iBAAiB0C,OAAO;YAC1B,MAAMC,MAAMD,KAAKE,gBAAgB;YACjCtB,UAAUrB,gBAAgB0C,MAAM;YAChC,IAAIN,eAAeM,KAAK;gBACtB,IAAIL,oBAAoB,QAAQC,mBAAmBD,iBAAiB;oBAClE,OAAO;gBACT;gBACA,IAAID,eAAe,MAAM;oBACvBC,kBAAkBC;gBACpB;gBACAF,aAAaM;gBACbJ,iBAAiB;YACnB;YACA,MAAMM,UAAUH,KAAKI,SAAS;YAC9B,IAAK,IAAIC,IAAI,GAAGA,IAAIF,SAASE,IAAK;gBAChC,IAAIX,WAAW,CAACG,iBAAiBQ,EAAE,KAAKC,WAAW;oBACjDZ,WAAW,CAACG,iBAAiBQ,EAAE,GAAG;gBACpC;gBACAX,WAAW,CAACG,iBAAiBQ,EAAE,IAAIL,KAAKO,SAAS;YACnD;YACAV,kBAAkBM;QACpB;IACF;IACA,OACE,AAACP,CAAAA,oBAAoB,QAAQC,mBAAmBD,eAAc,KAC9DF,YAAYc,KAAK,CAAC,CAACC,IAAMA,MAAMf,WAAW,CAAC,EAAE;AAEjD;AAEA,SAASgB;IACP,MAAM5B,YAAYd;IAClB,IACE,AAACG,kBAAkBW,cAAc,CAACA,UAAU6B,WAAW,MACtDnD,kBAAkBsB,cAAc,CAACA,UAAU8B,MAAM,CAACC,EAAE,CAAC/B,UAAUgC,KAAK,KACpE,CAAC3C,kBAAkBW,cAAc,CAACtB,kBAAkBsB,YACrD;QACA,OAAO;IACT;IACA,MAAM,CAACiC,KAAK,GAAGhE,gBAAgB+B,UAAU8B,MAAM;IAC/C,OAAOG,KAAKX,SAAS,GAAG,KAAKW,KAAKR,SAAS,GAAG;AAChD;AAEA,SAASS,4BAA4BD,IAAmB;IACtD,IAAIA,KAAKE,eAAe,OAAO,GAAG;QAChC,OAAO;IACT;IACA,MAAMC,aAAaH,KAAKI,oBAAoB;IAC5C,IAAI,CAACjD,iBAAiBgD,eAAe,CAACA,WAAWE,OAAO,IAAI;QAC1D,OAAO;IACT;IACA,OAAO;AACT;AAEA,SAASC,sBAAsBrB,IAAiB;IAC9C,MAAMsB,iBAAiBtB,KAAKuB,iBAAiB;IAC7C,IAAInD,YAAYkD,iBAAiB;QAC/BA,eAAeE,MAAM;IACvB,OAAO,IAAIvD,eAAeqD,iBAAiB;QACzCA,eAAeG,SAAS;IAC1B,OAAO,IAAIH,mBAAmB,MAAM;QAClCA,eAAeI,UAAU;IAC3B;AACF;AAUA,SAASC,gBAAgB,EACvBC,SAAS,EACTC,UAAU,EACVC,OAAO,EACPC,aAAa,EACbC,eAAeC,cAAc,EACJ;IACzB,MAAM,CAACC,OAAO,GAAGvF;IACjB,MAAMwF,cAAc3D,OAA8B;IAClD,MAAM,CAACwD,eAAeI,oBAAoB,GAAG3D,SAASwD;IACtD,MAAM,CAACI,iBAAiBC,sBAAsB,GAAG7D,SAAS;QACxDQ,SAAS;QACTG,MAAM;IACR;IACA,MAAM,CAACmD,eAAeC,iBAAiB,GAAG/D,SAAS;IACnD,MAAM,CAACgE,gBAAgBC,kBAAkB,GAAGjE,SAAS;IACrD,MAAM,EAAEkE,CAAC,EAAE,GAAG9E;IAEdU,UAAU;QACR,OAAO2D,OAAOU,wBAAwB,CAACjF,eAAe,CAACkF;YACrD,MAAMC,cAAcD,cAAcE,GAAG,CAACf,cAAcgB,MAAM,QAAQ;YAElE,IAAIF,aAAa;gBACfZ,OAAOe,cAAc,GAAGC,IAAI,CAAC;oBAC3Bd,oBAAoBJ,cAAcmB,SAAS;gBAC7C;YACF;QACF;IACF,GAAG;QAACjB;QAAQF;KAAc;IAE1BzD,UAAU;QACR2D,OAAOe,cAAc,GAAGC,IAAI,CAAC;YAC3B,MAAMpE,YAAYd;YAClB,cAAc;YACd,IAAIR,kBAAkBsB,YAAY;gBAChC,MAAMsE,yBAAyBvE,sBAAsBC;gBACrDwD,sBAAsBzD,sBAAsBC;gBAC5C0D,iBACEjD,4BAA4BT,cACzBsE,CAAAA,uBAAuBnE,OAAO,GAAG,KAAKmE,uBAAuBhE,IAAI,GAAG,CAAA;YAE3E;YACA,eAAe;YACfsD,kBAAkBhC;QACpB;IACF,GAAG;QAACwB;KAAO;IAEX3D,UAAU;QACR,MAAM8E,oBAAoBxB,WAAWyB,OAAO;QAC5C,MAAMC,kBAAkBpB,YAAYmB,OAAO;QAC3C,MAAME,cAActB,OAAOuB,cAAc;QAEzC,IAAIJ,qBAAqB,QAAQE,mBAAmB,QAAQC,eAAe,MAAM;YAC/E,MAAME,cAAcF,YAAYG,qBAAqB;YACrD,MAAMC,iBAAiBP,kBAAkBM,qBAAqB;YAC9DJ,gBAAgBM,KAAK,CAACC,OAAO,GAAG;YAChC,MAAMC,sBAAsBR,gBAAgBI,qBAAqB;YACjE,MAAMK,SAAS;YACf,IAAIC,eAAeL,eAAeM,KAAK,GAAGF;YAC1C,IACEC,eAAeF,oBAAoBI,KAAK,GAAGC,OAAOC,UAAU,IAC5DJ,eAAeF,oBAAoBI,KAAK,GAAGT,YAAYQ,KAAK,EAC5D;gBACA,MAAMI,WAAWV,eAAeW,IAAI,GAAGR,oBAAoBI,KAAK,GAAGH;gBACnEC,eAAe,AAACK,CAAAA,WAAW,IAAIN,SAASM,QAAO,IAAKF,OAAOI,WAAW;YACxE;YACAjB,gBAAgBM,KAAK,CAACU,IAAI,GAAG,CAAC,EAAEN,eAAeG,OAAOI,WAAW,CAAC,EAAE,CAAC;YAErE,IAAIC,cAAcb,eAAec,GAAG;YACpC,IAAID,cAAcV,oBAAoBY,MAAM,GAAGP,OAAOQ,WAAW,EAAE;gBACjE,MAAMN,WAAWV,eAAeiB,MAAM,GAAGd,oBAAoBY,MAAM;gBACnEF,cAAc,AAACH,CAAAA,WAAW,IAAIN,SAASM,QAAO,IAAKF,OAAOU,WAAW;YACvE;YACAvB,gBAAgBM,KAAK,CAACa,GAAG,GAAG,CAAC,EAAED,YAAY,EAAE,CAAC;QAChD;IACF,GAAG;QAAC5C;QAAYM;QAAaD;QAAQS;KAAE;IAEvCpE,UAAU;QACR,SAASwG,mBAAmBC,KAAiB;YAC3C,IACE7C,YAAYmB,OAAO,IAAI,QACvBzB,WAAWyB,OAAO,IAAI,QACtB,CAACnB,YAAYmB,OAAO,CAAC2B,QAAQ,CAACD,MAAME,MAAM,KAC1C,CAACrD,WAAWyB,OAAO,CAAC2B,QAAQ,CAACD,MAAME,MAAM,GACzC;gBACAnD,cAAc;YAChB;QACF;QAEAqC,OAAOe,gBAAgB,CAAC,SAASJ;QAEjC,OAAO,IAAMX,OAAOgB,mBAAmB,CAAC,SAASL;IACnD,GAAG;QAAChD;QAAeF;KAAW;IAE9B,MAAMwD,sBAAsB/G,YAAY;QACtC4D,OAAOoD,MAAM,CAAC;YACZ,IAAItD,cAAcuD,UAAU,IAAI;gBAC9B,MAAMC,YAAYtI,oCAAoC8E;gBACtD,MAAMyD,eAAevD,OAAOwD,eAAe,CACzCF,UAAUxC,MAAM;gBAGlB,IAAI,CAACyC,cAAc;oBACjB,MAAM,IAAIE,MAAM;gBAClB;gBAEA,MAAMC,iBAAiBhI,iCAAiC6H;gBACxD,IAAIG,mBAAmB,MAAM;oBAC3BA,eAAeC,cAAc;gBAC/B;gBAEAL,UAAUM,SAAS;gBACnB1D,oBAAoBJ,cAAcmB,SAAS;YAC7C;YAEA,MAAM4C,WAAWhI;YACjBgI,SAASC,WAAW;QACtB;IACF,GAAG;QAAC9D;QAAQF;KAAc;IAE1B,MAAMiE,6BAA6B;QACjC/D,OAAOoD,MAAM,CAAC;YACZ,MAAMxG,YAAYd;YAClB,IAAIR,kBAAkBsB,YAAY;gBAChC,MAAM,EAAEG,OAAO,EAAEG,IAAI,EAAE,GAAGP,sBAAsBC;gBAChD,MAAMU,QAAQV,UAAUW,QAAQ;gBAChC,IAAIyG,YAAkC;gBACtC,IAAK,IAAIpG,IAAI,GAAGA,IAAIN,MAAMO,MAAM,EAAED,IAAK;oBACrC,MAAME,OAAOR,KAAK,CAACM,EAAE;oBACrB,IAAIxC,iBAAiB0C,OAAO;wBAC1B,IAAIkG,cAAc,MAAM;4BACtBlG,KAAKmG,UAAU,CAAClH,SAASmH,UAAU,CAAChH;4BACpC8G,YAAYlG;4BACZ,MAAMoB,UAAUJ,4BAA4BhB;4BAC5C,IAAIkB;4BACJ,IAAIE,WAAWlD,iBAAkBgD,aAAalB,KAAKqG,aAAa,KAAM;gCACpEnF,WAAWoF,MAAM;4BACnB;wBACF,OAAO,IAAIhJ,iBAAiB4I,YAAY;4BACtC,MAAM9E,UAAUJ,4BAA4BhB;4BAC5C,IAAI,CAACoB,SAAS;gCACZ8E,UAAUK,MAAM,IAAIvG,KAAKwG,WAAW;4BACtC;4BACAxG,KAAKsG,MAAM;wBACb;oBACF;gBACF;gBACA,IAAIJ,cAAc,MAAM;oBACtB,IAAIA,UAAUjF,eAAe,OAAO,GAAG;wBACrCiF,UAAUK,MAAM,CAACzI;oBACnB;oBACAuD,sBAAsB6E;gBACxB;gBACApE;YACF;QACF;IACF;IAEA,MAAM2E,+BAA+B;QACnCvE,OAAOoD,MAAM,CAAC;YACZ7H;QACF;IACF;IAEA,MAAMiJ,4BAA4BpI,YAChC,CAACqI;QACCzE,OAAOoD,MAAM,CAAC;YACZjI,8BAA8BsJ;YAC9B7E;QACF;IACF,GACA;QAACI;QAAQJ;KAAQ;IAGnB,MAAM8E,+BAA+BtI,YACnC,CAACqI;QACCzE,OAAOoD,MAAM,CAAC;YACZ,IAAK,IAAIxF,IAAI,GAAGA,IAAIuC,gBAAgBpD,OAAO,EAAEa,IAAK;gBAChD1C,iCAAiCuJ;YACnC;YACA7E;QACF;IACF,GACA;QAACI;QAAQJ;QAASO,gBAAgBpD,OAAO;KAAC;IAG5C,MAAM4H,4BAA4BvI,YAAY;QAC5C4D,OAAOoD,MAAM,CAAC;YACZxI;YACAgF;QACF;IACF,GAAG;QAACI;QAAQJ;KAAQ;IAEpB,MAAMgF,yBAAyBxI,YAAY;QACzC4D,OAAOoD,MAAM,CAAC;YACZ,MAAME,YAAYtI,oCAAoC8E;YACtDwD,UAAUc,MAAM;YAEhBjB;YACAvD;QACF;IACF,GAAG;QAACI;QAAQF;QAAeqD;QAAqBvD;KAAQ;IAExD,MAAMiF,+BAA+BzI,YAAY;QAC/C4D,OAAOoD,MAAM,CAAC;YACZzI;YACAiF;QACF;IACF,GAAG;QAACI;QAAQJ;KAAQ;IAEpB,MAAMkF,yBAAyB1I,YAAY;QACzC4D,OAAOoD,MAAM,CAAC;YACZ,MAAME,YAAYtI,oCAAoC8E;YAEtD,MAAMiF,gBAAgB9J,mCAAmC6E;YAEzD,MAAMkF,YAAY1B,UAAUgB,WAAW;YAEvC,IAAIS,iBAAiBC,UAAUnH,MAAM,IAAIkH,gBAAgB,GAAG;gBAC1D,MAAM,IAAItB,MAAM;YAClB;YAEA,MAAMwB,WAAWD,SAAS,CAACD,cAAc;YAEzC,IAAI,CAAC1J,gBAAgB4J,WAAW;gBAC9B,MAAM,IAAIxB,MAAM;YAClB;YAEAwB,SAASX,WAAW,GAAGY,OAAO,CAAC,CAACC;gBAC9B,IAAI,CAAC/J,iBAAiB+J,YAAY;oBAChC,MAAM,IAAI1B,MAAM;gBAClB;gBAEA0B,UAAUC,iBAAiB,CAAC5J,sBAAsB6J,GAAG;YACvD;YAEAlC;YACAvD;QACF;IACF,GAAG;QAACI;QAAQF;QAAeqD;QAAqBvD;KAAQ;IAExD,MAAM0F,4BAA4BlJ,YAAY;QAC5C4D,OAAOoD,MAAM,CAAC;YACZ,MAAME,YAAYtI,oCAAoC8E;YAEtD,MAAMyF,mBAAmBxK,sCAAsC+E;YAE/D,MAAMkF,YAAY1B,UAAUgB,WAAW;YACvC,MAAMkB,gBAAgBC,KAAKC,GAAG,IAAIV,UAAUW,GAAG,CAAC,CAAC5H,MAAQA,IAAIuG,WAAW,GAAGzG,MAAM;YAEjF,IAAI0H,oBAAoBC,iBAAiBD,mBAAmB,GAAG;gBAC7D,MAAM,IAAI9B,MAAM;YAClB;YAEA,IAAK,IAAImC,IAAI,GAAGA,IAAIZ,UAAUnH,MAAM,EAAE+H,IAAK;gBACzC,MAAMX,WAAWD,SAAS,CAACY,EAAE;gBAE7B,IAAI,CAACvK,gBAAgB4J,WAAW;oBAC9B,MAAM,IAAIxB,MAAM;gBAClB;gBAEA,MAAMoC,aAAaZ,SAASX,WAAW;gBACvC,IAAIiB,oBAAoBM,WAAWhI,MAAM,EAAE;oBAEzC;gBACF;gBAEA,MAAMsH,YAAYU,UAAU,CAACN,iBAAiB;gBAE9C,IAAI,CAACnK,iBAAiB+J,YAAY;oBAChC,MAAM,IAAI1B,MAAM;gBAClB;gBAEA0B,UAAUC,iBAAiB,CAAC5J,sBAAsBsK,MAAM;YAC1D;YAEA3C;YACAvD;QACF;IACF,GAAG;QAACI;QAAQF;QAAeqD;QAAqBvD;KAAQ;IAExD,IAAImG,kBAAsC;IAC1C,IAAIrG,WAAW;QACb,IAAIW,eAAe;YACjB0F,gCACE,KAACC;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMpC;gBACfqC,MAAK;0BACN;;QAIL,OAAO,IAAI7F,gBAAgB;YACzBwF,gCACE,KAACC;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAM5B;gBACf6B,MAAK;0BACN;;QAIL;IACF;IAEA,qBAAO5J,aACL,yGAAyG;kBACzG,MAAC6J;QACCJ,WAAU;QACVE,SAAS,CAACG;YACRA,EAAEC,eAAe;QACnB;QACAC,KAAKvG;;YAEJ8F,gCACC,MAAC5J,MAAMsK,QAAQ;;oBACZV;kCACD,KAACW;;iBAED;0BAEJ,KAACV;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAM3B,0BAA0B;gBACzC4B,MAAK;0BAEL,cAAA,MAACO;oBAAKV,WAAU;;wBAAO;wBACb9F,gBAAgBjD,IAAI,KAAK,IAAI,QAAQ,CAAC,EAAEiD,gBAAgBjD,IAAI,CAAC,KAAK,CAAC;wBAAC;;;;0BAGhF,KAAC8I;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAM3B,0BAA0B;gBACzC4B,MAAK;0BAEL,cAAA,MAACO;oBAAKV,WAAU;;wBAAO;wBACb9F,gBAAgBjD,IAAI,KAAK,IAAI,QAAQ,CAAC,EAAEiD,gBAAgBjD,IAAI,CAAC,KAAK,CAAC;wBAAC;;;;0BAGhF,KAACwJ;0BACD,KAACV;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMzB,6BAA6B;gBAC5C0B,MAAK;0BAEL,cAAA,MAACO;oBAAKV,WAAU;;wBAAO;wBACb9F,gBAAgBpD,OAAO,KAAK,IAAI,WAAW,CAAC,EAAEoD,gBAAgBpD,OAAO,CAAC,QAAQ,CAAC;wBAAE;wBAAI;;;;0BAIjG,KAACiJ;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMzB,6BAA6B;gBAC5C0B,MAAK;0BAEL,cAAA,MAACO;oBAAKV,WAAU;;wBAAO;wBACb9F,gBAAgBpD,OAAO,KAAK,IAAI,WAAW,CAAC,EAAEoD,gBAAgBpD,OAAO,CAAC,QAAQ,CAAC;wBAAE;wBAAI;;;;0BAIjG,KAAC2J;0BACD,KAACV;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMtB;gBACfuB,MAAK;0BAEL,cAAA,KAACO;oBAAKV,WAAU;8BAAO;;;0BAEzB,KAACD;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMxB;gBACfyB,MAAK;0BAEL,cAAA,KAACO;oBAAKV,WAAU;8BAAO;;;0BAEzB,KAACD;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMvB;gBACfwB,MAAK;0BAEL,cAAA,KAACO;oBAAKV,WAAU;8BAAO;;;0BAEzB,KAACS;0BACD,KAACV;gBAAOC,WAAU;gBAAOE,SAAS,IAAMrB;gBAA0BsB,MAAK;0BACrE,cAAA,MAACO;oBAAKV,WAAU;;wBACZnG,CAAAA,cAAc8G,aAAa,GAAGpL,sBAAsB6J,GAAG,AAAD,MAAO7J,sBAAsB6J,GAAG,GACpF,WACA;wBAAO;wBAAI;;;;0BAInB,KAACW;gBACCC,WAAU;gBACVC,gBAAa;gBACbC,SAAS,IAAMb;gBACfc,MAAK;0BAEL,cAAA,MAACO;oBAAKV,WAAU;;wBACZnG,CAAAA,cAAc8G,aAAa,GAAGpL,sBAAsBsK,MAAM,AAAD,MAC3DtK,sBAAsBsK,MAAM,GACxB,WACA;wBAAO;wBAAI;;;;;QAKrBe,SAASC,IAAI;AAEjB;AAEA,SAASC,6BAA6B,EACpCC,UAAU,EACVtH,SAAS,EAIV;IACC,MAAM,CAACM,OAAO,GAAGvF;IAEjB,MAAMwM,gBAAgB3K,OAAO;IAC7B,MAAM4K,cAAc5K,OAAO;IAC3B,MAAM,CAAC6K,YAAYtH,cAAc,GAAGtD,SAAS;IAE7C,MAAM,CAACuD,eAAesH,qBAAqB,GAAG7K,SAA+B;IAE7E,MAAM8K,YAAYjL,YAAY;QAC5B,MAAMkL,OAAOL,cAAc7F,OAAO;QAClC,MAAMxE,YAAYd;QAClB,MAAMyL,kBAAkBrF,OAAOsF,YAAY;QAC3C,MAAMC,gBAAgBZ,SAASY,aAAa;QAE5C,IAAI7K,aAAa,QAAQ0K,QAAQ,MAAM;YACrCF,qBAAqB;YACrB;QACF;QAEA,MAAM9F,cAActB,OAAOuB,cAAc;QAEzC,IACEtF,kBAAkBW,cAClB0E,gBAAgB,QAChBiG,oBAAoB,QACpBjG,YAAYyB,QAAQ,CAACwE,gBAAgBG,UAAU,GAC/C;YACA,MAAMC,6BAA6B7M,iCACjC8B,UAAU8B,MAAM,CAACkJ,OAAO;YAG1B,IAAID,8BAA8B,MAAM;gBACtCP,qBAAqB;gBACrB;YACF;YAEA,MAAMS,yBAAyB7H,OAAOwD,eAAe,CAACmE,2BAA2B7G,MAAM;YAEvF,IAAI+G,0BAA0B,MAAM;gBAClCT,qBAAqB;gBACrB;YACF;YAEAA,qBAAqBO;QACvB,OAAO,IAAI,CAACF,eAAe;YACzBL,qBAAqB;QACvB;IACF,GAAG;QAACpH;KAAO;IAEX3D,UAAU;QACR,OAAO2D,OAAO8H,sBAAsB,CAAC;YACnC9H,OAAOe,cAAc,GAAGC,IAAI,CAAC;gBAC3BqG;YACF;QACF;IACF;IAEAhL,UAAU;QACR,MAAM0L,gBAAgBd,cAAc7F,OAAO;QAE3C,IAAI2G,iBAAiB,QAAQjI,iBAAiB,MAAM;YAClD,MAAMkI,mBAAmBhI,OAAOwD,eAAe,CAAC1D,cAAcgB,MAAM;YAEpE,IAAIkH,oBAAoB,MAAM;gBAC5B,MAAMC,gBAAgBD,iBAAiBvG,qBAAqB;gBAC5D,MAAMyG,WAAWH,cAActG,qBAAqB;gBACpD,MAAM0G,aAAanB,WAAWvF,qBAAqB;gBAEnD,MAAMe,MAAMyF,cAAczF,GAAG,GAAG2F,WAAW3F,GAAG,GAAG;gBACjD,MAAMH,OAAO4F,cAAcjG,KAAK,GAAGkG,SAASjG,KAAK,GAAG,KAAKkG,WAAW9F,IAAI;gBAExE0F,cAAcpG,KAAK,CAACC,OAAO,GAAG;gBAC9BmG,cAAcpG,KAAK,CAACyG,SAAS,GAAG,CAAC,UAAU,EAAE/F,KAAK,IAAI,EAAEG,IAAI,GAAG,CAAC;YAClE,OAAO;gBACLuF,cAAcpG,KAAK,CAACC,OAAO,GAAG;gBAC9BmG,cAAcpG,KAAK,CAACyG,SAAS,GAAG;YAClC;QACF;IACF,GAAG;QAACnB;QAAenH;QAAeE;QAAQgH;KAAW;IAErD,MAAMqB,mBAAmB/L,OAAOwD;IAEhCzD,UAAU;QACR,IAAIgM,iBAAiBjH,OAAO,KAAKtB,eAAe;YAC9CD,cAAc;QAChB;QAEAwI,iBAAiBjH,OAAO,GAAGtB;IAC7B,GAAG;QAACuI;QAAkBvI;KAAc;IAEpC,qBACE,KAACuG;QAAIJ,WAAU;QAAqCO,KAAKS;kBACtDnH,iBAAiB,sBAChB,MAAC3D,MAAMsK,QAAQ;;8BACb,KAACT;oBACCC,WAAU;oBACVE,SAAS,CAACG;wBACRA,EAAEC,eAAe;wBACjB1G,cAAc,CAACsH;oBACjB;oBACAX,KAAKU;oBACLd,MAAK;8BAEL,cAAA,KAAC3J;;gBAEF0K,4BACC,KAAC1H;oBACCC,WAAWA;oBACXC,YAAYuH;oBACZtH,SAAS,IAAMC,cAAc;oBAC7BA,eAAeA;oBACfC,eAAeA;;;;;AAO7B;AAEA,OAAO,MAAMwI,wBAAmD,CAAC,EAAEtB,UAAU,EAAE;IAC7E,MAAMuB,aAAa7N;IACnB,qBAAO8B,aACL+L,2BACE,KAACxB;QAA6BC,YAAYA,cAAcH,SAASC,IAAI;QAAEpH,SAAS;SAC9E,MACJsH,cAAcH,SAASC,IAAI;AAE/B,EAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PluginComponent } from '../../../typesClient.js';
2
+ import './index.scss';
3
+ export declare const TableCellResizerPlugin: PluginComponent;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAA6B,MAAM,yBAAyB,CAAA;AAEzF,OAAO,cAAc,CAAA;AAmXrB,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAA"}
@@ -0,0 +1,322 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
+ import { useLexicalEditable } from '@lexical/react/useLexicalEditable';
5
+ import { $computeTableMapSkipCellCheck, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $isTableCellNode, $isTableRowNode, getDOMCellFromTarget } from '@lexical/table';
6
+ import { calculateZoomLevel } from '@lexical/utils';
7
+ import { $getNearestNodeFromDOMNode } from 'lexical';
8
+ import * as React from 'react';
9
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
10
+ import { createPortal } from 'react-dom';
11
+ const MIN_ROW_HEIGHT = 33;
12
+ const MIN_COLUMN_WIDTH = 50;
13
+ function TableCellResizer({ editor }) {
14
+ const targetRef = useRef(null);
15
+ const resizerRef = useRef(null);
16
+ const tableRectRef = useRef(null);
17
+ const mouseStartPosRef = useRef(null);
18
+ const [mouseCurrentPos, updateMouseCurrentPos] = useState(null);
19
+ const [activeCell, updateActiveCell] = useState(null);
20
+ const [isMouseDown, updateIsMouseDown] = useState(false);
21
+ const [draggingDirection, updateDraggingDirection] = useState(null);
22
+ const resetState = useCallback(()=>{
23
+ updateActiveCell(null);
24
+ targetRef.current = null;
25
+ updateDraggingDirection(null);
26
+ mouseStartPosRef.current = null;
27
+ tableRectRef.current = null;
28
+ }, []);
29
+ const isMouseDownOnEvent = (event)=>{
30
+ return (event.buttons & 1) === 1;
31
+ };
32
+ useEffect(()=>{
33
+ const onMouseMove = (event)=>{
34
+ setTimeout(()=>{
35
+ const target = event.target;
36
+ if (draggingDirection) {
37
+ updateMouseCurrentPos({
38
+ x: event.clientX,
39
+ y: event.clientY
40
+ });
41
+ return;
42
+ }
43
+ updateIsMouseDown(isMouseDownOnEvent(event));
44
+ if (resizerRef.current && resizerRef.current.contains(target)) {
45
+ return;
46
+ }
47
+ if (targetRef.current !== target) {
48
+ targetRef.current = target;
49
+ const cell = getDOMCellFromTarget(target);
50
+ if (cell && activeCell !== cell) {
51
+ editor.update(()=>{
52
+ const tableCellNode = $getNearestNodeFromDOMNode(cell.elem);
53
+ if (!tableCellNode) {
54
+ throw new Error('TableCellResizer: Table cell node not found.');
55
+ }
56
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
57
+ const tableElement = editor.getElementByKey(tableNode.getKey());
58
+ if (!tableElement) {
59
+ throw new Error('TableCellResizer: Table element not found.');
60
+ }
61
+ targetRef.current = target;
62
+ tableRectRef.current = tableElement.getBoundingClientRect();
63
+ updateActiveCell(cell);
64
+ });
65
+ } else if (cell == null) {
66
+ resetState();
67
+ }
68
+ }
69
+ }, 0);
70
+ };
71
+ const onMouseDown = (event)=>{
72
+ setTimeout(()=>{
73
+ updateIsMouseDown(true);
74
+ }, 0);
75
+ };
76
+ const onMouseUp = (event)=>{
77
+ setTimeout(()=>{
78
+ updateIsMouseDown(false);
79
+ }, 0);
80
+ };
81
+ document.addEventListener('mousemove', onMouseMove);
82
+ document.addEventListener('mousedown', onMouseDown);
83
+ document.addEventListener('mouseup', onMouseUp);
84
+ return ()=>{
85
+ document.removeEventListener('mousemove', onMouseMove);
86
+ document.removeEventListener('mousedown', onMouseDown);
87
+ document.removeEventListener('mouseup', onMouseUp);
88
+ };
89
+ }, [
90
+ activeCell,
91
+ draggingDirection,
92
+ editor,
93
+ resetState
94
+ ]);
95
+ const isHeightChanging = (direction)=>{
96
+ if (direction === 'bottom') {
97
+ return true;
98
+ }
99
+ return false;
100
+ };
101
+ const updateRowHeight = useCallback((heightChange)=>{
102
+ if (!activeCell) {
103
+ throw new Error('TableCellResizer: Expected active cell.');
104
+ }
105
+ editor.update(()=>{
106
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
107
+ if (!$isTableCellNode(tableCellNode)) {
108
+ throw new Error('TableCellResizer: Table cell node not found.');
109
+ }
110
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
111
+ const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
112
+ const tableRows = tableNode.getChildren();
113
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
114
+ throw new Error('Expected table cell to be inside of table row.');
115
+ }
116
+ const tableRow = tableRows[tableRowIndex];
117
+ if (!$isTableRowNode(tableRow)) {
118
+ throw new Error('Expected table row');
119
+ }
120
+ let height = tableRow.getHeight();
121
+ if (height === undefined) {
122
+ const rowCells = tableRow.getChildren();
123
+ height = Math.min(...rowCells.map((cell)=>getCellNodeHeight(cell, editor) ?? Infinity));
124
+ }
125
+ const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
126
+ tableRow.setHeight(newHeight);
127
+ }, {
128
+ tag: 'skip-scroll-into-view'
129
+ });
130
+ }, [
131
+ activeCell,
132
+ editor
133
+ ]);
134
+ const getCellNodeWidth = (cell, activeEditor)=>{
135
+ const width = cell.getWidth();
136
+ if (width !== undefined) {
137
+ return width;
138
+ }
139
+ const domCellNode = activeEditor.getElementByKey(cell.getKey());
140
+ if (domCellNode == null) {
141
+ return undefined;
142
+ }
143
+ const computedStyle = getComputedStyle(domCellNode);
144
+ return domCellNode.clientWidth - parseFloat(computedStyle.paddingLeft) - parseFloat(computedStyle.paddingRight);
145
+ };
146
+ const getCellNodeHeight = (cell, activeEditor)=>{
147
+ const domCellNode = activeEditor.getElementByKey(cell.getKey());
148
+ return domCellNode?.clientHeight;
149
+ };
150
+ const getCellColumnIndex = (tableCellNode, tableMap)=>{
151
+ for(let row = 0; row < tableMap.length; row++){
152
+ for(let column = 0; column < tableMap[row].length; column++){
153
+ if (tableMap[row][column].cell === tableCellNode) {
154
+ return column;
155
+ }
156
+ }
157
+ }
158
+ };
159
+ const updateColumnWidth = useCallback((widthChange)=>{
160
+ if (!activeCell) {
161
+ throw new Error('TableCellResizer: Expected active cell.');
162
+ }
163
+ editor.update(()=>{
164
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
165
+ if (!$isTableCellNode(tableCellNode)) {
166
+ throw new Error('TableCellResizer: Table cell node not found.');
167
+ }
168
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
169
+ const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null);
170
+ const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
171
+ if (columnIndex === undefined) {
172
+ throw new Error('TableCellResizer: Table column not found.');
173
+ }
174
+ for(let row = 0; row < tableMap.length; row++){
175
+ const cell = tableMap[row][columnIndex];
176
+ if (cell.startRow === row && (columnIndex === tableMap[row].length - 1 || tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)) {
177
+ const width = getCellNodeWidth(cell.cell, editor);
178
+ if (width === undefined) {
179
+ continue;
180
+ }
181
+ const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
182
+ cell.cell.setWidth(newWidth);
183
+ }
184
+ }
185
+ }, {
186
+ tag: 'skip-scroll-into-view'
187
+ });
188
+ }, [
189
+ activeCell,
190
+ editor
191
+ ]);
192
+ const mouseUpHandler = useCallback((direction)=>{
193
+ const handler = (event)=>{
194
+ event.preventDefault();
195
+ event.stopPropagation();
196
+ if (!activeCell) {
197
+ throw new Error('TableCellResizer: Expected active cell.');
198
+ }
199
+ if (mouseStartPosRef.current) {
200
+ const { x, y } = mouseStartPosRef.current;
201
+ if (activeCell === null) {
202
+ return;
203
+ }
204
+ const zoom = calculateZoomLevel(event.target);
205
+ if (isHeightChanging(direction)) {
206
+ const heightChange = (event.clientY - y) / zoom;
207
+ updateRowHeight(heightChange);
208
+ } else {
209
+ const widthChange = (event.clientX - x) / zoom;
210
+ updateColumnWidth(widthChange);
211
+ }
212
+ resetState();
213
+ document.removeEventListener('mouseup', handler);
214
+ }
215
+ };
216
+ return handler;
217
+ }, [
218
+ activeCell,
219
+ resetState,
220
+ updateColumnWidth,
221
+ updateRowHeight
222
+ ]);
223
+ const toggleResize = useCallback((direction)=>(event)=>{
224
+ event.preventDefault();
225
+ event.stopPropagation();
226
+ if (!activeCell) {
227
+ throw new Error('TableCellResizer: Expected active cell.');
228
+ }
229
+ mouseStartPosRef.current = {
230
+ x: event.clientX,
231
+ y: event.clientY
232
+ };
233
+ updateMouseCurrentPos(mouseStartPosRef.current);
234
+ updateDraggingDirection(direction);
235
+ document.addEventListener('mouseup', mouseUpHandler(direction));
236
+ }, [
237
+ activeCell,
238
+ mouseUpHandler
239
+ ]);
240
+ const getResizers = useCallback(()=>{
241
+ if (activeCell) {
242
+ const { height, left, top, width } = activeCell.elem.getBoundingClientRect();
243
+ const zoom = calculateZoomLevel(activeCell.elem);
244
+ const zoneWidth = 10 // Pixel width of the zone where you can drag the edge
245
+ ;
246
+ const styles = {
247
+ bottom: {
248
+ backgroundColor: 'none',
249
+ cursor: 'row-resize',
250
+ height: `${zoneWidth}px`,
251
+ left: `${window.pageXOffset + left}px`,
252
+ top: `${window.pageYOffset + top + height - zoneWidth / 2}px`,
253
+ width: `${width}px`
254
+ },
255
+ right: {
256
+ backgroundColor: 'none',
257
+ cursor: 'col-resize',
258
+ height: `${height}px`,
259
+ left: `${window.pageXOffset + left + width - zoneWidth / 2}px`,
260
+ top: `${window.pageYOffset + top}px`,
261
+ width: `${zoneWidth}px`
262
+ }
263
+ };
264
+ const tableRect = tableRectRef.current;
265
+ if (draggingDirection && mouseCurrentPos && tableRect) {
266
+ if (isHeightChanging(draggingDirection)) {
267
+ styles[draggingDirection].left = `${window.pageXOffset + tableRect.left}px`;
268
+ styles[draggingDirection].top = `${window.pageYOffset + mouseCurrentPos.y / zoom}px`;
269
+ styles[draggingDirection].height = '3px';
270
+ styles[draggingDirection].width = `${tableRect.width}px`;
271
+ } else {
272
+ styles[draggingDirection].top = `${window.pageYOffset + tableRect.top}px`;
273
+ styles[draggingDirection].left = `${window.pageXOffset + mouseCurrentPos.x / zoom}px`;
274
+ styles[draggingDirection].width = '3px';
275
+ styles[draggingDirection].height = `${tableRect.height}px`;
276
+ }
277
+ styles[draggingDirection].backgroundColor = '#adf';
278
+ }
279
+ return styles;
280
+ }
281
+ return {
282
+ bottom: null,
283
+ left: null,
284
+ right: null,
285
+ top: null
286
+ };
287
+ }, [
288
+ activeCell,
289
+ draggingDirection,
290
+ mouseCurrentPos
291
+ ]);
292
+ const resizerStyles = getResizers();
293
+ return /*#__PURE__*/ _jsx("div", {
294
+ ref: resizerRef,
295
+ children: activeCell != null && !isMouseDown && /*#__PURE__*/ _jsxs(React.Fragment, {
296
+ children: [
297
+ /*#__PURE__*/ _jsx("div", {
298
+ className: "TableCellResizer__resizer TableCellResizer__ui",
299
+ onMouseDown: toggleResize('right'),
300
+ style: resizerStyles.right || undefined
301
+ }),
302
+ /*#__PURE__*/ _jsx("div", {
303
+ className: "TableCellResizer__resizer TableCellResizer__ui",
304
+ onMouseDown: toggleResize('bottom'),
305
+ style: resizerStyles.bottom || undefined
306
+ })
307
+ ]
308
+ })
309
+ });
310
+ }
311
+ export const TableCellResizerPlugin = ()=>{
312
+ const [editor] = useLexicalComposerContext();
313
+ const isEditable = useLexicalEditable();
314
+ return useMemo(()=>isEditable ? /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsx(TableCellResizer, {
315
+ editor: editor
316
+ }), document.body) : null, [
317
+ editor,
318
+ isEditable
319
+ ]);
320
+ };
321
+
322
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx"],"sourcesContent":["'use client'\n\nimport type { TableCellNode, TableDOMCell, TableMapType, TableMapValueType } from '@lexical/table'\nimport type { LexicalEditor } from 'lexical'\nimport type { JSX, MouseEventHandler } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'\nimport { useLexicalEditable } from '@lexical/react/useLexicalEditable'\nimport {\n $computeTableMapSkipCellCheck,\n $getTableNodeFromLexicalNodeOrThrow,\n $getTableRowIndexFromTableCellNode,\n $isTableCellNode,\n $isTableRowNode,\n getDOMCellFromTarget,\n} from '@lexical/table'\nimport { calculateZoomLevel } from '@lexical/utils'\nimport { $getNearestNodeFromDOMNode } from 'lexical'\nimport * as React from 'react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\nimport type { PluginComponent, PluginComponentWithAnchor } from '../../../typesClient.js'\n\nimport './index.scss'\n\ntype MousePosition = {\n x: number\n y: number\n}\n\ntype MouseDraggingDirection = 'bottom' | 'right'\n\nconst MIN_ROW_HEIGHT = 33\nconst MIN_COLUMN_WIDTH = 50\n\nfunction TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {\n const targetRef = useRef<HTMLElement | null>(null)\n const resizerRef = useRef<HTMLDivElement | null>(null)\n const tableRectRef = useRef<ClientRect | null>(null)\n\n const mouseStartPosRef = useRef<MousePosition | null>(null)\n const [mouseCurrentPos, updateMouseCurrentPos] = useState<MousePosition | null>(null)\n\n const [activeCell, updateActiveCell] = useState<TableDOMCell | null>(null)\n const [isMouseDown, updateIsMouseDown] = useState<boolean>(false)\n const [draggingDirection, updateDraggingDirection] = useState<MouseDraggingDirection | null>(null)\n\n const resetState = useCallback(() => {\n updateActiveCell(null)\n targetRef.current = null\n updateDraggingDirection(null)\n mouseStartPosRef.current = null\n tableRectRef.current = null\n }, [])\n\n const isMouseDownOnEvent = (event: MouseEvent) => {\n return (event.buttons & 1) === 1\n }\n\n useEffect(() => {\n const onMouseMove = (event: MouseEvent) => {\n setTimeout(() => {\n const target = event.target\n\n if (draggingDirection) {\n updateMouseCurrentPos({\n x: event.clientX,\n y: event.clientY,\n })\n return\n }\n updateIsMouseDown(isMouseDownOnEvent(event))\n if (resizerRef.current && resizerRef.current.contains(target as Node)) {\n return\n }\n\n if (targetRef.current !== target) {\n targetRef.current = target as HTMLElement\n const cell = getDOMCellFromTarget(target as HTMLElement)\n\n if (cell && activeCell !== cell) {\n editor.update(() => {\n const tableCellNode = $getNearestNodeFromDOMNode(cell.elem)\n\n if (!tableCellNode) {\n throw new Error('TableCellResizer: Table cell node not found.')\n }\n\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n const tableElement = editor.getElementByKey(tableNode.getKey())\n\n if (!tableElement) {\n throw new Error('TableCellResizer: Table element not found.')\n }\n\n targetRef.current = target as HTMLElement\n tableRectRef.current = tableElement.getBoundingClientRect()\n updateActiveCell(cell)\n })\n } else if (cell == null) {\n resetState()\n }\n }\n }, 0)\n }\n\n const onMouseDown = (event: MouseEvent) => {\n setTimeout(() => {\n updateIsMouseDown(true)\n }, 0)\n }\n\n const onMouseUp = (event: MouseEvent) => {\n setTimeout(() => {\n updateIsMouseDown(false)\n }, 0)\n }\n\n document.addEventListener('mousemove', onMouseMove)\n document.addEventListener('mousedown', onMouseDown)\n document.addEventListener('mouseup', onMouseUp)\n\n return () => {\n document.removeEventListener('mousemove', onMouseMove)\n document.removeEventListener('mousedown', onMouseDown)\n document.removeEventListener('mouseup', onMouseUp)\n }\n }, [activeCell, draggingDirection, editor, resetState])\n\n const isHeightChanging = (direction: MouseDraggingDirection) => {\n if (direction === 'bottom') {\n return true\n }\n return false\n }\n\n const updateRowHeight = useCallback(\n (heightChange: number) => {\n if (!activeCell) {\n throw new Error('TableCellResizer: Expected active cell.')\n }\n\n editor.update(\n () => {\n const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem)\n if (!$isTableCellNode(tableCellNode)) {\n throw new Error('TableCellResizer: Table cell node not found.')\n }\n\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n\n const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode)\n\n const tableRows = tableNode.getChildren()\n\n if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {\n throw new Error('Expected table cell to be inside of table row.')\n }\n\n const tableRow = tableRows[tableRowIndex]\n\n if (!$isTableRowNode(tableRow)) {\n throw new Error('Expected table row')\n }\n\n let height = tableRow.getHeight()\n if (height === undefined) {\n const rowCells = tableRow.getChildren<TableCellNode>()\n height = Math.min(\n ...rowCells.map((cell) => getCellNodeHeight(cell, editor) ?? Infinity),\n )\n }\n\n const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT)\n tableRow.setHeight(newHeight)\n },\n { tag: 'skip-scroll-into-view' },\n )\n },\n [activeCell, editor],\n )\n\n const getCellNodeWidth = (\n cell: TableCellNode,\n activeEditor: LexicalEditor,\n ): number | undefined => {\n const width = cell.getWidth()\n if (width !== undefined) {\n return width\n }\n\n const domCellNode = activeEditor.getElementByKey(cell.getKey())\n if (domCellNode == null) {\n return undefined\n }\n const computedStyle = getComputedStyle(domCellNode)\n return (\n domCellNode.clientWidth -\n parseFloat(computedStyle.paddingLeft) -\n parseFloat(computedStyle.paddingRight)\n )\n }\n\n const getCellNodeHeight = (\n cell: TableCellNode,\n activeEditor: LexicalEditor,\n ): number | undefined => {\n const domCellNode = activeEditor.getElementByKey(cell.getKey())\n return domCellNode?.clientHeight\n }\n\n const getCellColumnIndex = (tableCellNode: TableCellNode, tableMap: TableMapType) => {\n for (let row = 0; row < tableMap.length; row++) {\n for (let column = 0; column < tableMap[row].length; column++) {\n if (tableMap[row][column].cell === tableCellNode) {\n return column\n }\n }\n }\n }\n\n const updateColumnWidth = useCallback(\n (widthChange: number) => {\n if (!activeCell) {\n throw new Error('TableCellResizer: Expected active cell.')\n }\n editor.update(\n () => {\n const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem)\n if (!$isTableCellNode(tableCellNode)) {\n throw new Error('TableCellResizer: Table cell node not found.')\n }\n\n const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)\n const [tableMap] = $computeTableMapSkipCellCheck(tableNode, null, null)\n const columnIndex = getCellColumnIndex(tableCellNode, tableMap)\n if (columnIndex === undefined) {\n throw new Error('TableCellResizer: Table column not found.')\n }\n\n for (let row = 0; row < tableMap.length; row++) {\n const cell: TableMapValueType = tableMap[row][columnIndex]\n if (\n cell.startRow === row &&\n (columnIndex === tableMap[row].length - 1 ||\n tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)\n ) {\n const width = getCellNodeWidth(cell.cell, editor)\n if (width === undefined) {\n continue\n }\n const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH)\n cell.cell.setWidth(newWidth)\n }\n }\n },\n { tag: 'skip-scroll-into-view' },\n )\n },\n [activeCell, editor],\n )\n\n const mouseUpHandler = useCallback(\n (direction: MouseDraggingDirection) => {\n const handler = (event: MouseEvent) => {\n event.preventDefault()\n event.stopPropagation()\n\n if (!activeCell) {\n throw new Error('TableCellResizer: Expected active cell.')\n }\n\n if (mouseStartPosRef.current) {\n const { x, y } = mouseStartPosRef.current\n\n if (activeCell === null) {\n return\n }\n const zoom = calculateZoomLevel(event.target as Element)\n\n if (isHeightChanging(direction)) {\n const heightChange = (event.clientY - y) / zoom\n updateRowHeight(heightChange)\n } else {\n const widthChange = (event.clientX - x) / zoom\n updateColumnWidth(widthChange)\n }\n\n resetState()\n document.removeEventListener('mouseup', handler)\n }\n }\n return handler\n },\n [activeCell, resetState, updateColumnWidth, updateRowHeight],\n )\n\n const toggleResize = useCallback(\n (direction: MouseDraggingDirection): MouseEventHandler<HTMLDivElement> =>\n (event) => {\n event.preventDefault()\n event.stopPropagation()\n\n if (!activeCell) {\n throw new Error('TableCellResizer: Expected active cell.')\n }\n\n mouseStartPosRef.current = {\n x: event.clientX,\n y: event.clientY,\n }\n updateMouseCurrentPos(mouseStartPosRef.current)\n updateDraggingDirection(direction)\n\n document.addEventListener('mouseup', mouseUpHandler(direction))\n },\n [activeCell, mouseUpHandler],\n )\n\n const getResizers = useCallback(() => {\n if (activeCell) {\n const { height, left, top, width } = activeCell.elem.getBoundingClientRect()\n const zoom = calculateZoomLevel(activeCell.elem)\n const zoneWidth = 10 // Pixel width of the zone where you can drag the edge\n const styles = {\n bottom: {\n backgroundColor: 'none',\n cursor: 'row-resize',\n height: `${zoneWidth}px`,\n left: `${window.pageXOffset + left}px`,\n top: `${window.pageYOffset + top + height - zoneWidth / 2}px`,\n width: `${width}px`,\n },\n right: {\n backgroundColor: 'none',\n cursor: 'col-resize',\n height: `${height}px`,\n left: `${window.pageXOffset + left + width - zoneWidth / 2}px`,\n top: `${window.pageYOffset + top}px`,\n width: `${zoneWidth}px`,\n },\n }\n\n const tableRect = tableRectRef.current\n\n if (draggingDirection && mouseCurrentPos && tableRect) {\n if (isHeightChanging(draggingDirection)) {\n styles[draggingDirection].left = `${window.pageXOffset + tableRect.left}px`\n styles[draggingDirection].top = `${window.pageYOffset + mouseCurrentPos.y / zoom}px`\n styles[draggingDirection].height = '3px'\n styles[draggingDirection].width = `${tableRect.width}px`\n } else {\n styles[draggingDirection].top = `${window.pageYOffset + tableRect.top}px`\n styles[draggingDirection].left = `${window.pageXOffset + mouseCurrentPos.x / zoom}px`\n styles[draggingDirection].width = '3px'\n styles[draggingDirection].height = `${tableRect.height}px`\n }\n\n styles[draggingDirection].backgroundColor = '#adf'\n }\n\n return styles\n }\n\n return {\n bottom: null,\n left: null,\n right: null,\n top: null,\n }\n }, [activeCell, draggingDirection, mouseCurrentPos])\n\n const resizerStyles = getResizers()\n\n return (\n <div ref={resizerRef}>\n {activeCell != null && !isMouseDown && (\n <React.Fragment>\n <div\n className=\"TableCellResizer__resizer TableCellResizer__ui\"\n onMouseDown={toggleResize('right')}\n style={resizerStyles.right || undefined}\n />\n <div\n className=\"TableCellResizer__resizer TableCellResizer__ui\"\n onMouseDown={toggleResize('bottom')}\n style={resizerStyles.bottom || undefined}\n />\n </React.Fragment>\n )}\n </div>\n )\n}\n\nexport const TableCellResizerPlugin: PluginComponent = () => {\n const [editor] = useLexicalComposerContext()\n const isEditable = useLexicalEditable()\n\n return useMemo(\n () => (isEditable ? createPortal(<TableCellResizer editor={editor} />, document.body) : null),\n [editor, isEditable],\n )\n}\n"],"names":["useLexicalComposerContext","useLexicalEditable","$computeTableMapSkipCellCheck","$getTableNodeFromLexicalNodeOrThrow","$getTableRowIndexFromTableCellNode","$isTableCellNode","$isTableRowNode","getDOMCellFromTarget","calculateZoomLevel","$getNearestNodeFromDOMNode","React","useCallback","useEffect","useMemo","useRef","useState","createPortal","MIN_ROW_HEIGHT","MIN_COLUMN_WIDTH","TableCellResizer","editor","targetRef","resizerRef","tableRectRef","mouseStartPosRef","mouseCurrentPos","updateMouseCurrentPos","activeCell","updateActiveCell","isMouseDown","updateIsMouseDown","draggingDirection","updateDraggingDirection","resetState","current","isMouseDownOnEvent","event","buttons","onMouseMove","setTimeout","target","x","clientX","y","clientY","contains","cell","update","tableCellNode","elem","Error","tableNode","tableElement","getElementByKey","getKey","getBoundingClientRect","onMouseDown","onMouseUp","document","addEventListener","removeEventListener","isHeightChanging","direction","updateRowHeight","heightChange","tableRowIndex","tableRows","getChildren","length","tableRow","height","getHeight","undefined","rowCells","Math","min","map","getCellNodeHeight","Infinity","newHeight","max","setHeight","tag","getCellNodeWidth","activeEditor","width","getWidth","domCellNode","computedStyle","getComputedStyle","clientWidth","parseFloat","paddingLeft","paddingRight","clientHeight","getCellColumnIndex","tableMap","row","column","updateColumnWidth","widthChange","columnIndex","startRow","newWidth","setWidth","mouseUpHandler","handler","preventDefault","stopPropagation","zoom","toggleResize","getResizers","left","top","zoneWidth","styles","bottom","backgroundColor","cursor","window","pageXOffset","pageYOffset","right","tableRect","resizerStyles","div","ref","Fragment","className","style","TableCellResizerPlugin","isEditable","body"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { EditorThemeClasses, Klass, LexicalCommand, LexicalEditor, LexicalNode } from 'lexical';
2
+ import type { JSX } from 'react';
3
+ import * as React from 'react';
4
+ import type { PluginComponent } from '../../../typesClient.js';
5
+ import './index.scss';
6
+ export type CellContextShape = {
7
+ cellEditorConfig: CellEditorConfig | null;
8
+ cellEditorPlugins: Array<JSX.Element> | JSX.Element | null;
9
+ set: (cellEditorConfig: CellEditorConfig | null, cellEditorPlugins: Array<JSX.Element> | JSX.Element | null) => void;
10
+ };
11
+ export type CellEditorConfig = Readonly<{
12
+ namespace: string;
13
+ nodes?: ReadonlyArray<Klass<LexicalNode>>;
14
+ onError: (error: Error, editor: LexicalEditor) => void;
15
+ readOnly?: boolean;
16
+ theme?: EditorThemeClasses;
17
+ }>;
18
+ export declare const OPEN_TABLE_DRAWER_COMMAND: LexicalCommand<{}>;
19
+ export declare const CellContext: React.Context<CellContextShape>;
20
+ export declare function TableContext({ children }: {
21
+ children: JSX.Element;
22
+ }): import("react/jsx-runtime").JSX.Element;
23
+ export declare const TablePlugin: PluginComponent;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/experimental_table/plugins/TablePlugin/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,KAAK,EACL,cAAc,EACd,aAAa,EACb,WAAW,EAEZ,MAAM,SAAS,CAAA;AAChB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAShC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAI9D,OAAO,cAAc,CAAA;AAErB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACzC,iBAAiB,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;IAC1D,GAAG,EAAE,CACH,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,EACzC,iBAAiB,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,KACvD,IAAI,CAAA;CACV,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAA;IACzC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAA;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,kBAAkB,CAAA;CAC3B,CAAC,CAAA;AAEF,eAAO,MAAM,yBAAyB,EAAE,cAAc,CAAC,EAAE,CAExD,CAAA;AAED,eAAO,MAAM,WAAW,iCAMtB,CAAA;AAGF,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,2CAwBnE;AAED,eAAO,MAAM,WAAW,EAAE,eAyDzB,CAAA"}
@@ -0,0 +1,99 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
4
+ import { TablePlugin as LexicalReactTablePlugin } from '@lexical/react/LexicalTablePlugin';
5
+ import { INSERT_TABLE_COMMAND, TableNode } from '@lexical/table';
6
+ import { mergeRegister } from '@lexical/utils';
7
+ import { useModal } from '@payloadcms/ui';
8
+ import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
9
+ import { createContext, useContext, useEffect, useMemo, useState } from 'react';
10
+ import * as React from 'react';
11
+ import { invariant } from '../../../../lexical/utils/invariant.js';
12
+ import { FieldsDrawer } from '../../../../utilities/fieldsDrawer/Drawer.js';
13
+ export const OPEN_TABLE_DRAWER_COMMAND = createCommand('OPEN_EMBED_DRAWER_COMMAND');
14
+ export const CellContext = /*#__PURE__*/ createContext({
15
+ cellEditorConfig: null,
16
+ cellEditorPlugins: null,
17
+ set: ()=>{
18
+ // Empty
19
+ }
20
+ });
21
+ const drawerSlug = 'lexical-table-create';
22
+ export function TableContext({ children }) {
23
+ const [contextValue, setContextValue] = useState({
24
+ cellEditorConfig: null,
25
+ cellEditorPlugins: null
26
+ });
27
+ return /*#__PURE__*/ _jsx(CellContext.Provider, {
28
+ value: useMemo(()=>({
29
+ cellEditorConfig: contextValue.cellEditorConfig,
30
+ cellEditorPlugins: contextValue.cellEditorPlugins,
31
+ set: (cellEditorConfig, cellEditorPlugins)=>{
32
+ setContextValue({
33
+ cellEditorConfig,
34
+ cellEditorPlugins
35
+ });
36
+ }
37
+ }), [
38
+ contextValue.cellEditorConfig,
39
+ contextValue.cellEditorPlugins
40
+ ]),
41
+ children: children
42
+ });
43
+ }
44
+ export const TablePlugin = ()=>{
45
+ const [editor] = useLexicalComposerContext();
46
+ const cellContext = useContext(CellContext);
47
+ const { closeModal, toggleModal } = useModal();
48
+ useEffect(()=>{
49
+ if (!editor.hasNodes([
50
+ TableNode
51
+ ])) {
52
+ invariant(false, 'TablePlugin: TableNode is not registered on editor');
53
+ }
54
+ return mergeRegister(editor.registerCommand(OPEN_TABLE_DRAWER_COMMAND, ()=>{
55
+ let rangeSelection = null;
56
+ editor.getEditorState().read(()=>{
57
+ const selection = $getSelection();
58
+ if ($isRangeSelection(selection)) {
59
+ rangeSelection = selection;
60
+ }
61
+ });
62
+ if (rangeSelection) {
63
+ toggleModal(drawerSlug);
64
+ }
65
+ return true;
66
+ }, COMMAND_PRIORITY_EDITOR));
67
+ }, [
68
+ cellContext,
69
+ editor,
70
+ toggleModal
71
+ ]);
72
+ return /*#__PURE__*/ _jsxs(React.Fragment, {
73
+ children: [
74
+ /*#__PURE__*/ _jsx(FieldsDrawer, {
75
+ data: {},
76
+ drawerSlug: drawerSlug,
77
+ drawerTitle: "Create Table",
78
+ featureKey: "experimental_table",
79
+ handleDrawerSubmit: (_fields, data)=>{
80
+ closeModal(drawerSlug);
81
+ if (!data.columns || !data.rows) {
82
+ return;
83
+ }
84
+ editor.dispatchCommand(INSERT_TABLE_COMMAND, {
85
+ columns: String(data.columns),
86
+ rows: String(data.rows)
87
+ });
88
+ },
89
+ schemaPathSuffix: "fields"
90
+ }),
91
+ /*#__PURE__*/ _jsx(LexicalReactTablePlugin, {
92
+ hasCellBackgroundColor: false,
93
+ hasCellMerge: true
94
+ })
95
+ ]
96
+ });
97
+ };
98
+
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/features/experimental_table/plugins/TablePlugin/index.tsx"],"sourcesContent":["'use client'\n\nimport type {\n EditorThemeClasses,\n Klass,\n LexicalCommand,\n LexicalEditor,\n LexicalNode,\n RangeSelection,\n} from 'lexical'\nimport type { JSX } from 'react'\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'\nimport { TablePlugin as LexicalReactTablePlugin } from '@lexical/react/LexicalTablePlugin'\nimport { INSERT_TABLE_COMMAND, TableNode } from '@lexical/table'\nimport { mergeRegister } from '@lexical/utils'\nimport { useModal } from '@payloadcms/ui'\nimport { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical'\nimport { createContext, useContext, useEffect, useMemo, useState } from 'react'\nimport * as React from 'react'\n\nimport type { PluginComponent } from '../../../typesClient.js'\n\nimport { invariant } from '../../../../lexical/utils/invariant.js'\nimport { FieldsDrawer } from '../../../../utilities/fieldsDrawer/Drawer.js'\nimport './index.scss'\n\nexport type CellContextShape = {\n cellEditorConfig: CellEditorConfig | null\n cellEditorPlugins: Array<JSX.Element> | JSX.Element | null\n set: (\n cellEditorConfig: CellEditorConfig | null,\n cellEditorPlugins: Array<JSX.Element> | JSX.Element | null,\n ) => void\n}\n\nexport type CellEditorConfig = Readonly<{\n namespace: string\n nodes?: ReadonlyArray<Klass<LexicalNode>>\n onError: (error: Error, editor: LexicalEditor) => void\n readOnly?: boolean\n theme?: EditorThemeClasses\n}>\n\nexport const OPEN_TABLE_DRAWER_COMMAND: LexicalCommand<{}> = createCommand(\n 'OPEN_EMBED_DRAWER_COMMAND',\n)\n\nexport const CellContext = createContext<CellContextShape>({\n cellEditorConfig: null,\n cellEditorPlugins: null,\n set: () => {\n // Empty\n },\n})\nconst drawerSlug = 'lexical-table-create'\n\nexport function TableContext({ children }: { children: JSX.Element }) {\n const [contextValue, setContextValue] = useState<{\n cellEditorConfig: CellEditorConfig | null\n cellEditorPlugins: Array<JSX.Element> | JSX.Element | null\n }>({\n cellEditorConfig: null,\n cellEditorPlugins: null,\n })\n return (\n <CellContext.Provider\n value={useMemo(\n () => ({\n cellEditorConfig: contextValue.cellEditorConfig,\n cellEditorPlugins: contextValue.cellEditorPlugins,\n set: (cellEditorConfig, cellEditorPlugins) => {\n setContextValue({ cellEditorConfig, cellEditorPlugins })\n },\n }),\n [contextValue.cellEditorConfig, contextValue.cellEditorPlugins],\n )}\n >\n {children}\n </CellContext.Provider>\n )\n}\n\nexport const TablePlugin: PluginComponent = () => {\n const [editor] = useLexicalComposerContext()\n const cellContext = useContext(CellContext)\n const { closeModal, toggleModal } = useModal()\n\n useEffect(() => {\n if (!editor.hasNodes([TableNode])) {\n invariant(false, 'TablePlugin: TableNode is not registered on editor')\n }\n\n return mergeRegister(\n editor.registerCommand(\n OPEN_TABLE_DRAWER_COMMAND,\n () => {\n let rangeSelection: RangeSelection | null = null\n\n editor.getEditorState().read(() => {\n const selection = $getSelection()\n if ($isRangeSelection(selection)) {\n rangeSelection = selection\n }\n })\n\n if (rangeSelection) {\n toggleModal(drawerSlug)\n }\n return true\n },\n COMMAND_PRIORITY_EDITOR,\n ),\n )\n }, [cellContext, editor, toggleModal])\n\n return (\n <React.Fragment>\n <FieldsDrawer\n data={{}}\n drawerSlug={drawerSlug}\n drawerTitle=\"Create Table\"\n featureKey=\"experimental_table\"\n handleDrawerSubmit={(_fields, data) => {\n closeModal(drawerSlug)\n\n if (!data.columns || !data.rows) {\n return\n }\n\n editor.dispatchCommand(INSERT_TABLE_COMMAND, {\n columns: String(data.columns),\n rows: String(data.rows),\n })\n }}\n schemaPathSuffix=\"fields\"\n />\n <LexicalReactTablePlugin hasCellBackgroundColor={false} hasCellMerge />\n </React.Fragment>\n )\n}\n"],"names":["useLexicalComposerContext","TablePlugin","LexicalReactTablePlugin","INSERT_TABLE_COMMAND","TableNode","mergeRegister","useModal","$getSelection","$isRangeSelection","COMMAND_PRIORITY_EDITOR","createCommand","createContext","useContext","useEffect","useMemo","useState","React","invariant","FieldsDrawer","OPEN_TABLE_DRAWER_COMMAND","CellContext","cellEditorConfig","cellEditorPlugins","set","drawerSlug","TableContext","children","contextValue","setContextValue","Provider","value","editor","cellContext","closeModal","toggleModal","hasNodes","registerCommand","rangeSelection","getEditorState","read","selection","Fragment","data","drawerTitle","featureKey","handleDrawerSubmit","_fields","columns","rows","dispatchCommand","String","schemaPathSuffix","hasCellBackgroundColor","hasCellMerge"],"mappings":"AAAA;;AAYA,SAASA,yBAAyB,QAAQ,wCAAuC;AACjF,SAASC,eAAeC,uBAAuB,QAAQ,oCAAmC;AAC1F,SAASC,oBAAoB,EAAEC,SAAS,QAAQ,iBAAgB;AAChE,SAASC,aAAa,QAAQ,iBAAgB;AAC9C,SAASC,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,aAAa,EAAEC,iBAAiB,EAAEC,uBAAuB,EAAEC,aAAa,QAAQ,UAAS;AAClG,SAASC,aAAa,EAAEC,UAAU,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AAC/E,YAAYC,WAAW,QAAO;AAI9B,SAASC,SAAS,QAAQ,yCAAwC;AAClE,SAASC,YAAY,QAAQ,+CAA8C;AAoB3E,OAAO,MAAMC,4BAAgDT,cAC3D,6BACD;AAED,OAAO,MAAMU,4BAAcT,cAAgC;IACzDU,kBAAkB;IAClBC,mBAAmB;IACnBC,KAAK;IACH,QAAQ;IACV;AACF,GAAE;AACF,MAAMC,aAAa;AAEnB,OAAO,SAASC,aAAa,EAAEC,QAAQ,EAA6B;IAClE,MAAM,CAACC,cAAcC,gBAAgB,GAAGb,SAGrC;QACDM,kBAAkB;QAClBC,mBAAmB;IACrB;IACA,qBACE,KAACF,YAAYS,QAAQ;QACnBC,OAAOhB,QACL,IAAO,CAAA;gBACLO,kBAAkBM,aAAaN,gBAAgB;gBAC/CC,mBAAmBK,aAAaL,iBAAiB;gBACjDC,KAAK,CAACF,kBAAkBC;oBACtBM,gBAAgB;wBAAEP;wBAAkBC;oBAAkB;gBACxD;YACF,CAAA,GACA;YAACK,aAAaN,gBAAgB;YAAEM,aAAaL,iBAAiB;SAAC;kBAGhEI;;AAGP;AAEA,OAAO,MAAMzB,cAA+B;IAC1C,MAAM,CAAC8B,OAAO,GAAG/B;IACjB,MAAMgC,cAAcpB,WAAWQ;IAC/B,MAAM,EAAEa,UAAU,EAAEC,WAAW,EAAE,GAAG5B;IAEpCO,UAAU;QACR,IAAI,CAACkB,OAAOI,QAAQ,CAAC;YAAC/B;SAAU,GAAG;YACjCa,UAAU,OAAO;QACnB;QAEA,OAAOZ,cACL0B,OAAOK,eAAe,CACpBjB,2BACA;YACE,IAAIkB,iBAAwC;YAE5CN,OAAOO,cAAc,GAAGC,IAAI,CAAC;gBAC3B,MAAMC,YAAYjC;gBAClB,IAAIC,kBAAkBgC,YAAY;oBAChCH,iBAAiBG;gBACnB;YACF;YAEA,IAAIH,gBAAgB;gBAClBH,YAAYV;YACd;YACA,OAAO;QACT,GACAf;IAGN,GAAG;QAACuB;QAAaD;QAAQG;KAAY;IAErC,qBACE,MAAClB,MAAMyB,QAAQ;;0BACb,KAACvB;gBACCwB,MAAM,CAAC;gBACPlB,YAAYA;gBACZmB,aAAY;gBACZC,YAAW;gBACXC,oBAAoB,CAACC,SAASJ;oBAC5BT,WAAWT;oBAEX,IAAI,CAACkB,KAAKK,OAAO,IAAI,CAACL,KAAKM,IAAI,EAAE;wBAC/B;oBACF;oBAEAjB,OAAOkB,eAAe,CAAC9C,sBAAsB;wBAC3C4C,SAASG,OAAOR,KAAKK,OAAO;wBAC5BC,MAAME,OAAOR,KAAKM,IAAI;oBACxB;gBACF;gBACAG,kBAAiB;;0BAEnB,KAACjD;gBAAwBkD,wBAAwB;gBAAOC,YAAY;;;;AAG1E,EAAC"}