@blocknote/core 0.10.1 → 0.11.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 (36) hide show
  1. package/README.md +1 -1
  2. package/dist/blocknote.js +1543 -1462
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +5 -5
  5. package/dist/blocknote.umd.cjs.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/dist/webpack-stats.json +1 -1
  8. package/package.json +2 -5
  9. package/src/api/blockManipulation/blockManipulation.ts +144 -30
  10. package/src/api/exporters/copyExtension.ts +97 -24
  11. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -1
  12. package/src/api/exporters/html/__snapshots__/image/button/internal.html +1 -1
  13. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -1
  14. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
  15. package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -1
  16. package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -1
  17. package/src/api/exporters/html/__snapshots__/simpleImage/button/internal.html +1 -1
  18. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -1
  19. package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -1
  20. package/src/api/exporters/html/util/sharedHTMLConversion.ts +1 -0
  21. package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +0 -1
  22. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +9 -0
  23. package/src/api/parsers/pasteExtension.ts +0 -1
  24. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +39 -25
  25. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +1 -1
  26. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +1 -1
  27. package/src/editor/Block.css +23 -14
  28. package/src/editor/BlockNoteEditor.ts +11 -11
  29. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +5 -3
  30. package/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts +12 -1
  31. package/src/extensions/SideMenu/SideMenuPlugin.ts +6 -3
  32. package/src/extensions/TableHandles/TableHandlesPlugin.ts +3 -1
  33. package/src/pm-nodes/BlockContainer.ts +1 -1
  34. package/types/src/api/blockManipulation/blockManipulation.d.ts +8 -6
  35. package/types/src/editor/BlockNoteEditor.d.ts +9 -6
  36. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +1 -1
@@ -268,6 +268,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
268
268
  "attrs": {
269
269
  "class": null,
270
270
  "href": "https://www.website.com",
271
+ "rel": "noopener noreferrer nofollow",
271
272
  "target": "_blank",
272
273
  },
273
274
  "type": "link",
@@ -285,6 +286,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
285
286
  "attrs": {
286
287
  "class": null,
287
288
  "href": "https://www.website2.com",
289
+ "rel": "noopener noreferrer nofollow",
288
290
  "target": "_blank",
289
291
  },
290
292
  "type": "link",
@@ -348,6 +350,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
348
350
  "attrs": {
349
351
  "class": null,
350
352
  "href": "https://www.website.com",
353
+ "rel": "noopener noreferrer nofollow",
351
354
  "target": "_blank",
352
355
  },
353
356
  "type": "link",
@@ -365,6 +368,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
365
368
  "attrs": {
366
369
  "class": null,
367
370
  "href": "https://www.website.com",
371
+ "rel": "noopener noreferrer nofollow",
368
372
  "target": "_blank",
369
373
  },
370
374
  "type": "link",
@@ -618,6 +622,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
618
622
  "attrs": {
619
623
  "class": null,
620
624
  "href": "https://www.website.com",
625
+ "rel": "noopener noreferrer nofollow",
621
626
  "target": "_blank",
622
627
  },
623
628
  "type": "link",
@@ -632,6 +637,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
632
637
  "attrs": {
633
638
  "class": null,
634
639
  "href": "https://www.website2.com",
640
+ "rel": "noopener noreferrer nofollow",
635
641
  "target": "_blank",
636
642
  },
637
643
  "type": "link",
@@ -667,6 +673,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
667
673
  "attrs": {
668
674
  "class": null,
669
675
  "href": "https://www.website.com",
676
+ "rel": "noopener noreferrer nofollow",
670
677
  "target": "_blank",
671
678
  },
672
679
  "type": "link",
@@ -705,6 +712,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
705
712
  "attrs": {
706
713
  "class": null,
707
714
  "href": "https://www.website.com",
715
+ "rel": "noopener noreferrer nofollow",
708
716
  "target": "_blank",
709
717
  },
710
718
  "type": "link",
@@ -719,6 +727,7 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
719
727
  "attrs": {
720
728
  "class": null,
721
729
  "href": "https://www.website.com",
730
+ "rel": "noopener noreferrer nofollow",
722
731
  "target": "_blank",
723
732
  },
