@blocknote/core 0.42.3 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/dist/BlockNoteExtension-BWw0r8Gy.cjs +2 -0
  2. package/dist/BlockNoteExtension-BWw0r8Gy.cjs.map +1 -0
  3. package/dist/BlockNoteExtension-C2X7LW-V.js +25 -0
  4. package/dist/BlockNoteExtension-C2X7LW-V.js.map +1 -0
  5. package/dist/BlockNoteSchema-B4gm-Qco.cjs +2 -0
  6. package/dist/BlockNoteSchema-B4gm-Qco.cjs.map +1 -0
  7. package/dist/BlockNoteSchema-C-l154WP.js +270 -0
  8. package/dist/BlockNoteSchema-C-l154WP.js.map +1 -0
  9. package/dist/EventEmitter-CLwfmbqG.cjs +2 -0
  10. package/dist/EventEmitter-CLwfmbqG.cjs.map +1 -0
  11. package/dist/EventEmitter-CjSwpTbz.js +27 -0
  12. package/dist/EventEmitter-CjSwpTbz.js.map +1 -0
  13. package/dist/ShowSelection-BW37oJ6h.cjs +2 -0
  14. package/dist/ShowSelection-BW37oJ6h.cjs.map +1 -0
  15. package/dist/ShowSelection-Dz-NEase.js +43 -0
  16. package/dist/ShowSelection-Dz-NEase.js.map +1 -0
  17. package/dist/TrailingNode-B_zPMWxw.js +2098 -0
  18. package/dist/TrailingNode-B_zPMWxw.js.map +1 -0
  19. package/dist/TrailingNode-CRHrgOnK.cjs +2 -0
  20. package/dist/TrailingNode-CRHrgOnK.cjs.map +1 -0
  21. package/dist/{blockToNode-DIfPWLH8.js → blockToNode-DBNbhwwC.js} +33 -33
  22. package/dist/blockToNode-DBNbhwwC.js.map +1 -0
  23. package/dist/blockToNode-w7H99R6p.cjs.map +1 -1
  24. package/dist/blocknote.cjs +4 -4
  25. package/dist/blocknote.cjs.map +1 -1
  26. package/dist/blocknote.js +2496 -5686
  27. package/dist/blocknote.js.map +1 -1
  28. package/dist/blocks.cjs +1 -1
  29. package/dist/blocks.js +71 -70
  30. package/dist/blocks.js.map +1 -1
  31. package/dist/comments.cjs +1 -1
  32. package/dist/comments.cjs.map +1 -1
  33. package/dist/comments.js +451 -137
  34. package/dist/comments.js.map +1 -1
  35. package/dist/defaultBlocks-DLJ4Q1_J.cjs +6 -0
  36. package/dist/defaultBlocks-DLJ4Q1_J.cjs.map +1 -0
  37. package/dist/{BlockNoteSchema-Bi-eeHal.js → defaultBlocks-DgA_mtQV.js} +974 -1027
  38. package/dist/defaultBlocks-DgA_mtQV.js.map +1 -0
  39. package/dist/extensions.cjs +2 -0
  40. package/dist/extensions.cjs.map +1 -0
  41. package/dist/extensions.js +57 -0
  42. package/dist/extensions.js.map +1 -0
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/webpack-stats.json +1 -1
  45. package/dist/yjs.js +1 -1
  46. package/package.json +9 -3
  47. package/src/api/nodeConversions/blockToNode.ts +1 -1
  48. package/src/api/nodeConversions/nodeToBlock.ts +1 -1
  49. package/src/blocks/Code/block.ts +4 -4
  50. package/src/blocks/Divider/block.ts +2 -2
  51. package/src/blocks/File/helpers/render/createAddFileButton.ts +7 -5
  52. package/src/blocks/Heading/block.ts +23 -20
  53. package/src/blocks/ListItem/BulletListItem/block.ts +2 -2
  54. package/src/blocks/ListItem/CheckListItem/block.ts +2 -2
  55. package/src/blocks/ListItem/NumberedListItem/block.ts +3 -3
  56. package/src/blocks/ListItem/ToggleListItem/block.ts +2 -2
  57. package/src/blocks/PageBreak/getPageBreakSlashMenuItems.ts +2 -2
  58. package/src/blocks/Paragraph/block.ts +2 -2
  59. package/src/blocks/Quote/block.ts +2 -2
  60. package/src/blocks/Table/block.ts +4 -3
  61. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +2 -1
  62. package/src/comments/extension.ts +353 -0
  63. package/src/comments/index.ts +2 -1
  64. package/src/comments/types.ts +8 -0
  65. package/src/{extensions/Comments → comments}/userstore/UserStore.ts +2 -2
  66. package/src/editor/BlockNoteEditor.test.ts +2 -23
  67. package/src/editor/BlockNoteEditor.ts +60 -453
  68. package/src/editor/BlockNoteExtension.test.ts +103 -0
  69. package/src/editor/BlockNoteExtension.ts +174 -56
  70. package/src/editor/managers/EventManager.ts +64 -35
  71. package/src/editor/managers/ExtensionManager/extensions.ts +214 -0
  72. package/src/editor/managers/ExtensionManager/index.ts +514 -0
  73. package/src/editor/managers/ExtensionManager/symbol.ts +6 -0
  74. package/src/editor/managers/SelectionManager.ts +5 -1
  75. package/src/editor/managers/StateManager.ts +29 -17
  76. package/src/editor/managers/index.ts +1 -5
  77. package/src/extensions/BlockChange/{BlockChangePlugin.ts → BlockChange.ts} +27 -29
  78. package/src/extensions/Collaboration/{ForkYDocPlugin.test.ts → ForkYDoc.test.ts} +6 -5
  79. package/src/extensions/Collaboration/ForkYDoc.ts +158 -0
  80. package/src/extensions/Collaboration/YCursorPlugin.ts +183 -0
  81. package/src/extensions/Collaboration/YSync.ts +16 -0
  82. package/src/extensions/Collaboration/YUndo.ts +12 -0
  83. package/src/extensions/Collaboration/schemaMigration/SchemaMigration.ts +59 -0
  84. package/src/extensions/DropCursor/DropCursor.ts +26 -0
  85. package/src/extensions/FilePanel/FilePanel.ts +41 -0
  86. package/src/extensions/FormattingToolbar/FormattingToolbar.ts +119 -0
  87. package/src/extensions/History/History.ts +11 -0
  88. package/src/extensions/LinkToolbar/LinkToolbar.ts +121 -0
  89. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.ts +74 -0
  90. package/src/extensions/Placeholder/Placeholder.ts +148 -0
  91. package/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.ts → PreviousBlockType.ts} +9 -13
  92. package/src/extensions/ShowSelection/{ShowSelectionPlugin.ts → ShowSelection.ts} +27 -33
  93. package/src/extensions/SideMenu/{SideMenuPlugin.ts → SideMenu.ts} +63 -83
  94. package/src/extensions/SuggestionMenu/{SuggestionPlugin.ts → SuggestionMenu.ts} +71 -77
  95. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +29 -44
  96. package/src/extensions/TableHandles/{TableHandlesPlugin.ts → TableHandles.ts} +416 -437
  97. package/src/extensions/TrailingNode/{TrailingNodeExtension.ts → TrailingNode.ts} +8 -17
  98. package/src/extensions/index.ts +24 -0
  99. package/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.ts +1 -1
  100. package/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.ts +21 -16
  101. package/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.ts +1 -1
  102. package/src/extensions/tiptap-extensions/index.ts +31 -0
  103. package/src/index.ts +1 -13
  104. package/src/schema/blocks/createSpec.ts +14 -11
  105. package/src/schema/blocks/internal.ts +2 -2
  106. package/src/schema/blocks/types.ts +8 -5
  107. package/src/schema/schema.ts +11 -36
  108. package/src/util/topo-sort.ts +46 -0
  109. package/types/src/comments/extension.d.ts +70 -0
  110. package/types/src/comments/index.d.ts +2 -1
  111. package/types/src/comments/types.d.ts +8 -0
  112. package/types/src/{extensions/Comments → comments}/userstore/UserStore.d.ts +2 -2
  113. package/types/src/editor/BlockNoteEditor.d.ts +34 -105
  114. package/types/src/editor/BlockNoteExtension.d.ts +87 -22
  115. package/types/src/editor/managers/EventManager.d.ts +25 -16
  116. package/types/src/editor/managers/ExtensionManager/extensions.d.ts +8 -0
  117. package/types/src/editor/managers/ExtensionManager/index.d.ts +83 -0
  118. package/types/src/editor/managers/ExtensionManager/symbol.d.ts +5 -0
  119. package/types/src/editor/managers/StateManager.d.ts +1 -12
  120. package/types/src/editor/managers/index.d.ts +1 -2
  121. package/types/src/extensions/BlockChange/BlockChange.d.ts +16 -0
  122. package/types/src/extensions/Collaboration/ForkYDoc.d.ts +34 -0
  123. package/types/src/extensions/Collaboration/ForkYDoc.test.d.ts +1 -0
  124. package/types/src/extensions/Collaboration/YCursorPlugin.d.ts +24 -0
  125. package/types/src/extensions/Collaboration/YSync.d.ts +8 -0
  126. package/types/src/extensions/Collaboration/YUndo.d.ts +12 -0
  127. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigration.d.ts +8 -0
  128. package/types/src/extensions/DropCursor/DropCursor.d.ts +5 -0
  129. package/types/src/extensions/FilePanel/FilePanel.d.ts +11 -0
  130. package/types/src/extensions/FormattingToolbar/FormattingToolbar.d.ts +9 -0
  131. package/types/src/extensions/History/History.d.ts +6 -0
  132. package/types/src/extensions/LinkToolbar/LinkToolbar.d.ts +24 -0
  133. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.d.ts +5 -0
  134. package/types/src/extensions/Placeholder/Placeholder.d.ts +6 -0
  135. package/types/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.d.ts → PreviousBlockType.d.ts} +9 -5
  136. package/types/src/extensions/ShowSelection/ShowSelection.d.ts +21 -0
  137. package/types/src/extensions/SideMenu/{SideMenuPlugin.d.ts → SideMenu.d.ts} +11 -15
  138. package/types/src/extensions/SuggestionMenu/SuggestionMenu.d.ts +54 -0
  139. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +1 -1
  140. package/types/src/extensions/TableHandles/{TableHandlesPlugin.d.ts → TableHandles.d.ts} +28 -31
  141. package/types/src/extensions/TrailingNode/TrailingNode.d.ts +8 -0
  142. package/types/src/extensions/index.d.ts +24 -0
  143. package/types/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.d.ts +1 -1
  144. package/types/src/extensions/tiptap-extensions/index.d.ts +11 -0
  145. package/types/src/index.d.ts +1 -13
  146. package/types/src/schema/blocks/createSpec.d.ts +4 -4
  147. package/types/src/schema/blocks/internal.d.ts +2 -2
  148. package/types/src/schema/blocks/types.d.ts +5 -5
  149. package/types/src/util/topo-sort.d.ts +8 -0
  150. package/dist/BlockNoteSchema-Bi-eeHal.js.map +0 -1
  151. package/dist/BlockNoteSchema-DjDaA2C3.cjs +0 -6
  152. package/dist/BlockNoteSchema-DjDaA2C3.cjs.map +0 -1
  153. package/dist/blockToNode-DIfPWLH8.js.map +0 -1
  154. package/src/comments/models/User.ts +0 -8
  155. package/src/editor/BlockNoteExtensions.ts +0 -325
  156. package/src/editor/managers/CollaborationManager.ts +0 -212
  157. package/src/editor/managers/ExtensionManager.ts +0 -130
  158. package/src/extensions/Collaboration/CursorPlugin.ts +0 -189
  159. package/src/extensions/Collaboration/ForkYDocPlugin.ts +0 -192
  160. package/src/extensions/Collaboration/SyncPlugin.ts +0 -18
  161. package/src/extensions/Collaboration/UndoPlugin.ts +0 -18
  162. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +0 -59
  163. package/src/extensions/Comments/CommentsPlugin.ts +0 -392
  164. package/src/extensions/FilePanel/FilePanelPlugin.ts +0 -206
  165. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +0 -363
  166. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +0 -380
  167. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +0 -75
  168. package/src/extensions/Placeholder/PlaceholderPlugin.ts +0 -147
  169. package/types/src/comments/models/User.d.ts +0 -8
  170. package/types/src/editor/BlockNoteExtensions.d.ts +0 -43
  171. package/types/src/editor/managers/CollaborationManager.d.ts +0 -115
  172. package/types/src/editor/managers/ExtensionManager.d.ts +0 -68
  173. package/types/src/extensions/BlockChange/BlockChangePlugin.d.ts +0 -15
  174. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +0 -37
  175. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +0 -41
  176. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +0 -7
  177. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +0 -9
  178. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +0 -7
  179. package/types/src/extensions/Comments/CommentsPlugin.d.ts +0 -66
  180. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +0 -31
  181. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +0 -41
  182. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +0 -42
  183. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +0 -5
  184. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +0 -6
  185. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +0 -15
  186. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +0 -31
  187. package/types/src/extensions/TrailingNode/TrailingNodeExtension.d.ts +0 -13
  188. /package/src/{extensions/Comments/CommentMark.ts → comments/mark.ts} +0 -0
  189. /package/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.ts +0 -0
  190. /package/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.ts +0 -0
  191. /package/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.ts +0 -0
  192. /package/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.ts +0 -0
  193. /package/types/src/{extensions/Comments/CommentMark.d.ts → comments/mark.d.ts} +0 -0
  194. /package/types/src/{extensions/Collaboration/ForkYDocPlugin.test.d.ts → editor/BlockNoteExtension.test.d.ts} +0 -0
  195. /package/types/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.d.ts +0 -0
  196. /package/types/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.d.ts +0 -0
  197. /package/types/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.d.ts +0 -0
  198. /package/types/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.d.ts +0 -0
  199. /package/types/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.d.ts +0 -0
  200. /package/types/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.d.ts +0 -0
