Skip to content

Commit cc0011c

Browse files
authored
Merge pull request #2909 from udecode/liboul/toggle/fix/delete-backward-forward
Toggle > Handle deleteForward before a non-selectable and deleteBackward after a non-selectable
2 parents 9fbc79e + 3cca1ac commit cc0011c

File tree

5 files changed

+104
-3
lines changed

5 files changed

+104
-3
lines changed

.changeset/cool-lions-cry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@udecode/plate-toggle": patch
3+
---
4+
5+
Toggle > Handle deleteForward before a non-selectable and deleteBackward after a non-selectable

packages/toggle/src/transforms/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
* @file Automatically generated by barrelsby.
33
*/
44

5+
export * from './moveCurrentBlockAfterPreviousSelectable';
6+
export * from './moveNextSelectableAfterCurrentBlock';
57
export * from './openNextToggles';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {
2+
getBlockAbove,
3+
getPointBefore,
4+
getPreviousNode,
5+
isElement,
6+
isSelectionAtBlockStart,
7+
moveNodes,
8+
PlateEditor,
9+
} from '@udecode/plate-common';
10+
11+
import { isInClosedToggle } from '../queries';
12+
13+
// Return false only if the all previous blocks are not selectable
14+
export const moveCurrentBlockAfterPreviousSelectable = (
15+
editor: PlateEditor
16+
): boolean | undefined => {
17+
const { selection } = editor;
18+
if (!selection) return;
19+
const aboveBlock = getBlockAbove(editor);
20+
if (!aboveBlock) return;
21+
if (!isSelectionAtBlockStart(editor)) return;
22+
const beforePoint = getPointBefore(editor, selection);
23+
if (!beforePoint) return;
24+
const blockBefore = getBlockAbove(editor, { at: beforePoint });
25+
if (!blockBefore) return;
26+
if (!isInClosedToggle(editor, blockBefore[0].id)) return; // We're already after a selectable then
27+
const previousSelectableBlock = getPreviousNode(editor, {
28+
match: (node) =>
29+
isElement(node) && !isInClosedToggle(editor, node.id as string),
30+
});
31+
if (!previousSelectableBlock) return false;
32+
const afterSelectableBlock = [previousSelectableBlock[1][0] + 1];
33+
moveNodes(editor, {
34+
at: aboveBlock[1],
35+
to: afterSelectableBlock,
36+
});
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {
2+
getBlockAbove,
3+
getNextNode,
4+
getPointAfter,
5+
isElement,
6+
isSelectionAtBlockEnd,
7+
moveNodes,
8+
PlateEditor,
9+
} from '@udecode/plate-common';
10+
11+
import { isInClosedToggle } from '../queries';
12+
13+
// Return false only if all next blocks are not selectable
14+
export const moveNextSelectableAfterCurrentBlock = (editor: PlateEditor) => {
15+
const { selection } = editor;
16+
if (!selection) return;
17+
const aboveBlock = getBlockAbove(editor);
18+
if (!aboveBlock) return;
19+
if (!isSelectionAtBlockEnd(editor)) return;
20+
const afterPoint = getPointAfter(editor, selection);
21+
if (!afterPoint) return;
22+
const blockAfter = getBlockAbove(editor, { at: afterPoint });
23+
if (!blockAfter) return;
24+
if (!isInClosedToggle(editor, blockAfter[0].id)) return; // We're already before a selectable then
25+
const nextSelectableBlock = getNextNode(editor, {
26+
match: (node) =>
27+
isElement(node) && !isInClosedToggle(editor, node.id as string),
28+
});
29+
if (!nextSelectableBlock) return false;
30+
const afterCurrentBlock = [aboveBlock[1][0] + 1];
31+
moveNodes(editor, {
32+
at: nextSelectableBlock[1],
33+
to: afterCurrentBlock,
34+
});
35+
};

packages/toggle/src/withToggle.ts

+25-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import { indent, TIndentElement } from '@udecode/plate-indent';
1010

1111
import { getLastEntryEnclosedInToggle, isInClosedToggle } from './queries';
1212
import { isToggleOpen } from './toggle-controller-store';
13+
import {
14+
moveCurrentBlockAfterPreviousSelectable,
15+
moveNextSelectableAfterCurrentBlock,
16+
} from './transforms';
1317
import { ELEMENT_TOGGLE } from './types';
1418

1519
export const withToggle = <
@@ -18,14 +22,28 @@ export const withToggle = <
1822
>(
1923
editor: E
2024
) => {
21-
const { insertBreak, isSelectable } = editor;
25+
const { insertBreak, isSelectable, deleteBackward, deleteForward } = editor;
2226

2327
editor.isSelectable = (element) => {
2428
if (isNode(element) && isInClosedToggle<V, E>(editor, element.id as string))
2529
return false;
2630
return isSelectable(element);
2731
};
2832

33+
editor.deleteBackward = (unit) => {
34+
if (
35+
moveCurrentBlockAfterPreviousSelectable(editor as PlateEditor) === false
36+
)
37+
return;
38+
deleteBackward(unit);
39+
};
40+
41+
editor.deleteForward = (unit) => {
42+
if (moveNextSelectableAfterCurrentBlock(editor as PlateEditor) === false)
43+
return;
44+
deleteForward(unit);
45+
};
46+
2947
editor.insertBreak = () => {
3048
// If we are inserting a break in a toggle:
3149
// If the toggle is open
@@ -57,9 +75,13 @@ export const withToggle = <
5775
insertBreak();
5876

5977
if (lastEntryEnclosedInToggle) {
78+
const newlyInsertedTogglePath = [currentBlockEntry[1][0] + 1];
79+
const afterLastEntryEncloseInToggle = [
80+
lastEntryEnclosedInToggle[1][0] + 1,
81+
];
6082
moveNodes(editor, {
61-
at: [currentBlockEntry[1][0] + 1], // Newly inserted toggle
62-
to: [lastEntryEnclosedInToggle[1][0] + 1], // Right after the last enclosed element
83+
at: newlyInsertedTogglePath,
84+
to: afterLastEntryEncloseInToggle,
6385
});
6486
}
6587
}

0 commit comments

Comments
 (0)