@@ -6,6 +6,7 @@ import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
66import  { 
77  BlockConfig , 
88  createBlockSpecFromTiptapNode , 
9+   TableContent , 
910}  from  "../../schema/index.js" ; 
1011import  {  mergeCSSClasses  }  from  "../../util/browser.js" ; 
1112import  {  createDefaultBlockDOMOutputSpec  }  from  "../defaultBlockHelpers.js" ; 
@@ -265,59 +266,6 @@ const TiptapTableParagraph = Node.create({
265266  group : "tableContent" , 
266267  content : "inline*" , 
267268
268-   addKeyboardShortcuts ( )  { 
269-     return  { 
270-       // If the table is empty while all cells are selected, deletes the table. 
271-       Backspace : ( {  editor } )  =>  { 
272-         if  ( ! ( editor . state . selection  instanceof  CellSelection ) )  { 
273-           return  false ; 
274-         } 
275- 
276-         const  anchorCellColIndex  =  editor . state . selection . $anchorCell . index ( ) ; 
277-         const  anchorCellRowIndex  =  editor . state . selection . $anchorCell . index ( - 1 ) ; 
278-         const  headCellColIndex  =  editor . state . selection . $headCell . index ( ) ; 
279-         const  headCellRowIndex  =  editor . state . selection . $headCell . index ( - 1 ) ; 
280- 
281-         const  minColIndex  =  Math . min ( anchorCellColIndex ,  headCellColIndex ) ; 
282-         const  maxColIndex  =  Math . max ( anchorCellColIndex ,  headCellColIndex ) ; 
283-         const  minRowIndex  =  Math . min ( anchorCellRowIndex ,  headCellRowIndex ) ; 
284-         const  maxRowIndex  =  Math . max ( anchorCellRowIndex ,  headCellRowIndex ) ; 
285- 
286-         const  posBeforeTable  =  editor . state . selection . $anchorCell . before ( - 1 ) ; 
287-         const  tableNode  =  editor . state . doc . resolve ( posBeforeTable ) . nodeAfter ! ; 
288- 
289-         const  tableMap  =  TableMap . get ( tableNode ) ; 
290- 
291-         if  ( 
292-           minColIndex  !==  0  || 
293-           maxColIndex  !==  tableMap . width  -  1  || 
294-           minRowIndex  !==  0  || 
295-           maxRowIndex  !==  tableMap . height  -  1 
296-         )  { 
297-           return  false ; 
298-         } 
299- 
300-         for  ( 
301-           let  cellIndex  =  0 ; 
302-           cellIndex  <  tableMap . height  *  tableMap . width ; 
303-           cellIndex ++ 
304-         )  { 
305-           const  posBeforeCell  =  posBeforeTable  +  tableMap . map [ cellIndex ]  +  1 ; 
306-           const  cellNode  =  editor . state . doc . resolve ( posBeforeCell ) . nodeAfter ! ; 
307- 
308-           if  ( cellNode . firstChild  &&  cellNode . firstChild ?. content . size  >  0 )  { 
309-             return  false ; 
310-           } 
311-         } 
312- 
313-         return  editor . commands . deleteRange ( { 
314-           from : posBeforeTable , 
315-           to : posBeforeTable  +  tableNode . nodeSize , 
316-         } ) ; 
317-       } , 
318-     } ; 
319-   } , 
320- 
321269  parseHTML ( )  { 
322270    return  [ 
323271      { 
@@ -447,6 +395,87 @@ export const createTableBlockSpec = () =>
447395          TiptapTableRow , 
448396        ] , 
449397      } ) , 
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+             const  rows  =  content . rows . length ; 
414+             let  cols  =  0 ; 
415+ 
416+             for  ( let  rowIndex  =  0 ;  rowIndex  <  content . rows . length ;  rowIndex ++ )  { 
417+               for  ( 
418+                 let  cellIndex  =  0 ; 
419+                 cellIndex  <  content . rows [ rowIndex ] . cells . length ; 
420+                 cellIndex ++ 
421+               )  { 
422+                 const  cell  =  content . rows [ rowIndex ] . cells [ cellIndex ] ; 
423+ 
424+                 // Counts number of columns in table from first row. 
425+                 if  ( rowIndex  ===  0 )  { 
426+                   const  colSpan  = 
427+                     "type"  in  cell  &&  cell . props . colspan 
428+                       ? cell . props . colspan 
429+                       : 1 ; 
430+                   cols  +=  colSpan ; 
431+                 } 
432+ 
433+                 // Returns `false` if any cell isn't empty. 
434+                 if  ( 
435+                   ( "type"  in  cell  &&  cell . content . length  >  0 )  || 
436+                   ( ! ( "type"  in  cell )  &&  cell . length  >  0 ) 
437+                 )  { 
438+                   return  false ; 
439+                 } 
440+               } 
441+             } 
442+ 
443+             // Need to use ProseMirror API to check if selection spans table. 
444+             const  anchorCellColIndex  = 
445+               editor . prosemirrorState . selection . $anchorCell . index ( ) ; 
446+             const  anchorCellRowIndex  = 
447+               editor . prosemirrorState . selection . $anchorCell . index ( - 1 ) ; 
448+             const  headCellColIndex  = 
449+               editor . prosemirrorState . selection . $headCell . index ( ) ; 
450+             const  headCellRowIndex  = 
451+               editor . prosemirrorState . selection . $headCell . index ( - 1 ) ; 
452+ 
453+             const  minColIndex  =  Math . min ( anchorCellColIndex ,  headCellColIndex ) ; 
454+             const  maxColIndex  =  Math . max ( anchorCellColIndex ,  headCellColIndex ) ; 
455+             const  minRowIndex  =  Math . min ( anchorCellRowIndex ,  headCellRowIndex ) ; 
456+             const  maxRowIndex  =  Math . max ( anchorCellRowIndex ,  headCellRowIndex ) ; 
457+ 
458+             if  ( 
459+               minColIndex  !==  0  || 
460+               maxColIndex  !==  cols  -  1  || 
461+               minRowIndex  !==  0  || 
462+               maxRowIndex  !==  rows  -  1 
463+             )  { 
464+               return  false ; 
465+             } 
466+ 
467+             const  selectionBlock  = 
468+               editor . getPrevBlock ( block )  ||  editor . getNextBlock ( block ) ; 
469+             if  ( selectionBlock )  { 
470+               editor . setTextCursorPosition ( block ) ; 
471+             } 
472+ 
473+             editor . removeBlocks ( [ block ] ) ; 
474+ 
475+             return  true ; 
476+           } , 
477+         } , 
478+       } ) , 
450479    ] , 
451480  ) ; 
452481
0 commit comments