@@ -32,29 +32,27 @@ import {
32
32
  } from "../../blocks/defaultBlockTypeGuards.js";
33
33
  import { DefaultBlockSchema } from "../../blocks/defaultBlocks.js";
34
34
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
35
- import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js";
35
+ import {
36
+ createExtension,
37
+ createStore,
38
+ } from "../../editor/BlockNoteExtension.js";
36
39
  import {
37
40
  BlockFromConfigNoChildren,
38
41
  BlockSchemaWithBlock,
39
- InlineContentSchema,
40
- StyleSchema,
41
42
  } from "../../schema/index.js";
42
43
  import { getDraggableBlockFromElement } from "../getDraggableBlockFromElement.js";
43
44
 
44
45
  let dragImageElement: HTMLElement | undefined;
45
46
 
46
47
  // TODO consider switching this to jotai, it is a bit messy and noisy
47
- export type TableHandlesState<
48
- I extends InlineContentSchema,
49
- S extends StyleSchema,
50
- > = {
48
+ export type TableHandlesState = {
51
49
  show: boolean;
52
50
  showAddOrRemoveRowsButton: boolean;
53
51
  showAddOrRemoveColumnsButton: boolean;
54
52
  referencePosCell: DOMRect | undefined;
55
53
  referencePosTable: DOMRect;
56
54
 
57
- block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], I, S>;
55
+ block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>;
58
56
  colIndex: number | undefined;
59
57
  rowIndex: number | undefined;
60
58
 
@@ -144,12 +142,8 @@ function hideElements(selector: string, rootEl: Document | ShadowRoot) {
144
142
  }
145
143
  }
