@blocknote/core 0.29.1 → 0.30.1

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 (182) hide show
  1. package/README.md +125 -0
  2. package/dist/blocknote.cjs +9 -9
  3. package/dist/blocknote.cjs.map +1 -1
  4. package/dist/blocknote.js +1501 -1359
  5. package/dist/blocknote.js.map +1 -1
  6. package/dist/comments.cjs.map +1 -1
  7. package/dist/comments.js.map +1 -1
  8. package/dist/locales.cjs +1 -1
  9. package/dist/locales.cjs.map +1 -1
  10. package/dist/locales.js +751 -9
  11. package/dist/locales.js.map +1 -1
  12. package/dist/style.css +1 -1
  13. package/dist/tsconfig.tsbuildinfo +1 -1
  14. package/dist/webpack-stats.json +1 -1
  15. package/package.json +7 -8
  16. package/src/api/README.md +1 -1
  17. package/src/api/blockManipulation/commands/insertBlocks/__snapshots__/insertBlocks.test.ts.snap +0 -7
  18. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.test.ts +19 -14
  19. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +5 -5
  20. package/src/api/blockManipulation/commands/mergeBlocks/__snapshots__/mergeBlocks.test.ts.snap +0 -5
  21. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.test.ts +3 -3
  22. package/src/api/blockManipulation/commands/mergeBlocks/mergeBlocks.ts +12 -12
  23. package/src/api/blockManipulation/commands/moveBlocks/__snapshots__/moveBlocks.test.ts.snap +0 -20
  24. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.test.ts +14 -14
  25. package/src/api/blockManipulation/commands/moveBlocks/moveBlocks.ts +16 -16
  26. package/src/api/blockManipulation/commands/nestBlock/nestBlock.ts +8 -8
  27. package/src/api/blockManipulation/commands/replaceBlocks/__snapshots__/replaceBlocks.test.ts.snap +0 -12
  28. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.test.ts +12 -12
  29. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +7 -7
  30. package/src/api/blockManipulation/commands/splitBlock/__snapshots__/splitBlock.test.ts.snap +0 -6
  31. package/src/api/blockManipulation/commands/splitBlock/splitBlock.test.ts +10 -10
  32. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +2 -2
  33. package/src/api/blockManipulation/commands/updateBlock/__snapshots__/updateBlock.test.ts.snap +0 -17
  34. package/src/api/blockManipulation/commands/updateBlock/updateBlock.test.ts +42 -42
  35. package/src/api/blockManipulation/commands/updateBlock/updateBlock.ts +18 -18
  36. package/src/api/blockManipulation/getBlock/getBlock.ts +9 -9
  37. package/src/api/blockManipulation/insertContentAt.ts +1 -1
  38. package/src/api/blockManipulation/selections/selection.ts +11 -11
  39. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.test.ts +7 -7
  40. package/src/api/blockManipulation/selections/textCursorPosition/textCursorPosition.ts +6 -6
  41. package/src/api/blockManipulation/tables/tables.test.ts +106 -106
  42. package/src/api/blockManipulation/tables/tables.ts +35 -35
  43. package/src/api/clipboard/fromClipboard/fileDropExtension.ts +2 -2
  44. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +9 -9
  45. package/src/api/clipboard/fromClipboard/handleVSCodePaste.ts +3 -3
  46. package/src/api/clipboard/fromClipboard/pasteExtension.ts +21 -3
  47. package/src/api/clipboard/toClipboard/copyExtension.ts +22 -22
  48. package/src/api/exporters/html/externalHTMLExporter.ts +6 -6
  49. package/src/api/exporters/html/internalHTMLSerializer.ts +3 -3
  50. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +16 -16
  51. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +14 -14
  52. package/src/api/exporters/markdown/markdownExporter.ts +3 -3
  53. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +3 -3
  54. package/src/api/getBlockInfoFromPos.ts +6 -6
  55. package/src/api/nodeConversions/blockToNode.ts +26 -26
  56. package/src/api/nodeConversions/fragmentToBlocks.ts +1 -1
  57. package/src/api/nodeConversions/nodeToBlock.ts +37 -33
  58. package/src/api/nodeUtil.test.ts +16 -16
  59. package/src/api/nodeUtil.ts +10 -10
  60. package/src/api/parsers/html/parseHTML.ts +1 -1
  61. package/src/api/parsers/html/util/nestedLists.ts +2 -2
  62. package/src/api/parsers/markdown/parseMarkdown.ts +1 -1
  63. package/src/api/pmUtil.ts +4 -4
  64. package/src/api/positionMapping.test.ts +3 -3
  65. package/src/api/positionMapping.ts +5 -5
  66. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +9 -4
  67. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +40 -26
  68. package/src/blocks/FileBlockContent/FileBlockContent.ts +7 -2
  69. package/src/blocks/FileBlockContent/helpers/parse/parseFigureElement.ts +2 -2
  70. package/src/blocks/FileBlockContent/helpers/render/createAddFileButton.ts +5 -5
  71. package/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.ts +2 -2
  72. package/src/blocks/FileBlockContent/helpers/render/createFileNameWithIcon.ts +1 -1
  73. package/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.ts +15 -8
  74. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createFigureWithCaption.ts +1 -1
  75. package/src/blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.ts +1 -1
  76. package/src/blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +2 -2
  77. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +9 -6
  78. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +14 -6
  79. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +13 -29
  80. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +24 -13
  81. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  82. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  83. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +13 -30
  84. package/src/blocks/ListItemBlockContent/getListItemContent.ts +115 -0
  85. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +1 -1
  86. package/src/blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.ts +3 -3
  87. package/src/blocks/PageBreakBlockContent/schema.ts +2 -2
  88. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +9 -5
  89. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +10 -5
  90. package/src/blocks/README.md +1 -1
  91. package/src/blocks/TableBlockContent/TableBlockContent.ts +76 -19
  92. package/src/blocks/TableBlockContent/TableExtension.ts +3 -3
  93. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +14 -6
  94. package/src/blocks/defaultBlockHelpers.ts +24 -8
  95. package/src/blocks/defaultBlockTypeGuards.ts +16 -16
  96. package/src/blocks/defaultBlocks.ts +3 -3
  97. package/src/comments/threadstore/DefaultThreadStoreAuth.ts +3 -3
  98. package/src/comments/threadstore/ThreadStore.ts +1 -1
  99. package/src/comments/threadstore/TipTapThreadStore.ts +10 -10
  100. package/src/comments/threadstore/yjs/RESTYjsThreadStore.ts +4 -4
  101. package/src/comments/threadstore/yjs/YjsThreadStore.test.ts +2 -2
  102. package/src/comments/threadstore/yjs/YjsThreadStore.ts +14 -14
  103. package/src/comments/threadstore/yjs/YjsThreadStoreBase.ts +1 -1
  104. package/src/comments/threadstore/yjs/yjsHelpers.ts +6 -6
  105. package/src/editor/Block.css +10 -1
  106. package/src/editor/BlockNoteEditor.test.ts +3 -3
  107. package/src/editor/BlockNoteEditor.ts +110 -61
  108. package/src/editor/BlockNoteExtensions.ts +24 -15
  109. package/src/editor/BlockNoteSchema.ts +4 -4
  110. package/src/editor/BlockNoteTipTapEditor.ts +10 -10
  111. package/src/editor/README.md +1 -1
  112. package/src/editor/cursorPositionTypes.ts +1 -1
  113. package/src/editor/editor.css +15 -3
  114. package/src/editor/selectionTypes.ts +1 -1
  115. package/src/editor/transformPasted.ts +2 -2
  116. package/src/exporter/Exporter.ts +5 -5
  117. package/src/exporter/mapping.ts +7 -7
  118. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +1 -1
  119. package/src/extensions/Collaboration/CursorPlugin.ts +152 -0
  120. package/src/extensions/Collaboration/SyncPlugin.ts +15 -0
  121. package/src/extensions/Collaboration/UndoPlugin.ts +14 -0
  122. package/src/extensions/Comments/CommentsPlugin.ts +9 -9
  123. package/src/extensions/Comments/userstore/UserStore.ts +2 -2
  124. package/src/extensions/FilePanel/FilePanelPlugin.ts +37 -28
  125. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +6 -8
  126. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +29 -26
  127. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +11 -11
  128. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +4 -4
  129. package/src/extensions/Placeholder/PlaceholderPlugin.ts +10 -10
  130. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +2 -2
  131. package/src/extensions/README.md +1 -1
  132. package/src/extensions/SideMenu/MultipleNodeSelection.ts +1 -1
  133. package/src/extensions/SideMenu/SideMenuPlugin.ts +31 -31
  134. package/src/extensions/SideMenu/dragging.ts +8 -8
  135. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +17 -17
  136. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +2 -2
  137. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +12 -12
  138. package/src/extensions/TableHandles/TableHandlesPlugin.ts +54 -53
  139. package/src/extensions/TrailingNode/TrailingNodeExtension.ts +1 -1
  140. package/src/extensions/UniqueID/UniqueID.ts +6 -6
  141. package/src/extensions/getDraggableBlockFromElement.ts +1 -1
  142. package/src/fonts/inter.css +18 -9
  143. package/src/i18n/locales/index.ts +2 -0
  144. package/src/i18n/locales/ru.ts +2 -2
  145. package/src/i18n/locales/sk.ts +355 -0
  146. package/src/i18n/locales/zh-tw.ts +390 -0
  147. package/src/locales.ts +1 -1
  148. package/src/pm-nodes/BlockContainer.ts +7 -6
  149. package/src/pm-nodes/BlockGroup.ts +1 -1
  150. package/src/pm-nodes/Doc.ts +4 -4
  151. package/src/schema/README.md +1 -1
  152. package/src/schema/blocks/createSpec.ts +15 -15
  153. package/src/schema/blocks/internal.ts +17 -18
  154. package/src/schema/blocks/types.ts +27 -26
  155. package/src/schema/inlineContent/createSpec.ts +16 -20
  156. package/src/schema/inlineContent/internal.ts +9 -9
  157. package/src/schema/inlineContent/types.ts +26 -26
  158. package/src/schema/propTypes.ts +8 -8
  159. package/src/schema/styles/createSpec.ts +2 -2
  160. package/src/schema/styles/internal.ts +7 -7
  161. package/src/schema/styles/types.ts +2 -2
  162. package/src/util/EventEmitter.ts +4 -4
  163. package/src/util/README.md +1 -1
  164. package/src/util/combineByGroup.ts +1 -1
  165. package/src/util/table.ts +33 -30
  166. package/types/src/api/blockManipulation/setupTestEnv.d.ts +8 -4
  167. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +8 -4
  168. package/types/src/blocks/ListItemBlockContent/getListItemContent.d.ts +28 -0
  169. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +8 -4
  170. package/types/src/blocks/defaultBlockHelpers.d.ts +1 -0
  171. package/types/src/blocks/defaultBlocks.d.ts +16 -8
  172. package/types/src/editor/BlockNoteEditor.d.ts +21 -2
  173. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +31 -0
  174. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +7 -0
  175. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +6 -0
  176. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +1 -1
  177. package/types/src/i18n/locales/index.d.ts +2 -0
  178. package/types/src/i18n/locales/sk.d.ts +313 -0
  179. package/types/src/i18n/locales/zh-tw.d.ts +2 -0
  180. package/types/src/schema/blocks/types.d.ts +2 -1
  181. package/src/extensions/Collaboration/createCollaborationExtensions.ts +0 -147
  182. package/types/src/extensions/Collaboration/createCollaborationExtensions.d.ts +0 -17
