Skip to content

Commit

Permalink
Merge pull request #1887 from epam/fix-colspan-rowspan
Browse files Browse the repository at this point in the history
[SlateEditor] Fix colspan / rowspan & add merged cells to example
  • Loading branch information
AlekseyManetov authored Dec 29, 2023
2 parents 5f4e8b0 + 18cedf2 commit e33146e
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 46 deletions.
190 changes: 157 additions & 33 deletions uui-docs/src/demoData/slateInitialValue.ts

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions uui-editor/src/__tests__/__snapshots__/migration.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`migrate should migrate content correctly 1`] = `
Array [
Object {
"children": Array [
Object {
"text": "All queries and requests for should be sent initially to [email protected].
",
},
],
"data": Object {},
"type": "paragraph",
},
Object {
"children": Array [
Object {
"children": Array [
Object {
"children": Array [
Object {
"children": Array [
Object {
"text": "Country",
},
],
"data": Object {},
"type": "paragraph",
},
],
"type": "table_header_cell",
},
Object {
"children": Array [
Object {
"children": Array [
Object {
"text": "Name and address of supervisory authority",
},
],
"data": Object {},
"type": "paragraph",
},
],
"type": "table_header_cell",
},
],
"data": Object {},
"type": "table_row",
},
Object {
"children": Array [
Object {
"children": Array [
Object {
"children": Array [
Object {
"text": "Belgium",
},
],
"data": Object {},
"type": "paragraph",
},
Object {
"children": Array [
Object {
"text": "Data Protection Authority
",
},
],
"data": Object {},
"type": "paragraph",
},
],
"colSpan": 2,
"type": "table_cell",
},
],
"data": Object {},
"type": "table_row",
},
],
"data": Object {
"cellSizes": Array [
112,
288,
],
},
"type": "table",
},
]
`;
125 changes: 125 additions & 0 deletions uui-editor/src/__tests__/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
export const initialValue = {
object: 'value',
document: {
object: 'document',
data: {},
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'text',
text: 'All queries and requests for should be sent initially to [email protected].\r',
marks: [],
},
],
},
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'block',
type: 'table',
data: {
cellSizes: [
112,
288,
],
},
nodes: [
{
object: 'block',
type: 'table_row',
data: {},
nodes: [
{
object: 'block',
type: 'table_header_cell',
data: {},
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'text',
text: 'Country',
marks: [],
},
],
},
],
},
{
object: 'block',
type: 'table_header_cell',
data: {},
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'text',
text: 'Name and address of supervisory authority',
marks: [],
},
],
},
],
},
],
},
{
object: 'block',
type: 'table_row',
data: {},
nodes: [
{
object: 'block',
type: 'table_cell',
data: { colSpan: 2 },
nodes: [
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'text',
text: 'Belgium',
marks: [],
},

],
},
{
object: 'block',
type: 'paragraph',
data: {},
nodes: [
{
object: 'text',
text: 'Data Protection Authority\r',
marks: [],
},
],
},
],
},

],
},
],
},
],
},
],
},
};
35 changes: 35 additions & 0 deletions uui-editor/src/__tests__/migration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { TTableCellElement } from '@udecode/plate-table';
import { migrateSchema, migrateTableCell } from '../migration';
import { initialValue } from './data';

describe('migrate', () => {
it('should migrate content correctly', () => {
const migrated = migrateSchema(initialValue);

expect(migrated).toMatchSnapshot();
});

it('should migrate table cell correctly', () => {
const element: TTableCellElement = {
type: 'table-cell',
colSpan: 2,
rowSpan: 1,
data: {
colSpan: 3,
rowSpan: 2,
},
attributes: {},
children: [],
};

const migrated = migrateTableCell(element);

expect(migrated).toEqual({
type: 'table-cell',
colSpan: 3,
rowSpan: 2,
attributes: {},
children: [],
});
});
});
27 changes: 24 additions & 3 deletions uui-editor/src/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
* https://github.com/react-page/react-page/blob/b6c83a8650cfe9089e0c3eaf471ab58a0f7db761/packages/plugins/content/slate/src/migrations/v004.ts
*/

import { ExtendedTTableCellElement } from './plugins/tablePlugin/types';
import { TTableCellElement } from '@udecode/plate-table';

const mediaTypes = ['image', 'iframe'];