146
144
 
147
- export class TableHandlesView<
148
- I extends InlineContentSchema,
149
- S extends StyleSchema,
150
- > implements PluginView
151
- {
152
- public state?: TableHandlesState<I, S>;
145
+ export class TableHandlesView implements PluginView {
146
+ public state?: TableHandlesState;
153
147
  public emitUpdate: () => void;
154
148
 
155
149
  public tableId: string | undefined;
@@ -165,11 +159,11 @@ export class TableHandlesView<
165
159
  constructor(
166
160
  private readonly editor: BlockNoteEditor<
167
161
  BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
168
- I,
169
- S
162
+ any,
163
+ any
170
164
  >,
171
165
  private readonly pmView: EditorView,
172
- emitUpdate: (state: TableHandlesState<I, S>) => void,
166
+ emitUpdate: (state: TableHandlesState) => void,
173
167
  ) {
174
168
  this.emitUpdate = () => {
175
169
  if (!this.state) {
@@ -260,7 +254,7 @@ export class TableHandlesView<
260
254
  this.tableElement = blockEl.node;
261
255
 
262
256
  let tableBlock:
263
- | BlockFromConfigNoChildren<DefaultBlockSchema["table"], I, S>
257
+ | BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>
264
258
  | undefined;
265
259
 
266
260
  const pmNodeInfo = this.editor.transact((tr) =>
@@ -614,57 +608,52 @@ export class TableHandlesView<
614
608
 
615
609
  export const tableHandlesPluginKey = new PluginKey("TableHandlesPlugin");
616
610
 
617
- export class TableHandlesProsemirrorPlugin<
618
- I extends InlineContentSchema,
619
- S extends StyleSchema,
620
- > extends BlockNoteExtension {
621
- public static key() {
622
- return "tableHandles";
623
- }
611
+ export const TableHandlesExtension = createExtension(({ editor }) => {
612
+ let view: TableHandlesView | undefined = undefined;
624
613
 
625
- private view: TableHandlesView<I, S> | undefined;
614
+ const store = createStore<TableHandlesState | undefined>(undefined);
626
615
 
627
- constructor(
628
- private readonly editor: BlockNoteEditor<
629
- BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
630
- I,
631
- S
632
- >,
633
- ) {
634
- super();
635
- this.addProsemirrorPlugin(
616
+ return {
617
+ key: "tableHandles",
618
+ store,
619
+ prosemirrorPlugins: [
636
620
  new Plugin({
637
621
  key: tableHandlesPluginKey,
638
622
  view: (editorView) => {
639
- this.view = new TableHandlesView(editor, editorView, (state) => {
640
- this.emit("update", state);
623
+ view = new TableHandlesView(editor as any, editorView, (state) => {
624
+ store.setState({
625
+ ...state,
626
+ draggingState: state.draggingState
627
+ ? { ...state.draggingState }
628
+ : undefined,
629
+ });
641
630
  });
642
- return this.view;
631
+ return view;
643
632
  },
644
633
  // We use decorations to render the drop cursor when dragging a table row
645
634
  // or column. The decorations are updated in the `dragOverHandler` method.
646
635
  props: {
647
636
  decorations: (state) => {
648
637
  if (
649
- this.view === undefined ||
650
- this.view.state === undefined ||
651
- this.view.state.draggingState === undefined ||
652
- this.view.tablePos === undefined
638
+ view === undefined ||
639
+ view.state === undefined ||
640
+ view.state.draggingState === undefined ||
641
+ view.tablePos === undefined
653
642
  ) {
654
643
  return;
655
644
  }
656
645
 
657
646
  const newIndex =
658
- this.view.state.draggingState.draggedCellOrientation === "row"
659
- ? this.view.state.rowIndex
660
- : this.view.state.colIndex;
647
+ view.state.draggingState.draggedCellOrientation === "row"
648
+ ? view.state.rowIndex
649
+ : view.state.colIndex;
661
650
 
662
651
  if (newIndex === undefined) {
663
652
  return;
664
653
  }
665
654
 
666
655
  const decorations: Decoration[] = [];
667
- const { block, draggingState } = this.view.state;
656
+ const { block, draggingState } = view.state;
668
657
  const { originalIndex, draggedCellOrientation } = draggingState;
669
658
 
670
659
  // Return empty decorations if:
@@ -684,13 +673,11 @@ export class TableHandlesProsemirrorPlugin<
684
673
  }
685
674
 
686
675
  // Gets the table to show the drop cursor in.
687
- const tableResolvedPos = state.doc.resolve(this.view.tablePos + 1);
676
+ const tableResolvedPos = state.doc.resolve(view.tablePos + 1);
688
677
 
689
- if (
690
- this.view.state.draggingState.draggedCellOrientation === "row"
691
- ) {
678
+ if (view.state.draggingState.draggedCellOrientation === "row") {
692
679
  const cellsInRow = getCellsAtRowHandle(
693
- this.view.state.block,
680
+ view.state.block,
694
681
  newIndex,
695
682
  );
696
683
 
@@ -736,7 +723,7 @@ export class TableHandlesProsemirrorPlugin<
736
723
  });
737
724
  } else {
738
725
  const cellsInColumn = getCellsAtColumnHandle(
739
- this.view.state.block,
726
+ view.state.block,
740
727
  newIndex,
741
728
  );
742
729
 
@@ -788,423 +775,415 @@ export class TableHandlesProsemirrorPlugin<
788
775
  },
789
776
  },
790
777
  }),
791
- );
792
- }
793
-
794
- public onUpdate(callback: (state: TableHandlesState<I, S>) => void) {
795
- return this.on("update", callback);
796
- }
797
-
798
- /**
799
- * Callback that should be set on the `dragStart` event for whichever element
800
- * is used as the column drag handle.
801
- */
802
- colDragStart = (event: {
803
- dataTransfer: DataTransfer | null;
804
- clientX: number;
805
- }) => {
806
- if (
807
- this.view!.state === undefined ||
808
- this.view!.state.colIndex === undefined
809
- ) {
810
- throw new Error(
811
- "Attempted to drag table column, but no table block was hovered prior.",
812
- );
813
- }
814
-
815
- this.view!.state.draggingState = {
816
- draggedCellOrientation: "col",
817
- originalIndex: this.view!.state.colIndex,
818
- mousePos: event.clientX,
819
- };
820
- this.view!.emitUpdate();
821
-
822
- this.editor.transact((tr) =>
823
- tr.setMeta(tableHandlesPluginKey, {
824
- draggedCellOrientation:
825
- this.view!.state!.draggingState!.draggedCellOrientation,
826
- originalIndex: this.view!.state!.colIndex,
827
- newIndex: this.view!.state!.colIndex,
828
- tablePos: this.view!.tablePos,
829
- }),
830
- );
831
-
832
- if (this.editor.headless) {
833
- return;
834
- }
835
-
836
- setHiddenDragImage(this.editor.prosemirrorView.root);
837
- event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);
838
- event.dataTransfer!.effectAllowed = "move";
839
- };
778
+ ],
779
+
780
+ /**
781
+ * Callback that should be set on the `dragStart` event for whichever element
782
+ * is used as the column drag handle.
783
+ */
784
+ colDragStart(event: {
785
+ dataTransfer: DataTransfer | null;
786
+ clientX: number;
787
+ }) {
788
+ if (
789
+ view === undefined ||
790
+ view.state === undefined ||
791
+ view.state.colIndex === undefined
792
+ ) {
793
+ throw new Error(
794
+ "Attempted to drag table column, but no table block was hovered prior.",
795
+ );
796
+ }
840
797
 
841
- /**
842
- * Callback that should be set on the `dragStart` event for whichever element
843
- * is used as the row drag handle.
844
- */
845
- rowDragStart = (event: {
846
- dataTransfer: DataTransfer | null;
847
- clientY: number;
848
- }) => {
849
- if (
850
- this.view!.state === undefined ||
851
- this.view!.state.rowIndex === undefined
852
- ) {
853
- throw new Error(
854
- "Attempted to drag table row, but no table block was hovered prior.",
798
+ view.state.draggingState = {
799
+ draggedCellOrientation: "col",
800
+ originalIndex: view.state.colIndex,
801
+ mousePos: event.clientX,
802
+ };
803
+ view.emitUpdate();
804
+
805
+ editor.transact((tr) =>
806
+ tr.setMeta(tableHandlesPluginKey, {
807
+ draggedCellOrientation:
808
+ view!.state!.draggingState!.draggedCellOrientation,
809
+ originalIndex: view!.state!.colIndex,
810
+ newIndex: view!.state!.colIndex,
811
+ tablePos: view!.tablePos,
812
+ }),
855
813
  );
856
- }
857
-
858
- this.view!.state.draggingState = {
859
- draggedCellOrientation: "row",
860
- originalIndex: this.view!.state.rowIndex,
861
- mousePos: event.clientY,
862
- };
863
- this.view!.emitUpdate();
864
-
865
- this.editor.transact((tr) =>
866
- tr.setMeta(tableHandlesPluginKey, {
867
- draggedCellOrientation:
868
- this.view!.state!.draggingState!.draggedCellOrientation,
869
- originalIndex: this.view!.state!.rowIndex,
870
- newIndex: this.view!.state!.rowIndex,
871
- tablePos: this.view!.tablePos,
872
- }),
873
- );
874
814
 
875
- if (this.editor.headless) {
876
- return;
877
- }
815
+ if (editor.headless) {
816
+ return;
817
+ }
878
818
 
879
- setHiddenDragImage(this.editor.prosemirrorView.root);
880
- event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);
881
- event.dataTransfer!.effectAllowed = "copyMove";
882
- };
819
+ setHiddenDragImage(editor.prosemirrorView.root);
820
+ event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);
821
+ event.dataTransfer!.effectAllowed = "move";
822
+ },
823
+
824
+ /**
825
+ * Callback that should be set on the `dragStart` event for whichever element
826
+ * is used as the row drag handle.
827
+ */
828
+ rowDragStart(event: {
829
+ dataTransfer: DataTransfer | null;
830
+ clientY: number;
831
+ }) {
832
+ if (view!.state === undefined || view!.state.rowIndex === undefined) {
833
+ throw new Error(
834
+ "Attempted to drag table row, but no table block was hovered prior.",
835
+ );
836
+ }
883
837
 
884
- /**
885
- * Callback that should be set on the `dragEnd` event for both the element
886
- * used as the row drag handle, and the one used as the column drag handle.
887
- */
888
- dragEnd = () => {
889
- if (this.view!.state === undefined) {
890
- throw new Error(
891
- "Attempted to drag table row, but no table block was hovered prior.",
838
+ view!.state.draggingState = {
839
+ draggedCellOrientation: "row",
840
+ originalIndex: view!.state.rowIndex,
841
+ mousePos: event.clientY,
842
+ };
843
+ view!.emitUpdate();
844
+
845
+ editor.transact((tr) =>
846
+ tr.setMeta(tableHandlesPluginKey, {
847
+ draggedCellOrientation:
848
+ view!.state!.draggingState!.draggedCellOrientation,
849
+ originalIndex: view!.state!.rowIndex,
850
+ newIndex: view!.state!.rowIndex,
851
+ tablePos: view!.tablePos,
852
+ }),
892
853
  );
893
- }
894
854
 
895
- this.view!.state.draggingState = undefined;
896
- this.view!.emitUpdate();
897
-
898
- this.editor.transact((tr) => tr.setMeta(tableHandlesPluginKey, null));
899
-
900
- if (this.editor.headless) {
901
- return;
902
- }
903
-
904
- unsetHiddenDragImage(this.editor.prosemirrorView.root);
905
- };
906
-
907
- /**
908
- * Freezes the drag handles. When frozen, they will stay attached to the same
909
- * cell regardless of which cell is hovered by the mouse cursor.
910
- */
911
- freezeHandles = () => {
912
- this.view!.menuFrozen = true;
913
- };
914
-
915
- /**
916
- * Unfreezes the drag handles. When frozen, they will stay attached to the
917
- * same cell regardless of which cell is hovered by the mouse cursor.
918
- */
919
- unfreezeHandles = () => {
920
- this.view!.menuFrozen = false;
921
- };
855
+ if (editor.headless) {
856
+ return;
857
+ }
922
858
 
923
- getCellsAtRowHandle = (
924
- block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
925
- relativeRowIndex: RelativeCellIndices["row"],
926
- ) => {
927
- return getCellsAtRowHandle(block, relativeRowIndex);
928
- };
859
+ setHiddenDragImage(editor.prosemirrorView.root);
860
+ event.dataTransfer!.setDragImage(dragImageElement!, 0, 0);
861
+ event.dataTransfer!.effectAllowed = "copyMove";
862
+ },
863
+
864
+ /**
865
+ * Callback that should be set on the `dragEnd` event for both the element
866
+ * used as the row drag handle, and the one used as the column drag handle.
867
+ */
868
+ dragEnd() {
869
+ if (view!.state === undefined) {
870
+ throw new Error(
871
+ "Attempted to drag table row, but no table block was hovered prior.",
872
+ );
873
+ }
929
874
 
930
- /**
931
- * Get all the cells in a column of the table block.
932
- */
933
- getCellsAtColumnHandle = (
934
- block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
935
- relativeColumnIndex: RelativeCellIndices["col"],
936
- ) => {
937
- return getCellsAtColumnHandle(block, relativeColumnIndex);
938
- };
875
+ view!.state.draggingState = undefined;
876
+ view!.emitUpdate();
939
877
 
940
- /**
941
- * Sets the selection to the given cell or a range of cells.
942
- * @returns The new state after the selection has been set.
943
- */
944
- private setCellSelection = (
945
- state: EditorState,
946
- relativeStartCell: RelativeCellIndices,
947
- relativeEndCell: RelativeCellIndices = relativeStartCell,
948
- ) => {
949
- const view = this.view;
950
-
951
- if (!view) {
952
- throw new Error("Table handles view not initialized");
953
- }
878
+ editor.transact((tr) => tr.setMeta(tableHandlesPluginKey, null));
954
879
 
955
- const tableResolvedPos = state.doc.resolve(view.tablePos! + 1);
956
- const startRowResolvedPos = state.doc.resolve(
957
- tableResolvedPos.posAtIndex(relativeStartCell.row) + 1,
958
- );
959
- const startCellResolvedPos = state.doc.resolve(
960
- // No need for +1, since CellSelection expects the position before the cell
961
- startRowResolvedPos.posAtIndex(relativeStartCell.col),
962
- );
963
- const endRowResolvedPos = state.doc.resolve(
964
- tableResolvedPos.posAtIndex(relativeEndCell.row) + 1,
965
- );
966
- const endCellResolvedPos = state.doc.resolve(
967
- // No need for +1, since CellSelection expects the position before the cell
968
- endRowResolvedPos.posAtIndex(relativeEndCell.col),
969
- );
880
+ if (editor.headless) {
881
+ return;
882
+ }
970
883
 
971
- // Begin a new transaction to set the selection
972
- const tr = state.tr;
884
+ unsetHiddenDragImage(editor.prosemirrorView.root);
885
+ },
886
+
887
+ /**
888
+ * Freezes the drag handles. When frozen, they will stay attached to the same
889
+ * cell regardless of which cell is hovered by the mouse cursor.
890
+ */
891
+ freezeHandles() {
892
+ view!.menuFrozen = true;
893
+ },
894
+
895
+ /**
896
+ * Unfreezes the drag handles. When frozen, they will stay attached to the
897
+ * same cell regardless of which cell is hovered by the mouse cursor.
898
+ */
899
+ unfreezeHandles() {
900
+ view!.menuFrozen = false;
901
+ },
902
+
903
+ getCellsAtRowHandle(
904
+ block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
905
+ relativeRowIndex: RelativeCellIndices["row"],
906
+ ) {
907
+ return getCellsAtRowHandle(block, relativeRowIndex);
908
+ },
909
+
910
+ /**
911
+ * Get all the cells in a column of the table block.
912
+ */
913
+ getCellsAtColumnHandle(
914
+ block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
915
+ relativeColumnIndex: RelativeCellIndices["col"],
916
+ ) {
917
+ return getCellsAtColumnHandle(block, relativeColumnIndex);
918
+ },
919
+
920
+ /**
921
+ * Sets the selection to the given cell or a range of cells.
922
+ * @returns The new state after the selection has been set.
923
+ */
924
+ setCellSelection(
925
+ state: EditorState,
926
+ relativeStartCell: RelativeCellIndices,
927
+ relativeEndCell: RelativeCellIndices = relativeStartCell,
928
+ ) {
929
+ if (!view) {
930
+ throw new Error("Table handles view not initialized");
931
+ }
973
932
 
974
- // Set the selection to the given cell or a range of cells
975
- tr.setSelection(
976
- new CellSelection(startCellResolvedPos, endCellResolvedPos),
977
- );
933
+ const tableResolvedPos = state.doc.resolve(view.tablePos! + 1);
934
+ const startRowResolvedPos = state.doc.resolve(
935
+ tableResolvedPos.posAtIndex(relativeStartCell.row) + 1,
936
+ );
937
+ const startCellResolvedPos = state.doc.resolve(
938
+ // No need for +1, since CellSelection expects the position before the cell
939
+ startRowResolvedPos.posAtIndex(relativeStartCell.col),
940
+ );
941
+ const endRowResolvedPos = state.doc.resolve(
942
+ tableResolvedPos.posAtIndex(relativeEndCell.row) + 1,
943
+ );
944
+ const endCellResolvedPos = state.doc.resolve(
945
+ // No need for +1, since CellSelection expects the position before the cell
946
+ endRowResolvedPos.posAtIndex(relativeEndCell.col),
947
+ );
978
948
 
979
- // Quickly apply the transaction to get the new state to update the selection before splitting the cell
980
- return state.apply(tr);
981
- };
949
+ // Begin a new transaction to set the selection
950
+ const tr = state.tr;
982
951
 
983
- /**
984
- * Adds a row or column to the table using prosemirror-table commands
985
- */
986
- addRowOrColumn = (
987
- index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
988
- direction:
989
- | { orientation: "row"; side: "above" | "below" }
990
- | { orientation: "column"; side: "left" | "right" },
991
- ) => {
992
- this.editor.exec((beforeState, dispatch) => {
993
- const state = this.setCellSelection(
994
- beforeState,
995
- direction.orientation === "row"
996
- ? { row: index, col: 0 }
997
- : { row: 0, col: index },
952
+ // Set the selection to the given cell or a range of cells
953
+ tr.setSelection(
954
+ new CellSelection(startCellResolvedPos, endCellResolvedPos),
998
955
  );
999
956
 
1000
- if (direction.orientation === "row") {
1001
- if (direction.side === "above") {
1002
- return addRowBefore(state, dispatch);
957
+ // Quickly apply the transaction to get the new state to update the selection before splitting the cell
958
+ return state.apply(tr);
959
+ },
960
+
961
+ /**
962
+ * Adds a row or column to the table using prosemirror-table commands
963
+ */
964
+ addRowOrColumn(
965
+ index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
966
+ direction:
967
+ | { orientation: "row"; side: "above" | "below" }
968
+ | { orientation: "column"; side: "left" | "right" },
969
+ ) {
970
+ editor.exec((beforeState, dispatch) => {
971
+ const state = this.setCellSelection(
972
+ beforeState,
973
+ direction.orientation === "row"
974
+ ? { row: index, col: 0 }
975
+ : { row: 0, col: index },
976
+ );
977
+
978
+ if (direction.orientation === "row") {
979
+ if (direction.side === "above") {
980
+ return addRowBefore(state, dispatch);
981
+ } else {
982
+ return addRowAfter(state, dispatch);
983
+ }
1003
984
  } else {
1004
- return addRowAfter(state, dispatch);
985
+ if (direction.side === "left") {
986
+ return addColumnBefore(state, dispatch);
987
+ } else {
988
+ return addColumnAfter(state, dispatch);
989
+ }
1005
990
  }
991
+ });
992
+ },
993
+
994
+ /**
995
+ * Removes a row or column from the table using prosemirror-table commands
996
+ */
997
+ removeRowOrColumn(
998
+ index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
999
+ direction: "row" | "column",
1000
+ ) {
1001
+ if (direction === "row") {
1002
+ return editor.exec((beforeState, dispatch) => {
1003
+ const state = this.setCellSelection(beforeState, {
1004
+ row: index,
1005
+ col: 0,
1006
+ });
1007
+ return deleteRow(state, dispatch);
1008
+ });
1006
1009
  } else {
1007
- if (direction.side === "left") {
1008
- return addColumnBefore(state, dispatch);
1009
- } else {
1010
- return addColumnAfter(state, dispatch);
1011
- }
1012
- }
1013
- });
1014
- };
1015
-
1016
- /**
1017
- * Removes a row or column from the table using prosemirror-table commands
1018
- */
1019
- removeRowOrColumn = (
1020
- index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
1021
- direction: "row" | "column",
1022
- ) => {
1023
- if (direction === "row") {
1024
- return this.editor.exec((beforeState, dispatch) => {
1025
- const state = this.setCellSelection(beforeState, {
1026
- row: index,
1027
- col: 0,
1010
+ return editor.exec((beforeState, dispatch) => {
1011
+ const state = this.setCellSelection(beforeState, {
1012
+ row: 0,
1013
+ col: index,
1014
+ });
1015
+ return deleteColumn(state, dispatch);
1028
1016
  });
1029
- return deleteRow(state, dispatch);
1017
+ }
1018
+ },
1019
+
1020
+ /**
1021
+ * Merges the cells in the table block.
1022
+ */
1023
+ mergeCells(cellsToMerge?: {
1024
+ relativeStartCell: RelativeCellIndices;
1025
+ relativeEndCell: RelativeCellIndices;
1026
+ }) {
1027
+ return editor.exec((beforeState, dispatch) => {
1028
+ const state = cellsToMerge
1029
+ ? this.setCellSelection(
1030
+ beforeState,
1031
+ cellsToMerge.relativeStartCell,
1032
+ cellsToMerge.relativeEndCell,
1033
+ )
1034
+ : beforeState;
1035
+
1036
+ return mergeCells(state, dispatch);
1030
1037
  });
1031
- } else {
1032
- return this.editor.exec((beforeState, dispatch) => {
1033
- const state = this.setCellSelection(beforeState, {
1034
- row: 0,
1035
- col: index,
1036
- });
1037
- return deleteColumn(state, dispatch);
1038
+ },
1039
+
1040
+ /**
1041
+ * Splits the cell in the table block.
1042
+ * If no cell is provided, the current cell selected will be split.
1043
+ */
1044
+ splitCell(relativeCellToSplit?: RelativeCellIndices) {
1045
+ return editor.exec((beforeState, dispatch) => {
1046
+ const state = relativeCellToSplit
1047
+ ? this.setCellSelection(beforeState, relativeCellToSplit)
1048
+ : beforeState;
1049
+
1050
+ return splitCell(state, dispatch);
1038
1051
  });
1039
- }
1040
- };
1041
-
1042
- /**
1043
- * Merges the cells in the table block.
1044
- */
1045
- mergeCells = (cellsToMerge?: {
1046
- relativeStartCell: RelativeCellIndices;
1047
- relativeEndCell: RelativeCellIndices;
1048
- }) => {
1049
- return this.editor.exec((beforeState, dispatch) => {
1050
- const state = cellsToMerge
1051
- ? this.setCellSelection(
1052
- beforeState,
1053
- cellsToMerge.relativeStartCell,
1054
- cellsToMerge.relativeEndCell,
1055
- )
1056
- : beforeState;
1057
-
1058
- return mergeCells(state, dispatch);
1059
- });
1060
- };
1061
-
1062
- /**
1063
- * Splits the cell in the table block.
1064
- * If no cell is provided, the current cell selected will be split.
1065
- */
1066
- splitCell = (relativeCellToSplit?: RelativeCellIndices) => {
1067
- return this.editor.exec((beforeState, dispatch) => {
1068
- const state = relativeCellToSplit
1069
- ? this.setCellSelection(beforeState, relativeCellToSplit)
1070
- : beforeState;
1071
-
1072
- return splitCell(state, dispatch);
1073
- });
1074
- };
1052
+ },
1053
+
1054
+ /**
1055
+ * Gets the start and end cells of the current cell selection.
1056
+ * @returns The start and end cells of the current cell selection.
1057
+ */
1058
+ getCellSelection():
1059
+ | undefined
1060
+ | {
1061
+ from: RelativeCellIndices;
1062
+ to: RelativeCellIndices;
1063
+ /**
1064
+ * All of the cells that are within the selected range.
1065
+ */
1066
+ cells: RelativeCellIndices[];
1067
+ } {
1068
+ // Based on the current selection, find the table cells that are within the selected range
1069
+
1070
+ return editor.transact((tr) => {
1071
+ const selection = tr.selection;
1072
+
1073
+ let $fromCell = selection.$from;
1074
+ let $toCell = selection.$to;
1075
+ if (isTableCellSelection(selection)) {
1076
+ // When the selection is a table cell selection, we can find the
1077
+ // from and to cells by iterating over the ranges in the selection
1078
+ const { ranges } = selection;
1079
+ ranges.forEach((range) => {
1080
+ $fromCell = range.$from.min($fromCell ?? range.$from);
1081
+ $toCell = range.$to.max($toCell ?? range.$to);
1082
+ });
1083
+ } else {
1084
+ // When the selection is a normal text selection
1085
+ // Assumes we are within a tableParagraph
1086
+ // And find the from and to cells by resolving the positions
1087
+ $fromCell = tr.doc.resolve(
1088
+ selection.$from.pos - selection.$from.parentOffset - 1,
1089
+ );
1090
+ $toCell = tr.doc.resolve(
1091
+ selection.$to.pos - selection.$to.parentOffset - 1,
1092
+ );
1093
+
1094
+ // Opt-out when the selection is not pointing into cells
1095
+ if ($fromCell.pos === 0 || $toCell.pos === 0) {
1096
+ return undefined;
1097
+ }
1098
+ }
1075
1099
 
1076
- /**
1077
- * Gets the start and end cells of the current cell selection.
1078
- * @returns The start and end cells of the current cell selection.
1079
- */
1080
- getCellSelection = ():
1081
- | undefined
1082
- | {
1083
- from: RelativeCellIndices;
1084
- to: RelativeCellIndices;
1085
- /**
1086
- * All of the cells that are within the selected range.
1087
- */
1088
- cells: RelativeCellIndices[];
1089
- } => {
1090
- // Based on the current selection, find the table cells that are within the selected range
1091
-
1092
- return this.editor.transact((tr) => {
1093
- const selection = tr.selection;
1094
-
1095
- let $fromCell = selection.$from;
1096
- let $toCell = selection.$to;
1097
- if (isTableCellSelection(selection)) {
1098
- // When the selection is a table cell selection, we can find the
1099
- // from and to cells by iterating over the ranges in the selection
1100
- const { ranges } = selection;
1101
- ranges.forEach((range) => {
1102
- $fromCell = range.$from.min($fromCell ?? range.$from);
1103
- $toCell = range.$to.max($toCell ?? range.$to);
1104
- });
1105
- } else {
1106
- // When the selection is a normal text selection
1107
- // Assumes we are within a tableParagraph
1108
- // And find the from and to cells by resolving the positions
1109
- $fromCell = tr.doc.resolve(
1110
- selection.$from.pos - selection.$from.parentOffset - 1,
1111
- );
1112
- $toCell = tr.doc.resolve(
1113
- selection.$to.pos - selection.$to.parentOffset - 1,
1100
+ // Find the row and table that the from and to cells are in
1101
+ const $fromRow = tr.doc.resolve(
1102
+ $fromCell.pos - $fromCell.parentOffset - 1,
1114
1103
  );
1104
+ const $toRow = tr.doc.resolve($toCell.pos - $toCell.parentOffset - 1);
1105
+
1106
+ // Find the table
1107
+ const $table = tr.doc.resolve($fromRow.pos - $fromRow.parentOffset - 1);
1108
+
1109
+ // Find the column and row indices of the from and to cells
1110
+ const fromColIndex = $fromCell.index($fromRow.depth);
1111
+ const fromRowIndex = $fromRow.index($table.depth);
1112
+ const toColIndex = $toCell.index($toRow.depth);
1113
+ const toRowIndex = $toRow.index($table.depth);
1114
+
1115
+ const cells: RelativeCellIndices[] = [];
1116
+ for (let row = fromRowIndex; row <= toRowIndex; row++) {
1117
+ for (let col = fromColIndex; col <= toColIndex; col++) {
1118
+ cells.push({ row, col });
1119
+ }
1120
+ }
1115
1121
 
1116
- // Opt-out when the selection is not pointing into cells
1117
- if ($fromCell.pos === 0 || $toCell.pos === 0) {
1122
+ return {
1123
+ from: {
1124
+ row: fromRowIndex,
1125
+ col: fromColIndex,
1126
+ },
1127
+ to: {
1128
+ row: toRowIndex,
1129
+ col: toColIndex,
1130
+ },
1131
+ cells,
1132
+ };
1133
+ });
1134
+ },
1135
+
1136
+ /**
1137
+ * Gets the direction of the merge based on the current cell selection.
1138
+ *
1139
+ * Returns undefined when there is no cell selection, or the selection is not within a table.
1140
+ */
1141
+ getMergeDirection(
1142
+ block:
1143
+ | BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>
1144
+ | undefined,
1145
+ ) {
1146
+ return editor.transact((tr) => {
1147
+ const isSelectingTableCells = isTableCellSelection(tr.selection)
1148
+ ? tr.selection
1149
+ : undefined;
1150
+
1151
+ if (
1152
+ !isSelectingTableCells ||
1153
+ !block ||
1154
+ // Only offer the merge button if there is more than one cell selected.
1155
+ isSelectingTableCells.ranges.length <= 1
1156
+ ) {
1118
1157
  return undefined;
1119
1158
  }
1120
- }
1121
1159
 
1122
- // Find the row and table that the from and to cells are in
1123
- const $fromRow = tr.doc.resolve(
1124
- $fromCell.pos - $fromCell.parentOffset - 1,
1125
- );
1126
- const $toRow = tr.doc.resolve($toCell.pos - $toCell.parentOffset - 1);
1160
+ const cellSelection = this.getCellSelection();
1127
1161
 
1128
- // Find the table
1129
- const $table = tr.doc.resolve($fromRow.pos - $fromRow.parentOffset - 1);
1130
-
1131
- // Find the column and row indices of the from and to cells
1132
- const fromColIndex = $fromCell.index($fromRow.depth);
1133
- const fromRowIndex = $fromRow.index($table.depth);
1134
- const toColIndex = $toCell.index($toRow.depth);
1135
- const toRowIndex = $toRow.index($table.depth);
1136
-
1137
- const cells: RelativeCellIndices[] = [];
1138
- for (let row = fromRowIndex; row <= toRowIndex; row++) {
1139
- for (let col = fromColIndex; col <= toColIndex; col++) {
1140
- cells.push({ row, col });
1162
+ if (!cellSelection) {
1163
+ return undefined;
1141
1164
  }
1142
- }
1143
-
1144
- return {
1145
- from: {
1146
- row: fromRowIndex,
1147
- col: fromColIndex,
1148
- },
1149
- to: {
1150
- row: toRowIndex,
1151
- col: toColIndex,
1152
- },
1153
- cells,
1154
- };
1155
- });
1156
- };
1157
1165
 
1158
- /**
1159
- * Gets the direction of the merge based on the current cell selection.
1160
- *
1161
- * Returns undefined when there is no cell selection, or the selection is not within a table.
1162
- */
1163
- getMergeDirection = (
1164
- block:
1165
- | BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>
1166
- | undefined,
1167
- ) => {
1168
- return this.editor.transact((tr) => {
1169
- const isSelectingTableCells = isTableCellSelection(tr.selection)
1170
- ? tr.selection
1171
- : undefined;
1172
-
1173
- if (
1174
- !isSelectingTableCells ||
1175
- !block ||
1176
- // Only offer the merge button if there is more than one cell selected.
1177
- isSelectingTableCells.ranges.length <= 1
1178
- ) {
1179
- return undefined;
1180
- }
1181
-
1182
- const cellSelection = this.getCellSelection();
1183
-
1184
- if (!cellSelection) {
1185
- return undefined;
1186
- }
1187
-
1188
- if (areInSameColumn(cellSelection.from, cellSelection.to, block)) {
1189
- return "vertical";
1190
- }
1166
+ if (areInSameColumn(cellSelection.from, cellSelection.to, block)) {
1167
+ return "vertical";
1168
+ }
1191
1169
 
1192
- return "horizontal";
1193
- });
1194
- };
1170
+ return "horizontal";
1171
+ });
1172
+ },
1195
1173
 
1196
- cropEmptyRowsOrColumns = (
1197
- block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
1198
- removeEmpty: "columns" | "rows",
1199
- ) => {
1200
- return cropEmptyRowsOrColumns(block, removeEmpty);
1201
- };
1174
+ cropEmptyRowsOrColumns(
1175
+ block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
1176
+ removeEmpty: "columns" | "rows",
1177
+ ) {
1178
+ return cropEmptyRowsOrColumns(block, removeEmpty);
1179
+ },
1202
1180
 
1203
- addRowsOrColumns = (
1204
- block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
1205
- addType: "columns" | "rows",
1206
- numToAdd: number,
1207
- ) => {
1208
- return addRowsOrColumns(block, addType, numToAdd);
1209
- };
1210
- }
1181
+ addRowsOrColumns(
1182
+ block: BlockFromConfigNoChildren<DefaultBlockSchema["table"], any, any>,
1183
+ addType: "columns" | "rows",
1184
+ numToAdd: number,
1185
+ ) {
1186
+ return addRowsOrColumns(block, addType, numToAdd);
1187
+ },
1188
+ } as const;
1189
+ });