724
733
  "type": "link",
@@ -44,7 +44,6 @@ export const createPasteFromClipboardExtension = <
44
44
  );
45
45
 
46
46
  data = htmlNode.innerHTML;
47
- console.log(data);
48
47
  }
49
48
  editor._tiptapEditor.view.pasteHTML(data);
50
49
  }
@@ -69,7 +69,6 @@ export const renderImage = (
69
69
  // Button element that acts as a placeholder for images with no src.
70
70
  const addImageButton = document.createElement("div");
71
71
  addImageButton.className = "bn-add-image-button";
72
- addImageButton.style.display = block.props.url === "" ? "" : "none";
73
72
 
74
73
  // Icon for the add image button.
75
74
  const addImageButtonIcon = document.createElement("div");
@@ -83,12 +82,10 @@ export const renderImage = (
83
82
  // Wrapper element for the image, resize handles and caption.
84
83
  const imageAndCaptionWrapper = document.createElement("div");
85
84
  imageAndCaptionWrapper.className = "bn-image-and-caption-wrapper";
86
- imageAndCaptionWrapper.style.display = block.props.url !== "" ? "" : "none";
87
85
 
88
86
  // Wrapper element for the image and resize handles.
89
87
  const imageWrapper = document.createElement("div");
90
88
  imageWrapper.className = "bn-image-wrapper";
91
- imageWrapper.style.display = block.props.url !== "" ? "" : "none";
92
89
 
93
90
  // Image element.
94
91
  const image = document.createElement("img");
@@ -151,6 +148,15 @@ export const renderImage = (
151
148
  // offset from when the resize began, and which resize handle is being used.
152
149
  const windowMouseMoveHandler = (event: MouseEvent) => {
153
150
  if (!resizeParams) {
151
+ if (
152
+ !editor.isEditable &&
153
+ imageWrapper.contains(leftResizeHandle) &&
154
+ imageWrapper.contains(rightResizeHandle)
155
+ ) {
156
+ imageWrapper.removeChild(leftResizeHandle);
157
+ imageWrapper.removeChild(rightResizeHandle);
158
+ }
159
+
154
160
  return;
155
161
  }
156
162
 
@@ -195,18 +201,20 @@ export const renderImage = (
195
201
  // Stops mouse movements from resizing the image and updates the block's
196
202
  // `width` prop to the new value.
197
203
  const windowMouseUpHandler = (event: MouseEvent) => {
198
- if (!resizeParams) {
199
- return;
200
- }
201
-
202
204
  // Hides the drag handles if the cursor is no longer over the image.
203
205
  if (
204
- (!event.target || !imageWrapper.contains(event.target as Node)) &&
206
+ (!event.target ||
207
+ !imageWrapper.contains(event.target as Node) ||
208
+ !editor.isEditable) &&
205
209
  imageWrapper.contains(leftResizeHandle) &&
206
210
  imageWrapper.contains(rightResizeHandle)
207
211
  ) {
208
- leftResizeHandle.style.display = "none";
209
- rightResizeHandle.style.display = "none";
212
+ imageWrapper.removeChild(leftResizeHandle);
213
+ imageWrapper.removeChild(rightResizeHandle);
214
+ }
215
+
216
+ if (!resizeParams) {
217
+ return;
210
218
  }
211
219
 
212
220
  resizeParams = undefined;
@@ -236,11 +244,8 @@ export const renderImage = (
236
244
  // Shows the resize handles when hovering over the image with the cursor.
237
245
  const imageMouseEnterHandler = () => {
238
246
  if (editor.isEditable) {
239
- leftResizeHandle.style.display = "block";
240
- rightResizeHandle.style.display = "block";
241
- } else {
242
- leftResizeHandle.style.display = "none";
243
- rightResizeHandle.style.display = "none";
247
+ imageWrapper.appendChild(leftResizeHandle);
248
+ imageWrapper.appendChild(rightResizeHandle);
244
249
  }
245
250
  };
246
251
  // Hides the resize handles when the cursor leaves the image, unless the
@@ -257,8 +262,14 @@ export const renderImage = (
257
262
  return;
258
263
  }
259
264
 
260
- leftResizeHandle.style.display = "none";
261
- rightResizeHandle.style.display = "none";
265
+ if (
266
+ editor.isEditable &&
267
+ imageWrapper.contains(leftResizeHandle) &&
268
+ imageWrapper.contains(rightResizeHandle)
269
+ ) {
270
+ imageWrapper.removeChild(leftResizeHandle);
271
+ imageWrapper.removeChild(rightResizeHandle);
272
+ }
262
273
  };
263
274
 
264
275
  // Sets the resize params, allowing the user to begin resizing the image by
@@ -266,8 +277,8 @@ export const renderImage = (
266
277
  const leftResizeHandleMouseDownHandler = (event: MouseEvent) => {
267
278
  event.preventDefault();
268
279
 
269
- leftResizeHandle.style.display = "block";
270
- rightResizeHandle.style.display = "block";
280
+ imageWrapper.appendChild(leftResizeHandle);
281
+ imageWrapper.appendChild(rightResizeHandle);
271
282
 
272
283
  resizeParams = {
273
284
  handleUsed: "left",
@@ -278,8 +289,8 @@ export const renderImage = (
278
289
  const rightResizeHandleMouseDownHandler = (event: MouseEvent) => {
279
290
  event.preventDefault();
280
291
 
281
- leftResizeHandle.style.display = "block";
282
- rightResizeHandle.style.display = "block";
292
+ imageWrapper.appendChild(leftResizeHandle);
293
+ imageWrapper.appendChild(rightResizeHandle);
283
294
 
284
295
  resizeParams = {
285
296
  handleUsed: "right",
@@ -288,16 +299,19 @@ export const renderImage = (
288
299
  };
289
300
  };
290
301
 
291
- wrapper.appendChild(addImageButton);
292
302
  addImageButton.appendChild(addImageButtonIcon);
293
303
  addImageButton.appendChild(addImageButtonText);
294
- wrapper.appendChild(imageAndCaptionWrapper);
304
+
295
305
  imageAndCaptionWrapper.appendChild(imageWrapper);
296
306
  imageWrapper.appendChild(image);
297
- imageWrapper.appendChild(leftResizeHandle);
298
- imageWrapper.appendChild(rightResizeHandle);
299
307
  imageAndCaptionWrapper.appendChild(caption);
300
308
 
309
+ if (block.props.url === "") {
310
+ wrapper.appendChild(addImageButton);
311
+ } else {
312
+ wrapper.appendChild(imageAndCaptionWrapper);
313
+ }
314
+
301
315
  window.addEventListener("mousemove", windowMouseMoveHandler);
302
316
  window.addEventListener("mouseup", windowMouseUpHandler);
303
317
  addImageButton.addEventListener("mousedown", addImageButtonMouseDownHandler);
@@ -37,7 +37,7 @@ const BulletListItemBlockContent = createStronglyTypedTiptapNode({
37
37
  addKeyboardShortcuts() {
38
38
  return {
39
39
  Enter: () => handleEnter(this.editor),
40
- "Mod-Shift-7": () =>
40
+ "Mod-Shift-8": () =>
41
41
  this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {
42
42
  type: "bulletListItem",
43
43
  props: {},
@@ -52,7 +52,7 @@ const NumberedListItemBlockContent = createStronglyTypedTiptapNode({
52
52
  addKeyboardShortcuts() {
53
53
  return {
54
54
  Enter: () => handleEnter(this.editor),
55
- "Mod-Shift-8": () =>
55
+ "Mod-Shift-7": () =>
56
56
  this.editor.commands.BNUpdateBlock(this.editor.state.selection.anchor, {
57
57
  type: "numberedListItem",
58
58
  props: {},
@@ -48,7 +48,8 @@ NESTED BLOCKS
48
48
  position: relative;
49
49
  }
50
50
 
51
- .bn-block-group .bn-block-group
51
+ .bn-block-group
52
+ .bn-block-group
52
53
  > .bn-block-outer:not([data-prev-depth-changed])::before {
53
54
  content: " ";
54
55
  display: inline;
@@ -58,11 +59,16 @@ NESTED BLOCKS
58
59
  transition: all 0.2s 0.1s;
59
60
  }
60
61
 
61
- .bn-block-group .bn-block-group
62
+ .bn-block-group
63
+ .bn-block-group
62
64
  > .bn-block-outer[data-prev-depth-change="-2"]::before {
63
65
  height: 0;
64
66
  }
65
67
 
68
+ .bn-inline-content code {
69
+ font-family: monospace;
70
+ }
71
+
66
72
  /* NESTED BLOCK ANIMATIONS (change in indent) */
67
73
 
68
74
  [data-prev-depth-change="1"] {
@@ -147,6 +153,11 @@ NESTED BLOCKS
147
153
  }
148
154
 
149
155
  /* Ordered */
156
+ .bn-block-content[data-content-type="numberedListItem"] {
157
+ display: flex;
158
+ gap: 1.2em;
159
+ }
160
+
150
161
  [data-content-type="numberedListItem"] {
151
162
  --index: attr(data-index);
152
163
  }
@@ -158,30 +169,31 @@ NESTED BLOCKS
158
169
  .bn-block-outer[data-prev-type="numberedListItem"]:not([data-prev-index="none"])
159
170
  > .bn-block
160
171
  > .bn-block-content::before {
161
- margin-right: 1.2em;
162
172
  content: var(--prev-index) ".";
163
173
  }
164
174
 
165
175
  .bn-block-outer:not([data-prev-type])
166
176
  > .bn-block
167
177
  > .bn-block-content[data-content-type="numberedListItem"]::before {
168
- margin-right: 1.2em;
169
178
  content: var(--index) ".";
170
179
  }
171
180
 
172
181
  /* Unordered */
182
+ .bn-block-content[data-content-type="bulletListItem"] {
183
+ display: flex;
184
+ gap: 1.2em;
185
+ }
186
+
173
187
  /* No list nesting */
174
188
  .bn-block-outer[data-prev-type="bulletListItem"]
175
189
  > .bn-block
176
190
  > .bn-block-content::before {
177
- margin-right: 1.2em;
178
191
  content: "•";
179
192
  }
180
193
 
181
194
  .bn-block-outer:not([data-prev-type])
182
195
  > .bn-block
183
196
  > .bn-block-content[data-content-type="bulletListItem"]::before {
184
- margin-right: 1.2em;
185
197
  content: "•";
186
198
  }
187
199
 
@@ -191,7 +203,6 @@ NESTED BLOCKS
191
203
  > .bn-block-outer[data-prev-type="bulletListItem"]
192
204
  > .bn-block
193
205
  > .bn-block-content::before {
194
- margin-right: 1.2em;
195
206
  content: "◦";
196
207
  }
197
208
 
@@ -200,7 +211,6 @@ NESTED BLOCKS
200
211
  > .bn-block-outer:not([data-prev-type])
201
212
  > .bn-block
202
213
  > .bn-block-content[data-content-type="bulletListItem"]::before {
203
- margin-right: 1.2em;
204
214
  content: "◦";
205
215
  }
206
216
 
@@ -212,7 +222,6 @@ NESTED BLOCKS
212
222
  > .bn-block-outer[data-prev-type="bulletListItem"]
213
223
  > .bn-block
214
224
  > .bn-block-content::before {
215
- margin-right: 1.2em;
216
225
  content: "▪";
217
226
  }
218
227
 
@@ -223,7 +232,6 @@ NESTED BLOCKS
223
232
  > .bn-block-outer:not([data-prev-type])
224
233
  > .bn-block
225
234
  > .bn-block-content[data-content-type="bulletListItem"]::before {
226
- margin-right: 1.2em;
227
235
  content: "▪";
228
236
  }
229
237
 
@@ -283,7 +291,6 @@ NESTED BLOCKS
283
291
  }
284
292
 
285
293
  [data-content-type="image"] .bn-image-resize-handle {
286
- display: none;
287
294
  position: absolute;
288
295
  width: 8px;
289
296
  height: 30px;
@@ -294,7 +301,7 @@ NESTED BLOCKS
294
301
  }
295
302
 
296
303
  [data-content-type="image"] .caption {
297
- font-size: 0.8em
304
+ font-size: 0.8em;
298
305
  }
299
306
 
300
307
  /* PLACEHOLDERS*/
@@ -327,12 +334,14 @@ NESTED BLOCKS
327
334
 
328
335
  .bn-block-content[data-content-type="bulletListItem"].bn-is-empty
329
336
  .bn-inline-content:before,
330
- .bn-block-content[data-content-type="numberedListItem"].bn-is-empty
337
+ .bn-block-content[data-content-type="numberedListItem"].bn-is-empty
331
338
  .bn-inline-content:before {
332
339
  content: "List";
333
340
  }
334
341
 
335
- .bn-is-empty .bn-block-content[data-content-type="captionedImage"] .bn-inline-content:before {
342
+ .bn-is-empty
343
+ .bn-block-content[data-content-type="captionedImage"]
344
+ .bn-inline-content:before {
336
345
  content: "Caption";
337
346
  }
338
347
 
@@ -21,11 +21,11 @@ import { HTMLToBlocks } from "../api/parsers/html/parseHTML";
21
21
  import { markdownToBlocks } from "../api/parsers/markdown/parseMarkdown";
22
22
  import {
23
23
  DefaultBlockSchema,
24
- DefaultInlineContentSchema,
25
- DefaultStyleSchema,
26
24
  defaultBlockSchema,
27
25
  defaultBlockSpecs,
26
+ DefaultInlineContentSchema,
28
27
  defaultInlineContentSpecs,
28
+ DefaultStyleSchema,
29
29
  defaultStyleSpecs,
30
30
  } from "../blocks/defaultBlocks";
31
31
  import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin";
@@ -45,17 +45,17 @@ import {
45
45
  BlockSchemaFromSpecs,
46
46
  BlockSchemaWithBlock,
47
47
  BlockSpecs,
48
+ getBlockSchemaFromSpecs,
49
+ getInlineContentSchemaFromSpecs,
50
+ getStyleSchemaFromSpecs,
48
51
  InlineContentSchema,
49
52
  InlineContentSchemaFromSpecs,
50
53
  InlineContentSpecs,
51
54
  PartialBlock,
55
+ Styles,
52
56
  StyleSchema,
53
57
  StyleSchemaFromSpecs,
54
58
  StyleSpecs,
55
- Styles,
56
- getBlockSchemaFromSpecs,
57
- getInlineContentSchemaFromSpecs,
58
- getStyleSchemaFromSpecs,
59
59
  } from "../schema";
60
60
  import { mergeCSSClasses } from "../util/browser";
61
61
  import { UnreachableCaseError } from "../util/typescript";
@@ -775,8 +775,8 @@ export class BlockNoteEditor<
775
775
  blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],
776
776
  referenceBlock: BlockIdentifier,
777
777
  placement: "before" | "after" | "nested" = "before"
778
- ): void {
779
- insertBlocks(blocksToInsert, referenceBlock, placement, this);
778
+ ) {
779
+ return insertBlocks(blocksToInsert, referenceBlock, placement, this);
780
780
  }
781
781
 
782
782
  /**
@@ -790,7 +790,7 @@ export class BlockNoteEditor<
790
790
  blockToUpdate: BlockIdentifier,
791
791
  update: PartialBlock<BSchema, ISchema, SSchema>
792
792
  ) {
793
- updateBlock(blockToUpdate, update, this._tiptapEditor);
793
+ return updateBlock(blockToUpdate, update, this);
794
794
  }
795
795
 
796
796
  /**
@@ -798,7 +798,7 @@ export class BlockNoteEditor<
798
798
  * @param blocksToRemove An array of identifiers for existing blocks that should be removed.
799
799
  */
800
800
  public removeBlocks(blocksToRemove: BlockIdentifier[]) {
801
- removeBlocks(blocksToRemove, this._tiptapEditor);
801
+ return removeBlocks(blocksToRemove, this);
802
802
  }
803
803
 
804
804
  /**
@@ -812,7 +812,7 @@ export class BlockNoteEditor<
812
812
  blocksToRemove: BlockIdentifier[],
813
813
  blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[]
814
814
  ) {
815
- replaceBlocks(blocksToRemove, blocksToInsert, this);
815
+ return replaceBlocks(blocksToRemove, blocksToInsert, this);
816
816
  }
817
817
 
818
818
  /**
@@ -52,7 +52,8 @@ export class FormattingToolbarView {
52
52
 
53
53
  pmView.dom.addEventListener("mousedown", this.viewMousedownHandler);
54
54
  pmView.dom.addEventListener("mouseup", this.viewMouseupHandler);
55
- pmView.dom.addEventListener("dragstart", this.dragstartHandler);
55
+ pmView.dom.addEventListener("dragstart", this.dragHandler);
56
+ pmView.dom.addEventListener("dragover", this.dragHandler);
56
57
 
57
58
  pmView.dom.addEventListener("focus", this.focusHandler);
58
59
  pmView.dom.addEventListener("blur", this.blurHandler);
@@ -70,7 +71,7 @@ export class FormattingToolbarView {
70
71
  };
71
72
 
72
73
  // For dragging the whole editor.
73
- dragstartHandler = () => {
74
+ dragHandler = () => {
74
75
  if (this.formattingToolbarState?.show) {
75
76
  this.formattingToolbarState.show = false;
76
77
  this.updateFormattingToolbar();
@@ -177,7 +178,8 @@ export class FormattingToolbarView {
177
178
  destroy() {
178
179
  this.pmView.dom.removeEventListener("mousedown", this.viewMousedownHandler);
179
180
  this.pmView.dom.removeEventListener("mouseup", this.viewMouseupHandler);
180
- this.pmView.dom.removeEventListener("dragstart", this.dragstartHandler);
181
+ this.pmView.dom.removeEventListener("dragstart", this.dragHandler);
182
+ this.pmView.dom.removeEventListener("dragover", this.dragHandler);
181
183
 
182
184
  this.pmView.dom.removeEventListener("focus", this.focusHandler);
183
185
  this.pmView.dom.removeEventListener("blur", this.blurHandler);
@@ -8,8 +8,19 @@ export const NonEditableBlockPlugin = () => {
8
8
  key: PLUGIN_KEY,
9
9
  props: {
10
10
  handleKeyDown: (view, event) => {
11
+ // Checks for node selection
11
12
  if ("node" in view.state.selection) {
12
- event.preventDefault();
13
+ // Checks if key input will insert a character - we want to block this
14
+ // as it will convert the block into a paragraph.
15
+ if (
16
+ event.key.length === 1 &&
17
+ !event.ctrlKey &&
18
+ !event.altKey &&
19
+ !event.metaKey &&
20
+ !event.shiftKey
21
+ ) {
22
+ event.preventDefault();
23
+ }
13
24
  }
14
25
  },
15
26
  },
@@ -547,10 +547,13 @@ export class SideMenuView<
547
547
  return;
548
548
  }
549
549
 
550
- const { contentNode, endPos } = blockInfo;
550
+ const { contentNode, startPos, endPos } = blockInfo;
551
551
 
552
552
  // Creates a new block if current one is not empty for the suggestion menu to open in.
553
- if (contentNode.textContent.length !== 0) {
553
+ if (
554
+ contentNode.type.spec.content !== "inline*" ||
555
+ contentNode.textContent.length !== 0
556
+ ) {
554
557
  const newBlockInsertionPos = endPos + 1;
555
558
  const newBlockContentPos = newBlockInsertionPos + 2;
556
559
 
@@ -561,7 +564,7 @@ export class SideMenuView<
561
564
  .setTextSelection(newBlockContentPos)
562
565
  .run();
563
566
  } else {
564
- this.editor._tiptapEditor.commands.setTextSelection(endPos);
567
+ this.editor._tiptapEditor.commands.setTextSelection(startPos + 1);
565
568
  }
566
569
 
567
570
  // Focuses and activates the suggestion menu.
@@ -24,7 +24,9 @@ function setHiddenDragImage() {
24
24
 
25
25
  dragImageElement = document.createElement("div");
26
26
  dragImageElement.innerHTML = "_";
27
- dragImageElement.style.visibility = "hidden";
27
+ dragImageElement.style.opacity = "0";
28
+ dragImageElement.style.height = "1px";
29
+ dragImageElement.style.width = "1px";
28
30
  document.body.appendChild(dragImageElement);
29
31
  }
30
32
 
@@ -567,7 +567,7 @@ export const BlockContainer = Node.create<{
567
567
  state.selection.from
568
568
  )!;
569
569
 
570
- const blockAtDocEnd = false;
570
+ const blockAtDocEnd = endPos === state.doc.nodeSize - 4;
571
571
  const selectionAtBlockEnd = state.selection.from === endPos - 1;
572
572
  const selectionEmpty = state.selection.empty;
573
573
  const hasChildBlocks = node.childCount === 2;
@@ -1,7 +1,9 @@
1
- import { Editor } from "@tiptap/core";
2
1
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
3
- import { BlockIdentifier, BlockSchema, InlineContentSchema, PartialBlock, StyleSchema } from "../../schema";
4
- export declare function insertBlocks<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blocksToInsert: PartialBlock<BSchema, I, S>[], referenceBlock: BlockIdentifier, placement: "before" | "after" | "nested" | undefined, editor: BlockNoteEditor<BSchema, I, S>): void;
5
- export declare function updateBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blockToUpdate: BlockIdentifier, update: PartialBlock<BSchema, I, S>, editor: Editor): void;
6
- export declare function removeBlocks(blocksToRemove: BlockIdentifier[], editor: Editor): void;
7
- export declare function replaceBlocks<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blocksToRemove: BlockIdentifier[], blocksToInsert: PartialBlock<BSchema, I, S>[], editor: BlockNoteEditor<BSchema, I, S>): void;
2
+ import { Block, BlockIdentifier, BlockSchema, InlineContentSchema, PartialBlock, StyleSchema } from "../../schema";
3
+ export declare function insertBlocks<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blocksToInsert: PartialBlock<BSchema, I, S>[], referenceBlock: BlockIdentifier, placement: "before" | "after" | "nested" | undefined, editor: BlockNoteEditor<BSchema, I, S>): Block<BSchema, I, S>[];
4
+ export declare function updateBlock<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blockToUpdate: BlockIdentifier, update: PartialBlock<BSchema, I, S>, editor: BlockNoteEditor<BSchema, I, S>): Block<BSchema, I, S>;
5
+ export declare function removeBlocks<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blocksToRemove: BlockIdentifier[], editor: BlockNoteEditor<BSchema, I, S>): Block<BSchema, I, S>[];
6
+ export declare function replaceBlocks<BSchema extends BlockSchema, I extends InlineContentSchema, S extends StyleSchema>(blocksToRemove: BlockIdentifier[], blocksToInsert: PartialBlock<BSchema, I, S>[], editor: BlockNoteEditor<BSchema, I, S>): {
7
+ insertedBlocks: Block<BSchema, I, S>[];
8
+ removedBlocks: Block<BSchema, I, S>[];
9
+ };
@@ -2,7 +2,7 @@ import { EditorOptions } from "@tiptap/core";
2
2
  import { Node } from "prosemirror-model";
3
3
  import { Editor as TiptapEditor } from "@tiptap/core/dist/packages/core/src/Editor";
4
4
  import * as Y from "yjs";
5
- import { DefaultBlockSchema, DefaultInlineContentSchema, DefaultStyleSchema, defaultBlockSpecs, defaultInlineContentSpecs, defaultStyleSpecs } from "../blocks/defaultBlocks";
5
+ import { DefaultBlockSchema, defaultBlockSpecs, DefaultInlineContentSchema, defaultInlineContentSpecs, DefaultStyleSchema, defaultStyleSpecs } from "../blocks/defaultBlocks";
6
6
  import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin";
7
7
  import { HyperlinkToolbarProsemirrorPlugin } from "../extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
8
8
  import { ImageToolbarProsemirrorPlugin } from "../extensions/ImageToolbar/ImageToolbarPlugin";
@@ -10,7 +10,7 @@ import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin
10
10
  import { BaseSlashMenuItem } from "../extensions/SlashMenu/BaseSlashMenuItem";
11
11
  import { SlashMenuProsemirrorPlugin } from "../extensions/SlashMenu/SlashMenuPlugin";
12
12
  import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin";
13
- import { Block, BlockIdentifier, BlockNoteDOMAttributes, BlockSchema, BlockSchemaFromSpecs, BlockSchemaWithBlock, BlockSpecs, InlineContentSchema, InlineContentSchemaFromSpecs, InlineContentSpecs, PartialBlock, StyleSchema, StyleSchemaFromSpecs, StyleSpecs, Styles } from "../schema";
13
+ import { Block, BlockIdentifier, BlockNoteDOMAttributes, BlockSchema, BlockSchemaFromSpecs, BlockSchemaWithBlock, BlockSpecs, InlineContentSchema, InlineContentSchemaFromSpecs, InlineContentSpecs, PartialBlock, Styles, StyleSchema, StyleSchemaFromSpecs, StyleSpecs } from "../schema";
14
14
  import { TextCursorPosition } from "./cursorPositionTypes";
15
15
  import { Selection } from "./selectionTypes";
16
16
  import "./Block.css";
@@ -187,7 +187,7 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
187
187
  * @param placement Whether the blocks should be inserted just before, just after, or nested inside the
188
188
  * `referenceBlock`. Inserts the blocks at the start of the existing block's children if "nested" is used.
189
189
  */
190
- insertBlocks(blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[], referenceBlock: BlockIdentifier, placement?: "before" | "after" | "nested"): void;
190
+ insertBlocks(blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[], referenceBlock: BlockIdentifier, placement?: "before" | "after" | "nested"): Block<BSchema, ISchema, SSchema>[];
191
191
  /**
192
192
  * Updates an existing block in the editor. Since updatedBlock is a PartialBlock object, some fields might not be
193
193
  * defined. These undefined fields are kept as-is from the existing block. Throws an error if the block to update could
@@ -195,12 +195,12 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
195
195
  * @param blockToUpdate The block that should be updated.
196
196
  * @param update A partial block which defines how the existing block should be changed.
197
197
  */
198
- updateBlock(blockToUpdate: BlockIdentifier, update: PartialBlock<BSchema, ISchema, SSchema>): void;
198
+ updateBlock(blockToUpdate: BlockIdentifier, update: PartialBlock<BSchema, ISchema, SSchema>): Block<BSchema, ISchema, SSchema>;
199
199
  /**
200
200
  * Removes existing blocks from the editor. Throws an error if any of the blocks could not be found.
201
201
  * @param blocksToRemove An array of identifiers for existing blocks that should be removed.
202
202
  */
203
- removeBlocks(blocksToRemove: BlockIdentifier[]): void;
203
+ removeBlocks(blocksToRemove: BlockIdentifier[]): Block<BSchema, ISchema, SSchema>[];
204
204
  /**
205
205
  * Replaces existing blocks in the editor with new blocks. If the blocks that should be removed are not adjacent or
206
206
  * are at different nesting levels, `blocksToInsert` will be inserted at the position of the first block in
@@ -208,7 +208,10 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
208
208
  * @param blocksToRemove An array of blocks that should be replaced.
209
209
  * @param blocksToInsert An array of partial blocks to replace the old ones with.
210
210
  */
211
- replaceBlocks(blocksToRemove: BlockIdentifier[], blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[]): void;
211
+ replaceBlocks(blocksToRemove: BlockIdentifier[], blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[]): {
212
+ insertedBlocks: Block<BSchema, ISchema, SSchema>[];
213
+ removedBlocks: Block<BSchema, ISchema, SSchema>[];
214
+ };
212
215
  /**
213
216
  * Gets the active text styles at the text cursor position or at the end of the current selection if it's active.
214
217
  */
@@ -23,7 +23,7 @@ export declare class FormattingToolbarView {
23
23
  constructor(editor: BlockNoteEditor<BlockSchema, InlineContentSchema, StyleSchema>, pmView: EditorView, updateFormattingToolbar: (formattingToolbarState: FormattingToolbarState) => void);
24
24
  viewMousedownHandler: () => void;
25
25
  viewMouseupHandler: () => void;
26
- dragstartHandler: () => void;
26
+ dragHandler: () => void;
27
27
  focusHandler: () => void;
28
28
  blurHandler: (event: FocusEvent) => void;
29
29
  scrollHandler: () => void;