diff --git a/.changeset/slimy-suns-joke.md b/.changeset/slimy-suns-joke.md new file mode 100644 index 0000000000..1d3f0dcfde --- /dev/null +++ b/.changeset/slimy-suns-joke.md @@ -0,0 +1,5 @@ +--- +"@udecode/plate-table": patch +--- + +Fix unmerging a single column diff --git a/packages/table/src/merge/computeCellIndices.ts b/packages/table/src/merge/computeCellIndices.ts index 57c727f86c..c1e1efdc45 100644 --- a/packages/table/src/merge/computeCellIndices.ts +++ b/packages/table/src/merge/computeCellIndices.ts @@ -1,6 +1,7 @@ import { getPluginOptions, PlateEditor, Value } from '@udecode/plate-common'; import { ELEMENT_TABLE } from '../createTablePlugin'; +import { getRowSpan } from '../queries/getRowSpan'; import { TablePlugin, TTableCellElement, @@ -40,15 +41,16 @@ export function computeCellIndices( prevRow.children.forEach((pC) => { const prevCell = pC as TTableCellElement; const prevIndices = options?._cellIndices?.get(prevCell); + const _rowSpan = getRowSpan(prevCell); if (prevIndices) { const { col: prevColIndex } = prevIndices; if ( // colIndex affects prevColIndex <= colIndex && // rowSpan affects - prevCell.rowSpan && - prevCell.rowSpan > 1 && - rowIndex - _rowIndex < prevCell.rowSpan + _rowSpan && + _rowSpan > 1 && + rowIndex - _rowIndex < _rowSpan ) { colIndex += prevCell.colSpan || 1; } diff --git a/packages/table/src/merge/isTableRectangular.ts b/packages/table/src/merge/isTableRectangular.ts index ff3b216712..d0f3d42fff 100644 --- a/packages/table/src/merge/isTableRectangular.ts +++ b/packages/table/src/merge/isTableRectangular.ts @@ -1,3 +1,4 @@ +import { getRowSpan } from '../queries/getRowSpan'; import { TTableCellElement, TTableElement, TTableRowElement } from '../types'; const allEqual = (arr: number[]) => arr.every((val) => val === arr[0]); @@ -14,7 +15,7 @@ export const isTableRectangular = (table?: TTableElement) => { const cellElem = cell as TTableCellElement; Array.from({ - length: cellElem?.rowSpan || 1, + length: getRowSpan(cellElem) || 1, } as ArrayLike).forEach((_, i) => { if (!arr[rI + i]) { arr[rI + i] = 0; diff --git a/packages/table/src/merge/unmergeTableCells.ts b/packages/table/src/merge/unmergeTableCells.ts index 400e34f21d..a0451d9768 100644 --- a/packages/table/src/merge/unmergeTableCells.ts +++ b/packages/table/src/merge/unmergeTableCells.ts @@ -13,6 +13,7 @@ import { import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin'; import { getTableGridAbove } from '../queries'; import { getColSpan } from '../queries/getColSpan'; +import { getRowSpan } from '../queries/getRowSpan'; import { TablePlugin, TTableCellElement, TTableRowElement } from '../types'; import { getEmptyCellNode } from '../utils'; import { getCellIndices } from './getCellIndices'; @@ -45,8 +46,8 @@ export const unmergeTableCells = ( const cellPath = path.slice(-2); const [rowPath, colPath] = cellPath; - const colSpan = cellElem.colSpan as number; - const rowSpan = cellElem.rowSpan as number; + const colSpan = getColSpan(cellElem as TTableCellElement); + const rowSpan = getRowSpan(cellElem as TTableCellElement); // Generate an array of column paths from the colspan const colPaths: number[] = []; @@ -69,8 +70,12 @@ export const unmergeTableCells = ( at: [...tablePath, row], match: { type: getPluginType(editor, ELEMENT_TR) }, })!; // TODO: improve typing - const rowEl = rowEntry[0] as TTableRowElement; + if (!rowEntry) { + return newColPath; + } + + const rowEl = rowEntry[0] as TTableRowElement; for (const item of rowEl.children) { const { col: c } = getCellIndices( cellIndices!, @@ -93,16 +98,39 @@ export const unmergeTableCells = ( for (let i = 0; i < rowSpan; i++) { const currentRowPath = rowPath + i; const pathForNextRows = getColPathForRow(currentRowPath); - for (let j = 0; j < colPaths.length; j++) { - const currentColPath = i === 0 ? colPaths[j] : pathForNextRows; + const newRowChildren = []; + const _rowPath = [...tablePath, currentRowPath]; + const rowEntry = findNode(editor, { + at: _rowPath, + match: { type: getPluginType(editor, ELEMENT_TABLE) }, + }); - const pathForNewCell = [...tablePath, currentRowPath, currentColPath]; + for (let j = 0; j < colPaths.length; j++) { const cellToInsert = i === 0 && j === 0 ? createEmptyCell(cellElem.children) : createEmptyCell(); - insertElements(editor, cellToInsert, { at: pathForNewCell }); + // if row exists, insert into it, otherwise insert row + if (rowEntry) { + const currentColPath = i === 0 ? colPaths[j] : pathForNextRows; + const pathForNewCell = [...tablePath, currentRowPath, currentColPath]; + + insertElements(editor, cellToInsert, { at: pathForNewCell }); + } else { + newRowChildren.push(cellToInsert); + } + } + + if (!rowEntry) { + insertElements( + editor, + { + type: getPluginType(editor, ELEMENT_TR), + children: newRowChildren, + }, + { at: _rowPath } + ); } } }); diff --git a/packages/table/src/merge/useTableMergeState.ts b/packages/table/src/merge/useTableMergeState.ts index 32e8806e92..f142dd8f37 100644 --- a/packages/table/src/merge/useTableMergeState.ts +++ b/packages/table/src/merge/useTableMergeState.ts @@ -11,6 +11,8 @@ import { useReadOnly, useSelected } from 'slate-react'; import { ELEMENT_TABLE } from '../createTablePlugin'; import { getTableGridAbove } from '../queries'; +import { getColSpan } from '../queries/getColSpan'; +import { getRowSpan } from '../queries/getRowSpan'; import { useTableStore } from '../stores'; import { TablePlugin } from '../types'; import { isTableRectangular } from './isTableRectangular'; @@ -56,8 +58,8 @@ export const useTableMergeState = () => { collapsed && selectedCellEntries && selectedCellEntries.length === 1 && - ((selectedCellEntries[0][0] as any)?.colSpan > 1 || - (selectedCellEntries[0][0] as any)?.rowSpan > 1); + (getColSpan(selectedCellEntries[0][0] as any) > 1 || + getRowSpan(selectedCellEntries[0][0] as any) > 1); return { canMerge, canUnmerge }; };