From 8ee4a9e018656c4fc8c82d56b2feb3cf3d15dc9c Mon Sep 17 00:00:00 2001 From: Dzmitry Tamashevich Date: Wed, 15 Nov 2023 20:17:33 +0300 Subject: [PATCH] sync indices --- .../useTableCellElementState.ts | 73 +++++++++++-------- .../TableElement/useTableElement.ts | 12 +-- .../table/src/merge/computeCellIndices.ts | 25 +------ packages/table/src/merge/deleteRow.ts | 1 + packages/table/src/merge/findCellByIndexes.ts | 3 +- packages/table/src/merge/mergeTableCells.ts | 19 ----- packages/table/src/merge/unmergeTableCells.ts | 9 +-- packages/table/src/withMergedCells.ts | 54 ++++++++++++++ packages/table/src/withTable.ts | 4 + 9 files changed, 109 insertions(+), 91 deletions(-) create mode 100644 packages/table/src/withMergedCells.ts diff --git a/packages/table/src/components/TableCellElement/useTableCellElementState.ts b/packages/table/src/components/TableCellElement/useTableCellElementState.ts index 3dff3c1433..81648be4b5 100644 --- a/packages/table/src/components/TableCellElement/useTableCellElementState.ts +++ b/packages/table/src/components/TableCellElement/useTableCellElementState.ts @@ -1,4 +1,4 @@ -import { useEffect, useMemo } from 'react'; +import { useEffect } from 'react'; import { getPluginOptions, useEditorRef, @@ -59,45 +59,60 @@ export const useTableCellElementState = ({ const tableElement = useElement(ELEMENT_TABLE); const rowElement = useElement(ELEMENT_TR); + const rowSizeOverrides = useTableStore().get.rowSizeOverrides(); - const { _cellIndices } = useMemo( - () => getPluginOptions(editor as any, ELEMENT_TABLE), - [editor] + const { disableCellsMerging, _cellIndices } = getPluginOptions( + editor as any, + ELEMENT_TABLE ); + if (disableCellsMerging) { + const colIndex = getTableColumnIndex(editor, cellElement); + const rowIndex = getTableRowIndex(editor, cellElement); + + const rowSize = + rowSizeOverrides.get(rowIndex) ?? rowElement?.size ?? undefined; + + const isFirstCell = colIndex === 0; + const isFirstRow = tableElement.children?.[0] === rowElement; + + const borders = getTableCellBorders(cellElement, { + isFirstCell, + isFirstRow, + }); + + return { + colIndex, + rowIndex, + readOnly: !ignoreReadOnly && readOnly, + selected: isCellSelected, + hovered: hoveredColIndex === colIndex, + hoveredLeft: isFirstCell && hoveredColIndex === -1, + rowSize, + borders, + isSelectingCell: !!selectedCells, + colSpan, + }; + } - let x: { col: number; row: number }; - const fromWeakMap = _cellIndices.get(cellElement); - // const cellContent = cellElement.children.map((i) => { - // return (i.children as any)[0].text; - // }); + let result: { col: number; row: number }; - // const spans = { - // colSpan: getColSpan(cellElement), - // rowSpan: getRowSpan(cellElement), - // }; + const calculated = + _cellIndices.get(cellElement) || + computeCellIndices(editor, tableElement, cellElement); - if (fromWeakMap) { - x = fromWeakMap; - // console.log('cellContent', cellContent, x); + if (calculated) { + result = calculated; } else { - const x1 = computeCellIndices(editor, tableElement, cellElement); - if (x1) { - x = x1; - // console.log('computed', x, 'cellContent', cellContent, 'spans', spans); - } else { - const defaultColIndex = getTableColumnIndex(editor, cellElement); - const defaultRowIndex = getTableRowIndex(editor, cellElement); - x = { col: defaultColIndex, row: defaultRowIndex }; - // console.log('get default', x, 'cellContent', cellContent); - } + const defaultColIndex = getTableColumnIndex(editor, cellElement); + const defaultRowIndex = getTableRowIndex(editor, cellElement); + result = { col: defaultColIndex, row: defaultRowIndex }; } - const colIndex = x.col; - const rowIndex = x.row; + const colIndex = result.col; + const rowIndex = result.row; const endingRowIndex = rowIndex + rowSpan - 1; const endingColIndex = colIndex + colSpan - 1; - const rowSizeOverrides = useTableStore().get.rowSizeOverrides(); const rowSize = rowSizeOverrides.get(endingRowIndex) ?? rowElement?.size ?? undefined; diff --git a/packages/table/src/components/TableElement/useTableElement.ts b/packages/table/src/components/TableElement/useTableElement.ts index 80e239a325..73fef3193f 100644 --- a/packages/table/src/components/TableElement/useTableElement.ts +++ b/packages/table/src/components/TableElement/useTableElement.ts @@ -1,4 +1,3 @@ -import { useEffect } from 'react'; import { collapseSelection, getPluginOptions, @@ -7,7 +6,6 @@ import { } from '@udecode/plate-common'; import { ELEMENT_TABLE } from '../../createTablePlugin'; -import { computeAllCellIndices } from '../../merge/computeCellIndices'; import { useTableStore } from '../../stores/tableStore'; import { TablePlugin, TTableElement } from '../../types'; import { useSelectedCells } from './useSelectedCells'; @@ -30,10 +28,8 @@ export const useTableElementState = ({ } = {}): TableElementState => { const editor = useEditorRef(); - const { minColumnWidth, disableMarginLeft } = getPluginOptions( - editor, - ELEMENT_TABLE - ); + const { minColumnWidth, disableMarginLeft, disableCellsMerging } = + getPluginOptions(editor, ELEMENT_TABLE); const element = useElement(); const selectedCells = useTableStore().get.selectedCells(); @@ -45,10 +41,6 @@ export const useTableElementState = ({ let colSizes = useTableColSizes(element); - useEffect(() => { - computeAllCellIndices(editor, element); - }, [editor, element]); - if (transformColSizes) { colSizes = transformColSizes(colSizes); } diff --git a/packages/table/src/merge/computeCellIndices.ts b/packages/table/src/merge/computeCellIndices.ts index 4a7e396b2c..d6767736c0 100644 --- a/packages/table/src/merge/computeCellIndices.ts +++ b/packages/table/src/merge/computeCellIndices.ts @@ -1,9 +1,4 @@ -import { - findNodePath, - getPluginOptions, - PlateEditor, - Value, -} from '@udecode/plate-common'; +import { getPluginOptions, PlateEditor, Value } from '@udecode/plate-common'; import { ELEMENT_TABLE } from '../createTablePlugin'; import { @@ -62,7 +57,7 @@ export function computeCellIndices( }); if (rowIndex === -1 || colIndex === -1) { - console.log('Invalid cell location.'); + console.log('Invalid cell location.', rowIndex, colIndex); return null; } @@ -78,34 +73,18 @@ export const computeAllCellIndices = ( ) => { const options = getPluginOptions(editor, ELEMENT_TABLE); - // Initialize an array to store the indices of each cell - const cellIndicesArray = []; - - // const tablePath = findNodePath(editor, tableNode)!; - // Iterate through the table rows for (let r = 0; r < tableNode.children.length; r++) { const row = tableNode.children[r] as TTableRowElement; - const rowIndicesArray = []; // Iterate through the row cells for (let c = 0; c < row.children.length; c++) { const cell = row.children[c] as TTableCellElement; - // Get cell indices and store them in the row's array - // const cellPath = [r, c]; - const indices = computeCellIndices(editor, tableNode, cell); if (indices) { options._cellIndices.set(cell, indices); } - rowIndicesArray.push(indices); } - - // Push the rowIndicesArray to the cellIndicesArray - cellIndicesArray.push(rowIndicesArray); - // console.log('calculated array', cellIndicesArray); } - - return cellIndicesArray; }; diff --git a/packages/table/src/merge/deleteRow.ts b/packages/table/src/merge/deleteRow.ts index 9896298195..8292adcc8d 100644 --- a/packages/table/src/merge/deleteRow.ts +++ b/packages/table/src/merge/deleteRow.ts @@ -21,6 +21,7 @@ import { TTableRowElement, } from '../types'; import { getCellTypes } from '../utils'; +import { computeAllCellIndices } from './computeCellIndices'; import { findCellByIndexes } from './findCellByIndexes'; import { getIndices } from './getIndices'; diff --git a/packages/table/src/merge/findCellByIndexes.ts b/packages/table/src/merge/findCellByIndexes.ts index 9607f688ca..6227525b49 100644 --- a/packages/table/src/merge/findCellByIndexes.ts +++ b/packages/table/src/merge/findCellByIndexes.ts @@ -18,13 +18,13 @@ export const findCellByIndexes = ( (current) => current.children ) as TTableCellElement[]; - // console.log('searching for', searchRowIndex, searchColIndex); const foundCell = allCells.find((cell) => { const cellElement = cell as TTableCellElement; const indices = getIndices(options, cellElement) || computeCellIndices(editor, table, cellElement)!; + // getIndices(options, cellElement)!; const { col: _startColIndex, row: _startRowIndex } = indices; const { row: _endRowIndex, col: _endColIndex } = getIndicesWithSpans( @@ -32,7 +32,6 @@ export const findCellByIndexes = ( cellElement ); - // console.log('current', colIndex, endColIndex, rowIndex, endRowIndex); if ( searchColIndex >= _startColIndex && searchColIndex <= _endColIndex && diff --git a/packages/table/src/merge/mergeTableCells.ts b/packages/table/src/merge/mergeTableCells.ts index bf397a2f57..4e8af77107 100644 --- a/packages/table/src/merge/mergeTableCells.ts +++ b/packages/table/src/merge/mergeTableCells.ts @@ -106,24 +106,5 @@ export const mergeTableCells = ( // insert the new merged cell in place of the first cell in the selection insertElements(editor, mergedCell, { at: cellEntries[0][1] }); - - // /** - // * Update cell indices in weak map - // */ - // const tableEntry = findNode(editor, { - // at: cellEntries[0][1], - // match: { type: getPluginType(editor, ELEMENT_TABLE) }, - // })!; // TODO: improve typing - // const cellEntry = findNode(editor, { - // at: cellEntries[0][1], - // match: { type: getCellTypes(editor) }, - // })!; // TODO: improve typing - - // const realTable = tableEntry[0] as TTableElement; - // const mC = cellEntry[0] as TTableCellElement; - // console.log('realTable', realTable, 'mC', mC); - - // computeCellIndices(editor, realTable, mC); - // console.log('should be computed'); }); }; diff --git a/packages/table/src/merge/unmergeTableCells.ts b/packages/table/src/merge/unmergeTableCells.ts index 395ba1163d..9d8076a994 100644 --- a/packages/table/src/merge/unmergeTableCells.ts +++ b/packages/table/src/merge/unmergeTableCells.ts @@ -13,12 +13,7 @@ import { import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin'; import { getTableGridAbove } from '../queries'; import { getColSpan } from '../queries/getColSpan'; -import { - TablePlugin, - TTableCellElement, - TTableElement, - TTableRowElement, -} from '../types'; +import { TablePlugin, TTableCellElement, TTableRowElement } from '../types'; import { getEmptyCellNode } from '../utils'; export const unmergeTableCells = ( @@ -73,12 +68,10 @@ export const unmergeTableCells = ( const { col: c } = options._cellIndices.get(item as TTableCellElement)!; if (c === col - 1) { newColPath = rowEl.children.indexOf(item) + 1; - // console.log('found first', newColPath); break; } if (col + getColSpan(cellElem as TTableCellElement) === c - 1) { newColPath = rowEl.children.indexOf(item); - // console.log('found last', newColPath); break; } } diff --git a/packages/table/src/withMergedCells.ts b/packages/table/src/withMergedCells.ts new file mode 100644 index 0000000000..f1f754bcfc --- /dev/null +++ b/packages/table/src/withMergedCells.ts @@ -0,0 +1,54 @@ +import { + getBlockAbove, + getPluginType, + PlateEditor, + TElement, + Value, +} from '@udecode/plate-common'; +import { BaseSelection } from 'slate'; + +import { + ELEMENT_TABLE, + ELEMENT_TD, + ELEMENT_TH, + ELEMENT_TR, +} from './createTablePlugin'; +import { computeAllCellIndices } from './merge/computeCellIndices'; +import { TTableElement } from './types'; + +export const withMergedCells = < + V extends Value = Value, + E extends PlateEditor = PlateEditor, +>( + editor: E +) => { + const { apply } = editor; + + editor.apply = (op) => { + const needsSync = + op.type === 'insert_node' || + op.type === 'merge_node' || + op.type === 'move_node' || + op.type === 'remove_node' || + op.type === 'set_node'; + + const updateTable = (selection: BaseSelection) => { + const tableEntry = getBlockAbove(editor, { + at: selection?.anchor, + match: { type: getPluginType(editor, ELEMENT_TABLE) }, + }); + if (tableEntry) { + const realTable = tableEntry[0] as TTableElement; + computeAllCellIndices(editor, realTable); + } + }; + + if (needsSync) { + updateTable(editor.selection); + } + + apply(op); + }; + + return editor; +}; diff --git a/packages/table/src/withTable.ts b/packages/table/src/withTable.ts index 71392dde4e..59d34a0c5e 100644 --- a/packages/table/src/withTable.ts +++ b/packages/table/src/withTable.ts @@ -5,6 +5,7 @@ import { withDeleteTable } from './withDeleteTable'; import { withGetFragmentTable } from './withGetFragmentTable'; import { withInsertFragmentTable } from './withInsertFragmentTable'; import { withInsertTextTable } from './withInsertTextTable'; +import { withMergedCells } from './withMergedCells'; import { withNormalizeTable } from './withNormalizeTable'; import { withSelectionTable } from './withSelectionTable'; import { withSetFragmentDataTable } from './withSetFragmentDataTable'; @@ -16,6 +17,9 @@ export const withTable = < editor: E, plugin: WithPlatePlugin, V, E> ) => { + editor = plugin.options.disableCellsMerging + ? editor + : withMergedCells(editor); editor = withNormalizeTable(editor); editor = withDeleteTable(editor); editor = withGetFragmentTable(editor);