@@ -10,10 +10,11 @@ import type {
10
10
  StyleSchema,
11
11
  } from "../../schema/index.js";
12
12
  import { EventEmitter } from "../../util/EventEmitter.js";
13
+ import { ySyncPluginKey } from "y-prosemirror";
13
14
 
14
15
  export type FilePanelState<
15
16
  I extends InlineContentSchema,
16
- S extends StyleSchema
17
+ S extends StyleSchema,
17
18
  > = UiElementPosition & {
18
19
  // TODO: This typing is not quite right (children should be from BSchema)
19
20
  block: BlockFromConfig<FileBlockConfig, I, S>;
@@ -31,9 +32,9 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
31
32
  I,
32
33
  S
33
34
  >,
34
- private readonly pluginKey: PluginKey,
35
+ private readonly pluginKey: PluginKey<FilePanelState<I, S>>,
35
36
  private readonly pmView: EditorView,
36
- emitUpdate: (state: FilePanelState<I, S>) => void
37
+ emitUpdate: (state: FilePanelState<I, S>) => void,
37
38
  ) {
38
39
  this.emitUpdate = () => {
39
40
  if (!this.state) {
@@ -70,7 +71,7 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
70
71
  scrollHandler = () => {
71
72
  if (this.state?.show) {
72
73
  const blockElement = this.pmView.root.querySelector(
73
- `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]`
74
+ `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]`,
74
75
  );
75
76
  if (!blockElement) {
76
77
  return;
@@ -81,13 +82,12 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
81
82
  };
82
83
 
83
84
  update(view: EditorView, prevState: EditorState) {
84
- const pluginState: {
85
- block: BlockFromConfig<FileBlockConfig, I, S>;
86
- } = this.pluginKey.getState(view.state);
85
+ const pluginState = this.pluginKey.getState(view.state);
86
+ const prevPluginState = this.pluginKey.getState(prevState);
87
87
 
88
- if (!this.state?.show && pluginState.block && this.editor.isEditable) {
88
+ if (!this.state?.show && pluginState?.block && this.editor.isEditable) {
89
89
  const blockElement = this.pmView.root.querySelector(
90
- `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]`
90
+ `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]`,
91
91
  );
92
92
  if (!blockElement) {
93
93
  return;
@@ -103,16 +103,15 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
103
103
  return;
104
104
  }
105
105
 
106
- if (
107
- !view.state.selection.eq(prevState.selection) ||
108
- !view.state.doc.eq(prevState.doc) ||
109
- !this.editor.isEditable
110
- ) {
111
- if (this.state?.show) {
112
- this.state.show = false;
113
-
114
- this.emitUpdate();
115
- }
106
+ const isOpening = pluginState?.block && !prevPluginState?.block;
107
+ const isClosing = !pluginState?.block && prevPluginState?.block;
108
+ if (isOpening && this.state && !this.state.show) {
109
+ this.state.show = true;
110
+ this.emitUpdate();
111
+ }
112
+ if (isClosing && this.state?.show) {
113
+ this.state.show = false;
114
+ this.emitUpdate();
116
115
  }
117
116
  }
118
117
 
@@ -132,11 +131,13 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
132
131
  }
133
132
  }
134
133
 
135
- const filePanelPluginKey = new PluginKey("FilePanelPlugin");
134
+ const filePanelPluginKey = new PluginKey<FilePanelState<any, any>>(
135
+ "FilePanelPlugin",
136
+ );
136
137
 
137
138
  export class FilePanelProsemirrorPlugin<
138
139
  I extends InlineContentSchema,
139
- S extends StyleSchema
140
+ S extends StyleSchema,
140
141
  > extends EventEmitter<any> {
141
142
  private view: FilePanelView<I, S> | undefined;
142
143
  public readonly plugin: Plugin;
@@ -154,7 +155,7 @@ export class FilePanelProsemirrorPlugin<
154
155
  editorView,
155
156
  (state) => {
156
157
  this.emit("update", state);
157
- }
158
+ },
158
159
  );
159
160
  return this.view;
160
161
  },
@@ -173,13 +174,21 @@ export class FilePanelProsemirrorPlugin<
173
174
  block: undefined,
174
175
  };
175
176
  },
176
- apply: (transaction) => {
177
- const block: BlockFromConfig<FileBlockConfig, I, S> | undefined =
178
- transaction.getMeta(filePanelPluginKey)?.block;
177
+ apply: (transaction, prev) => {
178
+ const state: FilePanelState<I, S> | undefined =
179
+ transaction.getMeta(filePanelPluginKey);
179
180
 
180
- return {
181
- block,
182
- };
181
+ if (state) {
182
+ return state;
183
+ }
184
+
185
+ if (
186
+ !transaction.getMeta(ySyncPluginKey) &&
187
+ (transaction.selectionSet || transaction.docChanged)
188
+ ) {
189
+ return { block: undefined };
190
+ }
191
+ return prev;
183
192
  },
184
193
  },
185
194
  });