const migrateTextNode = (oldNode: any) => {
return {
text: oldNode.text,
Expand All @@ -22,6 +27,20 @@ const migrateTextNode = (oldNode: any) => {
};
};

export const migrateTableCell = (element: TTableCellElement): TTableCellElement => {
const oldElem = element as ExtendedTTableCellElement;
if (oldElem.data) {
if (oldElem.data.colSpan) {
element.colSpan = oldElem.data.colSpan;
}
if (oldElem.data.rowSpan) {
element.rowSpan = oldElem.data.rowSpan;
}
delete element.data;
}
return element;
};

const migrateTable = (oldTable: any) => {
oldTable.nodes.forEach((row: any) => {
const newRowNodes: any[] = [];
Expand All @@ -37,18 +56,20 @@ const migrateTable = (oldTable: any) => {
};

const migrateElementNode = (node: any) => {
const mediaTypes = ['image', 'iframe'];

if (node.type === 'paragraph' && node.nodes?.[0]?.type === 'table') {
const tableNode = node.nodes[0];
node = migrateTable(tableNode);
}

const omitData = node.type === 'table_cell' || node.type === 'table_header_cell';
const dataProps = omitData ? {} : { data: node.data ?? {} };
return {
data: node.data ?? {},
...dataProps,
type: node.type,
...(mediaTypes.includes(node.type) ? { url: node.data?.src } : {}),
...(node?.data?.url ? { url: node.data.url } : {}),
...(node?.data?.colSpan ? { colSpan: node.data.colSpan } : {}),
...(node?.data?.rowSpan ? { rowSpan: node.data.rowSpan } : {}),
children: node.nodes?.map(migrateNode).flat() ?? [],
};
};
Expand Down
11 changes: 7 additions & 4 deletions uui-editor/src/plugins/tablePlugin/TableCellElement.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from 'react';
import cx from 'classnames';
import { PlateElement, PlateElementProps, Value } from '@udecode/plate-common';
import { PlateElement, PlateElementProps, Value, getPluginType, useEditorRef } from '@udecode/plate-common';
import {
ELEMENT_TH,
TTableCellElement,
useTableCellElement, useTableCellElementResizable, useTableCellElementResizableState, useTableCellElementState,
} from '@udecode/plate-table';

import css from './TableCell.module.scss';
import { ResizeHandle } from '../../implementation/Resizable';
import { migrateTableCell } from '../../migration';

export interface TableCellElementProps
extends PlateElementProps<Value, TTableCellElement> {
Expand All @@ -19,7 +21,8 @@ const TableCellElement = React.forwardRef<
React.ElementRef<typeof PlateElement>,
TableCellElementProps
>(({ children, className, style, hideBorder, ...props }, ref) => {
const { element } = props;
const editor = useEditorRef();
props.element = migrateTableCell(props.element);

const {
colIndex,
Expand All @@ -40,7 +43,7 @@ TableCellElementProps
colSpan,
});
const { rightProps, bottomProps, leftProps, hiddenLeft } = useTableCellElementResizable(resizableState);
const isHeader = element.type === 'table_header_cell';
const isHeader = props.element.type === getPluginType(editor, ELEMENT_TH);
const Cell = isHeader ? 'th' : 'td';

return (
Expand Down Expand Up @@ -69,7 +72,7 @@ TableCellElementProps
{ ...cellProps }
style={
{
'--cellBackground': element.background,
'--cellBackground': props.element.background,
...style,
} as React.CSSProperties
}
Expand Down
2 changes: 1 addition & 1 deletion uui-editor/src/plugins/tablePlugin/tablePlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ReactComponent as TableIcon } from '../../icons/table-add.svg';
import { PositionedToolbar } from '../../implementation/PositionedToolbar';
import { ToolbarButton } from '../../implementation/ToolbarButton';

import { PlateEditor, getPluginOptions, getPluginType, insertNodes, someNode, useEditorRef, withoutNormalizing } from '@udecode/plate-common';
import { PlateEditor, getPluginType, insertNodes, someNode, useEditorRef, withoutNormalizing } from '@udecode/plate-common';
import { ELEMENT_TABLE, ELEMENT_TD, ELEMENT_TH, ELEMENT_TR, TablePlugin, createTablePlugin, getTableGridAbove, useTableMergeState } from '@udecode/plate-table';
import { MergeToolbarContent } from './MergeToolbarContent';
import { TableToolbarContent } from './ToolbarContent';
Expand Down
6 changes: 1 addition & 5 deletions uui-editor/src/plugins/tablePlugin/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { TTableCellElement } from '@udecode/plate-table';

export type ExtendedTTableCellElement = TTableCellElement & {
rowSpan?: number;
colIndex?: number;
rowIndex?: number;
data: {
data?: {
colSpan?: number;
rowSpan?: number;
colIndex?: number;
},
attributes?: {
colspan?: number;
Expand Down

0 comments on commit e33146e

Please sign in to comment.