Skip to content

Commit 516a2ac

Browse files
committed
Toggle > Handle deleteForward before a non-selectable and deleteBackward after a non-selectable
1 parent aa0b607 commit 516a2ac

File tree

4 files changed

+101
-3
lines changed

4 files changed

+101
-3
lines changed

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

+27-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ import {
33
isNode,
44
moveNodes,
55
PlateEditor,
6+
select,
67
toggleNodeType,
78
Value,
89
} from '@udecode/plate-common';
910
import { indent, TIndentElement } from '@udecode/plate-indent';
1011

1112
import { getLastEntryEnclosedInToggle, isInClosedToggle } from './queries';
1213
import { isToggleOpen } from './toggle-controller-store';
14+
import {
15+
moveCurrentBlockAfterPreviousSelectable,
16+
moveNextSelectableAfterCurrentBlock,
17+
} from './transforms';
1318
import { ELEMENT_TOGGLE } from './types';
1419

1520
export const withToggle = <
@@ -18,14 +23,28 @@ export const withToggle = <
1823
>(
1924
editor: E
2025
) => {
21-
const { insertBreak, isSelectable } = editor;
26+
const { insertBreak, isSelectable, deleteBackward, deleteForward } = editor;
2227

2328
editor.isSelectable = (element) => {
2429
if (isNode(element) && isInClosedToggle<V, E>(editor, element.id as string))
2530
return false;
2631
return isSelectable(element);
2732
};
2833

34+
editor.deleteBackward = (unit) => {
35+
if (
36+
moveCurrentBlockAfterPreviousSelectable(editor as PlateEditor) === false
37+
)
38+
return;
39+
deleteBackward(unit);
40+
};
41+
42+
editor.deleteForward = (unit) => {
43+
if (moveNextSelectableAfterCurrentBlock(editor as PlateEditor) === false)
44+
return;
45+
deleteForward(unit);
46+
};
47+
2948
editor.insertBreak = () => {
3049
// If we are inserting a break in a toggle:
3150
// If the toggle is open
@@ -57,10 +76,15 @@ export const withToggle = <
5776
insertBreak();
5877

5978
if (lastEntryEnclosedInToggle) {
79+
const newlyInsertedTogglePath = [currentBlockEntry[1][0] + 1];
80+
const afterLastEntryEncloseInToggle = [
81+
lastEntryEnclosedInToggle[1][0] + 1,
82+
];
6083
moveNodes(editor, {
61-
at: [currentBlockEntry[1][0] + 1], // Newly inserted toggle
62-
to: [lastEntryEnclosedInToggle[1][0] + 1], // Right after the last enclosed element
84+
at: newlyInsertedTogglePath,
85+
to: afterLastEntryEncloseInToggle,
6386
});
87+
select(editor, afterLastEntryEncloseInToggle);
6488
}
6589
}
6690
});

0 commit comments

Comments
 (0)