@blocknote/core 0.15.7 → 0.15.9

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 (78) hide show
  1. package/dist/blocknote.js +1284 -1182
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +5 -5
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/webpack-stats.json +1 -1
  6. package/package.json +23 -23
  7. package/src/api/exporters/copyExtension.ts +48 -33
  8. package/src/api/exporters/html/__snapshots__/complex/misc/external.html +1 -1
  9. package/src/api/exporters/html/__snapshots__/customParagraph/styled/external.html +1 -1
  10. package/src/api/exporters/html/__snapshots__/file/basic/external.html +1 -1
  11. package/src/api/exporters/html/__snapshots__/file/nested/external.html +1 -1
  12. package/src/api/exporters/html/__snapshots__/file/noCaption/external.html +1 -1
  13. package/src/api/exporters/html/__snapshots__/file/noName/external.html +1 -1
  14. package/src/api/exporters/html/__snapshots__/fontSize/basic/external.html +1 -1
  15. package/src/api/exporters/html/__snapshots__/hardbreak/basic/external.html +1 -1
  16. package/src/api/exporters/html/__snapshots__/hardbreak/between-links/external.html +1 -1
  17. package/src/api/exporters/html/__snapshots__/hardbreak/end/external.html +1 -1
  18. package/src/api/exporters/html/__snapshots__/hardbreak/link/external.html +1 -1
  19. package/src/api/exporters/html/__snapshots__/hardbreak/multiple/external.html +1 -1
  20. package/src/api/exporters/html/__snapshots__/hardbreak/only/external.html +1 -1
  21. package/src/api/exporters/html/__snapshots__/hardbreak/start/external.html +1 -1
  22. package/src/api/exporters/html/__snapshots__/hardbreak/styles/external.html +1 -1
  23. package/src/api/exporters/html/__snapshots__/image/basic/external.html +1 -1
  24. package/src/api/exporters/html/__snapshots__/image/nested/external.html +1 -1
  25. package/src/api/exporters/html/__snapshots__/image/noCaption/external.html +1 -1
  26. package/src/api/exporters/html/__snapshots__/image/noName/external.html +1 -1
  27. package/src/api/exporters/html/__snapshots__/image/noPreview/external.html +1 -1
  28. package/src/api/exporters/html/__snapshots__/link/adjacent/external.html +1 -1
  29. package/src/api/exporters/html/__snapshots__/link/basic/external.html +1 -1
  30. package/src/api/exporters/html/__snapshots__/link/styled/external.html +1 -1
  31. package/src/api/exporters/html/__snapshots__/mention/basic/external.html +1 -1
  32. package/src/api/exporters/html/__snapshots__/paragraph/basic/external.html +1 -1
  33. package/src/api/exporters/html/__snapshots__/paragraph/empty/external.html +1 -1
  34. package/src/api/exporters/html/__snapshots__/paragraph/lineBreaks/external.html +1 -1
  35. package/src/api/exporters/html/__snapshots__/paragraph/nested/external.html +1 -1
  36. package/src/api/exporters/html/__snapshots__/paragraph/styled/external.html +1 -1
  37. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/basic/external.html +1 -1
  38. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/nested/external.html +1 -1
  39. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/styled/external.html +1 -1
  40. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
  41. package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -1
  42. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -1
  43. package/src/api/exporters/html/__snapshots__/simpleImage/noCaption/external.html +1 -1
  44. package/src/api/exporters/html/__snapshots__/simpleImage/noName/external.html +1 -1
  45. package/src/api/exporters/html/__snapshots__/simpleImage/noPreview/external.html +1 -1
  46. package/src/api/exporters/html/__snapshots__/small/basic/external.html +1 -1
  47. package/src/api/exporters/html/__snapshots__/tag/basic/external.html +1 -1
  48. package/src/api/exporters/html/__snapshots_fragment_edge_cases__/selectionLeavesBlockChildren.html +1 -1
  49. package/src/api/exporters/html/__snapshots_fragment_edge_cases__/selectionSpansBlocksChildren.html +1 -1
  50. package/src/api/exporters/html/__snapshots_fragment_edge_cases__/selectionWithinBlockChildren.html +1 -1
  51. package/src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts +51 -2
  52. package/src/api/parsers/handleFileInsertion.ts +30 -17
  53. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +23 -47
  54. package/src/blocks/FileBlockContent/FileBlockContent.ts +4 -22
  55. package/src/blocks/FileBlockContent/fileBlockHelpers.ts +72 -1
  56. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +35 -61
  57. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +33 -58
  58. package/src/editor/BlockNoteEditor.test.ts +13 -0
  59. package/src/editor/BlockNoteEditor.ts +71 -6
  60. package/src/editor/BlockNoteExtensions.ts +4 -2
  61. package/src/editor/BlockNoteTipTapEditor.ts +4 -1
  62. package/src/extensions/FilePanel/FilePanelPlugin.ts +10 -6
  63. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +0 -1
  64. package/src/extensions/SideMenu/SideMenuPlugin.ts +22 -11
  65. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +6 -3
  66. package/src/extensions/TableHandles/TableHandlesPlugin.ts +5 -1
  67. package/src/extensions/UniqueID/UniqueID.ts +15 -4
  68. package/src/pm-nodes/BlockContainer.ts +1 -2
  69. package/src/schema/inlineContent/createSpec.ts +54 -5
  70. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +2 -2
  71. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +2 -2
  72. package/types/src/blocks/FileBlockContent/fileBlockHelpers.d.ts +11 -1
  73. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +2 -2
  74. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +2 -2
  75. package/types/src/editor/BlockNoteEditor.d.ts +23 -4
  76. package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
  77. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +1 -1
  78. package/types/src/schema/inlineContent/createSpec.d.ts +3 -3
