Skip to content

Commit 47923dd

Browse files
feat: Shortcut to delete empty table while cells are selected (#2052)
* Added shortcut to delete table while it's empty and all cells are selected * Changed keyboard handler to use BlockNote APIs * Implemented PR feedback * Fixed build
1 parent e6f80cc commit 47923dd

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

packages/core/src/blocks/Table/block.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Node, mergeAttributes } from "@tiptap/core";
22
import { DOMParser, Fragment, Node as PMNode, Schema } from "prosemirror-model";
3-
import { TableView } from "prosemirror-tables";
3+
import { CellSelection, TableView } from "prosemirror-tables";
44
import { NodeView } from "prosemirror-view";
55
import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
66
import {
77
BlockConfig,
88
createBlockSpecFromTiptapNode,
9+
TableContent,
910
} from "../../schema/index.js";
1011
import { mergeCSSClasses } from "../../util/browser.js";
1112
import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
@@ -394,6 +395,60 @@ export const createTableBlockSpec = () =>
394395
TiptapTableRow,
395396
],
396397
}),
398+
// Extension for keyboard shortcut which deletes the table if it's empty
399+
// and all cells are selected. Uses a separate extension as it needs
400+
// priority over keyboard handlers in the `TableExtension`'s
401+
// `tableEditing` plugin.
402+
createBlockNoteExtension({
403+
key: "table-keyboard-delete",
404+
keyboardShortcuts: {
405+
Backspace: ({ editor }) => {
406+
if (!(editor.prosemirrorState.selection instanceof CellSelection)) {
407+
return false;
408+
}
409+
410+
const block = editor.getTextCursorPosition().block;
411+
const content = block.content as TableContent<any, any>;
412+
413+
let numCells = 0;
414+
for (const row of content.rows) {
415+
for (const cell of row.cells) {
416+
// Returns `false` if any cell isn't empty.
417+
if (
418+
("type" in cell && cell.content.length > 0) ||
419+
(!("type" in cell) && cell.length > 0)
420+
) {
421+
return false;
422+
}
423+
424+
numCells++;
425+
}
426+
}
427+
428+
// Need to use ProseMirror API to check number of selected cells.
429+
let selectionNumCells = 0;
430+
editor.prosemirrorState.selection.forEachCell(() => {
431+
selectionNumCells++;
432+
});
433+
434+
if (selectionNumCells < numCells) {
435+
return false;
436+
}
437+
438+
editor.transact(() => {
439+
const selectionBlock =
440+
editor.getPrevBlock(block) || editor.getNextBlock(block);
441+
if (selectionBlock) {
442+
editor.setTextCursorPosition(block);
443+
}
444+
445+
editor.removeBlocks([block]);
446+
});
447+
448+
return true;
449+
},
450+
},
451+
}),
397452
],
398453
);
399454

0 commit comments

Comments
 (0)