diff --git a/.changeset/sixty-bats-explode.md b/.changeset/sixty-bats-explode.md
new file mode 100644
index 0000000000..c7231d2dd6
--- /dev/null
+++ b/.changeset/sixty-bats-explode.md
@@ -0,0 +1,6 @@
+---
+'@udecode/plate-serializer-html': major
+---
+
+- [Breaking] `serializeHtml`: replaced option `slateProps` by `plateProps`.
+- Fix errors when the components were using Plate hooks.
diff --git a/.changeset/table.md b/.changeset/table.md
new file mode 100644
index 0000000000..bf18831c1b
--- /dev/null
+++ b/.changeset/table.md
@@ -0,0 +1,5 @@
+---
+'@udecode/plate-table': minor
+---
+
+- Table plugin has now merging support. To enable it, use option `enableMerging: true`
diff --git a/apps/www/src/components/icons.tsx b/apps/www/src/components/icons.tsx
index 793de4ff5d..bc3fb4ef83 100644
--- a/apps/www/src/components/icons.tsx
+++ b/apps/www/src/components/icons.tsx
@@ -15,6 +15,7 @@ import {
ChevronsUpDown,
ClipboardCheck,
Code2,
+ Combine,
Copy,
DownloadCloud,
ExternalLink,
@@ -73,6 +74,7 @@ import {
Trash,
Twitter,
Underline,
+ Ungroup,
Unlink,
WrapText,
X,
@@ -281,6 +283,8 @@ export const Icons = {
codeblock: FileCode,
color: Baseline,
column: RectangleVertical,
+ combine: Combine,
+ ungroup: Ungroup,
comment: MessageSquare,
commentAdd: MessageSquarePlus,
conflict: Unlink,
diff --git a/apps/www/src/lib/plate/demo/values/tableValue.tsx b/apps/www/src/lib/plate/demo/values/tableValue.tsx
index e124c81caf..ecf8252c97 100644
--- a/apps/www/src/lib/plate/demo/values/tableValue.tsx
+++ b/apps/www/src/lib/plate/demo/values/tableValue.tsx
@@ -118,4 +118,4 @@ export const tableValue: any = (
{createSpanningTable()}
-);
+);
\ No newline at end of file
diff --git a/apps/www/src/registry/default/plate-ui/table-cell-element.tsx b/apps/www/src/registry/default/plate-ui/table-cell-element.tsx
index 0effb3e381..818f19b8b8 100644
--- a/apps/www/src/registry/default/plate-ui/table-cell-element.tsx
+++ b/apps/www/src/registry/default/plate-ui/table-cell-element.tsx
@@ -34,12 +34,15 @@ const TableCellElement = React.forwardRef<
rowSize,
borders,
isSelectingCell,
+ colSpan,
} = useTableCellElementState();
const { props: cellProps } = useTableCellElement({ element: props.element });
const resizableState = useTableCellElementResizableState({
colIndex,
rowIndex,
+ colSpan,
});
+
const { rightProps, bottomProps, leftProps, hiddenLeft } =
useTableCellElementResizable(resizableState);
@@ -50,7 +53,7 @@ const TableCellElement = React.forwardRef<
asChild
ref={ref}
className={cn(
- 'relative overflow-visible border-none bg-background p-0',
+ 'relative h-full overflow-visible border-none bg-background p-0',
hideBorder && 'before:border-none',
element.background ? 'bg-[--cellBackground]' : 'bg-background',
!hideBorder &&
diff --git a/apps/www/src/registry/default/plate-ui/table-element.tsx b/apps/www/src/registry/default/plate-ui/table-element.tsx
index 713679f69b..b016d57db9 100644
--- a/apps/www/src/registry/default/plate-ui/table-element.tsx
+++ b/apps/www/src/registry/default/plate-ui/table-element.tsx
@@ -10,10 +10,13 @@ import {
useRemoveNodeButton,
} from '@udecode/plate-common';
import {
+ mergeTableCells,
TTableElement,
+ unmergeTableCells,
useTableBordersDropdownMenuContentState,
useTableElement,
useTableElementState,
+ useTableMergeState,
} from '@udecode/plate-table';
import { useReadOnly, useSelected } from 'slate-react';
@@ -114,35 +117,73 @@ const TableFloatingToolbar = React.forwardRef<
const readOnly = useReadOnly();
const selected = useSelected();
const editor = useEditorState();
- const open = !readOnly && selected && isCollapsed(editor.selection);
+
+ const collapsed = !readOnly && selected && isCollapsed(editor.selection);
+ const open = !readOnly && selected;
+
+ const { canMerge, canUnmerge } = useTableMergeState();
+
+ const mergeContent = canMerge && (
+
+ );
+
+ const unmergeButton = canUnmerge && (
+
+ );
+
+ const bordersContent = collapsed && (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
return (
{children}
- e.preventDefault()}
- {...props}
- >
-
-
-
-
-
-
-
-
-
-
-
-
+ {(canMerge || canUnmerge || collapsed) && (
+ e.preventDefault()}
+ {...props}
+ >
+ {unmergeButton}
+ {mergeContent}
+ {bordersContent}
+
+ )}
);
});
diff --git a/packages/resizable/src/components/ResizeHandle.tsx b/packages/resizable/src/components/ResizeHandle.tsx
index 4d71263674..74088de05d 100644
--- a/packages/resizable/src/components/ResizeHandle.tsx
+++ b/packages/resizable/src/components/ResizeHandle.tsx
@@ -51,6 +51,7 @@ export const ResizeHandleProvider = ({
export type ResizeHandleOptions = {
direction?: ResizeDirection;
+ initialSize?: number;
onResize?: (event: ResizeEvent) => void;
onMouseDown?: MouseEventHandler;
onTouchStart?: TouchEventHandler;
@@ -60,6 +61,7 @@ export type ResizeHandleOptions = {
export const useResizeHandleState = ({
direction = 'left',
+ initialSize: _initialSize,
onResize,
onMouseDown,
onTouchStart,
@@ -88,7 +90,12 @@ export const useResizeHandleState = ({
const currentPosition = isHorizontal ? clientX : clientY;
const delta = currentPosition - initialPosition;
- onResize?.({ initialSize, delta, finished, direction });
+ onResize?.({
+ initialSize: _initialSize || initialSize,
+ delta,
+ finished,
+ direction,
+ });
};
const handleMouseMove = (event: MouseEvent | TouchEvent) =>
diff --git a/packages/serializer-html/src/elementToHtml.ts b/packages/serializer-html/src/elementToHtml.ts
index 979ccba3fc..10de567a5f 100644
--- a/packages/serializer-html/src/elementToHtml.ts
+++ b/packages/serializer-html/src/elementToHtml.ts
@@ -2,9 +2,9 @@ import { ComponentClass, FunctionComponent } from 'react';
import {
pipeInjectProps,
PlateEditor,
+ PlateProps,
PlateRenderElementProps,
pluginRenderElement,
- SlateProps,
Value,
} from '@udecode/plate-common';
import { decode } from 'html-entities';
@@ -17,12 +17,12 @@ export const elementToHtml = (
editor: PlateEditor,
{
props,
- slateProps,
+ plateProps,
preserveClassNames,
dndWrapper,
}: {
props: PlateRenderElementProps;
- slateProps?: Partial;
+ plateProps?: Partial;
preserveClassNames?: string[];
dndWrapper?: string | FunctionComponent | ComponentClass;
}
@@ -50,8 +50,8 @@ export const elementToHtml = (
renderToStaticMarkup(
createElementWithSlate(
{
- ...slateProps,
-
+ editor: editor as any,
+ ...plateProps,
children:
plugin.serializeHtml?.(props as any) ??
pluginRenderElement(editor, plugin)(props),
diff --git a/packages/serializer-html/src/leafToHtml.ts b/packages/serializer-html/src/leafToHtml.ts
index 38d0deaf96..6d2cdf6af3 100644
--- a/packages/serializer-html/src/leafToHtml.ts
+++ b/packages/serializer-html/src/leafToHtml.ts
@@ -1,9 +1,9 @@
import {
pipeInjectProps,
PlateEditor,
+ PlateProps,
PlateRenderLeafProps,
pluginRenderLeaf,
- SlateProps,
Value,
} from '@udecode/plate-common';
import { decode } from 'html-entities';
@@ -16,11 +16,11 @@ export const leafToHtml = (
editor: PlateEditor,
{
props,
- slateProps,
+ plateProps,
preserveClassNames,
}: {
props: PlateRenderLeafProps;
- slateProps?: Partial;
+ plateProps?: Partial;
preserveClassNames?: string[];
}
) => {
@@ -43,7 +43,7 @@ export const leafToHtml = (
let html = decode(
renderToStaticMarkup(
createElementWithSlate({
- ...slateProps,
+ ...plateProps,
children: serialized,
})
)
diff --git a/packages/serializer-html/src/serializeHtml.ts b/packages/serializer-html/src/serializeHtml.ts
index 8bd95d5464..5978c17557 100644
--- a/packages/serializer-html/src/serializeHtml.ts
+++ b/packages/serializer-html/src/serializeHtml.ts
@@ -4,7 +4,7 @@ import {
EElement,
isText,
PlateEditor,
- SlateProps,
+ PlateProps,
Value,
} from '@udecode/plate-common';
import { encode } from 'html-entities';
@@ -22,7 +22,7 @@ export const serializeHtml = (
editor: PlateEditor,
{
nodes,
- slateProps,
+ plateProps,
stripDataAttributes = true,
preserveClassNames,
stripWhitespace = true,
@@ -45,9 +45,9 @@ export const serializeHtml = (
preserveClassNames?: string[];
/**
- * Slate props to provide if the rendering depends on slate hooks
+ * Slate props to provide if the rendering depends on plate/slate hooks
*/
- slateProps?: Partial;
+ plateProps?: Partial;
/**
* Whether stripping whitespaces from serialized HTML
@@ -82,7 +82,7 @@ export const serializeHtml = (
attributes: { 'data-slate-leaf': true },
editor,
},
- slateProps,
+ plateProps,
preserveClassNames,
});
}
@@ -99,7 +99,7 @@ export const serializeHtml = (
attributes: { 'data-slate-node': 'element', ref: null },
editor,
},
- slateProps,
+ plateProps,
preserveClassNames,
dndWrapper,
});
diff --git a/packages/serializer-html/src/utils/createElementWithSlate.ts b/packages/serializer-html/src/utils/createElementWithSlate.ts
index b6aff3354c..b18b3925a5 100644
--- a/packages/serializer-html/src/utils/createElementWithSlate.ts
+++ b/packages/serializer-html/src/utils/createElementWithSlate.ts
@@ -1,49 +1,35 @@
import React, { ComponentClass, FunctionComponent } from 'react';
-import { createTEditor, SlateProps, withTReact } from '@udecode/plate-common';
-import { Slate } from 'slate-react';
+import { Plate, PlateProps } from '@udecode/plate-common';
/**
- * Create a React element wrapped in a Slate provider.
- * By default, it will use an empty editor.
- * TODO: allow other providers
+ * Create a React element wrapped in a Plate provider.
*/
export const createElementWithSlate = (
- slateProps?: Partial,
+ plateProps?: Partial,
dndWrapper?: string | FunctionComponent | ComponentClass
) => {
const {
- editor = withTReact(createTEditor()),
+ editor,
value = [],
onChange = () => {},
children,
...props
- } = slateProps || {};
+ } = plateProps || {};
- if (dndWrapper) {
- return React.createElement(
- dndWrapper,
- null,
- React.createElement(
- Slate,
- {
- editor,
- initialValue: value,
- onChange,
- ...props,
- } as any,
- children
- )
- );
- }
-
- return React.createElement(
- Slate,
+ const plate = React.createElement(
+ Plate,
{
editor,
initialValue: value,
onChange,
...props,
- } as any,
+ } as PlateProps,
children
);
+
+ if (dndWrapper) {
+ return React.createElement(dndWrapper, null, plate);
+ }
+
+ return plate;
};
diff --git a/packages/table/src/components/TableCellElement/useTableCellElementResizable.ts b/packages/table/src/components/TableCellElement/useTableCellElementResizable.ts
index 7a08cdcb61..a4158dbed4 100644
--- a/packages/table/src/components/TableCellElement/useTableCellElementResizable.ts
+++ b/packages/table/src/components/TableCellElement/useTableCellElementResizable.ts
@@ -30,7 +30,7 @@ import { TableCellElementState } from './useTableCellElementState';
export type TableCellElementResizableOptions = Pick<
TableCellElementState,
- 'colIndex' | 'rowIndex'
+ 'colIndex' | 'rowIndex' | 'colSpan'
> & {
/**
* Resize by step instead of by pixel.
@@ -50,6 +50,7 @@ export const useTableCellElementResizableState = ({
step,
stepX = step,
stepY = step,
+ colSpan,
}: TableCellElementResizableOptions) => {
const editor = useEditorRef();
const { disableMarginLeft } = getPluginOptions(
@@ -63,6 +64,7 @@ export const useTableCellElementResizableState = ({
rowIndex,
stepX,
stepY,
+ colSpan,
};
};
@@ -72,6 +74,7 @@ export const useTableCellElementResizable = ({
rowIndex,
stepX,
stepY,
+ colSpan,
}: ReturnType): {
rightProps: ComponentPropsWithoutRef;
bottomProps: ComponentPropsWithoutRef;
@@ -86,6 +89,11 @@ export const useTableCellElementResizable = ({
ELEMENT_TABLE
);
+ let initialWidth: number | undefined;
+ if (colSpan > 1) {
+ initialWidth = tableElement.colSizes?.[colIndex];
+ }
+
const [hoveredColIndex, setHoveredColIndex] =
useTableStore().use.hoveredColIndex();
@@ -246,6 +254,7 @@ export const useTableCellElementResizable = ({
rightProps: {
options: {
direction: 'right',
+ initialSize: initialWidth,
onResize: handleResizeRight,
...getHandleHoverProps(colIndex),
},
diff --git a/packages/table/src/components/TableCellElement/useTableCellElementState.ts b/packages/table/src/components/TableCellElement/useTableCellElementState.ts
index e14c7eb809..3edf24fee1 100644
--- a/packages/table/src/components/TableCellElement/useTableCellElementState.ts
+++ b/packages/table/src/components/TableCellElement/useTableCellElementState.ts
@@ -1,11 +1,20 @@
import { useEffect } from 'react';
-import { useEditorRef, useElement } from '@udecode/plate-common';
+import {
+ getPluginOptions,
+ useEditorRef,
+ useElement,
+} from '@udecode/plate-common';
import { useReadOnly } from 'slate-react';
import { ELEMENT_TABLE, ELEMENT_TR } from '../../createTablePlugin';
+import { computeCellIndices } from '../../merge/computeCellIndices';
+import { getCellIndices } from '../../merge/getCellIndices';
+import { getColSpan } from '../../queries/getColSpan';
+import { getRowSpan } from '../../queries/getRowSpan';
import { getTableColumnIndex, getTableRowIndex } from '../../queries/index';
import { useTableStore } from '../../stores/tableStore';
import {
+ TablePlugin,
TTableCellElement,
TTableElement,
TTableRowElement,
@@ -26,6 +35,7 @@ export type TableCellElementState = {
rowSize: number | undefined;
borders: BorderStylesDefault;
isSelectingCell: boolean;
+ colSpan: number;
};
export const useTableCellElementState = ({
@@ -39,8 +49,8 @@ export const useTableCellElementState = ({
const editor = useEditorRef();
const cellElement = useElement();
- const colIndex = getTableColumnIndex(editor, cellElement);
- const rowIndex = getTableRowIndex(editor, cellElement);
+ const colSpan = getColSpan(cellElement);
+ const rowSpan = getRowSpan(cellElement);
const readOnly = useReadOnly();
@@ -51,8 +61,61 @@ export const useTableCellElementState = ({
const tableElement = useElement(ELEMENT_TABLE);
const rowElement = useElement(ELEMENT_TR);
const rowSizeOverrides = useTableStore().get.rowSizeOverrides();
+
+ const { enableMerging, _cellIndices } = getPluginOptions(
+ editor as any,
+ ELEMENT_TABLE
+ );
+ if (!enableMerging) {
+ 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 result: { col: number; row: number };
+
+ const calculated =
+ getCellIndices(_cellIndices!, cellElement) ||
+ computeCellIndices(editor, tableElement, cellElement);
+
+ if (calculated) {
+ result = calculated;
+ } else {
+ const defaultColIndex = getTableColumnIndex(editor, cellElement);
+ const defaultRowIndex = getTableRowIndex(editor, cellElement);
+ result = { col: defaultColIndex, row: defaultRowIndex };
+ }
+ const colIndex = result.col;
+ const rowIndex = result.row;
+
+ const endingRowIndex = rowIndex + rowSpan - 1;
+ const endingColIndex = colIndex + colSpan - 1;
+
const rowSize =
- rowSizeOverrides.get(rowIndex) ?? rowElement?.size ?? undefined;
+ rowSizeOverrides.get(endingRowIndex) ?? rowElement?.size ?? undefined;
const isFirstCell = colIndex === 0;
const isFirstRow = tableElement.children?.[0] === rowElement;
@@ -63,15 +126,16 @@ export const useTableCellElementState = ({
});
return {
- colIndex,
- rowIndex,
+ colIndex: endingColIndex,
+ rowIndex: endingRowIndex,
readOnly: !ignoreReadOnly && readOnly,
selected: isCellSelected,
- hovered: hoveredColIndex === colIndex,
+ hovered: hoveredColIndex === endingColIndex,
hoveredLeft: isFirstCell && hoveredColIndex === -1,
rowSize,
borders,
isSelectingCell: !!selectedCells,
+ colSpan,
};
};
@@ -89,6 +153,7 @@ export const useTableCellElement = ({
return {
props: {
colSpan: element.colSpan,
+ rowSpan: element.rowSpan,
},
};
};
diff --git a/packages/table/src/components/TableElement/useSelectedCells.ts b/packages/table/src/components/TableElement/useSelectedCells.ts
index 366b5cc164..b7f426c710 100644
--- a/packages/table/src/components/TableElement/useSelectedCells.ts
+++ b/packages/table/src/components/TableElement/useSelectedCells.ts
@@ -16,23 +16,38 @@ export const useSelectedCells = () => {
const editor = useEditorRef();
const [selectedCells, setSelectedCells] = useTableStore().use.selectedCells();
+ const setSelectedTable = useTableStore().set.selectedTable();
useEffect(() => {
- if (!selected || readOnly) setSelectedCells(null);
- }, [selected, editor, setSelectedCells, readOnly]);
+ if (!selected || readOnly) {
+ setSelectedCells(null);
+ setSelectedTable(null);
+ }
+ }, [selected, editor, setSelectedCells, readOnly, setSelectedTable]);
useEffect(() => {
if (readOnly) return;
+ const tableEntries = getTableGridAbove(editor, { format: 'table' });
const cellEntries = getTableGridAbove(editor, { format: 'cell' });
- if (cellEntries.length > 1) {
+ if (cellEntries?.length > 1) {
const cells = cellEntries.map((entry) => entry[0]);
+ const tables = tableEntries.map((entry) => entry[0]);
if (JSON.stringify(cells) !== JSON.stringify(selectedCells)) {
setSelectedCells(cells);
+ setSelectedTable(tables);
}
} else if (selectedCells) {
setSelectedCells(null);
+ setSelectedTable(null);
}
- }, [editor, editor?.selection, readOnly, selectedCells, setSelectedCells]);
+ }, [
+ editor,
+ editor.selection,
+ readOnly,
+ selectedCells,
+ setSelectedCells,
+ setSelectedTable,
+ ]);
};
diff --git a/packages/table/src/components/TableElement/useTableElement.ts b/packages/table/src/components/TableElement/useTableElement.ts
index e0d5b76765..694f098ffe 100644
--- a/packages/table/src/components/TableElement/useTableElement.ts
+++ b/packages/table/src/components/TableElement/useTableElement.ts
@@ -1,3 +1,4 @@
+import { useEffect } from 'react';
import {
collapseSelection,
getPluginOptions,
@@ -6,6 +7,7 @@ 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';
@@ -28,10 +30,8 @@ export const useTableElementState = ({
} = {}): TableElementState => {
const editor = useEditorRef();
- const { minColumnWidth, disableMarginLeft } = getPluginOptions(
- editor,
- ELEMENT_TABLE
- );
+ const { minColumnWidth, disableMarginLeft, enableMerging } =
+ getPluginOptions(editor, ELEMENT_TABLE);
const element = useElement();
const selectedCells = useTableStore().get.selectedCells();
@@ -43,6 +43,12 @@ export const useTableElementState = ({
let colSizes = useTableColSizes(element);
+ useEffect(() => {
+ if (enableMerging) {
+ computeAllCellIndices(editor, element);
+ }
+ }, [editor, element, enableMerging]);
+
if (transformColSizes) {
colSizes = transformColSizes(colSizes);
}
diff --git a/packages/table/src/constants.ts b/packages/table/src/constants.ts
index 1f876c4c97..38e37070b3 100644
--- a/packages/table/src/constants.ts
+++ b/packages/table/src/constants.ts
@@ -4,3 +4,5 @@ export const keyShiftEdges = {
'shift+down': 'bottom',
'shift+left': 'left',
};
+
+export const MIN_COLUMN_HEIGHT = 48;
diff --git a/packages/table/src/createTablePlugin.ts b/packages/table/src/createTablePlugin.ts
index 533f30ef13..9e1384ba0e 100644
--- a/packages/table/src/createTablePlugin.ts
+++ b/packages/table/src/createTablePlugin.ts
@@ -2,7 +2,7 @@ import { createPluginFactory } from '@udecode/plate-common';
import { onKeyDownTable } from './onKeyDownTable';
import { insertTableColumn, insertTableRow } from './transforms/index';
-import { TablePlugin } from './types';
+import { TablePlugin, TableStoreCellAttributes } from './types';
import { withTable } from './withTable';
export const ELEMENT_TABLE = 'table';
@@ -36,6 +36,8 @@ export const createTablePlugin = createPluginFactory({
});
},
minColumnWidth: 48,
+ enableMerging: false,
+ _cellIndices: new WeakMap() as TableStoreCellAttributes,
},
withOverrides: withTable,
plugins: [
diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts
index 81ea22f4b0..8821555967 100644
--- a/packages/table/src/index.ts
+++ b/packages/table/src/index.ts
@@ -19,3 +19,4 @@ export * from './queries/index';
export * from './stores/index';
export * from './transforms/index';
export * from './utils/index';
+export * from './merge/index';
diff --git a/packages/table/src/merge/computeCellIndices.ts b/packages/table/src/merge/computeCellIndices.ts
new file mode 100644
index 0000000000..57c727f86c
--- /dev/null
+++ b/packages/table/src/merge/computeCellIndices.ts
@@ -0,0 +1,89 @@
+import { getPluginOptions, PlateEditor, Value } from '@udecode/plate-common';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+
+export function computeCellIndices(
+ editor: PlateEditor,
+ tableEl: TTableElement,
+ cellEl: TTableCellElement
+) {
+ const options = getPluginOptions(editor, ELEMENT_TABLE);
+
+ const tableNodes = tableEl.children;
+
+ let rowIndex = -1;
+ let colIndex = -1;
+
+ for (let r = 0; r < tableNodes.length; r++) {
+ const row = tableNodes[r] as TTableRowElement;
+
+ let cIndex = 0;
+ for (let c = 0; c < row.children.length; c++) {
+ const cell = row.children[c] as TTableCellElement;
+ if (cellEl === cell) {
+ colIndex = cIndex;
+ rowIndex = r;
+ break;
+ }
+ cIndex += cell.colSpan || 1; // consider 0 and undefined as 1
+ }
+ }
+
+ tableNodes.slice(0, rowIndex).forEach((pR, _rowIndex) => {
+ const prevRow = pR as TTableRowElement;
+ prevRow.children.forEach((pC) => {
+ const prevCell = pC as TTableCellElement;
+ const prevIndices = options?._cellIndices?.get(prevCell);
+ if (prevIndices) {
+ const { col: prevColIndex } = prevIndices;
+ if (
+ // colIndex affects
+ prevColIndex <= colIndex &&
+ // rowSpan affects
+ prevCell.rowSpan &&
+ prevCell.rowSpan > 1 &&
+ rowIndex - _rowIndex < prevCell.rowSpan
+ ) {
+ colIndex += prevCell.colSpan || 1;
+ }
+ }
+ });
+ });
+
+ if (rowIndex === -1 || colIndex === -1) {
+ return null;
+ }
+
+ const indices = { row: rowIndex, col: colIndex };
+ options?._cellIndices?.set(cellEl, indices);
+
+ return indices;
+}
+
+export const computeAllCellIndices = (
+ editor: PlateEditor,
+ tableNode: TTableElement
+) => {
+ const options = getPluginOptions(editor, ELEMENT_TABLE);
+
+ // Iterate through the table rows
+ for (let r = 0; r < tableNode.children.length; r++) {
+ const row = tableNode.children[r] as TTableRowElement;
+
+ // Iterate through the row cells
+ for (let c = 0; c < row.children.length; c++) {
+ const cell = row.children[c] as TTableCellElement;
+
+ const indices = computeCellIndices(editor, tableNode, cell);
+ if (indices) {
+ options._cellIndices?.set(cell, indices);
+ }
+ }
+ }
+};
diff --git a/packages/table/src/merge/createEmptyCell.ts b/packages/table/src/merge/createEmptyCell.ts
new file mode 100644
index 0000000000..d9fd8c7ffd
--- /dev/null
+++ b/packages/table/src/merge/createEmptyCell.ts
@@ -0,0 +1,30 @@
+import {
+ getPluginType,
+ PlateEditor,
+ TDescendant,
+ TElement,
+ Value,
+} from '@udecode/plate-common';
+
+import { ELEMENT_TH } from '../createTablePlugin';
+import { TTableRowElement } from '../types';
+import { getEmptyCellNode } from '../utils';
+
+export const createEmptyCell = (
+ editor: PlateEditor,
+ row: TTableRowElement,
+ newCellChildren?: TDescendant[],
+ header?: boolean
+) => {
+ const isHeaderRow =
+ header === undefined
+ ? (row as TElement).children.every(
+ (c) => c.type === getPluginType(editor, ELEMENT_TH)
+ )
+ : header;
+
+ return getEmptyCellNode(editor, {
+ header: isHeaderRow,
+ newCellChildren,
+ });
+};
diff --git a/packages/table/src/merge/deleteColumn.ts b/packages/table/src/merge/deleteColumn.ts
new file mode 100644
index 0000000000..7b466576de
--- /dev/null
+++ b/packages/table/src/merge/deleteColumn.ts
@@ -0,0 +1,195 @@
+import {
+ getAboveNode,
+ getPluginOptions,
+ getPluginType,
+ PlateEditor,
+ removeNodes,
+ setNodes,
+ someNode,
+ Value,
+ withoutNormalizing,
+} from '@udecode/plate-common';
+import { Path } from 'slate';
+
+import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
+import { getColSpan } from '../queries/getColSpan';
+import { TablePlugin, TTableCellElement, TTableElement } from '../types';
+import { getCellTypes } from '../utils';
+import { findCellByIndexes } from './findCellByIndexes';
+import { getCellIndices } from './getCellIndices';
+import { getCellPath } from './getCellPath';
+
+export const deleteTableMergeColumn = (
+ editor: PlateEditor
+) => {
+ if (
+ someNode(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ })
+ ) {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const tableEntry = getAboveNode(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ });
+ if (!tableEntry) return;
+ const table = tableEntry[0] as TTableElement;
+
+ const selectedCellEntry = getAboveNode(editor, {
+ match: {
+ type: getCellTypes(editor),
+ },
+ });
+ if (!selectedCellEntry) return;
+ const selectedCell = selectedCellEntry[0] as TTableCellElement;
+
+ const { col: deletingColIndex } = getCellIndices(
+ cellIndices!,
+ selectedCell
+ )!;
+ const colsDeleteNumber = getColSpan(selectedCell);
+
+ const endingColIndex = deletingColIndex + colsDeleteNumber - 1;
+
+ const rowNumber = table.children.length;
+ const affectedCellsSet = new Set();
+ // iterating by rows is important here to keep the order of affected cells
+ Array.from({ length: rowNumber }, (_, i) => i).forEach((rI) => {
+ return Array.from({ length: colsDeleteNumber }, (_, i) => i).forEach(
+ (cI) => {
+ const colIndex = deletingColIndex + cI;
+ const found = findCellByIndexes(editor, table, rI, colIndex);
+ if (found) {
+ affectedCellsSet.add(found);
+ }
+ }
+ );
+ });
+ const affectedCells = Array.from(affectedCellsSet) as TTableCellElement[];
+
+ const { squizeColSpanCells } = affectedCells.reduce<{
+ squizeColSpanCells: TTableCellElement[];
+ }>(
+ (acc, cur) => {
+ if (!cur) return acc;
+
+ const currentCell = cur as TTableCellElement;
+ const { col: curColIndex } = getCellIndices(cellIndices!, currentCell)!;
+ const curColSpan = getColSpan(currentCell);
+
+ if (curColIndex < deletingColIndex && curColSpan > 1) {
+ acc.squizeColSpanCells.push(currentCell);
+ } else if (
+ curColSpan > 1 &&
+ curColIndex + curColSpan - 1 > endingColIndex
+ ) {
+ acc.squizeColSpanCells.push(currentCell);
+ }
+ return acc;
+ },
+ { squizeColSpanCells: [] }
+ );
+
+ /**
+ * Change colSpans
+ */
+ squizeColSpanCells.forEach((cur) => {
+ const curCell = cur as TTableCellElement;
+
+ const { col: curColIndex, row: curColRowIndex } = getCellIndices(
+ cellIndices!,
+ curCell
+ )!;
+ const curColSpan = getColSpan(curCell);
+
+ const curCellPath = getCellPath(
+ editor,
+ tableEntry,
+ curColRowIndex,
+ curColIndex
+ );
+
+ const curCellEndingColIndex = Math.min(
+ curColIndex + curColSpan - 1,
+ endingColIndex
+ );
+ const colsNumberAffected = curCellEndingColIndex - deletingColIndex + 1;
+
+ setNodes(
+ editor,
+ { ...curCell, colSpan: curColSpan - colsNumberAffected },
+ { at: curCellPath }
+ );
+ });
+
+ const trEntry = getAboveNode(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TR) },
+ });
+
+ /**
+ * Remove cells
+ */
+ if (
+ selectedCell &&
+ trEntry &&
+ tableEntry &&
+ // Cannot delete the last cell
+ trEntry[0].children.length > 1
+ ) {
+ const [tableNode, tablePath] = tableEntry;
+
+ // calc paths to delete
+ const paths: Array = [];
+ affectedCells.forEach((cur) => {
+ const curCell = cur as TTableCellElement;
+ const { col: curColIndex, row: curRowIndex } = getCellIndices(
+ cellIndices!,
+ curCell
+ )!;
+ if (
+ !squizeColSpanCells.includes(curCell) &&
+ curColIndex >= deletingColIndex &&
+ curColIndex <= endingColIndex
+ ) {
+ const cellPath = getCellPath(
+ editor,
+ tableEntry,
+ curRowIndex,
+ curColIndex
+ );
+
+ if (!paths[curRowIndex]) {
+ paths[curRowIndex] = [];
+ }
+ paths[curRowIndex].push(cellPath);
+ }
+ });
+
+ withoutNormalizing(editor, () => {
+ paths.forEach((cellPaths) => {
+ const pathToDelete = cellPaths[0];
+ cellPaths.forEach(() => {
+ removeNodes(editor, {
+ at: pathToDelete,
+ });
+ });
+ });
+
+ const { colSizes } = tableNode;
+ if (colSizes) {
+ const newColSizes = [...colSizes];
+ newColSizes.splice(deletingColIndex, 1);
+
+ setNodes(
+ editor,
+ { colSizes: newColSizes },
+ { at: tablePath }
+ );
+ }
+ });
+ }
+ }
+};
diff --git a/packages/table/src/merge/deleteRow.ts b/packages/table/src/merge/deleteRow.ts
new file mode 100644
index 0000000000..33155bd639
--- /dev/null
+++ b/packages/table/src/merge/deleteRow.ts
@@ -0,0 +1,189 @@
+import {
+ findNodePath,
+ getAboveNode,
+ getPluginOptions,
+ getPluginType,
+ insertElements,
+ PlateEditor,
+ removeNodes,
+ setNodes,
+ someNode,
+ Value,
+} from '@udecode/plate-common';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { getTableColumnCount } from '../queries';
+import { getRowSpan } from '../queries/getRowSpan';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+import { getCellTypes } from '../utils';
+import { findCellByIndexes } from './findCellByIndexes';
+import { getCellIndices } from './getCellIndices';
+
+export const deleteTableMergeRow = (
+ editor: PlateEditor
+) => {
+ if (
+ someNode(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ })
+ ) {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const currentTableItem = getAboveNode(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ });
+ if (!currentTableItem) return;
+ const table = currentTableItem[0] as TTableElement;
+
+ const selectedCellEntry = getAboveNode(editor, {
+ match: { type: getCellTypes(editor) },
+ });
+ if (!selectedCellEntry) return;
+
+ const selectedCell = selectedCellEntry[0] as TTableCellElement;
+ const { row: deletingRowIndex } = getCellIndices(
+ cellIndices!,
+ selectedCell
+ )!;
+ const rowsDeleteNumber = getRowSpan(selectedCell);
+ const endingRowIndex = deletingRowIndex + rowsDeleteNumber - 1;
+
+ const colNumber = getTableColumnCount(table);
+ const affectedCellsSet = new Set();
+ // iterating by columns is important here to keep the order of affected cells
+ Array.from({ length: colNumber }, (_, i) => i).forEach((cI) => {
+ return Array.from({ length: rowsDeleteNumber }, (_, i) => i).forEach(
+ (rI) => {
+ const rowIndex = deletingRowIndex + rI;
+ const found = findCellByIndexes(editor, table, rowIndex, cI);
+ affectedCellsSet.add(found);
+ }
+ );
+ });
+ const affectedCells = Array.from(affectedCellsSet) as TTableCellElement[];
+
+ const { moveToNextRowCells, squizeRowSpanCells } = affectedCells.reduce<{
+ squizeRowSpanCells: TTableCellElement[];
+ moveToNextRowCells: TTableCellElement[];
+ }>(
+ (acc, cur) => {
+ if (!cur) return acc;
+
+ const currentCell = cur as TTableCellElement;
+ const { row: curRowIndex } = getCellIndices(cellIndices!, currentCell)!;
+ const curRowSpan = getRowSpan(currentCell);
+
+ // if (!curRowIndex || !curRowSpan) return acc;
+
+ if (curRowIndex < deletingRowIndex && curRowSpan > 1) {
+ acc.squizeRowSpanCells.push(currentCell);
+ } else if (
+ curRowSpan > 1 &&
+ curRowIndex + curRowSpan - 1 > endingRowIndex
+ ) {
+ acc.moveToNextRowCells.push(currentCell);
+ }
+
+ return acc;
+ },
+ { squizeRowSpanCells: [], moveToNextRowCells: [] }
+ );
+
+ const nextRowIndex = deletingRowIndex + rowsDeleteNumber;
+ const nextRow = table.children[nextRowIndex] as
+ | TTableCellElement
+ | undefined;
+
+ if (nextRow) {
+ moveToNextRowCells.forEach((cur, index) => {
+ const curRowCell = cur as TTableCellElement;
+ const { col: curRowCellColIndex } = getCellIndices(
+ cellIndices!,
+ curRowCell
+ )!;
+ const curRowCellRowSpan = getRowSpan(curRowCell);
+
+ // search for anchor cell where to place current cell
+ const startingCellIndex = nextRow.children.findIndex((curC) => {
+ const cell = curC as TTableCellElement;
+ const { col: curColIndex } = getCellIndices(cellIndices!, cell)!;
+ return curColIndex >= curRowCellColIndex;
+ });
+
+ const startingCell = nextRow.children[
+ startingCellIndex
+ ] as TTableCellElement;
+ const { col: startingColIndex } = getCellIndices(
+ cellIndices!,
+ startingCell
+ )!;
+
+ // consider already inserted cell by adding index each time to the col path
+ let incrementBy = index;
+ if (startingColIndex < curRowCellColIndex) {
+ // place current cell after starting cell, if placing cell col index is grather than col index of starting cell
+ incrementBy += 1;
+ }
+
+ const startingCellPath = findNodePath(editor, startingCell)!;
+ const tablePath = startingCellPath.slice(0, -2);
+ const colPath = startingCellPath.at(-1)!;
+
+ const nextRowStartCellPath = [
+ ...tablePath,
+ nextRowIndex,
+ colPath + incrementBy,
+ ];
+
+ const rowsNumberAffected = endingRowIndex - curRowCellColIndex + 1;
+
+ // TODO: consider make deep clone here
+ // making cell smaller and moving it to next row
+ const newCell = {
+ ...curRowCell,
+ rowSpan: curRowCellRowSpan - rowsNumberAffected,
+ };
+ insertElements(editor, newCell, { at: nextRowStartCellPath });
+ });
+ }
+
+ squizeRowSpanCells.forEach((cur) => {
+ const curRowCell = cur as TTableCellElement;
+ const { row: curRowCellRowIndex } = getCellIndices(
+ cellIndices!,
+ curRowCell
+ )!;
+ const curRowCellRowSpan = getRowSpan(curRowCell);
+
+ const curCellPath = findNodePath(editor, curRowCell)!;
+
+ const curCellEndingRowIndex = Math.min(
+ curRowCellRowIndex + curRowCellRowSpan - 1,
+ endingRowIndex
+ );
+ const rowsNumberAffected = curCellEndingRowIndex - deletingRowIndex + 1;
+
+ setNodes(
+ editor,
+ { ...curRowCell, rowSpan: curRowCellRowSpan - rowsNumberAffected },
+ { at: curCellPath }
+ );
+ });
+
+ const rowToDelete = table.children[deletingRowIndex] as TTableRowElement;
+ const rowPath = findNodePath(editor, rowToDelete);
+ Array.from({ length: rowsDeleteNumber }).forEach(() => {
+ removeNodes(editor, {
+ at: rowPath,
+ });
+ });
+ }
+};
diff --git a/packages/table/src/merge/findCellByIndexes.ts b/packages/table/src/merge/findCellByIndexes.ts
new file mode 100644
index 0000000000..aeb0f352e5
--- /dev/null
+++ b/packages/table/src/merge/findCellByIndexes.ts
@@ -0,0 +1,50 @@
+import { getPluginOptions, PlateEditor, Value } from '@udecode/plate-common';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { getCellIndices } from '../merge/getCellIndices';
+import { TablePlugin, TTableCellElement, TTableElement } from '../types';
+import { computeCellIndices } from './computeCellIndices';
+import { getCellIndicesWithSpans } from './getCellIndicesWithSpans';
+
+export const findCellByIndexes = (
+ editor: PlateEditor,
+ table: TTableElement,
+ searchRowIndex: number,
+ searchColIndex: number
+) => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const allCells = table.children.flatMap(
+ (current) => current.children
+ ) as TTableCellElement[];
+
+ const foundCell = allCells.find((cell) => {
+ const cellElement = cell as TTableCellElement;
+
+ const indices =
+ getCellIndices(cellIndices!, cellElement) ||
+ computeCellIndices(editor, table, cellElement)!;
+
+ const { col: _startColIndex, row: _startRowIndex } = indices;
+ const { row: _endRowIndex, col: _endColIndex } = getCellIndicesWithSpans(
+ indices,
+ cellElement
+ );
+
+ if (
+ searchColIndex >= _startColIndex &&
+ searchColIndex <= _endColIndex &&
+ searchRowIndex >= _startRowIndex &&
+ searchRowIndex <= _endRowIndex
+ ) {
+ return true;
+ }
+
+ return false;
+ });
+
+ return foundCell;
+};
diff --git a/packages/table/src/merge/getCellIndices.ts b/packages/table/src/merge/getCellIndices.ts
new file mode 100644
index 0000000000..f690cf2cbe
--- /dev/null
+++ b/packages/table/src/merge/getCellIndices.ts
@@ -0,0 +1,9 @@
+import { TableStoreCellAttributes, TTableCellElement } from '../types';
+
+export const getCellIndices = (
+ cellIndices: TableStoreCellAttributes,
+ startCell: TTableCellElement
+) => {
+ // optional typing needs for tests
+ return cellIndices?.get(startCell);
+};
diff --git a/packages/table/src/merge/getCellIndicesWithSpans.ts b/packages/table/src/merge/getCellIndicesWithSpans.ts
new file mode 100644
index 0000000000..c3175eaf2b
--- /dev/null
+++ b/packages/table/src/merge/getCellIndicesWithSpans.ts
@@ -0,0 +1,13 @@
+import { getColSpan } from '../queries/getColSpan';
+import { getRowSpan } from '../queries/getRowSpan';
+import { TTableCellElement } from '../types';
+
+export const getCellIndicesWithSpans = (
+ { col, row }: { col: number; row: number },
+ endCell: TTableCellElement
+) => {
+ return {
+ row: row + getRowSpan(endCell) - 1,
+ col: col + getColSpan(endCell) - 1,
+ };
+};
diff --git a/packages/table/src/merge/getCellPath.ts b/packages/table/src/merge/getCellPath.ts
new file mode 100644
index 0000000000..63d07325b3
--- /dev/null
+++ b/packages/table/src/merge/getCellPath.ts
@@ -0,0 +1,36 @@
+import {
+ getPluginOptions,
+ PlateEditor,
+ TNodeEntry,
+ Value,
+} from '@udecode/plate-common';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+import { getCellIndices } from './getCellIndices';
+
+export const getCellPath = (
+ editor: PlateEditor,
+ tableEntry: TNodeEntry,
+ curRowIndex: number,
+ curColIndex: number
+) => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ const [tableNode, tablePath] = tableEntry;
+
+ const rowElem = tableNode.children[curRowIndex] as TTableRowElement;
+ const foundColIndex = rowElem.children.findIndex((c) => {
+ const cE = c as TTableCellElement;
+ const { col: colIndex } = getCellIndices(cellIndices!, cE)!;
+ return colIndex === curColIndex;
+ });
+ return tablePath.concat([curRowIndex, foundColIndex]);
+};
diff --git a/packages/table/src/merge/getTableGridByRange.ts b/packages/table/src/merge/getTableGridByRange.ts
new file mode 100644
index 0000000000..f832fb170c
--- /dev/null
+++ b/packages/table/src/merge/getTableGridByRange.ts
@@ -0,0 +1,164 @@
+import {
+ findNode,
+ findNodePath,
+ getPluginOptions,
+ getPluginType,
+ PlateEditor,
+ TElement,
+ TElementEntry,
+ Value,
+} from '@udecode/plate-common';
+import { Range } from 'slate';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { computeCellIndices } from '../merge/computeCellIndices';
+import { findCellByIndexes } from '../merge/findCellByIndexes';
+import { getCellIndices } from '../merge/getCellIndices';
+import { getCellIndicesWithSpans } from '../merge/getCellIndicesWithSpans';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+import { getCellTypes } from '../utils';
+import { getEmptyTableNode } from '../utils/getEmptyTableNode';
+
+export type FormatType = 'table' | 'cell' | 'all';
+
+export interface TableGridEntries {
+ tableEntries: TElementEntry[];
+ cellEntries: TElementEntry[];
+}
+
+export type GetTableGridReturnType = T extends 'all'
+ ? TableGridEntries
+ : TElementEntry[];
+
+export interface GetTableGridByRangeOptions {
+ at: Range;
+
+ /**
+ * Format of the output:
+ * - table element
+ * - array of cells
+ */
+ format?: T;
+}
+
+/**
+ * Get sub table between 2 cell paths.
+ */
+export const getTableMergeGridByRange = (
+ editor: PlateEditor,
+ { at, format }: GetTableGridByRangeOptions
+): GetTableGridReturnType => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const startCellEntry = findNode(editor, {
+ at: (at as any).anchor.path,
+ match: { type: getCellTypes(editor) },
+ })!; // TODO: improve typing
+ const endCellEntry = findNode(editor, {
+ at: (at as any).focus.path,
+ match: { type: getCellTypes(editor) },
+ })!;
+
+ const startCell = startCellEntry[0] as TTableCellElement;
+ const endCell = endCellEntry[0] as TTableCellElement;
+
+ const startCellPath = (at as any).anchor.path;
+ const tablePath = startCellPath.slice(0, -2);
+
+ const tableEntry = findNode(editor, {
+ at: tablePath,
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ })!; // TODO: improve typing
+ const realTable = tableEntry[0] as TTableElement;
+
+ const { col: _startColIndex, row: _startRowIndex } =
+ getCellIndices(cellIndices!, startCell) ||
+ computeCellIndices(editor, realTable, startCell)!;
+
+ const { row: _endRowIndex, col: _endColIndex } = getCellIndicesWithSpans(
+ getCellIndices(cellIndices!, endCell) ||
+ computeCellIndices(editor, realTable, endCell)!,
+ endCell
+ );
+
+ const startRowIndex = Math.min(_startRowIndex, _endRowIndex);
+ const endRowIndex = Math.max(_startRowIndex, _endRowIndex);
+ const startColIndex = Math.min(_startColIndex, _endColIndex);
+ const endColIndex = Math.max(_startColIndex, _endColIndex);
+
+ const relativeRowIndex = endRowIndex - startRowIndex;
+ const relativeColIndex = endColIndex - startColIndex;
+
+ const table: TTableElement = getEmptyTableNode(editor, {
+ rowCount: relativeRowIndex + 1,
+ colCount: relativeColIndex + 1,
+ newCellChildren: [],
+ });
+
+ const cellEntries: TElementEntry[] = [];
+ const cellsSet = new WeakSet();
+
+ let rowIndex = startRowIndex;
+ let colIndex = startColIndex;
+ while (true) {
+ const cell = findCellByIndexes(editor, realTable, rowIndex, colIndex);
+ if (!cell) {
+ break;
+ }
+
+ if (!cellsSet.has(cell)) {
+ cellsSet.add(cell);
+
+ const rows = table.children[rowIndex - startRowIndex]
+ .children as TElement[];
+ rows[colIndex - startColIndex] = cell;
+
+ const cellPath = findNodePath(editor, cell)!;
+ cellEntries.push([cell, cellPath]);
+ }
+
+ if (colIndex + 1 <= endColIndex) {
+ colIndex = colIndex + 1;
+ } else if (rowIndex + 1 <= endRowIndex) {
+ colIndex = startColIndex;
+ rowIndex = rowIndex + 1;
+ } else {
+ break;
+ }
+ }
+
+ const formatType = (format as string) || 'table';
+
+ if (formatType === 'cell') {
+ return cellEntries as GetTableGridReturnType;
+ }
+
+ // clear redundant cells
+ table.children?.forEach((rowEl) => {
+ const rowElement = rowEl as TTableRowElement;
+
+ const filteredChildren = rowElement.children?.filter((cellEl) => {
+ const cellElement = cellEl as TTableCellElement;
+ return !!cellElement?.children.length;
+ });
+
+ rowElement.children = filteredChildren;
+ });
+
+ if (formatType === 'table') {
+ return [[table, tablePath]] as GetTableGridReturnType;
+ }
+
+ return {
+ tableEntries: [[table, tablePath]],
+ cellEntries,
+ } as GetTableGridReturnType;
+};
diff --git a/packages/table/src/merge/index.ts b/packages/table/src/merge/index.ts
new file mode 100644
index 0000000000..099e84d8fd
--- /dev/null
+++ b/packages/table/src/merge/index.ts
@@ -0,0 +1,7 @@
+/**
+ * @file Automatically generated by barrelsby.
+ */
+
+export * from './mergeTableCells';
+export * from './unmergeTableCells';
+export * from './useTableMergeState';
diff --git a/packages/table/src/merge/insertTableColumn.ts b/packages/table/src/merge/insertTableColumn.ts
new file mode 100644
index 0000000000..aa4aad98bc
--- /dev/null
+++ b/packages/table/src/merge/insertTableColumn.ts
@@ -0,0 +1,202 @@
+import {
+ findNode,
+ getBlockAbove,
+ getParentNode,
+ getPluginOptions,
+ getPluginType,
+ insertElements,
+ PlateEditor,
+ setNodes,
+ Value,
+ withoutNormalizing,
+} from '@udecode/plate-common';
+import { Path } from 'slate';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { getColSpan } from '../queries/getColSpan';
+import { getRowSpan } from '../queries/getRowSpan';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+import { getCellTypes } from '../utils';
+import { createEmptyCell } from './createEmptyCell';
+import { findCellByIndexes } from './findCellByIndexes';
+import { getCellIndices } from './getCellIndices';
+import { getCellPath } from './getCellPath';
+
+export const insertTableMergeColumn = (
+ editor: PlateEditor,
+ {
+ disableSelect,
+ fromCell,
+ at,
+ header,
+ }: {
+ header?: boolean;
+
+ /**
+ * Path of the cell to insert the column from.
+ */
+ fromCell?: Path;
+
+ /**
+ * Exact path of the cell to insert the column at.
+ * Will overrule `fromCell`.
+ */
+ at?: Path;
+
+ /**
+ * Disable selection after insertion.
+ */
+ disableSelect?: boolean;
+ } = {}
+) => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const cellEntry = fromCell
+ ? findNode(editor, {
+ at: fromCell,
+ match: { type: getCellTypes(editor) },
+ })
+ : getBlockAbove(editor, {
+ match: { type: getCellTypes(editor) },
+ });
+ if (!cellEntry) return;
+
+ const [, cellPath] = cellEntry;
+ const cell = cellEntry[0] as TTableCellElement;
+
+ const tableEntry = getBlockAbove(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ at: cellPath,
+ });
+ if (!tableEntry) return;
+
+ const { newCellChildren, initialTableWidth, minColumnWidth } =
+ getPluginOptions(editor, ELEMENT_TABLE);
+ const [tableNode, tablePath] = tableEntry;
+
+ const { col: cellColIndex } = getCellIndices(cellIndices!, cell)!;
+ const cellColSpan = getColSpan(cell);
+
+ let nextColIndex: number;
+ let checkingColIndex: number;
+ if (Path.isPath(at)) {
+ nextColIndex = cellColIndex;
+ checkingColIndex = cellColIndex - 1;
+ } else {
+ nextColIndex = cellColIndex + cellColSpan;
+ checkingColIndex = cellColIndex + cellColSpan - 1;
+ }
+
+ const rowNumber = tableNode.children.length;
+ const firstCol = nextColIndex <= 0;
+
+ // const colCount = getTableColumnCount(tableNode);
+ // const lastRow = nextColIndex === colCount;
+
+ let placementCorrection = 1;
+ if (firstCol) {
+ checkingColIndex = 0;
+ placementCorrection = 0;
+ }
+
+ const affectedCellsSet = new Set();
+ Array.from({ length: rowNumber }, (_, i) => i).forEach((rI) => {
+ const found = findCellByIndexes(editor, tableNode, rI, checkingColIndex);
+ if (found) {
+ affectedCellsSet.add(found);
+ }
+ });
+ const affectedCells = Array.from(affectedCellsSet) as TTableCellElement[];
+
+ affectedCells.forEach((cur) => {
+ const curCell = cur as TTableCellElement;
+ const { row: curRowIndex, col: curColIndex } = getCellIndices(
+ cellIndices!,
+ curCell
+ )!;
+ const curRowSpan = getRowSpan(curCell);
+ const curColSpan = getColSpan(curCell);
+
+ const currentCellPath = getCellPath(
+ editor,
+ tableEntry,
+ curRowIndex,
+ curColIndex
+ );
+
+ const endCurI = curColIndex + curColSpan - 1;
+ if (endCurI >= nextColIndex && !firstCol) {
+ // make wider
+ setNodes(
+ editor,
+ { ...curCell, colSpan: curColSpan + 1 },
+ { at: currentCellPath }
+ );
+ } else {
+ // add new
+ const curRowPath = currentCellPath.slice(0, -1);
+ const curColPath = currentCellPath.at(-1)!;
+ const placementPath = [...curRowPath, curColPath + placementCorrection];
+
+ const row = getParentNode(editor, currentCellPath)!;
+ const rowElement = row[0] as TTableRowElement;
+ const emptyCell = {
+ ...createEmptyCell(editor, rowElement, newCellChildren, header),
+ rowSpan: curRowSpan,
+ colSpan: 1,
+ };
+ insertElements(editor, emptyCell, {
+ at: placementPath,
+ // select: !disableSelect && curRowIndex === currentRowIndex,
+ });
+ }
+ });
+
+ withoutNormalizing(editor, () => {
+ const { colSizes } = tableNode;
+
+ if (colSizes) {
+ let newColSizes = [
+ ...colSizes.slice(0, nextColIndex),
+ 0,
+ ...colSizes.slice(nextColIndex),
+ ];
+
+ if (initialTableWidth) {
+ newColSizes[nextColIndex] =
+ colSizes[nextColIndex] ??
+ colSizes[nextColIndex - 1] ??
+ initialTableWidth / colSizes.length;
+
+ const oldTotal = colSizes.reduce((a, b) => a + b, 0);
+ const newTotal = newColSizes.reduce((a, b) => a + b, 0);
+ const maxTotal = Math.max(oldTotal, initialTableWidth);
+
+ if (newTotal > maxTotal) {
+ const factor = maxTotal / newTotal;
+ newColSizes = newColSizes.map((size) =>
+ Math.max(minColumnWidth ?? 0, Math.floor(size * factor))
+ );
+ }
+ }
+
+ setNodes(
+ editor,
+ {
+ colSizes: newColSizes,
+ },
+ {
+ at: tablePath,
+ }
+ );
+ }
+ });
+};
diff --git a/packages/table/src/merge/insertTableRow.ts b/packages/table/src/merge/insertTableRow.ts
new file mode 100644
index 0000000000..6731e159f6
--- /dev/null
+++ b/packages/table/src/merge/insertTableRow.ts
@@ -0,0 +1,177 @@
+import {
+ findNode,
+ getBlockAbove,
+ getParentNode,
+ getPluginOptions,
+ getPluginType,
+ insertElements,
+ PlateEditor,
+ setNodes,
+ Value,
+ withoutNormalizing,
+} from '@udecode/plate-common';
+import { Path } from 'slate';
+
+import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
+import { getTableColumnCount } from '../queries';
+import { getColSpan } from '../queries/getColSpan';
+import { getRowSpan } from '../queries/getRowSpan';
+import {
+ TablePlugin,
+ TTableCellElement,
+ TTableElement,
+ TTableRowElement,
+} from '../types';
+import { getCellTypes } from '../utils';
+import { createEmptyCell } from './createEmptyCell';
+import { findCellByIndexes } from './findCellByIndexes';
+import { getCellIndices } from './getCellIndices';
+import { getCellPath } from './getCellPath';
+
+export const insertTableMergeRow = (
+ editor: PlateEditor,
+ {
+ header,
+ fromRow,
+ at,
+ disableSelect,
+ }: {
+ header?: boolean;
+ fromRow?: Path;
+ /**
+ * Exact path of the row to insert the column at.
+ * Will overrule `fromRow`.
+ */
+ at?: Path;
+ disableSelect?: boolean;
+ } = {}
+) => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const trEntry = fromRow
+ ? findNode(editor, {
+ at: fromRow,
+ match: { type: getPluginType(editor, ELEMENT_TR) },
+ })
+ : getBlockAbove(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TR) },
+ });
+ if (!trEntry) return;
+
+ const [, trPath] = trEntry;
+
+ const tableEntry = getBlockAbove(editor, {
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ at: trPath,
+ });
+ if (!tableEntry) return;
+ const tableNode = tableEntry[0] as TTableElement;
+
+ const { newCellChildren } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ const cellEntry = findNode(editor, {
+ at: fromRow,
+ match: { type: getCellTypes(editor) },
+ });
+ if (!cellEntry) return;
+ const [cellNode, cellPath] = cellEntry;
+ const cellElement = cellNode as TTableCellElement;
+ const cellRowSpan = getRowSpan(cellElement);
+ const { row: cellRowIndex } = getCellIndices(cellIndices!, cellElement)!;
+
+ const rowPath = cellPath.at(-2)!;
+ const tablePath = cellPath.slice(0, -2)!;
+
+ let nextRowIndex: number;
+ let checkingRowIndex: number;
+ let nextRowPath: number[];
+ if (Path.isPath(at)) {
+ nextRowIndex = at.at(-1)!;
+ checkingRowIndex = cellRowIndex - 1;
+ nextRowPath = at;
+ } else {
+ nextRowIndex = cellRowIndex + cellRowSpan;
+ checkingRowIndex = cellRowIndex + cellRowSpan - 1;
+ nextRowPath = [...tablePath, rowPath + cellRowSpan];
+ }
+
+ const firstRow = nextRowIndex === 0;
+ if (firstRow) {
+ checkingRowIndex = 0;
+ }
+
+ const colCount = getTableColumnCount(tableNode);
+ const affectedCellsSet = new Set();
+ Array.from({ length: colCount }, (_, i) => i).forEach((cI) => {
+ const found = findCellByIndexes(editor, tableNode, checkingRowIndex, cI);
+ if (found) {
+ affectedCellsSet.add(found);
+ }
+ });
+ const affectedCells = Array.from(affectedCellsSet) as TTableCellElement[];
+
+ const newRowChildren: TTableCellElement[] = [];
+ affectedCells.forEach((cur) => {
+ if (!cur) return;
+
+ const curCell = cur as TTableCellElement;
+ const { row: curRowIndex, col: curColIndex } = getCellIndices(
+ cellIndices!,
+ curCell
+ )!;
+
+ const curRowSpan = getRowSpan(curCell);
+ const curColSpan = getColSpan(curCell);
+ const currentCellPath = getCellPath(
+ editor,
+ tableEntry,
+ curRowIndex,
+ curColIndex
+ );
+
+ const endCurI = curRowIndex + curRowSpan - 1;
+ if (endCurI >= nextRowIndex && !firstRow) {
+ // make higher
+ setNodes(
+ editor,
+ { ...curCell, rowSpan: curRowSpan + 1 },
+ { at: currentCellPath }
+ );
+ } else {
+ // add new
+ const row = getParentNode(editor, currentCellPath)!;
+ const rowElement = row[0] as TTableRowElement;
+ const emptyCell = createEmptyCell(
+ editor,
+ rowElement,
+ newCellChildren,
+ header
+ ) as TTableCellElement;
+
+ newRowChildren.push({
+ ...emptyCell,
+ colSpan: curColSpan,
+ rowSpan: 1,
+ });
+ }
+ });
+
+ withoutNormalizing(editor, () => {
+ insertElements(
+ editor,
+ {
+ type: getPluginType(editor, ELEMENT_TR),
+ children: newRowChildren,
+ },
+ {
+ at: nextRowPath,
+ // select: !disableSelect
+ }
+ );
+ });
+};
diff --git a/packages/table/src/merge/isTableRectangular.ts b/packages/table/src/merge/isTableRectangular.ts
new file mode 100644
index 0000000000..ff3b216712
--- /dev/null
+++ b/packages/table/src/merge/isTableRectangular.ts
@@ -0,0 +1,28 @@
+import { TTableCellElement, TTableElement, TTableRowElement } from '../types';
+
+const allEqual = (arr: number[]) => arr.every((val) => val === arr[0]);
+
+/**
+ * Checks if the given table is rectangular, meaning all rows have the same effective number of cells, considering colspan and rowspan.
+ */
+export const isTableRectangular = (table?: TTableElement) => {
+ const arr: number[] = [];
+ table?.children?.forEach((row, rI) => {
+ const rowEl = row as TTableRowElement;
+
+ rowEl.children?.forEach((cell) => {
+ const cellElem = cell as TTableCellElement;
+
+ Array.from({
+ length: cellElem?.rowSpan || 1,
+ } as ArrayLike).forEach((_, i) => {
+ if (!arr[rI + i]) {
+ arr[rI + i] = 0;
+ }
+ arr[rI + i] += cellElem?.colSpan || 1;
+ });
+ });
+ });
+
+ return allEqual(arr);
+};
diff --git a/packages/table/src/merge/mergeTableCells.ts b/packages/table/src/merge/mergeTableCells.ts
new file mode 100644
index 0000000000..18b88d0ab5
--- /dev/null
+++ b/packages/table/src/merge/mergeTableCells.ts
@@ -0,0 +1,115 @@
+import {
+ getBlockAbove,
+ getPluginOptions,
+ getPluginType,
+ insertElements,
+ PlateEditor,
+ removeNodes,
+ Value,
+ withoutNormalizing,
+} from '@udecode/plate-common';
+import { cloneDeep } from 'lodash';
+
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { getTableGridAbove } from '../queries';
+import { getColSpan } from '../queries/getColSpan';
+import { getRowSpan } from '../queries/getRowSpan';
+import { TablePlugin, TTableCellElement, TTableElement } from '../types';
+import { getEmptyCellNode } from '../utils';
+import { computeCellIndices } from './computeCellIndices';
+import { getCellIndices } from './getCellIndices';
+
+/**
+ * Merges multiple selected cells into one.
+ */
+export const mergeTableCells = (
+ editor: PlateEditor
+) => {
+ withoutNormalizing(editor, () => {
+ const { _cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ const tableEntry = getBlockAbove(editor, {
+ at: editor.selection?.anchor.path,
+ match: { type: getPluginType(editor, ELEMENT_TABLE) },
+ })!;
+
+ const cellEntries = getTableGridAbove(editor, { format: 'cell' });
+
+ // calculate the colSpan which is the number of horizontal cells that a cell should span.
+ let colSpan = 0;
+ for (const entry of cellEntries) {
+ const [data, path] = entry;
+
+ // count only those cells that are in the first selected row.
+ if (path[1] === cellEntries[0][1][1]) {
+ const cellColSpan = getColSpan(data as TTableCellElement);
+ colSpan += cellColSpan;
+ }
+ }
+
+ // calculate the rowSpan which is the number of vertical cells that a cell should span.
+ let rowSpan = 0;
+ const { col } = getCellIndices(
+ _cellIndices!,
+ cellEntries[0][0] as TTableCellElement
+ )!;
+ cellEntries.forEach((cE) => {
+ const cell = cE[0] as TTableCellElement;
+ const { col: curCol } =
+ _cellIndices?.get(cell) ||
+ computeCellIndices(editor, tableEntry[0] as TTableElement, cell)!;
+ if (col === curCol) {
+ rowSpan += getRowSpan(cell);
+ }
+ });
+
+ // This will store the content of all cells we are merging
+ const contents = [];
+ for (const cellEntry of cellEntries) {
+ const [el] = cellEntry;
+ contents.push(...cloneDeep(el.children));
+ }
+
+ // Create a hash map where keys are col paths,
+ // and values are an array of all paths with that column
+ const cols: { [key: string]: number[][] } = {};
+
+ // A boolean to keep track if we have a header cell among the cells we are merging
+ let hasHeaderCell = false;
+
+ cellEntries.forEach(([entry, path]) => {
+ if (!hasHeaderCell && entry.type === 'table_header_cell') {
+ hasHeaderCell = true;
+ }
+ if (cols[path[1]]) {
+ cols[path[1]].push(path);
+ } else {
+ cols[path[1]] = [path];
+ }
+ });
+
+ // removes multiple cells with on same path.
+ // once cell removed, next cell in the row will settle down on that path
+ Object.values(cols).forEach((paths) => {
+ paths?.forEach(() => {
+ removeNodes(editor, { at: paths[0] });
+ });
+ });
+
+ // Create a new cell to replace the merged cells, with
+ // calculated colSpan and rowSpan attributes and combined content
+ const mergedCell = {
+ ...getEmptyCellNode(editor, {
+ header: cellEntries[0][0].type === 'th',
+ newCellChildren: contents,
+ }),
+ colSpan,
+ rowSpan,
+ };
+
+ // insert the new merged cell in place of the first cell in the selection
+ insertElements(editor, mergedCell, { at: cellEntries[0][1] });
+ });
+};
diff --git a/packages/table/src/merge/unmergeTableCells.ts b/packages/table/src/merge/unmergeTableCells.ts
new file mode 100644
index 0000000000..400e34f21d
--- /dev/null
+++ b/packages/table/src/merge/unmergeTableCells.ts
@@ -0,0 +1,109 @@
+import {
+ findNode,
+ getPluginOptions,
+ getPluginType,
+ insertElements,
+ PlateEditor,
+ removeNodes,
+ TDescendant,
+ Value,
+ withoutNormalizing,
+} from '@udecode/plate-common';
+
+import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
+import { getTableGridAbove } from '../queries';
+import { getColSpan } from '../queries/getColSpan';
+import { TablePlugin, TTableCellElement, TTableRowElement } from '../types';
+import { getEmptyCellNode } from '../utils';
+import { getCellIndices } from './getCellIndices';
+
+export const unmergeTableCells = (
+ editor: PlateEditor
+) => {
+ withoutNormalizing(editor, () => {
+ const { _cellIndices: cellIndices } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+
+ const cellEntries = getTableGridAbove(editor, { format: 'cell' });
+ const [[cellElem, path]] = cellEntries;
+
+ // creating new object per iteration is essential here
+ const createEmptyCell = (children?: TDescendant[]) => {
+ return {
+ ...getEmptyCellNode(editor, {
+ header: cellElem.type === 'th',
+ newCellChildren: children,
+ }),
+ colSpan: 1,
+ rowSpan: 1,
+ };
+ };
+
+ const tablePath = path.slice(0, -2);
+
+ const cellPath = path.slice(-2);
+ const [rowPath, colPath] = cellPath;
+ const colSpan = cellElem.colSpan as number;
+ const rowSpan = cellElem.rowSpan as number;
+
+ // Generate an array of column paths from the colspan
+ const colPaths: number[] = [];
+ for (let i = 0; i < colSpan; i++) {
+ colPaths.push(colPath + i);
+ }
+
+ // Remove the original merged cell from the editor
+ removeNodes(editor, { at: path });
+
+ const { col } = getCellIndices(
+ cellIndices!,
+ cellElem as TTableCellElement
+ )!;
+
+ const getColPathForRow = (row: number) => {
+ let newColPath = 0;
+
+ const rowEntry = findNode(editor, {
+ at: [...tablePath, row],
+ match: { type: getPluginType(editor, ELEMENT_TR) },
+ })!; // TODO: improve typing
+ const rowEl = rowEntry[0] as TTableRowElement;
+
+ for (const item of rowEl.children) {
+ const { col: c } = getCellIndices(
+ cellIndices!,
+ item as TTableCellElement
+ )!;
+ if (c === col - 1) {
+ newColPath = rowEl.children.indexOf(item) + 1;
+ break;
+ }
+ if (col + getColSpan(cellElem as TTableCellElement) === c - 1) {
+ newColPath = rowEl.children.indexOf(item);
+ break;
+ }
+ }
+
+ return newColPath;
+ };
+
+ // Generate an array of cell paths from the row and col spans and then insert empty cells at those paths
+ 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 pathForNewCell = [...tablePath, currentRowPath, currentColPath];
+ const cellToInsert =
+ i === 0 && j === 0
+ ? createEmptyCell(cellElem.children)
+ : createEmptyCell();
+
+ insertElements(editor, cellToInsert, { at: pathForNewCell });
+ }
+ }
+ });
+};
diff --git a/packages/table/src/merge/useTableMergeState.ts b/packages/table/src/merge/useTableMergeState.ts
new file mode 100644
index 0000000000..5c8308e296
--- /dev/null
+++ b/packages/table/src/merge/useTableMergeState.ts
@@ -0,0 +1,45 @@
+import { useMemo } from 'react';
+import { isCollapsed, isExpanded, useEditorState } from '@udecode/plate-common';
+import { useReadOnly, useSelected } from 'slate-react';
+
+import { getTableGridAbove } from '../queries';
+import { useTableStore } from '../stores';
+import { isTableRectangular } from './isTableRectangular';
+
+export const useTableMergeState = () => {
+ const editor = useEditorState();
+
+ const readOnly = useReadOnly();
+ const selected = useSelected();
+
+ const collapsed = !readOnly && selected && isCollapsed(editor.selection);
+ const selectedTables = useTableStore().get.selectedTable();
+ const selectedTable = selectedTables?.[0];
+
+ const selectedCellEntries = useMemo(
+ () =>
+ getTableGridAbove(editor, {
+ format: 'cell',
+ }),
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [editor.selection]
+ );
+
+ const canMerge = useMemo(() => {
+ return (
+ !readOnly &&
+ selected &&
+ isExpanded(editor.selection) &&
+ isTableRectangular(selectedTable)
+ );
+ }, [editor.selection, selectedTable, readOnly, selected]);
+
+ const canUnmerge =
+ collapsed &&
+ selectedCellEntries &&
+ selectedCellEntries.length === 1 &&
+ ((selectedCellEntries[0][0] as any)?.colSpan > 1 ||
+ (selectedCellEntries[0][0] as any)?.rowSpan > 1);
+
+ return { canMerge, canUnmerge };
+};
diff --git a/packages/table/src/queries/getColSpan.ts b/packages/table/src/queries/getColSpan.ts
new file mode 100644
index 0000000000..2df1070a04
--- /dev/null
+++ b/packages/table/src/queries/getColSpan.ts
@@ -0,0 +1,10 @@
+import { TTableCellElement } from '../types';
+
+/**
+ * Returns the colspan attribute of the table cell element.
+ * @default 1 if undefined.
+ */
+export const getColSpan = (cellElem: TTableCellElement) => {
+ const attrColSpan = Number(cellElem.attributes?.colspan);
+ return cellElem.colSpan || attrColSpan || 1;
+};
diff --git a/packages/table/src/queries/getRowSpan.ts b/packages/table/src/queries/getRowSpan.ts
new file mode 100644
index 0000000000..6e83104836
--- /dev/null
+++ b/packages/table/src/queries/getRowSpan.ts
@@ -0,0 +1,10 @@
+import { TTableCellElement } from '../types';
+
+/**
+ * Returns the rowspan attribute of the table cell element.
+ * @default 1 if undefined
+ */
+export const getRowSpan = (cellElem: TTableCellElement) => {
+ const attrRowSpan = Number(cellElem.attributes?.rowspan);
+ return cellElem.rowSpan || attrRowSpan || 1;
+};
diff --git a/packages/table/src/queries/getTableGridAbove.ts b/packages/table/src/queries/getTableGridAbove.ts
index c916df2e26..fe677ef16c 100644
--- a/packages/table/src/queries/getTableGridAbove.ts
+++ b/packages/table/src/queries/getTableGridAbove.ts
@@ -32,7 +32,6 @@ export const getTableGridAbove = (
},
...options,
});
-
if (edges) {
const [start, end] = edges;
diff --git a/packages/table/src/queries/getTableGridByRange.ts b/packages/table/src/queries/getTableGridByRange.ts
index 84caada168..ce65d711f1 100644
--- a/packages/table/src/queries/getTableGridByRange.ts
+++ b/packages/table/src/queries/getTableGridByRange.ts
@@ -1,5 +1,6 @@
import {
getNode,
+ getPluginOptions,
PlateEditor,
TElement,
TElementEntry,
@@ -7,7 +8,9 @@ import {
} from '@udecode/plate-common';
import { Range } from 'slate';
-import { TTableElement } from '../types';
+import { ELEMENT_TABLE } from '../createTablePlugin';
+import { getTableMergeGridByRange } from '../merge/getTableGridByRange';
+import { TablePlugin, TTableElement } from '../types';
import { getEmptyTableNode } from '../utils/getEmptyTableNode';
export interface GetTableGridByRangeOptions {
@@ -28,6 +31,14 @@ export const getTableGridByRange = (
editor: PlateEditor,
{ at, format = 'table' }: GetTableGridByRangeOptions
): TElementEntry[] => {
+ const { enableMerging } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ if (enableMerging) {
+ return getTableMergeGridByRange(editor, { at, format });
+ }
+
const startCellPath = at.anchor.path;
const endCellPath = at.focus.path;
diff --git a/packages/table/src/stores/tableStore.ts b/packages/table/src/stores/tableStore.ts
index 91842d9a93..c89ef2d363 100644
--- a/packages/table/src/stores/tableStore.ts
+++ b/packages/table/src/stores/tableStore.ts
@@ -12,6 +12,7 @@ export const { tableStore, useTableStore } = createAtomStore(
marginLeftOverride: null as number | null,
hoveredColIndex: null as number | null,
selectedCells: null as TElement[] | null,
+ selectedTable: null as TElement[] | null,
},
{ name: 'table' as const, scope: ELEMENT_TABLE }
);
diff --git a/packages/table/src/transforms/deleteColumn.ts b/packages/table/src/transforms/deleteColumn.ts
index fcd905f7c6..b7262d2c3d 100644
--- a/packages/table/src/transforms/deleteColumn.ts
+++ b/packages/table/src/transforms/deleteColumn.ts
@@ -1,5 +1,6 @@
import {
getAboveNode,
+ getPluginOptions,
getPluginType,
PlateEditor,
removeNodes,
@@ -16,9 +17,18 @@ import {
ELEMENT_TH,
ELEMENT_TR,
} from '../createTablePlugin';
-import { TTableElement } from '../types';
+import { deleteTableMergeColumn } from '../merge/deleteColumn';
+import { TablePlugin, TTableElement } from '../types';
export const deleteColumn = (editor: PlateEditor) => {
+ const { enableMerging } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ if (enableMerging) {
+ return deleteTableMergeColumn(editor);
+ }
+
if (
someNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
diff --git a/packages/table/src/transforms/deleteRow.ts b/packages/table/src/transforms/deleteRow.ts
index 703afed4ea..6bc239bf24 100644
--- a/packages/table/src/transforms/deleteRow.ts
+++ b/packages/table/src/transforms/deleteRow.ts
@@ -1,5 +1,6 @@
import {
getAboveNode,
+ getPluginOptions,
getPluginType,
PlateEditor,
removeNodes,
@@ -8,9 +9,18 @@ import {
} from '@udecode/plate-common';
import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
-import { TTableElement } from '../types';
+import { deleteTableMergeRow } from '../merge/deleteRow';
+import { TablePlugin, TTableElement } from '../types';
export const deleteRow = (editor: PlateEditor) => {
+ const { enableMerging } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ if (enableMerging) {
+ return deleteTableMergeRow(editor);
+ }
+
if (
someNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
diff --git a/packages/table/src/transforms/insertTableColumn.ts b/packages/table/src/transforms/insertTableColumn.ts
index fea3f48338..80233a52da 100644
--- a/packages/table/src/transforms/insertTableColumn.ts
+++ b/packages/table/src/transforms/insertTableColumn.ts
@@ -13,18 +13,14 @@ import {
import { Path } from 'slate';
import { ELEMENT_TABLE, ELEMENT_TH } from '../createTablePlugin';
+import { insertTableMergeColumn } from '../merge/insertTableColumn';
import { TablePlugin, TTableElement } from '../types';
import { getEmptyCellNode } from '../utils/getEmptyCellNode';
import { getCellTypes } from '../utils/index';
export const insertTableColumn = (
editor: PlateEditor,
- {
- disableSelect,
- fromCell,
- at,
- header,
- }: {
+ options: {
header?: boolean;
/**
@@ -44,6 +40,16 @@ export const insertTableColumn = (
disableSelect?: boolean;
} = {}
) => {
+ const { enableMerging } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ if (enableMerging) {
+ return insertTableMergeColumn(editor, options);
+ }
+
+ const { disableSelect, fromCell, at, header } = options;
+
const cellEntry = fromCell
? findNode(editor, {
at: fromCell,
diff --git a/packages/table/src/transforms/insertTableRow.spec.tsx b/packages/table/src/transforms/insertTableRow.spec.tsx
index b1c6161ede..7f036c86ea 100644
--- a/packages/table/src/transforms/insertTableRow.spec.tsx
+++ b/packages/table/src/transforms/insertTableRow.spec.tsx
@@ -76,7 +76,9 @@ describe('insertTableRow', () => {
editor: input,
plugins: [
createTablePlugin({
- options: { newCellChildren: [{ text: '' }] },
+ options: {
+ newCellChildren: [{ text: '' }],
+ },
}),
],
});
diff --git a/packages/table/src/transforms/insertTableRow.ts b/packages/table/src/transforms/insertTableRow.ts
index 5204bd182b..575543feb8 100644
--- a/packages/table/src/transforms/insertTableRow.ts
+++ b/packages/table/src/transforms/insertTableRow.ts
@@ -13,17 +13,13 @@ import {
import { Path } from 'slate';
import { ELEMENT_TABLE, ELEMENT_TH, ELEMENT_TR } from '../createTablePlugin';
+import { insertTableMergeRow } from '../merge/insertTableRow';
import { TablePlugin } from '../types';
import { getCellTypes, getEmptyCellNode } from '../utils/index';
export const insertTableRow = (
editor: PlateEditor,
- {
- header,
- fromRow,
- at,
- disableSelect,
- }: {
+ options: {
header?: boolean;
fromRow?: Path;
/**
@@ -34,6 +30,16 @@ export const insertTableRow = (
disableSelect?: boolean;
} = {}
) => {
+ const { enableMerging } = getPluginOptions(
+ editor,
+ ELEMENT_TABLE
+ );
+ if (enableMerging) {
+ return insertTableMergeRow(editor, options);
+ }
+
+ const { header, fromRow, at, disableSelect } = options;
+
const trEntry = fromRow
? findNode(editor, {
at: fromRow,
diff --git a/packages/table/src/types.ts b/packages/table/src/types.ts
index 36117f5c06..d8c3627daa 100644
--- a/packages/table/src/types.ts
+++ b/packages/table/src/types.ts
@@ -58,8 +58,24 @@ export interface TablePlugin {
* @default 48
*/
minColumnWidth?: number;
+
+ /**
+ * Enable cells merging functionality.
+ * @default false
+ */
+ enableMerging?: boolean;
+
+ /**
+ * For internal use. Keeps track of cell indices. Used only when enableMerging is true.
+ */
+ _cellIndices?: TableStoreCellAttributes;
}
+export type TableStoreCellAttributes = WeakMap<
+ TTableCellElement,
+ { row: number; col: number }
+>;
+
export interface BorderStyle {
// https://docx.js.org/api/enums/BorderStyle.html
style?: string;
@@ -78,6 +94,7 @@ export interface TTableRowElement extends TElement {
export interface TTableCellElement extends TElement {
colSpan?: number;
+ rowSpan?: number;
size?: number;
background?: string;
borders?: {
@@ -94,6 +111,10 @@ export interface TTableCellElement extends TElement {
*/
right?: BorderStyle;
};
+ attributes: {
+ colspan?: string;
+ rowspan?: string;
+ };
}
export type BorderDirection = 'top' | 'left' | 'bottom' | 'right';
diff --git a/packages/table/src/utils/getEmptyCellNode.ts b/packages/table/src/utils/getEmptyCellNode.ts
index d9b87b5b5f..98c84984bb 100644
--- a/packages/table/src/utils/getEmptyCellNode.ts
+++ b/packages/table/src/utils/getEmptyCellNode.ts
@@ -3,7 +3,8 @@ import { getPluginType, PlateEditor, Value } from '@udecode/plate-common';
import { ELEMENT_TD, ELEMENT_TH } from '../createTablePlugin';
import { TablePlugin } from '../types';
-export interface GetEmptyCellNodeOptions extends TablePlugin {
+export interface GetEmptyCellNodeOptions
+ extends Omit {
/**
* Header cell
*/
diff --git a/packages/table/src/utils/getEmptyRowNode.ts b/packages/table/src/utils/getEmptyRowNode.ts
index 38682507a0..063434e34e 100644
--- a/packages/table/src/utils/getEmptyRowNode.ts
+++ b/packages/table/src/utils/getEmptyRowNode.ts
@@ -3,7 +3,8 @@ import { getPluginType, PlateEditor, Value } from '@udecode/plate-common';
import { ELEMENT_TR } from '../createTablePlugin';
import { getEmptyCellNode, GetEmptyCellNodeOptions } from './getEmptyCellNode';
-export interface GetEmptyRowNodeOptions extends GetEmptyCellNodeOptions {
+export interface GetEmptyRowNodeOptions
+ extends Omit {
colCount?: number;
}
diff --git a/packages/table/src/withDeleteTable.spec.tsx b/packages/table/src/withDeleteTable.spec.tsx
index f40e3b6322..98ef7814d4 100644
--- a/packages/table/src/withDeleteTable.spec.tsx
+++ b/packages/table/src/withDeleteTable.spec.tsx
@@ -3,6 +3,7 @@
import { createPlateEditor, PlateEditor } from '@udecode/plate-common';
import { jsx } from '@udecode/plate-test-utils';
+import { createTablePlugin } from './createTablePlugin';
import { withDeleteTable } from './withDeleteTable';
jsx;
@@ -50,6 +51,7 @@ describe('withDeleteTable', () => {
let editor = createPlateEditor({
editor: input,
+ plugins: [createTablePlugin()],
});
editor = withDeleteTable(editor);
@@ -104,6 +106,7 @@ describe('withDeleteTable', () => {
let editor = createPlateEditor({
editor: input,
+ plugins: [createTablePlugin()],
});
editor = withDeleteTable(editor);
@@ -178,6 +181,7 @@ describe('withDeleteTable', () => {
editor = createPlateEditor({
editor: input,
+ plugins: [createTablePlugin()],
});
editor = withDeleteTable(editor);
diff --git a/yarn.lock b/yarn.lock
index 275d00b803..464392dbfc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7108,11 +7108,11 @@ __metadata:
languageName: node
linkType: hard
-"@udecode/plate-alignment@npm:24.5.2, @udecode/plate-alignment@workspace:^, @udecode/plate-alignment@workspace:packages/alignment":
+"@udecode/plate-alignment@npm:25.0.1, @udecode/plate-alignment@workspace:^, @udecode/plate-alignment@workspace:packages/alignment":
version: 0.0.0-use.local
resolution: "@udecode/plate-alignment@workspace:packages/alignment"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7123,11 +7123,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-autoformat@npm:24.5.2, @udecode/plate-autoformat@workspace:^, @udecode/plate-autoformat@workspace:packages/autoformat":
+"@udecode/plate-autoformat@npm:25.0.1, @udecode/plate-autoformat@workspace:^, @udecode/plate-autoformat@workspace:packages/autoformat":
version: 0.0.0-use.local
resolution: "@udecode/plate-autoformat@workspace:packages/autoformat"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7139,15 +7139,15 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-basic-elements@npm:24.5.2, @udecode/plate-basic-elements@workspace:^, @udecode/plate-basic-elements@workspace:packages/basic-elements":
+"@udecode/plate-basic-elements@npm:25.0.1, @udecode/plate-basic-elements@workspace:^, @udecode/plate-basic-elements@workspace:packages/basic-elements":
version: 0.0.0-use.local
resolution: "@udecode/plate-basic-elements@workspace:packages/basic-elements"
dependencies:
- "@udecode/plate-block-quote": "npm:24.5.2"
- "@udecode/plate-code-block": "npm:24.5.2"
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-heading": "npm:24.5.2"
- "@udecode/plate-paragraph": "npm:24.5.2"
+ "@udecode/plate-block-quote": "npm:25.0.1"
+ "@udecode/plate-code-block": "npm:25.0.1"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-heading": "npm:25.0.1"
+ "@udecode/plate-paragraph": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7158,11 +7158,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-basic-marks@npm:24.5.2, @udecode/plate-basic-marks@workspace:^, @udecode/plate-basic-marks@workspace:packages/basic-marks":
+"@udecode/plate-basic-marks@npm:25.0.1, @udecode/plate-basic-marks@workspace:^, @udecode/plate-basic-marks@workspace:packages/basic-marks":
version: 0.0.0-use.local
resolution: "@udecode/plate-basic-marks@workspace:packages/basic-marks"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7173,11 +7173,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-block-quote@npm:24.5.2, @udecode/plate-block-quote@workspace:^, @udecode/plate-block-quote@workspace:packages/block-quote":
+"@udecode/plate-block-quote@npm:25.0.1, @udecode/plate-block-quote@workspace:^, @udecode/plate-block-quote@workspace:packages/block-quote":
version: 0.0.0-use.local
resolution: "@udecode/plate-block-quote@workspace:packages/block-quote"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7188,11 +7188,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-break@npm:24.5.2, @udecode/plate-break@workspace:^, @udecode/plate-break@workspace:packages/break":
+"@udecode/plate-break@npm:25.0.1, @udecode/plate-break@workspace:^, @udecode/plate-break@workspace:packages/break":
version: 0.0.0-use.local
resolution: "@udecode/plate-break@workspace:packages/break"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7207,7 +7207,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate-caption@workspace:packages/caption"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
react-textarea-autosize: "npm:^8.5.2"
peerDependencies:
react: ">=16.8.0"
@@ -7224,7 +7224,7 @@ __metadata:
resolution: "@udecode/plate-cloud@workspace:packages/cloud"
dependencies:
"@portive/client": "npm:10.0.3"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
delay: "npm:5.0.0"
p-defer: "npm:^3.0.0"
peerDependencies:
@@ -7237,11 +7237,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-code-block@npm:24.5.2, @udecode/plate-code-block@workspace:^, @udecode/plate-code-block@workspace:packages/code-block":
+"@udecode/plate-code-block@npm:25.0.1, @udecode/plate-code-block@workspace:^, @udecode/plate-code-block@workspace:packages/code-block":
version: 0.0.0-use.local
resolution: "@udecode/plate-code-block@workspace:packages/code-block"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
prismjs: "npm:^1.29.0"
peerDependencies:
react: ">=16.8.0"
@@ -7253,11 +7253,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-combobox@npm:24.5.2, @udecode/plate-combobox@workspace:^, @udecode/plate-combobox@workspace:packages/combobox":
+"@udecode/plate-combobox@npm:25.0.1, @udecode/plate-combobox@workspace:^, @udecode/plate-combobox@workspace:packages/combobox":
version: 0.0.0-use.local
resolution: "@udecode/plate-combobox@workspace:packages/combobox"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
downshift: "npm:^6.1.12"
peerDependencies:
react: ">=16.8.0"
@@ -7269,11 +7269,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-comments@npm:24.5.2, @udecode/plate-comments@workspace:^, @udecode/plate-comments@workspace:packages/comments":
+"@udecode/plate-comments@npm:25.0.1, @udecode/plate-comments@workspace:^, @udecode/plate-comments@workspace:packages/comments":
version: 0.0.0-use.local
resolution: "@udecode/plate-comments@workspace:packages/comments"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7285,15 +7285,15 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-common@npm:24.5.2, @udecode/plate-common@workspace:^, @udecode/plate-common@workspace:packages/common":
+"@udecode/plate-common@npm:25.0.1, @udecode/plate-common@workspace:^, @udecode/plate-common@workspace:packages/common":
version: 0.0.0-use.local
resolution: "@udecode/plate-common@workspace:packages/common"
dependencies:
- "@udecode/plate-core": "npm:24.4.0"
- "@udecode/plate-utils": "npm:24.5.2"
- "@udecode/slate": "npm:24.3.6"
- "@udecode/slate-react": "npm:24.4.0"
- "@udecode/slate-utils": "npm:24.3.6"
+ "@udecode/plate-core": "npm:25.0.1"
+ "@udecode/plate-utils": "npm:25.0.1"
+ "@udecode/slate": "npm:25.0.0"
+ "@udecode/slate-react": "npm:25.0.0"
+ "@udecode/slate-utils": "npm:25.0.0"
"@udecode/utils": "npm:24.3.0"
peerDependencies:
react: ">=16.8.0"
@@ -7305,13 +7305,13 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-core@npm:24.4.0, @udecode/plate-core@workspace:^, @udecode/plate-core@workspace:packages/core":
+"@udecode/plate-core@npm:25.0.1, @udecode/plate-core@workspace:^, @udecode/plate-core@workspace:packages/core":
version: 0.0.0-use.local
resolution: "@udecode/plate-core@workspace:packages/core"
dependencies:
- "@udecode/slate": "npm:24.3.6"
- "@udecode/slate-react": "npm:24.4.0"
- "@udecode/slate-utils": "npm:24.3.6"
+ "@udecode/slate": "npm:25.0.0"
+ "@udecode/slate-react": "npm:25.0.0"
+ "@udecode/slate-utils": "npm:25.0.0"
"@udecode/utils": "npm:24.3.0"
"@udecode/zustood": "npm:^1.1.3"
clsx: "npm:^1.2.1"
@@ -7336,7 +7336,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate-cursor@workspace:packages/cursor"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7351,7 +7351,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate-dnd@workspace:packages/dnd"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
raf: "npm:^3.4.1"
peerDependencies:
@@ -7371,8 +7371,8 @@ __metadata:
resolution: "@udecode/plate-emoji@workspace:packages/emoji"
dependencies:
"@emoji-mart/data": "npm:^1.1.2"
- "@udecode/plate-combobox": "npm:24.5.2"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-combobox": "npm:25.0.1"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7388,7 +7388,7 @@ __metadata:
resolution: "@udecode/plate-excalidraw@workspace:packages/excalidraw"
dependencies:
"@excalidraw/excalidraw": "npm:0.12.0"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7399,11 +7399,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-find-replace@npm:24.5.2, @udecode/plate-find-replace@workspace:^, @udecode/plate-find-replace@workspace:packages/find-replace":
+"@udecode/plate-find-replace@npm:25.0.1, @udecode/plate-find-replace@workspace:^, @udecode/plate-find-replace@workspace:packages/find-replace":
version: 0.0.0-use.local
resolution: "@udecode/plate-find-replace@workspace:packages/find-replace"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7414,14 +7414,14 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-floating@npm:24.5.2, @udecode/plate-floating@workspace:^, @udecode/plate-floating@workspace:packages/floating":
+"@udecode/plate-floating@npm:25.0.1, @udecode/plate-floating@workspace:^, @udecode/plate-floating@workspace:packages/floating":
version: 0.0.0-use.local
resolution: "@udecode/plate-floating@workspace:packages/floating"
dependencies:
"@floating-ui/core": "npm:^1.3.1"
"@floating-ui/react": "npm:^0.22.3"
"@radix-ui/react-dropdown-menu": "npm:^2.0.5"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7432,11 +7432,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-font@npm:24.5.2, @udecode/plate-font@workspace:^, @udecode/plate-font@workspace:packages/font":
+"@udecode/plate-font@npm:25.0.1, @udecode/plate-font@workspace:^, @udecode/plate-font@workspace:packages/font":
version: 0.0.0-use.local
resolution: "@udecode/plate-font@workspace:packages/font"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7448,11 +7448,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-heading@npm:24.5.2, @udecode/plate-heading@workspace:^, @udecode/plate-heading@workspace:packages/heading":
+"@udecode/plate-heading@npm:25.0.1, @udecode/plate-heading@workspace:^, @udecode/plate-heading@workspace:packages/heading":
version: 0.0.0-use.local
resolution: "@udecode/plate-heading@workspace:packages/heading"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7463,11 +7463,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-highlight@npm:24.5.2, @udecode/plate-highlight@workspace:^, @udecode/plate-highlight@workspace:packages/highlight":
+"@udecode/plate-highlight@npm:25.0.1, @udecode/plate-highlight@workspace:^, @udecode/plate-highlight@workspace:packages/highlight":
version: 0.0.0-use.local
resolution: "@udecode/plate-highlight@workspace:packages/highlight"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7478,11 +7478,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-horizontal-rule@npm:24.5.2, @udecode/plate-horizontal-rule@workspace:^, @udecode/plate-horizontal-rule@workspace:packages/horizontal-rule":
+"@udecode/plate-horizontal-rule@npm:25.0.1, @udecode/plate-horizontal-rule@workspace:^, @udecode/plate-horizontal-rule@workspace:packages/horizontal-rule":
version: 0.0.0-use.local
resolution: "@udecode/plate-horizontal-rule@workspace:packages/horizontal-rule"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7493,13 +7493,13 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-indent-list@npm:24.5.2, @udecode/plate-indent-list@workspace:^, @udecode/plate-indent-list@workspace:packages/indent-list":
+"@udecode/plate-indent-list@npm:25.0.1, @udecode/plate-indent-list@workspace:^, @udecode/plate-indent-list@workspace:packages/indent-list":
version: 0.0.0-use.local
resolution: "@udecode/plate-indent-list@workspace:packages/indent-list"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-indent": "npm:24.5.2"
- "@udecode/plate-list": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-indent": "npm:25.0.1"
+ "@udecode/plate-list": "npm:25.0.1"
clsx: "npm:^1.2.1"
peerDependencies:
react: ">=16.8.0"
@@ -7511,11 +7511,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-indent@npm:24.5.2, @udecode/plate-indent@workspace:^, @udecode/plate-indent@workspace:packages/indent":
+"@udecode/plate-indent@npm:25.0.1, @udecode/plate-indent@workspace:^, @udecode/plate-indent@workspace:packages/indent":
version: 0.0.0-use.local
resolution: "@udecode/plate-indent@workspace:packages/indent"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7530,7 +7530,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate-juice@workspace:packages/juice"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
juice: "npm:^8.1.0"
peerDependencies:
react: ">=16.8.0"
@@ -7542,11 +7542,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-kbd@npm:24.5.2, @udecode/plate-kbd@workspace:^, @udecode/plate-kbd@workspace:packages/kbd":
+"@udecode/plate-kbd@npm:25.0.1, @udecode/plate-kbd@workspace:^, @udecode/plate-kbd@workspace:packages/kbd":
version: 0.0.0-use.local
resolution: "@udecode/plate-kbd@workspace:packages/kbd"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7557,11 +7557,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-line-height@npm:24.5.2, @udecode/plate-line-height@workspace:^, @udecode/plate-line-height@workspace:packages/line-height":
+"@udecode/plate-line-height@npm:25.0.1, @udecode/plate-line-height@workspace:^, @udecode/plate-line-height@workspace:packages/line-height":
version: 0.0.0-use.local
resolution: "@udecode/plate-line-height@workspace:packages/line-height"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7572,13 +7572,13 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-link@npm:24.5.2, @udecode/plate-link@workspace:^, @udecode/plate-link@workspace:packages/link":
+"@udecode/plate-link@npm:25.0.1, @udecode/plate-link@workspace:^, @udecode/plate-link@workspace:packages/link":
version: 0.0.0-use.local
resolution: "@udecode/plate-link@workspace:packages/link"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-floating": "npm:24.5.2"
- "@udecode/plate-normalizers": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-floating": "npm:25.0.1"
+ "@udecode/plate-normalizers": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7589,12 +7589,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-list@npm:24.5.2, @udecode/plate-list@workspace:^, @udecode/plate-list@workspace:packages/list":
+"@udecode/plate-list@npm:25.0.1, @udecode/plate-list@workspace:^, @udecode/plate-list@workspace:packages/list":
version: 0.0.0-use.local
resolution: "@udecode/plate-list@workspace:packages/list"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-reset-node": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-reset-node": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7606,11 +7606,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-media@npm:24.5.2, @udecode/plate-media@workspace:^, @udecode/plate-media@workspace:packages/media":
+"@udecode/plate-media@npm:25.0.1, @udecode/plate-media@workspace:^, @udecode/plate-media@workspace:packages/media":
version: 0.0.0-use.local
resolution: "@udecode/plate-media@workspace:packages/media"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
js-video-url-parser: "npm:^0.5.1"
peerDependencies:
react: ">=16.8.0"
@@ -7622,12 +7622,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-mention@npm:24.5.2, @udecode/plate-mention@workspace:^, @udecode/plate-mention@workspace:packages/mention":
+"@udecode/plate-mention@npm:25.0.1, @udecode/plate-mention@workspace:^, @udecode/plate-mention@workspace:packages/mention":
version: 0.0.0-use.local
resolution: "@udecode/plate-mention@workspace:packages/mention"
dependencies:
- "@udecode/plate-combobox": "npm:24.5.2"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-combobox": "npm:25.0.1"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7638,11 +7638,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-node-id@npm:24.5.2, @udecode/plate-node-id@workspace:^, @udecode/plate-node-id@workspace:packages/node-id":
+"@udecode/plate-node-id@npm:25.0.1, @udecode/plate-node-id@workspace:^, @udecode/plate-node-id@workspace:packages/node-id":
version: 0.0.0-use.local
resolution: "@udecode/plate-node-id@workspace:packages/node-id"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7654,11 +7654,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-normalizers@npm:24.5.2, @udecode/plate-normalizers@workspace:^, @udecode/plate-normalizers@workspace:packages/normalizers":
+"@udecode/plate-normalizers@npm:25.0.1, @udecode/plate-normalizers@workspace:^, @udecode/plate-normalizers@workspace:packages/normalizers":
version: 0.0.0-use.local
resolution: "@udecode/plate-normalizers@workspace:packages/normalizers"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7670,11 +7670,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-paragraph@npm:24.5.2, @udecode/plate-paragraph@workspace:^, @udecode/plate-paragraph@workspace:packages/paragraph":
+"@udecode/plate-paragraph@npm:25.0.1, @udecode/plate-paragraph@workspace:^, @udecode/plate-paragraph@workspace:packages/paragraph":
version: 0.0.0-use.local
resolution: "@udecode/plate-paragraph@workspace:packages/paragraph"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7685,11 +7685,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-reset-node@npm:24.5.2, @udecode/plate-reset-node@workspace:^, @udecode/plate-reset-node@workspace:packages/reset-node":
+"@udecode/plate-reset-node@npm:25.0.1, @udecode/plate-reset-node@workspace:^, @udecode/plate-reset-node@workspace:packages/reset-node":
version: 0.0.0-use.local
resolution: "@udecode/plate-reset-node@workspace:packages/reset-node"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7700,11 +7700,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-resizable@npm:24.5.2, @udecode/plate-resizable@workspace:^, @udecode/plate-resizable@workspace:packages/resizable":
+"@udecode/plate-resizable@npm:25.0.1, @udecode/plate-resizable@workspace:^, @udecode/plate-resizable@workspace:packages/resizable":
version: 0.0.0-use.local
resolution: "@udecode/plate-resizable@workspace:packages/resizable"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7715,11 +7715,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-select@npm:24.5.2, @udecode/plate-select@workspace:^, @udecode/plate-select@workspace:packages/select":
+"@udecode/plate-select@npm:25.0.1, @udecode/plate-select@workspace:^, @udecode/plate-select@workspace:packages/select":
version: 0.0.0-use.local
resolution: "@udecode/plate-select@workspace:packages/select"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7734,7 +7734,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate-selection@workspace:packages/selection"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
"@viselect/vanilla": "npm:3.2.5"
copy-to-clipboard: "npm:^3.3.3"
peerDependencies:
@@ -7747,13 +7747,13 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-serializer-csv@npm:24.5.2, @udecode/plate-serializer-csv@workspace:^, @udecode/plate-serializer-csv@workspace:packages/serializer-csv":
+"@udecode/plate-serializer-csv@npm:25.0.1, @udecode/plate-serializer-csv@workspace:^, @udecode/plate-serializer-csv@workspace:packages/serializer-csv":
version: 0.0.0-use.local
resolution: "@udecode/plate-serializer-csv@workspace:packages/serializer-csv"
dependencies:
"@types/papaparse": "npm:^5.3.7"
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-table": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-table": "npm:25.0.1"
papaparse: "npm:^5.4.1"
peerDependencies:
react: ">=16.8.0"
@@ -7765,17 +7765,17 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-serializer-docx@npm:24.5.2, @udecode/plate-serializer-docx@workspace:^, @udecode/plate-serializer-docx@workspace:packages/serializer-docx":
+"@udecode/plate-serializer-docx@npm:25.0.1, @udecode/plate-serializer-docx@workspace:^, @udecode/plate-serializer-docx@workspace:packages/serializer-docx":
version: 0.0.0-use.local
resolution: "@udecode/plate-serializer-docx@workspace:packages/serializer-docx"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-heading": "npm:24.5.2"
- "@udecode/plate-indent": "npm:24.5.2"
- "@udecode/plate-indent-list": "npm:24.5.2"
- "@udecode/plate-media": "npm:24.5.2"
- "@udecode/plate-paragraph": "npm:24.5.2"
- "@udecode/plate-table": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-heading": "npm:25.0.1"
+ "@udecode/plate-indent": "npm:25.0.1"
+ "@udecode/plate-indent-list": "npm:25.0.1"
+ "@udecode/plate-media": "npm:25.0.1"
+ "@udecode/plate-paragraph": "npm:25.0.1"
+ "@udecode/plate-table": "npm:25.0.1"
validator: "npm:^13.9.0"
peerDependencies:
react: ">=16.8.0"
@@ -7787,12 +7787,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-serializer-html@npm:24.5.2, @udecode/plate-serializer-html@workspace:^, @udecode/plate-serializer-html@workspace:packages/serializer-html":
+"@udecode/plate-serializer-html@npm:25.0.1, @udecode/plate-serializer-html@workspace:^, @udecode/plate-serializer-html@workspace:packages/serializer-html":
version: 0.0.0-use.local
resolution: "@udecode/plate-serializer-html@workspace:packages/serializer-html"
dependencies:
"@types/papaparse": "npm:^5.3.7"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
html-entities: "npm:^2.4.0"
peerDependencies:
react: ">=16.8.0"
@@ -7804,20 +7804,20 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-serializer-md@npm:24.5.2, @udecode/plate-serializer-md@workspace:^, @udecode/plate-serializer-md@workspace:packages/serializer-md":
+"@udecode/plate-serializer-md@npm:25.0.1, @udecode/plate-serializer-md@workspace:^, @udecode/plate-serializer-md@workspace:packages/serializer-md":
version: 0.0.0-use.local
resolution: "@udecode/plate-serializer-md@workspace:packages/serializer-md"
dependencies:
- "@udecode/plate-basic-marks": "npm:24.5.2"
- "@udecode/plate-block-quote": "npm:24.5.2"
- "@udecode/plate-code-block": "npm:24.5.2"
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-heading": "npm:24.5.2"
- "@udecode/plate-horizontal-rule": "npm:24.5.2"
- "@udecode/plate-link": "npm:24.5.2"
- "@udecode/plate-list": "npm:24.5.2"
- "@udecode/plate-media": "npm:24.5.2"
- "@udecode/plate-paragraph": "npm:24.5.2"
+ "@udecode/plate-basic-marks": "npm:25.0.1"
+ "@udecode/plate-block-quote": "npm:25.0.1"
+ "@udecode/plate-code-block": "npm:25.0.1"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-heading": "npm:25.0.1"
+ "@udecode/plate-horizontal-rule": "npm:25.0.1"
+ "@udecode/plate-link": "npm:25.0.1"
+ "@udecode/plate-list": "npm:25.0.1"
+ "@udecode/plate-media": "npm:25.0.1"
+ "@udecode/plate-paragraph": "npm:25.0.1"
remark-parse: "npm:^9.0.0"
unified: "npm:^9.2.2"
peerDependencies:
@@ -7830,11 +7830,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-suggestion@npm:24.5.2, @udecode/plate-suggestion@workspace:^, @udecode/plate-suggestion@workspace:packages/suggestion":
+"@udecode/plate-suggestion@npm:25.0.1, @udecode/plate-suggestion@workspace:^, @udecode/plate-suggestion@workspace:packages/suggestion":
version: 0.0.0-use.local
resolution: "@udecode/plate-suggestion@workspace:packages/suggestion"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7845,11 +7845,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-tabbable@npm:24.5.2, @udecode/plate-tabbable@workspace:^, @udecode/plate-tabbable@workspace:packages/tabbable":
+"@udecode/plate-tabbable@npm:25.0.1, @udecode/plate-tabbable@workspace:^, @udecode/plate-tabbable@workspace:packages/tabbable":
version: 0.0.0-use.local
resolution: "@udecode/plate-tabbable@workspace:packages/tabbable"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
tabbable: "npm:^6.2.0"
peerDependencies:
react: ">=16.8.0"
@@ -7861,12 +7861,12 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-table@npm:24.5.2, @udecode/plate-table@workspace:^, @udecode/plate-table@workspace:packages/table":
+"@udecode/plate-table@npm:25.0.1, @udecode/plate-table@workspace:^, @udecode/plate-table@workspace:packages/table":
version: 0.0.0-use.local
resolution: "@udecode/plate-table@workspace:packages/table"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-resizable": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-resizable": "npm:25.0.1"
lodash: "npm:^4.17.21"
peerDependencies:
react: ">=16.8.0"
@@ -7886,11 +7886,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-trailing-block@npm:24.5.2, @udecode/plate-trailing-block@workspace:^, @udecode/plate-trailing-block@workspace:packages/trailing-block":
+"@udecode/plate-trailing-block@npm:25.0.1, @udecode/plate-trailing-block@workspace:^, @udecode/plate-trailing-block@workspace:packages/trailing-block":
version: 0.0.0-use.local
resolution: "@udecode/plate-trailing-block@workspace:packages/trailing-block"
dependencies:
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -7930,15 +7930,15 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/plate-utils@npm:24.5.2, @udecode/plate-utils@workspace:^, @udecode/plate-utils@workspace:packages/plate-utils":
+"@udecode/plate-utils@npm:25.0.1, @udecode/plate-utils@workspace:^, @udecode/plate-utils@workspace:packages/plate-utils":
version: 0.0.0-use.local
resolution: "@udecode/plate-utils@workspace:packages/plate-utils"
dependencies:
"@radix-ui/react-slot": "npm:^1.0.2"
- "@udecode/plate-core": "npm:24.4.0"
- "@udecode/slate": "npm:24.3.6"
- "@udecode/slate-react": "npm:24.4.0"
- "@udecode/slate-utils": "npm:24.3.6"
+ "@udecode/plate-core": "npm:25.0.1"
+ "@udecode/slate": "npm:25.0.0"
+ "@udecode/slate-react": "npm:25.0.0"
+ "@udecode/slate-utils": "npm:25.0.0"
"@udecode/utils": "npm:24.3.0"
clsx: "npm:^1.2.1"
lodash: "npm:^4.17.21"
@@ -7958,7 +7958,7 @@ __metadata:
dependencies:
"@hocuspocus/provider": "npm:^2.2.1"
"@slate-yjs/core": "npm:^1.0.1"
- "@udecode/plate-common": "npm:24.5.2"
+ "@udecode/plate-common": "npm:25.0.1"
yjs: "npm:^13.5.42"
peerDependencies:
react: ">=16.8.0"
@@ -7974,44 +7974,44 @@ __metadata:
version: 0.0.0-use.local
resolution: "@udecode/plate@workspace:packages/plate"
dependencies:
- "@udecode/plate-alignment": "npm:24.5.2"
- "@udecode/plate-autoformat": "npm:24.5.2"
- "@udecode/plate-basic-elements": "npm:24.5.2"
- "@udecode/plate-basic-marks": "npm:24.5.2"
- "@udecode/plate-block-quote": "npm:24.5.2"
- "@udecode/plate-break": "npm:24.5.2"
- "@udecode/plate-code-block": "npm:24.5.2"
- "@udecode/plate-combobox": "npm:24.5.2"
- "@udecode/plate-comments": "npm:24.5.2"
- "@udecode/plate-common": "npm:24.5.2"
- "@udecode/plate-find-replace": "npm:24.5.2"
- "@udecode/plate-floating": "npm:24.5.2"
- "@udecode/plate-font": "npm:24.5.2"
- "@udecode/plate-heading": "npm:24.5.2"
- "@udecode/plate-highlight": "npm:24.5.2"
- "@udecode/plate-horizontal-rule": "npm:24.5.2"
- "@udecode/plate-indent": "npm:24.5.2"
- "@udecode/plate-indent-list": "npm:24.5.2"
- "@udecode/plate-kbd": "npm:24.5.2"
- "@udecode/plate-line-height": "npm:24.5.2"
- "@udecode/plate-link": "npm:24.5.2"
- "@udecode/plate-list": "npm:24.5.2"
- "@udecode/plate-media": "npm:24.5.2"
- "@udecode/plate-mention": "npm:24.5.2"
- "@udecode/plate-node-id": "npm:24.5.2"
- "@udecode/plate-normalizers": "npm:24.5.2"
- "@udecode/plate-paragraph": "npm:24.5.2"
- "@udecode/plate-reset-node": "npm:24.5.2"
- "@udecode/plate-resizable": "npm:24.5.2"
- "@udecode/plate-select": "npm:24.5.2"
- "@udecode/plate-serializer-csv": "npm:24.5.2"
- "@udecode/plate-serializer-docx": "npm:24.5.2"
- "@udecode/plate-serializer-html": "npm:24.5.2"
- "@udecode/plate-serializer-md": "npm:24.5.2"
- "@udecode/plate-suggestion": "npm:24.5.2"
- "@udecode/plate-tabbable": "npm:24.5.2"
- "@udecode/plate-table": "npm:24.5.2"
- "@udecode/plate-trailing-block": "npm:24.5.2"
+ "@udecode/plate-alignment": "npm:25.0.1"
+ "@udecode/plate-autoformat": "npm:25.0.1"
+ "@udecode/plate-basic-elements": "npm:25.0.1"
+ "@udecode/plate-basic-marks": "npm:25.0.1"
+ "@udecode/plate-block-quote": "npm:25.0.1"
+ "@udecode/plate-break": "npm:25.0.1"
+ "@udecode/plate-code-block": "npm:25.0.1"
+ "@udecode/plate-combobox": "npm:25.0.1"
+ "@udecode/plate-comments": "npm:25.0.1"
+ "@udecode/plate-common": "npm:25.0.1"
+ "@udecode/plate-find-replace": "npm:25.0.1"
+ "@udecode/plate-floating": "npm:25.0.1"
+ "@udecode/plate-font": "npm:25.0.1"
+ "@udecode/plate-heading": "npm:25.0.1"
+ "@udecode/plate-highlight": "npm:25.0.1"
+ "@udecode/plate-horizontal-rule": "npm:25.0.1"
+ "@udecode/plate-indent": "npm:25.0.1"
+ "@udecode/plate-indent-list": "npm:25.0.1"
+ "@udecode/plate-kbd": "npm:25.0.1"
+ "@udecode/plate-line-height": "npm:25.0.1"
+ "@udecode/plate-link": "npm:25.0.1"
+ "@udecode/plate-list": "npm:25.0.1"
+ "@udecode/plate-media": "npm:25.0.1"
+ "@udecode/plate-mention": "npm:25.0.1"
+ "@udecode/plate-node-id": "npm:25.0.1"
+ "@udecode/plate-normalizers": "npm:25.0.1"
+ "@udecode/plate-paragraph": "npm:25.0.1"
+ "@udecode/plate-reset-node": "npm:25.0.1"
+ "@udecode/plate-resizable": "npm:25.0.1"
+ "@udecode/plate-select": "npm:25.0.1"
+ "@udecode/plate-serializer-csv": "npm:25.0.1"
+ "@udecode/plate-serializer-docx": "npm:25.0.1"
+ "@udecode/plate-serializer-html": "npm:25.0.1"
+ "@udecode/plate-serializer-md": "npm:25.0.1"
+ "@udecode/plate-suggestion": "npm:25.0.1"
+ "@udecode/plate-tabbable": "npm:25.0.1"
+ "@udecode/plate-table": "npm:25.0.1"
+ "@udecode/plate-trailing-block": "npm:25.0.1"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
@@ -8022,11 +8022,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/slate-react@npm:24.4.0, @udecode/slate-react@workspace:^, @udecode/slate-react@workspace:packages/slate-react":
+"@udecode/slate-react@npm:25.0.0, @udecode/slate-react@workspace:^, @udecode/slate-react@workspace:packages/slate-react":
version: 0.0.0-use.local
resolution: "@udecode/slate-react@workspace:packages/slate-react"
dependencies:
- "@udecode/slate": "npm:24.3.6"
+ "@udecode/slate": "npm:25.0.0"
"@udecode/utils": "npm:24.3.0"
peerDependencies:
react: ">=16.8.0"
@@ -8037,11 +8037,11 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/slate-utils@npm:24.3.6, @udecode/slate-utils@workspace:^, @udecode/slate-utils@workspace:packages/slate-utils":
+"@udecode/slate-utils@npm:25.0.0, @udecode/slate-utils@workspace:^, @udecode/slate-utils@workspace:packages/slate-utils":
version: 0.0.0-use.local
resolution: "@udecode/slate-utils@workspace:packages/slate-utils"
dependencies:
- "@udecode/slate": "npm:24.3.6"
+ "@udecode/slate": "npm:25.0.0"
"@udecode/utils": "npm:24.3.0"
lodash: "npm:^4.17.21"
peerDependencies:
@@ -8050,7 +8050,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@udecode/slate@npm:24.3.6, @udecode/slate@workspace:^, @udecode/slate@workspace:packages/slate":
+"@udecode/slate@npm:25.0.0, @udecode/slate@workspace:^, @udecode/slate@workspace:packages/slate":
version: 0.0.0-use.local
resolution: "@udecode/slate@workspace:packages/slate"
dependencies: