Skip to content

Commit

Permalink
Fix: table (#1778)
Browse files Browse the repository at this point in the history
* style

* feat

* feat

* fix: cell height

* fix: delete table cells should replace cell children then reselect the range

* fix: default level should be 0

* fix: copy from a single cell

* feat

* feat

* fix: selection, replace cell children instead of cell, many blocks inside a table

* feat

* feat

* fix: insert text across many cells

* fix: normalize cell children

* style

* fix

* fix

* core.md

* Create table.md

* Create dnd.md

* Create ui-table.md

* fix

* fix
  • Loading branch information
zbeyens authored Aug 12, 2022
1 parent 10c2eb6 commit e179bf0
Show file tree
Hide file tree
Showing 31 changed files with 1,089 additions and 177 deletions.
5 changes: 5 additions & 0 deletions .changeset/dnd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@udecode/plate-ui-dnd": patch
---

- `withDraggable`: default `level` option is now 0 as expected
8 changes: 8 additions & 0 deletions .changeset/khaki-comics-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@udecode/plate-core": minor
---

- `isRangeAcrossBlocks`: Now returns true if one of the block above is found but not the other and returns undefined if no block is found.
- `isRangeInSameBlock`: Whether the range is in the same block.
- `removeNodeChildren`: Remove node children.
- `replaceNodeChildren`: Replace node children: remove then insert.
25 changes: 25 additions & 0 deletions .changeset/table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"@udecode/plate-table": minor
---

- on delete many cells:
- replace cell children by a paragraph then reselect all the selected cells
- on get fragment (copy):
- copying in a single cell should not copy the table anymore
- on insert fragment (paste):
- pasting multiple blocks into many selected cells will replace these cells children by the same blocks
- replace cell children by a paragraph then reselect all the selected cells
- on insert text:
- it should delete the cells content by preserving the cells
- normalize cells:
- wrap cell children in a paragraph if they are texts
- normalize selection:
- it was easy to destroy the table structure when selection goes beyond a table. The current fix is to normalize the selection so it selects the whole table (see the specs)
- specs:
- https://github.com/udecode/editor-protocol/issues/63
- https://github.com/udecode/editor-protocol/issues/64
- https://github.com/udecode/editor-protocol/issues/65
- https://github.com/udecode/editor-protocol/issues/66
- https://github.com/udecode/editor-protocol/issues/67
- https://github.com/udecode/editor-protocol/issues/68
- https://github.com/udecode/editor-protocol/issues/69
5 changes: 5 additions & 0 deletions .changeset/ui-table.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@udecode/plate-ui-table": patch
---

- fix: table cells are now full height and not vertically centered anymore
1 change: 1 addition & 0 deletions packages/core/src/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export * from './isFirstChild';
export * from './isMarkActive';
export * from './isPointAtWordEnd';
export * from './isRangeAcrossBlocks';
export * from './isRangeInSameBlock';
export * from './isRangeInSingleText';
export * from './isSelectionAtBlockEnd';
export * from './isSelectionAtBlockStart';
Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/queries/isRangeAcrossBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { getBlockAbove } from './getBlockAbove';

/**
* Is the range (default: selection) across blocks.
* - return undefined if block not found
* - return boolean whether one of the block is not found, but the other is found
* - return boolean whether block paths are unequal
*/
export const isRangeAcrossBlocks = <V extends Value>(
editor: TEditor<V>,
Expand All @@ -14,7 +17,7 @@ export const isRangeAcrossBlocks = <V extends Value>(
}: Omit<GetAboveNodeOptions<V>, 'at'> & { at?: Range | null } = {}
) => {
if (!at) at = editor.selection;
if (!at) return false;
if (!at) return;

const [start, end] = Range.edges(at);
const startBlock = getBlockAbove(editor, {
Expand All @@ -26,5 +29,9 @@ export const isRangeAcrossBlocks = <V extends Value>(
...options,
});

return startBlock && endBlock && !Path.equals(startBlock[1], endBlock[1]);
if (!startBlock && !endBlock) return;

if (!startBlock || !endBlock) return true;

return !Path.equals(startBlock[1], endBlock[1]);
};
31 changes: 31 additions & 0 deletions packages/core/src/queries/isRangeInSameBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Path, Range } from 'slate';
import { GetAboveNodeOptions, TEditor, Value } from '../slate/index';
import { getBlockAbove } from './getBlockAbove';

/**
* Whether the range is in the same block.
*/
export const isRangeInSameBlock = <V extends Value>(
editor: TEditor<V>,
{
at,
...options
}: Omit<GetAboveNodeOptions<V>, 'at'> & { at?: Range | null } = {}
) => {
if (!at) at = editor.selection;
if (!at) return;

const [start, end] = Range.edges(at);
const startBlock = getBlockAbove(editor, {
at: start,
...options,
});
const endBlock = getBlockAbove(editor, {
at: end,
...options,
});

if (!startBlock || !endBlock) return;

return Path.equals(startBlock[1], endBlock[1]);
};
2 changes: 2 additions & 0 deletions packages/core/src/transforms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export * from './insertElements';
export * from './insertEmptyElement';
export * from './moveChildren';
export * from './removeMark';
export * from './removeNodeChildren';
export * from './replaceNodeChildren';
export * from './selectEditor';
export * from './selectEndOfBlockAboveSelection';
export * from './setElements';
Expand Down
26 changes: 26 additions & 0 deletions packages/core/src/transforms/removeNodeChildren.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Path } from 'slate';
import {
getNodeChildren,
removeNodes,
RemoveNodesOptions,
TEditor,
Value,
withoutNormalizing,
} from '../slate/index';