@@ -12,8 +12,8 @@ import { Link } from "@tiptap/extension-link";
12
12
  import { Text } from "@tiptap/extension-text";
13
13
  import * as Y from "yjs";
14
14
  import { createCopyToClipboardExtension } from "../api/exporters/copyExtension";
15
- import { createPasteFromClipboardExtension } from "../api/parsers/pasteExtension";
16
15
  import { createDropFileExtension } from "../api/parsers/fileDropExtension";
16
+ import { createPasteFromClipboardExtension } from "../api/parsers/pasteExtension";
17
17
  import { BackgroundColorExtension } from "../extensions/BackgroundColor/BackgroundColorExtension";
18
18
  import { TextAlignmentExtension } from "../extensions/TextAlignment/TextAlignmentExtension";
19
19
  import { TextColorExtension } from "../extensions/TextColor/TextColorExtension";
@@ -55,6 +55,7 @@ export const getBlockNoteExtensions = <
55
55
  renderCursor?: (user: any) => HTMLElement;
56
56
  };
57
57
  disableExtensions: string[] | undefined;
58
+ setIdAttribute?: boolean;
58
59
  }) => {
59
60
  const ret: Extensions = [
60
61
  extensions.ClipboardTextSerializer,
@@ -69,6 +70,7 @@ export const getBlockNoteExtensions = <
69
70
  // DropCursor,
70
71
  UniqueID.configure({
71
72
  types: ["blockContainer"],
73
+ setIdAttribute: opts.setIdAttribute,
72
74
  }),
73
75
  HardBreak.extend({ priority: 10 }),
74
76
  // Comments,
@@ -197,5 +199,5 @@ export const getBlockNoteExtensions = <
197
199
  }
198
200
 
199
201
  const disableExtensions: string[] = opts.disableExtensions || [];
200
- return ret.filter(ex => !disableExtensions.includes(ex.name));
202
+ return ret.filter((ex) => !disableExtensions.includes(ex.name));
201
203
  };
@@ -168,8 +168,11 @@ export class BlockNoteTipTapEditor extends TiptapEditor {
168
168
  };
169
169
  }
170
170
 