@@ -53,12 +53,12 @@ export class FormattingToolbarView implements PluginView {
53
53
  StyleSchema
54
54
  >,
55
55
  private readonly pmView: EditorView,
56
- emitUpdate: (state: FormattingToolbarState) => void
56
+ emitUpdate: (state: FormattingToolbarState) => void,
57
57
  ) {
58
58
  this.emitUpdate = () => {
59
59
  if (!this.state) {
60
60
  throw new Error(
61
- "Attempting to update uninitialized formatting toolbar"
61
+ "Attempting to update uninitialized formatting toolbar",
62
62
  );
63
63
  }
64
64
 
@@ -96,7 +96,7 @@ export class FormattingToolbarView implements PluginView {
96
96
  (editorWrapper === (event.relatedTarget as Node) ||
97
97
  editorWrapper.contains(event.relatedTarget as Node) ||
98
98
  (event.relatedTarget as HTMLElement).matches(
99
- ".bn-ui-container, .bn-ui-container *"
99
+ ".bn-ui-container, .bn-ui-container *",
100
100
  ))
101
101
  ) {
102
102
  return;
@@ -140,11 +140,9 @@ export class FormattingToolbarView implements PluginView {
140
140
  // Wrapping in a setTimeout gives enough time to wait for the blur event to
141
141
  // occur before updating the toolbar.
142
142
  const { state, composing } = view;
143
- const { selection } = state;
143
+ const { doc, selection } = state;
144
144
  const isSame =
145
- oldState &&
146
- oldState.selection.from === state.selection.from &&
147
- oldState.selection.to === state.selection.to;
145
+ oldState && oldState.doc.eq(doc) && oldState.selection.eq(selection);
148
146
 
149
147
  if (composing || isSame) {
150
148
  return;
@@ -235,7 +233,7 @@ export class FormattingToolbarView implements PluginView {
235
233
  }
236
234
 
237
235
  export const formattingToolbarPluginKey = new PluginKey(
238
- "FormattingToolbarPlugin"
236
+ "FormattingToolbarPlugin",
239
237
  );
240
238
 
241
239
  export class FormattingToolbarProsemirrorPlugin extends EventEmitter<any> {
@@ -48,7 +48,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
48
48
  updateBlockCommand(blockInfo.bnBlock.beforePos, {
49
49
  type: "paragraph",
50
50
  props: {},
51
- })
51
+ }),
52
52
  );
53
53
  }
54
54
 
@@ -114,7 +114,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
114
114
 
115
115
  const prevBlockInfo = getPrevBlockInfo(
116
116
  state.doc,
117
- blockInfo.bnBlock.beforePos
117
+ blockInfo.bnBlock.beforePos,
118
118
  );
119
119
 
120
120
  if (prevBlockInfo) {
@@ -124,7 +124,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
124
124
 
125
125
  const parentBlockInfo = getParentBlockInfo(
126
126
  state.doc,
127
- blockInfo.bnBlock.beforePos
127
+ blockInfo.bnBlock.beforePos,
128
128
  );
129
129
 
130
130
  if (parentBlockInfo?.blockNoteType !== "column") {
@@ -135,7 +135,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
135
135
 
136
136
  const columnList = getParentBlockInfo(
137
137
  state.doc,
138
- column.bnBlock.beforePos
138
+ column.bnBlock.beforePos,
139
139
  );
140
140
  if (columnList?.blockNoteType !== "columnList") {
141
141
  throw new Error("parent of column is not a column list");
@@ -156,7 +156,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
156
156
  const blockToMove = state.doc.slice(
157
157
  blockInfo.bnBlock.beforePos,
158
158
  blockInfo.bnBlock.afterPos,
159
- false
159
+ false,
160
160
  );
161
161
 
162
162
  /*
@@ -180,8 +180,8 @@ export const KeyboardShortcutsExtension = Extension.create<{
180
180
  columnList.bnBlock.afterPos - 2,
181
181
  blockToMove,
182
182
  blockToMove.size, // append existing content to blockToMove
183
- false
184
- )
183
+ false,
184
+ ),
185
185
  );
186
186
  const pos = state.tr.doc.resolve(column.bnBlock.beforePos);
187
187
  state.tr.setSelection(TextSelection.between(pos, pos));
@@ -197,11 +197,11 @@ export const KeyboardShortcutsExtension = Extension.create<{
197
197
  column.bnBlock.beforePos - 1,
198
198
  blockToMove,
199
199
  0, // prepend existing content to blockToMove
200
- false
201
- )
200
+ false,
201
+ ),
202
202
  );
203
203
  const pos = state.tr.doc.resolve(
204
- state.tr.mapping.map(column.bnBlock.beforePos - 1)
204
+ state.tr.mapping.map(column.bnBlock.beforePos - 1),
205
205
  );
206
206
  state.tr.setSelection(TextSelection.between(pos, pos));
207
207
  }
@@ -210,43 +210,43 @@ export const KeyboardShortcutsExtension = Extension.create<{
210
210
  // delete column
211
211
  state.tr.delete(
212
212
  column.bnBlock.beforePos,
213
- column.bnBlock.afterPos
213
+ column.bnBlock.afterPos,
214
214
  );
215
215
 
216
216
  // move before columnlist
217
217
  state.tr.insert(
218
218
  columnList.bnBlock.beforePos,
219
- blockToMove.content
219
+ blockToMove.content,
220
220
  );
221
221
 
222
222
  const pos = state.tr.doc.resolve(
223
- columnList.bnBlock.beforePos
223
+ columnList.bnBlock.beforePos,
224
224
  );
225
225
  state.tr.setSelection(TextSelection.between(pos, pos));
226
226
  } else {
227
227
  // just delete the </column><column> closing and opening tags to merge the columns
228
228
  state.tr.delete(
229
229
  column.bnBlock.beforePos - 1,
230
- column.bnBlock.beforePos + 1
230
+ column.bnBlock.beforePos + 1,
231
231
  );
232
232
  }
233
233
  } else {
234
234
  // delete block
235
235
  state.tr.delete(
236
236
  blockInfo.bnBlock.beforePos,
237
- blockInfo.bnBlock.afterPos
237
+ blockInfo.bnBlock.afterPos,
238
238
  );
239
239
  if (isFirstColumn) {
240
240
  // move before columnlist
241
241
  state.tr.insert(
242
242
  columnList.bnBlock.beforePos - 1,
243
- blockToMove.content
243
+ blockToMove.content,
244
244
  );
245
245
  } else {
246
246
  // append block to previous column
247
247
  state.tr.insert(
248
248
  column.bnBlock.beforePos - 1,
249
- blockToMove.content
249
+ blockToMove.content,
250
250
  );
251
251
  }
252
252
  const pos = state.tr.doc.resolve(column.bnBlock.beforePos - 1);
@@ -272,7 +272,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
272
272
  if (blockEmpty) {
273
273
  const prevBlockInfo = getPrevBlockInfo(
274
274
  state.doc,
275
- blockInfo.bnBlock.beforePos
275
+ blockInfo.bnBlock.beforePos,
276
276
  );
277
277
  if (!prevBlockInfo || !prevBlockInfo.isBlockContainer) {
278
278
  return false;
@@ -291,7 +291,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
291
291
  const lastCellParagraphEndPos = lastCellEndPos - 1;
292
292
 
293
293
  chainedCommands = chainedCommands.setTextSelection(
294
- lastCellParagraphEndPos
294
+ lastCellParagraphEndPos,
295
295
  );
296
296
  } else if (
297
297
  prevBlockInfo.blockContent.node.type.spec.content === ""
@@ -301,7 +301,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
301
301
  prevBlockInfo.blockContent.node.nodeSize;
302
302
 
303
303
  chainedCommands = chainedCommands.setNodeSelection(
304
- nonEditableBlockContentStartPos
304
+ nonEditableBlockContentStartPos,
305
305
  );
306
306
  } else {
307
307
  const blockContentStartPos =
@@ -341,13 +341,13 @@ export const KeyboardShortcutsExtension = Extension.create<{
341
341
 
342
342
  const prevBlockInfo = getPrevBlockInfo(
343
343
  state.doc,
344
- blockInfo.bnBlock.beforePos
344
+ blockInfo.bnBlock.beforePos,
345
345
  );
346
346
 
347
347
  if (prevBlockInfo && selectionAtBlockStart && selectionEmpty) {
348
348
  const bottomBlock = getBottomNestedBlockInfo(
349
349
  state.doc,
350
- prevBlockInfo
350
+ prevBlockInfo,
351
351
  );
352
352
 
353
353
  if (!bottomBlock.isBlockContainer) {
@@ -368,7 +368,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
368
368
  from: blockInfo.bnBlock.beforePos,
369
369
  to: blockInfo.bnBlock.afterPos,
370
370
  },
371
- bottomBlock.bnBlock.afterPos
371
+ bottomBlock.bnBlock.afterPos,
372
372
  )
373
373
  .deleteRange({
374
374
  from: bottomBlock.bnBlock.beforePos,
@@ -521,7 +521,7 @@ export const KeyboardShortcutsExtension = Extension.create<{
521
521
  .insert(newBlockInsertionPos, newBlock)
522
522
  .scrollIntoView();
523
523
  state.tr.setSelection(
524
- new TextSelection(state.doc.resolve(newBlockContentPos))
524
+ new TextSelection(state.doc.resolve(newBlockContentPos)),
525
525
  );
526
526
  }
527
527
 
@@ -551,8 +551,8 @@ export const KeyboardShortcutsExtension = Extension.create<{
551
551
  splitBlockCommand(
552
552
  state.selection.from,
553
553
  selectionAtBlockStart,
554
- selectionAtBlockStart
555
- )
554
+ selectionAtBlockStart,
555
+ ),
556
556
  )
557
557
  .run();
558
558
 
@@ -605,6 +605,9 @@ export const KeyboardShortcutsExtension = Extension.create<{
605
605
  this.options.editor.moveBlocksDown();
606
606
  return true;
607
607
  },
608
+ "Mod-z": () => this.options.editor.undo(),
609
+ "Mod-y": () => this.options.editor.redo(),
610
+ "Shift-Mod-z": () => this.options.editor.redo(),
608
611
  };
609
612
  },
610
613
  });
@@ -41,7 +41,7 @@ class LinkToolbarView implements PluginView {
41
41
  constructor(
42
42
  private readonly editor: BlockNoteEditor<any, any, any>,
43
43
  private readonly pmView: EditorView,
44
- emitUpdate: (state: LinkToolbarState) => void
44
+ emitUpdate: (state: LinkToolbarState) => void,
45
45
  ) {
46
46
  this.emitUpdate = () => {
47
47
  if (!this.state) {
@@ -70,7 +70,7 @@ class LinkToolbarView implements PluginView {
70
70
  this.pmView.root.addEventListener(
71
71
  "click",
72
72
  this.clickHandler as EventListener,
73
- true
73
+ true,
74
74
  );
75
75
 
76
76
  // Setting capture=true ensures that any parent container of the editor that
@@ -146,7 +146,7 @@ class LinkToolbarView implements PluginView {
146
146
  this.state.referencePos = posToDOMRect(
147
147
  this.pmView,
148
148
  this.linkMarkRange!.from,
149
- this.linkMarkRange!.to
149
+ this.linkMarkRange!.to,
150
150
  );
151
151
  this.emitUpdate();
152
152
  }
@@ -160,7 +160,7 @@ class LinkToolbarView implements PluginView {
160
160
  tr.addMark(
161
161
  this.linkMarkRange!.from,
162
162
  this.linkMarkRange!.from + text.length,
163
- pmSchema.mark("link", { href: url })
163
+ pmSchema.mark("link", { href: url }),
164
164
  );
165
165
  });
166
166
  this.pmView.focus();
@@ -177,9 +177,9 @@ class LinkToolbarView implements PluginView {
177
177
  .removeMark(
178
178
  this.linkMarkRange!.from,
179
179
  this.linkMarkRange!.to,
180
- this.linkMark!.type
180
+ this.linkMark!.type,
181
181
  )
182
- .setMeta("preventAutolink", true)
182
+ .setMeta("preventAutolink", true),
183
183
  );
184
184
  this.pmView.focus();
185
185
 
@@ -226,7 +226,7 @@ class LinkToolbarView implements PluginView {
226
226
  getMarkRange(
227
227
  this.pmView.state.selection.$from,
228
228
  mark.type,
229
- mark.attrs
229
+ mark.attrs,
230
230
  ) || undefined;
231
231
 
232
232
  break;
@@ -251,12 +251,12 @@ class LinkToolbarView implements PluginView {
251
251
  referencePos: posToDOMRect(
252
252
  this.pmView,
253
253
  this.linkMarkRange!.from,
254
- this.linkMarkRange!.to
254
+ this.linkMarkRange!.to,
255
255
  ),
256
256
  url: this.linkMark!.attrs.href,
257
257
  text: this.pmView.state.doc.textBetween(
258
258
  this.linkMarkRange!.from,
259
- this.linkMarkRange!.to
259
+ this.linkMarkRange!.to,
260
260
  ),
261
261
  };
262
262
  this.emitUpdate();
@@ -290,7 +290,7 @@ class LinkToolbarView implements PluginView {
290
290
  this.pmView.root.removeEventListener(
291
291
  "click",
292
292
  this.clickHandler as EventListener,
293
- true
293
+ true,
294
294
  );
295
295
  }
296
296
  }
@@ -300,7 +300,7 @@ export const linkToolbarPluginKey = new PluginKey("LinkToolbarPlugin");
300
300
  export class LinkToolbarProsemirrorPlugin<
301
301
  BSchema extends BlockSchema,
302
302
  I extends InlineContentSchema,
303
- S extends StyleSchema
303
+ S extends StyleSchema,
304
304
  > extends EventEmitter<any> {
305
305
  private view: LinkToolbarView | undefined;
306
306
  public readonly plugin: Plugin;
@@ -47,13 +47,13 @@ export class NodeSelectionKeyboardPlugin {
47
47
  tr
48
48
  .insert(
49
49
  view.state.tr.selection.$to.after(),
50
- view.state.schema.nodes["paragraph"].createChecked()
50
+ view.state.schema.nodes["paragraph"].createChecked(),
51
51
  )
52
52
  .setSelection(
53
53
  new TextSelection(
54
- tr.doc.resolve(view.state.tr.selection.$to.after() + 1)
55
- )
56
- )
54
+ tr.doc.resolve(view.state.tr.selection.$to.after() + 1),
55
+ ),
56
+ ),
57
57
  );
58
58
 
59
59
  return true;
@@ -12,7 +12,7 @@ export class PlaceholderPlugin {
12
12
  placeholders: Record<
13
13
  string | "default" | "emptyDocument",
14
14
  string | undefined
15
- >
15
+ >,
16
16
  ) {
17
17
  this.plugin = new Plugin({
18
18
  key: PLUGIN_KEY,
@@ -51,8 +51,8 @@ export class PlaceholderPlugin {
51
51
 
52
52
  styleSheet.insertRule(
53
53
  `${getSelector(blockTypeSelector)} { content: ${JSON.stringify(
54
- placeholder
55
- )}; }`
54
+ placeholder,
55
+ )}; }`,
56
56
  );
57
57
  }
58
58
 
@@ -62,21 +62,21 @@ export class PlaceholderPlugin {
62
62
  // placeholder for when there's only one empty block
63
63
  styleSheet.insertRule(
64
64
  `${getSelector(onlyBlockSelector)} { content: ${JSON.stringify(
65
- emptyPlaceholder
66
- )}; }`
65
+ emptyPlaceholder,
66
+ )}; }`,
67
67
  );
68
68
 
69
69
  // placeholder for default blocks, only when the cursor is in the block (mustBeFocused)
70
70
  styleSheet.insertRule(
71
71
  `${getSelector(mustBeFocusedSelector)} { content: ${JSON.stringify(
72
- defaultPlaceholder
73
- )}; }`
72
+ defaultPlaceholder,
73
+ )}; }`,
74
74
  );
75
75
  } catch (e) {
76
76
  // eslint-disable-next-line no-console
77
77
  console.warn(
78
78
  `Failed to insert placeholder CSS rule - this is likely due to the browser not supporting certain CSS pseudo-element selectors (:has, :only-child:, or :before)`,
79
- e
79
+ e,
80
80
  );
81
81
  }
82
82
 
@@ -115,7 +115,7 @@ export class PlaceholderPlugin {
115
115
  decs.push(
116
116
  Decoration.node(2, 4, {
117
117
  "data-is-only-empty-block": "true",
118
- })
118
+ }),
119
119
  );
120
120
  }
121
121
 
@@ -128,7 +128,7 @@ export class PlaceholderPlugin {
128
128
  decs.push(
129
129
  Decoration.node(before, before + node.nodeSize, {
130
130
  "data-is-empty-and-focused": "true",
131
- })
131
+ }),
132
132
  );
133
133
  }
134
134
 
@@ -37,7 +37,7 @@ export class PreviousBlockTypePlugin {
37
37
  // for one DOM-render the decorations have been applied
38
38
  timeout = setTimeout(() => {
39
39
  view.dispatch(
40
- view.state.tr.setMeta(PLUGIN_KEY, { clearUpdate: true })
40
+ view.state.tr.setMeta(PLUGIN_KEY, { clearUpdate: true }),
41
41
  );
42
42
  }, 0);
43
43
  }
@@ -93,7 +93,7 @@ export class PreviousBlockTypePlugin {
93
93
 
94
94
  const oldNodes = findChildren(oldState.doc, (node) => node.attrs.id);
95
95
  const oldNodesById = new Map(
96
- oldNodes.map((node) => [node.node.attrs.id, node])
96
+ oldNodes.map((node) => [node.node.attrs.id, node]),
97
97
  );
98
98
  const newNodes = findChildren(newState.doc, (node) => node.attrs.id);
99
99
 
@@ -1,3 +1,3 @@
1
1
  ### @blocknote/core/src/extensions
2
2
 
3
- All extra extensions for TipTap / Prosemirror needed to implement the Prosemirror UX and editor behavior.
3
+ All extra extensions for TipTap / Prosemirror needed to implement the Prosemirror UX and editor behavior.
@@ -77,7 +77,7 @@ export class MultipleNodeSelection extends Selection {
77
77
 
78
78
  return new MultipleNodeSelection(
79
79
  doc.resolve(fromResult.pos),
80
- doc.resolve(toResult.pos)
80
+ doc.resolve(toResult.pos),
81
81
  );
82
82
  }
83
83