@blocknote/core 0.7.1-alpha.0 → 0.8.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 (77) hide show
  1. package/dist/blocknote.js +1711 -1469
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +6 -2
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -3
  7. package/src/BlockNoteEditor.ts +104 -53
  8. package/src/BlockNoteExtensions.ts +24 -14
  9. package/src/api/blockManipulation/blockManipulation.test.ts +6 -3
  10. package/src/api/blockManipulation/blockManipulation.ts +7 -6
  11. package/src/api/formatConversions/formatConversions.test.ts +13 -8
  12. package/src/api/formatConversions/formatConversions.ts +15 -12
  13. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +292 -0
  14. package/src/api/nodeConversions/nodeConversions.test.ts +265 -10
  15. package/src/api/nodeConversions/nodeConversions.ts +199 -47
  16. package/src/api/nodeConversions/testUtil.ts +8 -4
  17. package/src/editor.module.css +5 -6
  18. package/src/extensions/Blocks/api/block.ts +229 -0
  19. package/src/extensions/Blocks/api/blockTypes.ts +158 -71
  20. package/src/extensions/Blocks/api/cursorPositionTypes.ts +5 -5
  21. package/src/extensions/Blocks/api/defaultBlocks.ts +44 -0
  22. package/src/extensions/Blocks/api/selectionTypes.ts +3 -3
  23. package/src/extensions/Blocks/api/serialization.ts +29 -0
  24. package/src/extensions/Blocks/index.ts +0 -8
  25. package/src/extensions/Blocks/nodes/Block.module.css +28 -16
  26. package/src/extensions/Blocks/nodes/BlockContainer.ts +8 -4
  27. package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +4 -4
  28. package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +5 -5
  29. package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +100 -97
  30. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +4 -4
  31. package/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.ts +11 -9
  32. package/src/extensions/DraggableBlocks/DraggableBlocksExtension.ts +6 -5
  33. package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +57 -14
  34. package/src/extensions/FormattingToolbar/FormattingToolbarExtension.ts +21 -16
  35. package/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.ts +9 -5
  36. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +38 -58
  37. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +19 -0
  38. package/src/extensions/Placeholder/PlaceholderExtension.ts +1 -0
  39. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +5 -2
  40. package/src/extensions/SlashMenu/SlashMenuExtension.ts +37 -33
  41. package/src/extensions/SlashMenu/defaultSlashMenuItems.tsx +14 -10
  42. package/src/extensions/SlashMenu/index.ts +2 -2
  43. package/src/index.ts +4 -0
  44. package/src/shared/plugins/suggestion/SuggestionPlugin.ts +29 -13
  45. package/types/src/BlockNoteEditor.d.ts +38 -23
  46. package/types/src/BlockNoteExtensions.d.ts +15 -8
  47. package/types/src/api/blockManipulation/blockManipulation.d.ts +4 -4
  48. package/types/src/api/formatConversions/formatConversions.d.ts +5 -5
  49. package/types/src/api/nodeConversions/nodeConversions.d.ts +3 -3
  50. package/types/src/api/nodeConversions/testUtil.d.ts +2 -2
  51. package/types/src/extensions/Blocks/api/block.d.ts +2 -4
  52. package/types/src/extensions/Blocks/api/blockTypes.d.ts +77 -33
  53. package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +5 -5
  54. package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +4 -4
  55. package/types/src/extensions/Blocks/api/selectionTypes.d.ts +3 -3
  56. package/types/src/extensions/Blocks/api/serialization.d.ts +2 -0
  57. package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +3 -3
  58. package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +1 -2
  59. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +1 -2
  60. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +1 -2
  61. package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +1 -2
  62. package/types/src/extensions/DraggableBlocks/BlockSideMenuFactoryTypes.d.ts +7 -7
  63. package/types/src/extensions/DraggableBlocks/DraggableBlocksExtension.d.ts +5 -4
  64. package/types/src/extensions/DraggableBlocks/DraggableBlocksPlugin.d.ts +12 -11
  65. package/types/src/extensions/FormattingToolbar/FormattingToolbarExtension.d.ts +6 -5
  66. package/types/src/extensions/FormattingToolbar/FormattingToolbarFactoryTypes.d.ts +4 -3
  67. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +16 -19
  68. package/types/src/extensions/Placeholder/localisation/index.d.ts +2 -0
  69. package/types/src/extensions/Placeholder/localisation/translation.d.ts +51 -0
  70. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +4 -3
  71. package/types/src/extensions/SlashMenu/SlashMenuExtension.d.ts +5 -4
  72. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +66 -1
  73. package/types/src/extensions/SlashMenu/index.d.ts +2 -2
  74. package/types/src/index.d.ts +4 -0
  75. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +5 -4
  76. package/types/src/extensions/Blocks/api/alertBlock.d.ts +0 -13
  77. package/types/src/extensions/Blocks/api/alertBlock2.d.ts +0 -13