/**
* Remove node children.
*/
export const removeNodeChildren = <V extends Value = Value>(
editor: TEditor<V>,
path: Path,
options?: Omit<RemoveNodesOptions<V>, 'at'>
) => {
withoutNormalizing(editor, () => {
for (const [, childPath] of getNodeChildren(editor, path, {
reverse: true,
})) {
removeNodes(editor, { ...options, at: childPath });
}
});
};
41 changes: 41 additions & 0 deletions packages/core/src/transforms/replaceNodeChildren.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Path } from 'slate';
import {
EElementOrText,
insertNodes,
InsertNodesOptions,
RemoveNodesOptions,
TEditor,
Value,
withoutNormalizing,
} from '../slate/index';
import { removeNodeChildren } from './removeNodeChildren';

/**
* Replace node children: remove then insert.
*/
export const replaceNodeChildren = <
N extends EElementOrText<V>,
V extends Value = Value
>(
editor: TEditor<V>,
{
at,
nodes,
insertOptions,
removeOptions,
}: {
at: Path;
nodes: N | N[];
removeOptions?: Omit<RemoveNodesOptions<V>, 'at'>;
insertOptions?: Omit<InsertNodesOptions<V>, 'at'>;
}
) => {
withoutNormalizing(editor, () => {
removeNodeChildren(editor, at, removeOptions);

insertNodes(editor, nodes, {
...insertOptions,
at: at.concat([0]),
});
});
};
3 changes: 3 additions & 0 deletions packages/nodes/table/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export * from './types';
export * from './withDeleteTable';
export * from './withGetFragmentTable';
export * from './withInsertFragmentTable';
export * from './withInsertTextTable';
export * from './withNormalizeTable';
export * from './withSelectionTable';
export * from './withTable';
export * from './queries/index';
export * from './transforms/index';
Expand Down
19 changes: 19 additions & 0 deletions packages/nodes/table/src/queries/getTableAbove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
getBlockAbove,
getPluginType,
PlateEditor,
Value,
} from '@udecode/plate-core';
import { GetAboveNodeOptions } from '@udecode/plate-core/src/index';
import { ELEMENT_TABLE } from '../createTablePlugin';

export const getTableAbove = <V extends Value = Value>(
editor: PlateEditor<V>,
options?: GetAboveNodeOptions<V>
) =>
getBlockAbove(editor, {
match: {
type: getPluginType(editor, ELEMENT_TABLE),
},
...options,
});
1 change: 1 addition & 0 deletions packages/nodes/table/src/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './getCellInNextTableRow';
export * from './getCellInPreviousTableRow';
export * from './getNextTableCell';
export * from './getPreviousTableCell';
export * from './getTableAbove';
export * from './getTableCellEntry';
export * from './getTableColumnCount';
export * from './getTableColumnIndex';
Expand Down
82 changes: 61 additions & 21 deletions packages/nodes/table/src/transforms/insertTableColumn.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,22 @@ describe('insertTableColumn', () => {
<editor>
<htable>
<htr>
<htd>11</htd>
<htd>12</htd>
<htd>
<hp>11</hp>
</htd>
<htd>
<hp>12</hp>
</htd>
</htr>
<htr>
<htd>21</htd>
<htd>
22
<cursor />
<hp>21</hp>
</htd>
<htd>
<hp>
22
<cursor />
</hp>
</htd>
</htr>
</htable>
Expand All @@ -32,17 +40,29 @@ describe('insertTableColumn', () => {
<editor>
<htable>
<htr>
<htd>11</htd>
<htd>12</htd>
<htd>
<htext />
<hp>11</hp>
</htd>
<htd>
<hp>12</hp>
</htd>
<htd>
<hp>
<htext />
</hp>
</htd>
</htr>
<htr>
<htd>21</htd>
<htd>22</htd>
<htd>
<cursor />
<hp>21</hp>
</htd>
<htd>
<hp>22</hp>
</htd>
<htd>
<hp>
<cursor />
</hp>
</htd>
</htr>
</htable>
Expand Down Expand Up @@ -71,12 +91,20 @@ describe('insertTableColumn', () => {
<editor>
<htable>
<htr>
<htd>11</htd>
<htd>12</htd>
<htd>
<hp>11</hp>
</htd>
<htd>
<hp>12</hp>
</htd>
</htr>
<htr>
<htd>21</htd>
<htd>22</htd>
<htd>
<hp>21</hp>
</htd>
<htd>
<hp>22</hp>
</htd>
</htr>
</htable>
</editor>
Expand All @@ -86,18 +114,30 @@ describe('insertTableColumn', () => {
<editor>
<htable>
<htr>
<htd>11</htd>
<htd>
<htext />
<hp>11</hp>
</htd>
<htd>
<hp>
<htext />
</hp>
</htd>
<htd>
<hp>12</hp>
</htd>
<htd>12</htd>
</htr>
<htr>
<htd>21</htd>
<htd>
<cursor />
<hp>21</hp>
</htd>
<htd>
<hp>
<cursor />
</hp>
</htd>
<htd>
<hp>22</hp>
</htd>
<htd>22</htd>
</htr>
</htable>
</editor>
Expand Down
Loading

1 comment on commit e179bf0

@vercel
Copy link

@vercel vercel bot commented on e179bf0 Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

plate – ./

plate.udecode.io
plate-udecode.vercel.app
plate-git-main-udecode.vercel.app
www.plate.udecode.io

Please sign in to comment.