Skip to content

Commit

Permalink
Merge pull request #4118 from udecode/fix/block-paste
Browse files Browse the repository at this point in the history
Fix block selection paste
  • Loading branch information
zbeyens authored Feb 27, 2025
2 parents f3afaca + 9053839 commit 84dcca3
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 76 deletions.
7 changes: 7 additions & 0 deletions .changeset/olive-mayflies-drum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@udecode/plate-selection': minor
---

- Fix block selection when pasting blocks
- Block selection > Backspace now selects the previous block
- Block selection > Delete now selects the next block
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';

import { isHotkey } from '@udecode/plate';
import { isHotkey, PathApi } from '@udecode/plate';
import {
type EditableSiblingComponent,
useEditorPlugin,
Expand Down Expand Up @@ -121,14 +121,34 @@ export const BlockSelectionAfterEditable: EditableSiblingComponent = () => {
if (isHotkey(['backspace', 'delete'])(e) && !isReadonly) {
e.preventDefault();
editor.tf.withoutNormalizing(() => {
editor.tf.removeNodes({
const entry = editor.api.block({
at: [],
block: true,
match: (n) => !!n.id && selectedIds?.has(n.id as string),
});

if (editor.children.length === 0) {
editor.tf.focus();
if (entry) {
editor.tf.removeNodes({
at: entry[1],
});

if (editor.children.length === 0) {
editor.tf.focus();
} else {
const prevPath = isHotkey('backspace')(e)
? PathApi.previous(entry[1])
: entry[1];

if (prevPath) {
const prevEntry = editor.api.block({ at: prevPath });

if (prevEntry) {
setOption(
'selectedIds',
new Set([prevEntry[0].id as string])
);
}
}
}
}
});

Expand All @@ -150,7 +170,7 @@ export const BlockSelectionAfterEditable: EditableSiblingComponent = () => {
return;
}
},
[editor, selectedIds, api, getOptions, getOption]
[editor, getOptions, getOption, api.blockSelection, selectedIds, setOption]
);

/** Handle copy / cut / paste in block selection */
Expand All @@ -173,15 +193,31 @@ export const BlockSelectionAfterEditable: EditableSiblingComponent = () => {
copySelectedBlocks(editor);

if (!editor.api.isReadOnly()) {
editor.tf.removeNodes({
at: [],
match: (n) => selectedIds?.has(n.id as string),
});
editor.tf.focus();
const entries = [
...editor.api.nodes({
at: [],
match: (n) => selectedIds?.has(n.id as string),
}),
];

if (entries.length > 0) {
editor.tf.withoutNormalizing(() => {
for (const [, path] of [...entries].reverse()) {
editor.tf.removeNodes({
at: path,
});
}
});

const prevEntry = editor.api.block({ at: entries[0][1] });
if (prevEntry) {
setOption('selectedIds', new Set([prevEntry[0].id as string]));
}
}
}
}
},
[editor, selectedIds, getOption]
[getOption, editor, selectedIds, setOption]
);

const handlePaste = React.useCallback(
Expand Down
4 changes: 0 additions & 4 deletions packages/selection/src/react/utils/pasteSelectedBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ export const pasteSelectedBlocks = (editor: SlateEditor, e: ClipboardEvent) => {
const entry = entries.at(-1)!;
const [node, path] = entry;

editor.tf.focus({ at: path, edge: 'start' });

if (!editor.api.isEmpty(node as any)) {
const at = PathApi.next(path);

Expand All @@ -27,8 +25,6 @@ export const pasteSelectedBlocks = (editor: SlateEditor, e: ClipboardEvent) => {
// editor.tf.withoutMerging(() => {
editor.tf.insertData(e.clipboardData!);
// });
// insertData is focusing the editor so deselect
editor.tf.deselect();

selectInsertedBlocks(editor);
}
Expand Down
4 changes: 1 addition & 3 deletions packages/selection/src/react/utils/selectInsertedBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,5 @@ export const selectInsertedBlocks = (editor: SlateEditor) => {
}
});

setTimeout(() => {
setOption('selectedIds', ids);
}, 0);
setOption('selectedIds', ids);
};
Loading

0 comments on commit 84dcca3

Please sign in to comment.