171
- (BlockNoteTipTapEditor.prototype as any).createView = () => {
171
+ (BlockNoteTipTapEditor.prototype as any).createView = function () {
172
172
  // no-op
173
173
  // Disable default call to `createView` in the Editor constructor.
174
174
  // We should call `createView` manually only when a DOM element is available
175
+
176
+ // additional fix because onPaste and onDrop depend on installing plugins in constructor which we don't support
177
+ this.options.onPaste = this.options.onDrop = undefined;
175
178
  };
@@ -71,8 +71,10 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
71
71
  if (this.state?.show) {
72
72
  const blockElement = this.pmView.root.querySelector(
73
73
  `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]`
74
- )!;
75
-
74
+ );
75
+ if (!blockElement) {
76
+ return;
77
+ }
76
78
  this.state.referencePos = blockElement.getBoundingClientRect();
77
79
  this.emitUpdate();
78
80
  }
@@ -86,8 +88,10 @@ export class FilePanelView<I extends InlineContentSchema, S extends StyleSchema>
86
88
  if (!this.state?.show && pluginState.block && this.editor.isEditable) {
87
89
  const blockElement = this.pmView.root.querySelector(
88
90
  `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]`
89
- )!;
90
-
91
+ );
92
+ if (!blockElement) {
93
+ return;
94
+ }
91
95
  this.state = {
92
96
  show: true,
93
97
  referencePos: blockElement.getBoundingClientRect(),
@@ -157,7 +161,7 @@ export class FilePanelProsemirrorPlugin<
157
161
  props: {
158
162
  handleKeyDown: (_view, event: KeyboardEvent) => {
159
163
  if (event.key === "Escape" && this.shown) {
160
- this.view!.closeMenu();
164
+ this.view?.closeMenu();
161
165
  return true;
162
166
  }
163
167
  return false;
@@ -189,5 +193,5 @@ export class FilePanelProsemirrorPlugin<
189
193
  return this.on("update", callback);
190
194
  }
191
195
 
192
- public closeMenu = () => this.view!.closeMenu();
196
+ public closeMenu = () => this.view?.closeMenu();
193
197
  }
@@ -205,7 +205,6 @@ export class FormattingToolbarView implements PluginView {
205
205
 
206
206
  if (isNodeSelection(selection)) {
207
207
  const node = this.pmView.nodeDOM(from) as HTMLElement;
208
-
209
208
  if (node) {
210
209
  return node.getBoundingClientRect();
211
210
  }
@@ -267,7 +267,7 @@ export class SideMenuView<
267
267
  // When false, the drag handle with be just to the left of the element
268
268
  // TODO: Is there any case where we want this to be false?
269
269
  private horizontalPosAnchoredAtRoot: boolean;
270
- private horizontalPosAnchor: number;
270
+ private horizontalPosAnchor: number | undefined;
271
271
 
272
272
  private hoveredBlock: HTMLElement | undefined;
273
273
 
@@ -290,9 +290,12 @@ export class SideMenuView<
290
290
  };
291
291
 
292
292
  this.horizontalPosAnchoredAtRoot = true;
293
- this.horizontalPosAnchor = (
294
- this.pmView.dom.firstChild! as HTMLElement
295
- ).getBoundingClientRect().x;
293
+
294
+ if (this.pmView.dom.firstChild) {
295
+ this.horizontalPosAnchor = (
296
+ this.pmView.dom.firstChild as HTMLElement
297
+ ).getBoundingClientRect().x;
298
+ }
296
299
 
297
300
  this.pmView.root.addEventListener(
298
301
  "drop",
@@ -337,8 +340,12 @@ export class SideMenuView<
337
340
  // size/position, so we get the boundingRect of the first child (i.e. the
338
341
  // blockGroup that wraps all blocks in the editor) for more accurate side
339
342
  // menu placement.
343
+ if (!this.pmView.dom.firstChild) {
344
+ return;
345
+ }
346
+
340
347
  const editorBoundingBox = (
341
- this.pmView.dom.firstChild! as HTMLElement
348
+ this.pmView.dom.firstChild as HTMLElement
342
349
  ).getBoundingClientRect();
343
350
 
344
351
  this.horizontalPosAnchor = editorBoundingBox.x;
@@ -441,7 +448,7 @@ export class SideMenuView<
441
448
  if (!pos || pos.inside === -1) {
442
449
  const evt = new Event("drop", event) as any;
443
450
  const editorBoundingBox = (
444
- this.pmView.dom.firstChild! as HTMLElement
451
+ this.pmView.dom.firstChild as HTMLElement
445
452
  ).getBoundingClientRect();
446
453
  evt.clientX =
447
454
  event.clientX < editorBoundingBox.left ||
@@ -474,10 +481,10 @@ export class SideMenuView<
474
481
  top: event.clientY,
475
482
  });
476
483
 
477
- if (!pos || pos.inside === -1) {
484
+ if (!pos || (pos.inside === -1 && this.pmView.dom.firstChild)) {
478
485
  const evt = new Event("dragover", event) as any;
479
486
  const editorBoundingBox = (
480
- this.pmView.dom.firstChild! as HTMLElement
487
+ this.pmView.dom.firstChild as HTMLElement
481
488
  ).getBoundingClientRect();
482
489
  evt.clientX = editorBoundingBox.left + editorBoundingBox.width / 2;
483
490
  evt.clientY = event.clientY;
@@ -555,8 +562,8 @@ export class SideMenuView<
555
562
  };
556
563
 
557
564
  onScroll = () => {
558
- if (this.state?.show) {
559
- const blockContent = this.hoveredBlock!.firstChild as HTMLElement;
565
+ if (this.state?.show && this.hoveredBlock?.firstChild) {
566
+ const blockContent = this.hoveredBlock.firstChild as HTMLElement;
560
567
  const blockContentBoundingBox = blockContent.getBoundingClientRect();
561
568
 
562
569
  this.state.referencePos = new DOMRect(
@@ -624,7 +631,11 @@ export class SideMenuView<
624
631
  this.emitUpdate(this.state);
625
632
  }
626
633
 
627
- const blockContent = this.hoveredBlock!.firstChild! as HTMLElement;
634
+ if (!this.hoveredBlock?.firstChild) {
635
+ return;
636
+ }
637
+
638
+ const blockContent = this.hoveredBlock.firstChild as HTMLElement;
628
639
  const blockContentBoundingBox = blockContent.getBoundingClientRect();
629
640
 
630
641
  const pos = this.pmView.posAtCoords({
@@ -54,7 +54,10 @@ class SuggestionMenuView<
54
54
  const decorationNode = this.rootEl?.querySelector(
55
55
  `[data-decoration-id="${this.pluginState!.decorationId}"]`
56
56
  );
57
- this.state.referencePos = decorationNode!.getBoundingClientRect();
57
+ if (!decorationNode) {
58
+ return;
59
+ }
60
+ this.state.referencePos = decorationNode.getBoundingClientRect();
58
61
  this.emitUpdate(this.pluginState!.triggerCharacter!);
59
62
  }
60
63
  };
@@ -89,10 +92,10 @@ class SuggestionMenuView<
89
92
  `[data-decoration-id="${this.pluginState!.decorationId}"]`
90
93
  );
91
94
 
92
- if (this.editor.isEditable) {
95
+ if (this.editor.isEditable && decorationNode) {
93
96
  this.state = {
94
97
  show: true,
95
- referencePos: decorationNode!.getBoundingClientRect(),
98
+ referencePos: decorationNode.getBoundingClientRect(),
96
99
  query: this.pluginState!.query,
97
100
  };
98
101
 
@@ -159,7 +159,11 @@ export class TableHandlesView<
159
159
  const rowIndex = getChildIndex(target.parentElement!);
160
160
  const cellRect = target.getBoundingClientRect();
161
161
  const tableRect =
162
- target.parentElement!.parentElement!.getBoundingClientRect();
162
+ target.parentElement?.parentElement?.getBoundingClientRect();
163
+
164
+ if (!tableRect) {
165
+ return;
166
+ }
163
167
 
164
168
  const blockEl = getDraggableBlockFromElement(target, this.pmView);
165
169
  if (!blockEl) {
@@ -50,6 +50,7 @@ const UniqueID = Extension.create({
50
50
  return {
51
51
  attributeName: "id",
52
52
  types: [],
53
+ setIdAttribute: false,
53
54
  generateID: () => {
54
55
  // Use mock ID if tests are running.
55
56
  if (typeof window !== "undefined" && (window as any).__TEST_OPTIONS) {
@@ -77,10 +78,20 @@ const UniqueID = Extension.create({
77
78
  default: null,
78
79
  parseHTML: (element) =>
79
80
  element.getAttribute(`data-${this.options.attributeName}`),
80
- renderHTML: (attributes) => ({
81
- [`data-${this.options.attributeName}`]:
82
- attributes[this.options.attributeName],
83
- }),
81
+ renderHTML: (attributes) => {
82
+ const defaultIdAttributes = {
83
+ [`data-${this.options.attributeName}`]:
84
+ attributes[this.options.attributeName],
85
+ };
86
+ if (this.options.setIdAttribute) {
87
+ return {
88
+ ...defaultIdAttributes,
89
+ id: attributes[this.options.attributeName],
90
+ };
91
+ } else {
92
+ return defaultIdAttributes;
93
+ }
94
+ },
84
95
  },
85
96
  },
86
97
  },
@@ -11,7 +11,6 @@ import {
11
11
  import { PartialBlock } from "../blocks/defaultBlocks";
12
12
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor";
13
13
  import { NonEditableBlockPlugin } from "../extensions/NonEditableBlocks/NonEditableBlockPlugin";
14
- import { PreviousBlockTypePlugin } from "../extensions/PreviousBlockType/PreviousBlockTypePlugin";
15
14
  import {
16
15
  BlockNoteDOMAttributes,
17
16
  BlockSchema,
@@ -492,7 +491,7 @@ export const BlockContainer = Node.create<{
492
491
  },
493
492
 
494
493
  addProseMirrorPlugins() {
495
- return [PreviousBlockTypePlugin(), NonEditableBlockPlugin()];
494
+ return [NonEditableBlockPlugin()];
496
495
  },
497
496
 
498
497
  addKeyboardShortcuts() {
@@ -1,6 +1,9 @@
1
1
  import { Node } from "@tiptap/core";
2
2
  import { TagParseRule } from "@tiptap/pm/model";
3
- import { nodeToCustomInlineContent } from "../../api/nodeConversions/nodeConversions";
3
+ import {
4
+ inlineContentToNodes,
5
+ nodeToCustomInlineContent,
6
+ } from "../../api/nodeConversions/nodeConversions";
4
7
  import { propsToAttributes } from "../blocks/internal";
5
8
  import { Props } from "../propTypes";
6
9
  import { StyleSchema } from "../styles/types";
@@ -11,15 +14,15 @@ import {
11
14
  } from "./internal";
12
15
  import {
13
16
  CustomInlineContentConfig,
14
- InlineContentConfig,
15
17
  InlineContentFromConfig,
16
18
  InlineContentSpec,
19
+ PartialCustomInlineContentFromConfig,
17
20
  } from "./types";
18
21
 
19
22
  // TODO: support serialization
20
23
 
21
24
  export type CustomInlineContentImplementation<
22
- T extends InlineContentConfig,
25
+ T extends CustomInlineContentConfig,
23
26
  // B extends BlockSchema,
24
27
  // I extends InlineContentSchema,
25
28
  S extends StyleSchema
@@ -28,7 +31,10 @@ export type CustomInlineContentImplementation<
28
31
  /**
29
32
  * The custom inline content to render
30
33
  */
31
- inlineContent: InlineContentFromConfig<T, S>
34
+ inlineContent: InlineContentFromConfig<T, S>,
35
+ updateInlineContent: (
36
+ update: PartialCustomInlineContentFromConfig<T, S>
37
+ ) => void
32
38
  /**
33
39
  * The BlockNote editor instance
34
40
  * This is typed generically. If you want an editor with your custom schema, you need to
@@ -100,7 +106,10 @@ export function createInlineContentSpec<
100
106
  node,
101
107
  editor.schema.inlineContentSchema,
102
108
  editor.schema.styleSchema
103
- ) as any as InlineContentFromConfig<T, S> // TODO: fix cast
109
+ ) as any as InlineContentFromConfig<T, S>, // TODO: fix cast
110
+ () => {
111
+ // No-op
112
+ }
104
113
  );
105
114
 
106
115
  return addInlineContentAttributes(
@@ -110,6 +119,46 @@ export function createInlineContentSpec<
110
119
  inlineContentConfig.propSchema
111
120
  );
112
121
  },
122
+
123
+ addNodeView() {
124
+ return ({ node, getPos }) => {
125
+ const editor = this.options.editor;
126
+
127
+ const output = inlineContentImplementation.render(
128
+ nodeToCustomInlineContent(
129
+ node,
130
+ editor.schema.inlineContentSchema,
131
+ editor.schema.styleSchema
132
+ ) as any as InlineContentFromConfig<T, S>, // TODO: fix cast
133
+ (update) => {
134
+ if (typeof getPos === "boolean") {
135
+ return;
136
+ }
137
+
138
+ const content = inlineContentToNodes(
139
+ [update],
140
+ editor._tiptapEditor.schema,
141
+ editor.schema.styleSchema
142
+ );
143
+
144
+ editor._tiptapEditor.view.dispatch(
145
+ editor._tiptapEditor.view.state.tr.replaceWith(
146
+ getPos(),
147
+ getPos() + node.nodeSize,
148
+ content
149
+ )
150
+ );
151
+ }
152
+ );
153
+
154
+ return addInlineContentAttributes(
155
+ output,
156
+ inlineContentConfig.type,
157
+ node.attrs as Props<T["propSchema"]>,
158
+ inlineContentConfig.propSchema
159
+ );
160
+ };
161
+ },
113
162
  });
114
163
 
115
164
  return createInlineContentSpecFromTipTapNode(
@@ -42,10 +42,10 @@ export declare const audioBlockConfig: {
42
42
  };
43
43
  export declare const audioRender: (block: BlockFromConfig<typeof audioBlockConfig, any, any>, editor: BlockNoteEditor<any, any, any>) => {
44
44
  dom: HTMLDivElement;
45
- destroy: () => void;
45
+ destroy?: undefined;
46
46
  } | {
47
47
  dom: HTMLDivElement;
48
- destroy?: undefined;
48
+ destroy: (() => void) | undefined;
49
49
  };
50
50
  export declare const audioParse: (element: HTMLElement) => Partial<Props<typeof audioBlockConfig.propSchema>> | undefined;
51
51
  export declare const audioToExternalHTML: (block: BlockFromConfig<typeof audioBlockConfig, any, any>) => {
@@ -35,10 +35,10 @@ export declare const fileBlockConfig: {
35
35
  };
36
36
  export declare const fileRender: (block: BlockFromConfig<typeof fileBlockConfig, any, any>, editor: BlockNoteEditor<any, any, any>) => {
37
37
  dom: HTMLDivElement;
38
- destroy: () => void;
38
+ destroy?: undefined;
39
39
  } | {
40
40
  dom: HTMLDivElement;
41
- destroy?: undefined;
41
+ destroy: (() => void) | undefined;
42
42
  };
43
43
  export declare const fileParse: (element: HTMLElement) => {
44
44
  url: string | undefined;
@@ -1,5 +1,15 @@
1
1
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
2
- import { BlockFromConfig, FileBlockConfig } from "../../schema";
2
+ import { BlockFromConfig, BlockSchemaWithBlock, FileBlockConfig } from "../../schema";
3
+ export declare const createFileBlockWrapper: (block: BlockFromConfig<FileBlockConfig, any, any>, editor: BlockNoteEditor<BlockSchemaWithBlock<FileBlockConfig["type"], FileBlockConfig>, any, any>, element: {
4
+ dom: HTMLElement;
5
+ destroy?: () => void;
6
+ }, buttonText?: string, buttonIcon?: HTMLElement) => {
7
+ dom: HTMLDivElement;
8
+ destroy?: undefined;
9
+ } | {
10
+ dom: HTMLDivElement;
11
+ destroy: (() => void) | undefined;
12
+ };
3
13
  export declare const createDefaultFilePreview: (block: BlockFromConfig<FileBlockConfig, any, any>) => {
4
14
  dom: HTMLElement;
5
15
  destroy?: () => void;
@@ -56,10 +56,10 @@ export declare const imageBlockConfig: {
56
56
  };
57
57
  export declare const imageRender: (block: BlockFromConfig<typeof imageBlockConfig, any, any>, editor: BlockNoteEditor<any, any, any>) => {
58
58
  dom: HTMLDivElement;
59
- destroy: () => void;
59
+ destroy?: undefined;
60
60
  } | {
61
61
  dom: HTMLDivElement;
62
- destroy?: undefined;
62
+ destroy: (() => void) | undefined;
63
63
  };
64
64
  export declare const imageParse: (element: HTMLElement) => Partial<Props<typeof imageBlockConfig.propSchema>> | undefined;
65
65
  export declare const imageToExternalHTML: (block: BlockFromConfig<typeof imageBlockConfig, any, any>) => {
@@ -56,10 +56,10 @@ export declare const videoBlockConfig: {
56
56
  };
57
57
  export declare const videoRender: (block: BlockFromConfig<typeof videoBlockConfig, any, any>, editor: BlockNoteEditor<any, any, any>) => {
58
58
  dom: HTMLDivElement;
59
- destroy: () => void;
59
+ destroy?: undefined;
60
60
  } | {
61
61
  dom: HTMLDivElement;
62
- destroy?: undefined;
62
+ destroy: (() => void) | undefined;
63
63
  };
64
64
  export declare const videoParse: (element: HTMLElement) => Partial<Props<typeof videoBlockConfig.propSchema>> | undefined;
65
65
  export declare const videoToExternalHTML: (block: BlockFromConfig<typeof videoBlockConfig, any, any>) => {
@@ -8,7 +8,7 @@ import { LinkToolbarProsemirrorPlugin } from "../extensions/LinkToolbar/LinkTool
8
8
  import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin";
9
9
  import { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin";
10
10
  import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin";
11
- import { BlockIdentifier, BlockNoteDOMAttributes, BlockSchema, BlockSpecs, InlineContentSchema, InlineContentSpecs, PartialInlineContent, StyleSchema, StyleSpecs, Styles } from "../schema";
11
+ import { BlockIdentifier, BlockNoteDOMAttributes, BlockSchema, BlockSpecs, InlineContentSchema, InlineContentSpecs, PartialInlineContent, Styles, StyleSchema, StyleSpecs } from "../schema";
12
12
  import { NoInfer } from "../util/typescript";
13
13
  import { TextCursorPosition } from "./cursorPositionTypes";
14
14
  import { Selection } from "./selectionTypes";
@@ -18,6 +18,12 @@ import { Dictionary } from "../i18n/dictionary";
18
18
  import { Transaction } from "@tiptap/pm/state";
19
19
  import "../style.css";
20
20
  export type BlockNoteEditorOptions<BSchema extends BlockSchema, ISchema extends InlineContentSchema, SSchema extends StyleSchema> = {
21
+ /**
22
+ * Whether changes to blocks (like indentation, creating lists, changing headings) should be animated or not. Defaults to `true`.
23
+ *
24
+ * @default true
25
+ */
26
+ animations?: boolean;
21
27
  disableExtensions: string[];
22
28
  /**
23
29
  * A dictionary object containing translations for the editor.
@@ -53,7 +59,7 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema, ISchema extends
53
59
  * @param file The file that should be uploaded.
54
60
  * @returns The URL of the uploaded file OR an object containing props that should be set on the file block (such as an id)
55
61
  */
56
- uploadFile: (file: File) => Promise<string | Record<string, any>>;
62
+ uploadFile: (file: File, blockId?: string) => Promise<string | Record<string, any>>;
57
63
  /**
58
64
  * Resolve a URL of a file block to one that can be displayed or downloaded. This can be used for creating authenticated URL or
59
65
  * implementing custom protocols / schemes
@@ -94,9 +100,18 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema, ISchema extends
94
100
  * You probably don't need to set this manually, but use the `server-util` package instead that uses this option internally
95
101
  */
96
102
  _headless: boolean;
103
+ /**
104
+ * A flag indicating whether to set an HTML ID for every block
105
+ *
106
+ * When set to `true`, on each block an id attribute will be set with the block id
107
+ * Otherwise, the HTML ID attribute will not be set.
108
+ *
109
+ * (note that the id is always set on the `data-id` attribute)
110
+ */
111
+ setIdAttribute?: boolean;
97
112
  };
98
113
  export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema, ISchema extends InlineContentSchema = DefaultInlineContentSchema, SSchema extends StyleSchema = DefaultStyleSchema> {
99
- private readonly options;
114
+ protected readonly options: Partial<BlockNoteEditorOptions<any, any, any>>;
100
115
  private readonly _pmSchema;
101
116
  /**
102
117
  * Boolean indicating whether the editor is in headless mode.
@@ -146,7 +161,9 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
146
161
  * @param file The file that should be uploaded.
147
162
  * @returns The URL of the uploaded file OR an object containing props that should be set on the file block (such as an id)
148
163
  */
149
- readonly uploadFile: ((file: File) => Promise<string | Record<string, any>>) | undefined;
164
+ readonly uploadFile: ((file: File, blockId?: string) => Promise<string | Record<string, any>>) | undefined;
165
+ private onUploadStartCallbacks;
166
+ private onUploadEndCallbacks;
150
167
  readonly resolveFileUrl: (url: string) => Promise<string>;
151
168
  get pmSchema(): Schema<any, any>;
152
169
  static create<BSchema extends BlockSchema = DefaultBlockSchema, ISchema extends InlineContentSchema = DefaultInlineContentSchema, SSchema extends StyleSchema = DefaultStyleSchema>(options?: Partial<BlockNoteEditorOptions<BSchema, ISchema, SSchema>>): BlockNoteEditor<BSchema, ISchema, SSchema>;
@@ -162,6 +179,8 @@ export declare class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockS
162
179
  get domElement(): HTMLDivElement;
163
180
  isFocused(): boolean;
164
181
  focus(): void;
182
+ onUploadStart(callback: (blockId?: string) => void): () => void;
183
+ onUploadEnd(callback: (blockId?: string) => void): () => void;
165
184
  /**
166
185
  * @deprecated, use `editor.document` instead
167
186
  */
@@ -22,4 +22,5 @@ export declare const getBlockNoteExtensions: <BSchema extends Record<string, imp
22
22
  renderCursor?: (user: any) => HTMLElement;
23
23
  };
24
24
  disableExtensions: string[] | undefined;
25
+ setIdAttribute?: boolean;
25
26
  }) => import("@tiptap/core").AnyExtension[];
@@ -27,5 +27,5 @@ export declare class FilePanelProsemirrorPlugin<I extends InlineContentSchema, S
27
27
  constructor(editor: BlockNoteEditor<Record<string, FileBlockConfig>, I, S>);
28
28
  get shown(): boolean;
29
29
  onUpdate(callback: (state: FilePanelState<I, S>) => void): () => void;
30
- closeMenu: () => void;
30
+ closeMenu: () => void | undefined;
31
31
  }
@@ -1,12 +1,12 @@
1
1
  import { TagParseRule } from "@tiptap/pm/model";
2
2
  import { StyleSchema } from "../styles/types";
3
- import { CustomInlineContentConfig, InlineContentConfig, InlineContentFromConfig, InlineContentSpec } from "./types";
4
- export type CustomInlineContentImplementation<T extends InlineContentConfig, S extends StyleSchema> = {
3
+ import { CustomInlineContentConfig, InlineContentFromConfig, InlineContentSpec, PartialCustomInlineContentFromConfig } from "./types";
4
+ export type CustomInlineContentImplementation<T extends CustomInlineContentConfig, S extends StyleSchema> = {
5
5
  render: (
6
6
  /**
7
7
  * The custom inline content to render
8
8
  */
9
- inlineContent: InlineContentFromConfig<T, S>
9
+ inlineContent: InlineContentFromConfig<T, S>, updateInlineContent: (update: PartialCustomInlineContentFromConfig<T, S>) => void
10
10
  /**
11
11
  * The BlockNote editor instance
12
12
  * This is typed generically. If you want an editor with your custom schema, you need to