|
1 | 1 | import { Node, mergeAttributes } from "@tiptap/core"; |
2 | 2 | import { DOMParser, Fragment, Node as PMNode, Schema } from "prosemirror-model"; |
3 | | -import { TableView } from "prosemirror-tables"; |
| 3 | +import { CellSelection, TableView } from "prosemirror-tables"; |
4 | 4 | import { NodeView } from "prosemirror-view"; |
5 | 5 | import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js"; |
6 | 6 | import { |
7 | 7 | BlockConfig, |
8 | 8 | createBlockSpecFromTiptapNode, |
| 9 | + TableContent, |
9 | 10 | } from "../../schema/index.js"; |
10 | 11 | import { mergeCSSClasses } from "../../util/browser.js"; |
11 | 12 | import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js"; |
@@ -394,6 +395,60 @@ export const createTableBlockSpec = () => |
394 | 395 | TiptapTableRow, |
395 | 396 | ], |
396 | 397 | }), |
| 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 | + }), |
397 | 452 | ], |
398 | 453 | ); |
399 | 454 |
|
|
0 commit comments