@@ -1,117 +1,120 @@
1
- import { InputRule, mergeAttributes, Node } from "@tiptap/core";
2
- import styles from "../../../Block.module.css";
1
+ import { InputRule, mergeAttributes } from "@tiptap/core";
2
+ import { createTipTapBlock } from "../../../../api/block";
3
3
  import { handleEnter } from "../ListItemKeyboardShortcuts";
4
4
  import { NumberedListIndexingPlugin } from "./NumberedListIndexingPlugin";
5
+ import styles from "../../../Block.module.css";
5
6
 
6
- export const NumberedListItemBlockContent = Node.create({
7
- name: "numberedListItem",
8
- group: "blockContent",
9
- content: "inline*",
7
+ export const NumberedListItemBlockContent =
8
+ createTipTapBlock<"numberedListItem">({
9
+ name: "numberedListItem",
10
+ content: "inline*",
10
11
 
11
- addAttributes() {
12
- return {
13
- index: {
14
- default: null,
15
- parseHTML: (element) => element.getAttribute("data-index"),
16
- renderHTML: (attributes) => {
17
- return {
18
- "data-index": attributes.index,
19
- };
12
+ addAttributes() {
13
+ return {
14
+ index: {
15
+ default: null,
16
+ parseHTML: (element) => element.getAttribute("data-index"),
17
+ renderHTML: (attributes) => {
18
+ return {
19
+ "data-index": attributes.index,
20
+ };
21
+ },
20
22
  },
21
- },
22
- };
23
- },
23
+ };
24
+ },
24
25
 
25
- addInputRules() {
26
- return [
27
- // Creates an ordered list when starting with "1.".
28
- new InputRule({
29
- find: new RegExp(`^1\\.\\s$`),
30
- handler: ({ state, chain, range }) => {
31
- chain()
32
- .BNUpdateBlock(state.selection.from, {
33
- type: "numberedListItem",
34
- props: {},
35
- })
36
- // Removes the "1." characters used to set the list.
37
- .deleteRange({ from: range.from, to: range.to });
38
- },
39
- }),
40
- ];
41
- },
26
+ addInputRules() {
27
+ return [
28
+ // Creates an ordered list when starting with "1.".
29
+ new InputRule({
30
+ find: new RegExp(`^1\\.\\s$`),
31
+ handler: ({ state, chain, range }) => {
32
+ chain()
33
+ .BNUpdateBlock(state.selection.from, {
34
+ type: "numberedListItem",
35
+ props: {},
36
+ })
37
+ // Removes the "1." characters used to set the list.
38
+ .deleteRange({ from: range.from, to: range.to });
39
+ },
40
+ }),
41
+ ];
42
+ },
42
43
 
43
- addKeyboardShortcuts() {
44
- return {
45
- Enter: () => handleEnter(this.editor),
46
- };
47
- },
44
+ addKeyboardShortcuts() {
45
+ return {
46
+ Enter: () => handleEnter(this.editor),
47
+ };
48
+ },
48
49
 
49
- addProseMirrorPlugins() {
50
- return [NumberedListIndexingPlugin()];
51
- },
50
+ addProseMirrorPlugins() {
51
+ return [NumberedListIndexingPlugin()];
52
+ },
52
53
 
53
- parseHTML() {
54
- return [
55
- // Case for regular HTML list structure.
56
- // (e.g.: when pasting from other apps)
57
- {
58
- tag: "li",
59
- getAttrs: (element) => {
60
- if (typeof element === "string") {
61
- return false;
62
- }
54
+ parseHTML() {
55
+ return [
56
+ // Case for regular HTML list structure.
57
+ // (e.g.: when pasting from other apps)
58
+ {
59
+ tag: "li",
60
+ getAttrs: (element) => {
61
+ if (typeof element === "string") {
62
+ return false;
63
+ }
63
64
 
64
- const parent = element.parentElement;
65
+ const parent = element.parentElement;
65
66
 
66
- if (parent === null) {
67
- return false;
68
- }
67
+ if (parent === null) {
68
+ return false;
69
+ }
69
70
 
70
- if (parent.tagName === "OL") {
71
- return {};
72
- }
71
+ if (parent.tagName === "OL") {
72
+ return {};
73
+ }
73
74
 
74
- return false;
75
- },
76
- node: "numberedListItem",
77
- },
78
- // Case for BlockNote list structure.
79
- // (e.g.: when pasting from blocknote)
80
- {
81
- tag: "p",
82
- getAttrs: (element) => {
83
- if (typeof element === "string") {
84
75
  return false;
85
- }
76
+ },
77
+ node: "numberedListItem",
78
+ },
79
+ // Case for BlockNote list structure.
80
+ // (e.g.: when pasting from blocknote)
81
+ {
82
+ tag: "p",
83
+ getAttrs: (element) => {
84
+ if (typeof element === "string") {
85
+ return false;
86
+ }
86
87
 
87
- const parent = element.parentElement;
88
+ const parent = element.parentElement;
88
89
 
89
- if (parent === null) {
90
- return false;
91
- }
90
+ if (parent === null) {
91
+ return false;
92
+ }
92
93
 
93
- if (parent.getAttribute("data-content-type") === "numberedListItem") {
94
- return {};
95
- }
94
+ if (
95
+ parent.getAttribute("data-content-type") === "numberedListItem"
96
+ ) {
97
+ return {};
98
+ }
96
99
 
97
- return false;
100
+ return false;
101
+ },
102
+ priority: 300,
103
+ node: "numberedListItem",
98
104
  },
99
- priority: 300,
100
- node: "numberedListItem",
101
- },
102
- ];
103
- },
105
+ ];
106
+ },
104
107
 
105
- renderHTML({ HTMLAttributes }) {
106
- return [
107
- "div",
108
- mergeAttributes(HTMLAttributes, {
109
- class: styles.blockContent,
110
- "data-content-type": this.name,
111
- }),
112
- // we use a <p> tag, because for <li> tags we'd need to add a <ul> parent for around siblings to be semantically correct,
113
- // which would be quite cumbersome
114
- ["p", 0],
115
- ];
116
- },
117
- });
108
+ renderHTML({ HTMLAttributes }) {
109
+ return [
110
+ "div",
111
+ mergeAttributes(HTMLAttributes, {
112
+ class: styles.blockContent,
113
+ "data-content-type": this.name,
114
+ }),
115
+ // we use a <p> tag, because for <li> tags we'd need to add a <ul> parent for around siblings to be semantically correct,
116
+ // which would be quite cumbersome
117
+ ["p", { class: styles.inlineContent }, 0],
118
+ ];
119
+ },
120
+ });
@@ -1,9 +1,9 @@
1
- import { mergeAttributes, Node } from "@tiptap/core";
1
+ import { mergeAttributes } from "@tiptap/core";
2
+ import { createTipTapBlock } from "../../../api/block";
2
3
  import styles from "../../Block.module.css";
3
4
 
4
- export const ParagraphBlockContent = Node.create({
5
+ export const ParagraphBlockContent = createTipTapBlock<"paragraph">({
5
6
  name: "paragraph",
6
- group: "blockContent",
7
7
  content: "inline*",
8
8
 
9
9
  parseHTML() {
@@ -23,7 +23,7 @@ export const ParagraphBlockContent = Node.create({
23
23
  class: styles.blockContent,
24
24
  "data-content-type": this.name,
25
25
  }),
26
- ["p", 0],
26
+ ["p", { class: styles.inlineContent }, 0],
27
27
  ];
28
28
  },
29
29
  });
@@ -1,9 +1,9 @@
1
1
  import { EditorElement, ElementFactory } from "../../shared/EditorElement";
2
2
  import { BlockNoteEditor } from "../../BlockNoteEditor";
3
- import { Block } from "../Blocks/api/blockTypes";
3
+ import { Block, BlockSchema } from "../Blocks/api/blockTypes";
4
4
 
5
- export type BlockSideMenuStaticParams = {
6
- editor: BlockNoteEditor;
5
+ export type BlockSideMenuStaticParams<BSchema extends BlockSchema> = {
6
+ editor: BlockNoteEditor<BSchema>;
7
7
 
8
8
  addBlock: () => void;
9
9
 
@@ -14,14 +14,16 @@ export type BlockSideMenuStaticParams = {
14
14
  unfreezeMenu: () => void;
15
15
  };
16
16
 
17
- export type BlockSideMenuDynamicParams = {
18
- block: Block;
17
+ export type BlockSideMenuDynamicParams<BSchema extends BlockSchema> = {
18
+ block: Block<BSchema>;
19
19
 
20
20
  referenceRect: DOMRect;
21
21
  };
22
22
 
23
- export type BlockSideMenu = EditorElement<BlockSideMenuDynamicParams>;
24
- export type BlockSideMenuFactory = ElementFactory<
25
- BlockSideMenuStaticParams,
26
- BlockSideMenuDynamicParams
23
+ export type BlockSideMenu<BSchema extends BlockSchema> = EditorElement<
24
+ BlockSideMenuDynamicParams<BSchema>
25
+ >;
26
+ export type BlockSideMenuFactory<BSchema extends BlockSchema> = ElementFactory<
27
+ BlockSideMenuStaticParams<BSchema>,
28
+ BlockSideMenuDynamicParams<BSchema>
27
29
  >;
@@ -2,11 +2,12 @@ import { Editor, Extension } from "@tiptap/core";
2
2
  import { BlockSideMenuFactory } from "./BlockSideMenuFactoryTypes";
3
3
  import { createDraggableBlocksPlugin } from "./DraggableBlocksPlugin";
4
4
  import { BlockNoteEditor } from "../../BlockNoteEditor";
5
+ import { BlockSchema } from "../Blocks/api/blockTypes";
5
6
 
6
- export type DraggableBlocksOptions = {
7
+ export type DraggableBlocksOptions<BSchema extends BlockSchema> = {
7
8
  tiptapEditor: Editor;
8
- editor: BlockNoteEditor;
9
- blockSideMenuFactory: BlockSideMenuFactory;
9
+ editor: BlockNoteEditor<BSchema>;
10
+ blockSideMenuFactory: BlockSideMenuFactory<BSchema>;
10
11
  };
11
12
 
12
13
  /**
@@ -15,8 +16,8 @@ export type DraggableBlocksOptions = {
15
16
  *
16
17
  * code based on https://github.com/ueberdosis/tiptap/issues/323#issuecomment-506637799
17
18
  */
18
- export const DraggableBlocksExtension =
19
- Extension.create<DraggableBlocksOptions>({
19
+ export const createDraggableBlocksExtension = <BSchema extends BlockSchema>() =>
20
+ Extension.create<DraggableBlocksOptions<BSchema>>({
20
21
  name: "DraggableBlocksExtension",
21
22
  priority: 1000, // Need to be high, in order to hide menu when typing slash
22
23
  addProseMirrorPlugins() {
@@ -15,6 +15,7 @@ import {
15
15
  import { DraggableBlocksOptions } from "./DraggableBlocksExtension";
16
16
  import { MultipleNodeSelection } from "./MultipleNodeSelection";
17
17
  import { BlockNoteEditor } from "../../BlockNoteEditor";
18
+ import { BlockSchema } from "../Blocks/api/blockTypes";
18
19
 
19
20
  const serializeForClipboard = (pv as any).__serializeForClipboard;
20
21
  // code based on https://github.com/ueberdosis/tiptap/issues/323#issuecomment-506637799
@@ -223,15 +224,15 @@ function dragStart(e: DragEvent, view: EditorView) {
223
224
  }
224
225
  }
225
226
 
226
- export type BlockMenuViewProps = {
227
+ export type BlockMenuViewProps<BSchema extends BlockSchema> = {
227
228
  tiptapEditor: Editor;
228
- editor: BlockNoteEditor;
229
- blockMenuFactory: BlockSideMenuFactory;
229
+ editor: BlockNoteEditor<BSchema>;
230
+ blockMenuFactory: BlockSideMenuFactory<BSchema>;
230
231
  horizontalPosAnchoredAtRoot: boolean;
231
232
  };
232
233
 
233
- export class BlockMenuView {
234
- editor: BlockNoteEditor;
234
+ export class BlockMenuView<BSchema extends BlockSchema> {
235
+ editor: BlockNoteEditor<BSchema>;
235
236
  private ttEditor: Editor;
236
237
 
237
238
  // When true, the drag handle with be anchored at the same level as root elements
@@ -240,7 +241,7 @@ export class BlockMenuView {
240
241
 
241
242
  horizontalPosAnchor: number;
242
243
 
243
- blockMenu: BlockSideMenu;
244
+ blockMenu: BlockSideMenu<BSchema>;
244
245
 
245
246
  hoveredBlock: HTMLElement | undefined;
246
247
 
@@ -254,7 +255,7 @@ export class BlockMenuView {
254
255
  editor,
255
256
  blockMenuFactory,
256
257
  horizontalPosAnchoredAtRoot,
257
- }: BlockMenuViewProps) {
258
+ }: BlockMenuViewProps<BSchema>) {
258
259
  this.editor = editor;
259
260
  this.ttEditor = tiptapEditor;
260
261
  this.horizontalPosAnchoredAtRoot = horizontalPosAnchoredAtRoot;
@@ -319,7 +320,7 @@ export class BlockMenuView {
319
320
  };
320
321
 
321
322
  /**
322
- * If the event is outside of the editor contents,
323
+ * If the event is outside the editor contents,
323
324
  * we dispatch a fake event, so that we can still drop the content
324
325
  * when dragging / dropping to the side of the editor
325
326
  */
@@ -374,11 +375,45 @@ export class BlockMenuView {
374
375
  return;
375
376
  }
376
377
 
377
- // Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of
378
- // the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box.
378
+ // Editor itself may have padding or other styling which affects
379
+ // size/position, so we get the boundingRect of the first child (i.e. the
380
+ // blockGroup that wraps all blocks in the editor) for more accurate side
381
+ // menu placement.
379
382
  const editorBoundingBox = (
380
383
  this.ttEditor.view.dom.firstChild! as HTMLElement
381
384
  ).getBoundingClientRect();
385
+ // We want the full area of the editor to check if the cursor is hovering
386
+ // above it though.
387
+ const editorOuterBoundingBox =
388
+ this.ttEditor.view.dom.getBoundingClientRect();
389
+ const cursorWithinEditor =
390
+ event.clientX >= editorOuterBoundingBox.left &&
391
+ event.clientX <= editorOuterBoundingBox.right &&
392
+ event.clientY >= editorOuterBoundingBox.top &&
393
+ event.clientY <= editorOuterBoundingBox.bottom;
394
+
395
+ // Doesn't update if the mouse hovers an element that's over the editor but
396
+ // isn't a part of it or the side menu.
397
+ if (
398
+ // Cursor is within the editor area
399
+ cursorWithinEditor &&
400
+ // An element is hovered
401
+ event &&
402
+ event.target &&
403
+ // Element is outside the editor
404
+ this.ttEditor.view.dom !== event.target &&
405
+ !this.ttEditor.view.dom.contains(event.target as HTMLElement) &&
406
+ // Element is outside the side menu
407
+ this.blockMenu.element !== event.target &&
408
+ !this.blockMenu.element?.contains(event.target as HTMLElement)
409
+ ) {
410
+ if (this.menuOpen) {
411
+ this.menuOpen = false;
412
+ this.blockMenu.hide();
413
+ }
414
+
415
+ return;
416
+ }
382
417
 
383
418
  this.horizontalPosAnchor = editorBoundingBox.x;
384
419
 
@@ -429,6 +464,14 @@ export class BlockMenuView {
429
464
  };
430
465
 
431
466
  onScroll = () => {
467
+ // Editor itself may have padding or other styling which affects size/position, so we get the boundingRect of
468
+ // the first child (i.e. the blockGroup that wraps all blocks in the editor) for a more accurate bounding box.
469
+ const editorBoundingBox = (
470
+ this.ttEditor.view.dom.firstChild! as HTMLElement
471
+ ).getBoundingClientRect();
472
+
473
+ this.horizontalPosAnchor = editorBoundingBox.x;
474
+
432
475
  if (this.menuOpen) {
433
476
  this.blockMenu.render(this.getDynamicParams(), false);
434
477
  }
@@ -497,7 +540,7 @@ export class BlockMenuView {
497
540
  );
498
541
  }
499
542
 
500
- getStaticParams(): BlockSideMenuStaticParams {
543
+ getStaticParams(): BlockSideMenuStaticParams<BSchema> {
501
544
  return {
502
545
  editor: this.editor,
503
546
  addBlock: () => this.addBlock(),
@@ -516,7 +559,7 @@ export class BlockMenuView {
516
559
  };
517
560
  }
518
561
 
519
- getDynamicParams(): BlockSideMenuDynamicParams {
562
+ getDynamicParams(): BlockSideMenuDynamicParams<BSchema> {
520
563
  const blockContent = this.hoveredBlock!.firstChild! as HTMLElement;
521
564
  const blockContentBoundingBox = blockContent.getBoundingClientRect();
522
565
 
@@ -534,8 +577,8 @@ export class BlockMenuView {
534
577
  }
535
578
  }
536
579
 
537
- export const createDraggableBlocksPlugin = (
538
- options: DraggableBlocksOptions
580
+ export const createDraggableBlocksPlugin = <BSchema extends BlockSchema>(
581
+ options: DraggableBlocksOptions<BSchema>
539
582
  ) => {
540
583
  return new Plugin({
541
584
  key: new PluginKey("DraggableBlocksPlugin"),
@@ -1,17 +1,22 @@
1
1
  import { Extension } from "@tiptap/core";
2
2
  import { PluginKey } from "prosemirror-state";
3
- import { BlockNoteEditor } from "../..";
3
+ import { BlockNoteEditor, BlockSchema } from "../..";
4
4
  import { FormattingToolbarFactory } from "./FormattingToolbarFactoryTypes";
5
5
  import { createFormattingToolbarPlugin } from "./FormattingToolbarPlugin";
6
6
 
7
+ export type FormattingToolbarOptions<BSchema extends BlockSchema> = {
8
+ formattingToolbarFactory: FormattingToolbarFactory<BSchema>;
9
+ editor: BlockNoteEditor<BSchema>;
10
+ };
11
+
7
12
  /**
8
13
  * The menu that is displayed when selecting a piece of text.
9
14
  */
10
- export const FormattingToolbarExtension = Extension.create<{
11
- formattingToolbarFactory: FormattingToolbarFactory;
12
- editor: BlockNoteEditor;
13
- }>({
14
- name: "FormattingToolbarExtension",
15
+ export const createFormattingToolbarExtension = <
16
+ BSchema extends BlockSchema
17
+ >() =>
18
+ Extension.create<FormattingToolbarOptions<BSchema>>({
19
+ name: "FormattingToolbarExtension",
15
20
 
16
21
  addProseMirrorPlugins() {
17
22
  if (!this.options.formattingToolbarFactory || !this.options.editor) {
@@ -20,13 +25,13 @@ export const FormattingToolbarExtension = Extension.create<{
20
25
  );
21
26
  }
22
27
 
23
- return [
24
- createFormattingToolbarPlugin({
25
- tiptapEditor: this.editor,
26
- editor: this.options.editor,
27
- formattingToolbarFactory: this.options.formattingToolbarFactory,
28
- pluginKey: new PluginKey("FormattingToolbarPlugin"),
29
- }),
30
- ];
31
- },
32
- });
28
+ return [
29
+ createFormattingToolbarPlugin({
30
+ tiptapEditor: this.editor,
31
+ editor: this.options.editor,
32
+ formattingToolbarFactory: this.options.formattingToolbarFactory,
33
+ pluginKey: new PluginKey("FormattingToolbarPlugin"),
34
+ }),
35
+ ];
36
+ },
37
+ });
@@ -1,16 +1,20 @@
1
1
  import { EditorElement, ElementFactory } from "../../shared/EditorElement";
2
2
  import { BlockNoteEditor } from "../../BlockNoteEditor";
3
+ import { BlockSchema } from "../Blocks/api/blockTypes";
3
4
 
4
- export type FormattingToolbarStaticParams = {
5
- editor: BlockNoteEditor;
5
+ export type FormattingToolbarStaticParams<BSchema extends BlockSchema> = {
6
+ editor: BlockNoteEditor<BSchema>;
6
7
  };
7
8
 
8
9
  export type FormattingToolbarDynamicParams = {
9
10
  referenceRect: DOMRect;
10
11
  };
11
12
 
12
- export type FormattingToolbar = EditorElement<FormattingToolbarDynamicParams>;
13
- export type FormattingToolbarFactory = ElementFactory<
14
- FormattingToolbarStaticParams,
13
+ export type FormattingToolbar = EditorElement<
15
14
  FormattingToolbarDynamicParams
16
15
  >;
16
+ export type FormattingToolbarFactory<BSchema extends BlockSchema> =
17
+ ElementFactory<
18
+ FormattingToolbarStaticParams<BSchema>,
19
+ FormattingToolbarDynamicParams
20
+ >;