@blocknote/core 0.11.2 → 0.12.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 (138) hide show
  1. package/README.md +13 -17
  2. package/dist/blocknote.js +1662 -1447
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +6 -6
  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 +7 -3
  9. package/src/api/blockManipulation/blockManipulation.test.ts +19 -15
  10. package/src/api/blockManipulation/blockManipulation.ts +107 -17
  11. package/src/api/exporters/html/externalHTMLExporter.ts +3 -7
  12. package/src/api/exporters/html/htmlConversion.test.ts +6 -3
  13. package/src/api/exporters/html/internalHTMLSerializer.ts +3 -7
  14. package/src/api/exporters/html/util/sharedHTMLConversion.ts +3 -3
  15. package/src/api/exporters/markdown/markdownExporter.test.ts +7 -3
  16. package/src/api/exporters/markdown/markdownExporter.ts +2 -6
  17. package/src/api/getCurrentBlockContentType.ts +14 -0
  18. package/src/api/nodeConversions/nodeConversions.test.ts +14 -7
  19. package/src/api/nodeConversions/nodeConversions.ts +1 -2
  20. package/src/api/parsers/html/parseHTML.test.ts +5 -1
  21. package/src/api/parsers/html/parseHTML.ts +2 -6
  22. package/src/api/parsers/html/util/nestedLists.ts +11 -1
  23. package/src/api/parsers/markdown/parseMarkdown.test.ts +3 -0
  24. package/src/api/parsers/markdown/parseMarkdown.ts +2 -6
  25. package/src/api/testUtil/cases/customBlocks.ts +18 -16
  26. package/src/api/testUtil/cases/customInlineContent.ts +12 -13
  27. package/src/api/testUtil/cases/customStyles.ts +12 -10
  28. package/src/api/testUtil/index.ts +4 -2
  29. package/src/api/testUtil/partialBlockTestUtil.ts +2 -6
  30. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +50 -21
  31. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +1 -2
  32. package/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +8 -1
  33. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +18 -5
  34. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +7 -1
  35. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +18 -5
  36. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +14 -5
  37. package/src/blocks/defaultBlockHelpers.ts +3 -3
  38. package/src/blocks/defaultBlockTypeGuards.ts +84 -0
  39. package/src/blocks/defaultBlocks.ts +29 -3
  40. package/src/editor/Block.css +2 -31
  41. package/src/editor/BlockNoteEditor.ts +223 -267
  42. package/src/editor/BlockNoteExtensions.ts +5 -2
  43. package/src/editor/BlockNoteSchema.ts +98 -0
  44. package/src/editor/BlockNoteTipTapEditor.ts +162 -0
  45. package/src/editor/cursorPositionTypes.ts +2 -6
  46. package/src/editor/editor.css +0 -1
  47. package/src/editor/selectionTypes.ts +2 -6
  48. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +22 -29
  49. package/src/extensions/{ImageToolbar → ImagePanel}/ImageToolbarPlugin.ts +54 -60
  50. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +330 -0
  51. package/src/extensions/Placeholder/PlaceholderExtension.ts +81 -88
  52. package/src/extensions/SideMenu/SideMenuPlugin.ts +55 -56
  53. package/src/extensions/SuggestionMenu/DefaultSuggestionItem.ts +8 -0
  54. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +353 -0
  55. package/src/extensions/{SlashMenu/defaultSlashMenuItems.ts → SuggestionMenu/getDefaultSlashMenuItems.ts} +119 -89
  56. package/src/extensions/TableHandles/TableHandlesPlugin.ts +62 -45
  57. package/src/extensions-shared/UiElementPosition.ts +4 -0
  58. package/src/index.ts +8 -8
  59. package/src/pm-nodes/BlockContainer.ts +5 -5
  60. package/src/schema/blocks/types.ts +15 -15
  61. package/src/schema/inlineContent/createSpec.ts +2 -2
  62. package/src/schema/inlineContent/types.ts +1 -1
  63. package/src/util/browser.ts +6 -4
  64. package/src/util/typescript.ts +7 -4
  65. package/types/src/api/blockManipulation/blockManipulation.d.ts +6 -1
  66. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +2 -1
  67. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +2 -1
  68. package/types/src/api/exporters/markdown/markdownExporter.d.ts +2 -1
  69. package/types/src/api/getCurrentBlockContentType.d.ts +2 -0
  70. package/types/src/api/nodeConversions/nodeConversions.d.ts +2 -1
  71. package/types/src/api/parsers/html/parseHTML.d.ts +2 -1
  72. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -1
  73. package/types/src/api/testUtil/cases/customBlocks.d.ts +72 -13
  74. package/types/src/api/testUtil/cases/customInlineContent.d.ts +281 -6
  75. package/types/src/api/testUtil/cases/customStyles.d.ts +247 -13
  76. package/types/src/api/testUtil/index.d.ts +4 -2
  77. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +2 -1
  78. package/types/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +6 -1
  79. package/types/src/blocks/defaultBlockHelpers.d.ts +2 -2
  80. package/types/src/blocks/defaultBlockTypeGuards.d.ts +24 -0
  81. package/types/src/blocks/defaultBlocks.d.ts +21 -15
  82. package/types/src/editor/BlockNoteEditor.d.ts +51 -56
  83. package/types/src/editor/BlockNoteExtensions.d.ts +1 -0
  84. package/types/src/editor/BlockNoteSchema.d.ts +34 -0
  85. package/types/src/editor/BlockNoteTipTapEditor.d.ts +28 -0
  86. package/types/src/editor/cursorPositionTypes.d.ts +2 -1
  87. package/types/src/editor/selectionTypes.d.ts +2 -1
  88. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +5 -6
  89. package/types/src/extensions/ImagePanel/ImageToolbarPlugin.d.ts +32 -0
  90. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +40 -0
  91. package/types/src/extensions/Placeholder/PlaceholderExtension.d.ts +2 -15
  92. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +8 -7
  93. package/types/src/extensions/SuggestionMenu/DefaultSuggestionItem.d.ts +8 -0
  94. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +31 -0
  95. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +10 -0
  96. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +7 -7
  97. package/types/src/extensions-shared/UiElementPosition.d.ts +4 -0
  98. package/types/src/index.d.ts +8 -8
  99. package/types/src/pm-nodes/BlockContainer.d.ts +3 -2
  100. package/types/src/pm-nodes/BlockGroup.d.ts +1 -1
  101. package/types/src/schema/blocks/types.d.ts +15 -15
  102. package/types/src/schema/inlineContent/types.d.ts +1 -1
  103. package/types/src/util/browser.d.ts +1 -0
  104. package/types/src/util/typescript.d.ts +1 -0
  105. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +0 -335
  106. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +0 -12
  107. package/src/extensions/SlashMenu/SlashMenuPlugin.ts +0 -53
  108. package/src/extensions-shared/BaseUiElementTypes.ts +0 -8
  109. package/src/extensions-shared/README.md +0 -3
  110. package/src/extensions-shared/suggestion/SuggestionItem.ts +0 -3
  111. package/src/extensions-shared/suggestion/SuggestionPlugin.ts +0 -448
  112. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +0 -38
  113. package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +0 -31
  114. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +0 -7
  115. package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +0 -13
  116. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +0 -3
  117. package/types/src/extensions-shared/BaseUiElementTypes.d.ts +0 -7
  118. package/types/src/extensions-shared/suggestion/SuggestionItem.d.ts +0 -3
  119. package/types/src/extensions-shared/suggestion/SuggestionPlugin.d.ts +0 -36
  120. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff +0 -0
  121. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-100.woff2 +0 -0
  122. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff +0 -0
  123. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-200.woff2 +0 -0
  124. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff +0 -0
  125. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-300.woff2 +0 -0
  126. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff +0 -0
  127. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-500.woff2 +0 -0
  128. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff +0 -0
  129. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-600.woff2 +0 -0
  130. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff +0 -0
  131. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-700.woff2 +0 -0
  132. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff +0 -0
  133. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-800.woff2 +0 -0
  134. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff +0 -0
  135. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-900.woff2 +0 -0
  136. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff +0 -0
  137. /package/src/{assets → fonts}/inter-v12-latin/inter-v12-latin-regular.woff2 +0 -0
  138. /package/src/{assets/fonts-inter.css → fonts/inter.css} +0 -0
@@ -1,15 +1,14 @@
1
- import { defaultBlockSchema } from "../../blocks/defaultBlocks";
2
- import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
1
+ import { Block, PartialBlock } from "../../blocks/defaultBlocks";
2
+ import { checkDefaultBlockTypeInSchema } from "../../blocks/defaultBlockTypeGuards";
3
+ import { BlockNoteEditor } from "../../editor/BlockNoteEditor";
3
4
  import {
4
- Block,
5
5
  BlockSchema,
6
6
  InlineContentSchema,
7
- PartialBlock,
8
- StyleSchema,
9
7
  isStyledTextInlineContent,
8
+ StyleSchema,
10
9
  } from "../../schema";
11
- import { imageToolbarPluginKey } from "../ImageToolbar/ImageToolbarPlugin";
12
- import { BaseSlashMenuItem } from "./BaseSlashMenuItem";
10
+ import { formatKeyboardShortcut } from "../../util/browser";
11
+ import { DefaultSuggestionItem } from "./DefaultSuggestionItem";
13
12
 
14
13
  // Sets the editor's text cursor position to the next content editable block,
15
14
  // so either a block with inline content or a table. The last block is always a
@@ -21,11 +20,11 @@ function setSelectionToNextContentEditableBlock<
21
20
  S extends StyleSchema
22
21
  >(editor: BlockNoteEditor<BSchema, I, S>) {
23
22
  let block = editor.getTextCursorPosition().block;
24
- let contentType = editor.blockSchema[block.type].content;
23
+ let contentType = editor.schema.blockSchema[block.type].content;
25
24
 
26
25
  while (contentType === "none") {
27
26
  block = editor.getTextCursorPosition().nextBlock!;
28
- contentType = editor.blockSchema[block.type].content as
27
+ contentType = editor.schema.blockSchema[block.type].content as
29
28
  | "inline"
30
29
  | "table"
31
30
  | "none";
@@ -37,7 +36,7 @@ function setSelectionToNextContentEditableBlock<
37
36
  // updates the current block instead of inserting a new one below. If the new
38
37
  // block doesn't contain editable content, the cursor is moved to the next block
39
38
  // that does.
40
- function insertOrUpdateBlock<
39
+ export function insertOrUpdateBlock<
41
40
  BSchema extends BlockSchema,
42
41
  I extends InlineContentSchema,
43
42
  S extends StyleSchema
@@ -74,94 +73,106 @@ function insertOrUpdateBlock<
74
73
  return insertedBlock;
75
74
  }
76
75
 
77
- export const getDefaultSlashMenuItems = <
76
+ export function getDefaultSlashMenuItems<
78
77
  BSchema extends BlockSchema,
79
78
  I extends InlineContentSchema,
80
79
  S extends StyleSchema
81
- >(
82
- schema: BSchema = defaultBlockSchema as unknown as BSchema
83
- ) => {
84
- const slashMenuItems: BaseSlashMenuItem<BSchema, I, S>[] = [];
85
-
86
- if ("heading" in schema && "level" in schema.heading.propSchema) {
87
- // Command for creating a level 1 heading
88
- if (schema.heading.propSchema.level.values?.includes(1)) {
89
- slashMenuItems.push({
90
- name: "Heading",
91
- aliases: ["h", "heading1", "h1"],
92
- execute: (editor) =>
80
+ >(editor: BlockNoteEditor<BSchema, I, S>) {
81
+ const items: DefaultSuggestionItem[] = [];
82
+
83
+ if (checkDefaultBlockTypeInSchema("heading", editor)) {
84
+ items.push(
85
+ {
86
+ title: "Heading 1",
87
+ onItemClick: () => {
93
88
  insertOrUpdateBlock(editor, {
94
89
  type: "heading",
95
90
  props: { level: 1 },
96
- } as PartialBlock<BSchema, I, S>),
97
- });
98
- }
99
-
100
- // Command for creating a level 2 heading
101
- if (schema.heading.propSchema.level.values?.includes(2)) {
102
- slashMenuItems.push({
103
- name: "Heading 2",
104
- aliases: ["h2", "heading2", "subheading"],
105
- execute: (editor) =>
91
+ });
92
+ },
93
+ subtext: "Used for a top-level heading",
94
+ badge: formatKeyboardShortcut("Mod-Alt-1"),
95
+ aliases: ["h", "heading1", "h1"],
96
+ group: "Headings",
97
+ },
98
+ {
99
+ title: "Heading 2",
100
+ onItemClick: () => {
106
101
  insertOrUpdateBlock(editor, {
107
102
  type: "heading",
108
103
  props: { level: 2 },
109
- } as PartialBlock<BSchema, I, S>),
110
- });
111
- }
112
-
113
- // Command for creating a level 3 heading
114
- if (schema.heading.propSchema.level.values?.includes(3)) {
115
- slashMenuItems.push({
116
- name: "Heading 3",
117
- aliases: ["h3", "heading3", "subheading"],
118
- execute: (editor) =>
104
+ });
105
+ },
106
+ subtext: "Used for key sections",
107
+ badge: formatKeyboardShortcut("Mod-Alt-2"),
108
+ aliases: ["h2", "heading2", "subheading"],
109
+ group: "Headings",
110
+ },
111
+ {
112
+ title: "Heading 3",
113
+ onItemClick: () => {
119
114
  insertOrUpdateBlock(editor, {
120
115
  type: "heading",
121
116
  props: { level: 3 },
122
- } as PartialBlock<BSchema, I, S>),
123
- });
124
- }
117
+ });
118
+ },
119
+ subtext: "Used for subsections and group headings",
120
+ badge: formatKeyboardShortcut("Mod-Alt-3"),
121
+ aliases: ["h3", "heading3", "subheading"],
122
+ group: "Headings",
123
+ }
124
+ );
125
125
  }
126
126
 
127
- if ("bulletListItem" in schema) {
128
- slashMenuItems.push({
129
- name: "Bullet List",
130
- aliases: ["ul", "list", "bulletlist", "bullet list"],
131
- execute: (editor) =>
127
+ if (checkDefaultBlockTypeInSchema("numberedListItem", editor)) {
128
+ items.push({
129
+ title: "Numbered List",
130
+ onItemClick: () => {
132
131
  insertOrUpdateBlock(editor, {
133
- type: "bulletListItem",
134
- }),
132
+ type: "numberedListItem",
133
+ });
134
+ },
135
+ subtext: "Used to display a numbered list",
136
+ badge: formatKeyboardShortcut("Mod-Shift-7"),
137
+ aliases: ["ol", "li", "list", "numberedlist", "numbered list"],
138
+ group: "Basic blocks",
135
139
  });
136
140
  }
137
141
 
138
- if ("numberedListItem" in schema) {
139
- slashMenuItems.push({
140
- name: "Numbered List",
141
- aliases: ["li", "list", "numberedlist", "numbered list"],
142
- execute: (editor) =>
142
+ if (checkDefaultBlockTypeInSchema("bulletListItem", editor)) {
143
+ items.push({
144
+ title: "Bullet List",
145
+ onItemClick: () => {
143
146
  insertOrUpdateBlock(editor, {
144
- type: "numberedListItem",
145
- }),
147
+ type: "bulletListItem",
148
+ });
149
+ },
150
+ subtext: "Used to display an unordered list",
151
+ badge: formatKeyboardShortcut("Mod-Shift-8"),
152
+ aliases: ["ul", "li", "list", "bulletlist", "bullet list"],
153
+ group: "Basic blocks",
146
154
  });
147
155
  }
148
156
 
149
- if ("paragraph" in schema) {
150
- slashMenuItems.push({
151
- name: "Paragraph",
152
- aliases: ["p"],
153
- execute: (editor) =>
157
+ if (checkDefaultBlockTypeInSchema("paragraph", editor)) {
158
+ items.push({
159
+ title: "Paragraph",
160
+ onItemClick: () => {
154
161
  insertOrUpdateBlock(editor, {
155
162
  type: "paragraph",
156
- }),
163
+ });
164
+ },
165
+ subtext: "Used for the body of your document",
166
+ badge: formatKeyboardShortcut("Mod-Alt-0"),
167
+ aliases: ["p", "paragraph"],
168
+ group: "Basic blocks",
157
169
  });
158
170
  }
159
171
 
160
- if ("table" in schema) {
161
- slashMenuItems.push({
162
- name: "Table",
163
- aliases: ["table"],
164
- execute: (editor) => {
172
+ if (checkDefaultBlockTypeInSchema("table", editor)) {
173
+ items.push({
174
+ title: "Table",
175
+ onItemClick: () => {
165
176
  insertOrUpdateBlock(editor, {
166
177
  type: "table",
167
178
  content: {
@@ -175,14 +186,31 @@ export const getDefaultSlashMenuItems = <
175
186
  },
176
187
  ],
177
188
  },
178
- } as PartialBlock<BSchema, I, S>);
189
+ });
179
190
  },
191
+ subtext: "Used for for tables",
192
+ aliases: ["table"],
193
+ group: "Advanced",
194
+ badge: undefined,
180
195
  });
181
196
  }
182
197
 
183
- if ("image" in schema) {
184
- slashMenuItems.push({
185
- name: "Image",
198
+ if (checkDefaultBlockTypeInSchema("image", editor)) {
199
+ items.push({
200
+ title: "Image",
201
+ onItemClick: () => {
202
+ const insertedBlock = insertOrUpdateBlock(editor, {
203
+ type: "image",
204
+ });
205
+
206
+ // Immediately open the image toolbar
207
+ editor.prosemirrorView.dispatch(
208
+ editor._tiptapEditor.state.tr.setMeta(editor.imagePanel!.plugin, {
209
+ block: insertedBlock,
210
+ })
211
+ );
212
+ },
213
+ subtext: "Insert an image",
186
214
  aliases: [
187
215
  "image",
188
216
  "imageUpload",
@@ -194,20 +222,22 @@ export const getDefaultSlashMenuItems = <
194
222
  "drive",
195
223
  "dropbox",
196
224
  ],
197
- execute: (editor) => {
198
- const insertedBlock = insertOrUpdateBlock(editor, {
199
- type: "image",
200
- });
201
-
202
- // Immediately open the image toolbar
203
- editor._tiptapEditor.view.dispatch(
204
- editor._tiptapEditor.state.tr.setMeta(imageToolbarPluginKey, {
205
- block: insertedBlock,
206
- })
207
- );
208
- },
225
+ group: "Media",
209
226
  });
210
227
  }
211
228
 
212
- return slashMenuItems;
213
- };
229
+ return items;
230
+ }
231
+
232
+ export function filterSuggestionItems<
233
+ T extends { title: string; aliases?: readonly string[] }
234
+ >(items: T[], query: string) {
235
+ return items.filter(
236
+ ({ title, aliases }) =>
237
+ title.toLowerCase().startsWith(query.toLowerCase()) ||
238
+ (aliases &&
239
+ aliases.filter((alias) =>
240
+ alias.toLowerCase().startsWith(query.toLowerCase())
241
+ ).length !== 0)
242
+ );
243
+ }
@@ -1,42 +1,20 @@
1
1
  import { Plugin, PluginKey, PluginView } from "prosemirror-state";
2
2
  import { Decoration, DecorationSet, EditorView } from "prosemirror-view";
3
- import { EventEmitter } from "../../util/EventEmitter";
4
3
  import { nodeToBlock } from "../../api/nodeConversions/nodeConversions";
5
- import { DefaultBlockSchema } from "../../blocks/defaultBlocks";
4
+ import { Block, DefaultBlockSchema } from "../../blocks/defaultBlocks";
6
5
  import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
7
6
  import {
8
- Block,
9
7
  BlockFromConfigNoChildren,
10
8
  BlockSchemaWithBlock,
11
9
  InlineContentSchema,
12
- PartialBlock,
13
10
  SpecificBlock,
14
11
  StyleSchema,
15
12
  } from "../../schema";
13
+ import { EventEmitter } from "../../util/EventEmitter";
16
14
  import { getDraggableBlockFromCoords } from "../SideMenu/SideMenuPlugin";
17
15
 
18
16
  let dragImageElement: HTMLElement | undefined;
19
17
 
20
- function setHiddenDragImage() {
21
- if (dragImageElement) {
22
- return;
23
- }
24
-
25
- dragImageElement = document.createElement("div");
26
- dragImageElement.innerHTML = "_";
27
- dragImageElement.style.opacity = "0";
28
- dragImageElement.style.height = "1px";
29
- dragImageElement.style.width = "1px";
30
- document.body.appendChild(dragImageElement);
31
- }
32
-
33
- function unsetHiddenDragImage() {
34
- if (dragImageElement) {
35
- document.body.removeChild(dragImageElement);
36
- dragImageElement = undefined;
37
- }
38
- }
39
-
40
18
  export type TableHandlesState<
41
19
  I extends InlineContentSchema,
42
20
  S extends StyleSchema
@@ -58,6 +36,26 @@ export type TableHandlesState<
58
36
  | undefined;
59
37
  };
60
38
 
39
+ function setHiddenDragImage() {
40
+ if (dragImageElement) {
41
+ return;
42
+ }
43
+
44
+ dragImageElement = document.createElement("div");
45
+ dragImageElement.innerHTML = "_";
46
+ dragImageElement.style.opacity = "0";
47
+ dragImageElement.style.height = "1px";
48
+ dragImageElement.style.width = "1px";
49
+ document.body.appendChild(dragImageElement);
50
+ }
51
+
52
+ function unsetHiddenDragImage() {
53
+ if (dragImageElement) {
54
+ document.body.removeChild(dragImageElement);
55
+ dragImageElement = undefined;
56
+ }
57
+ }
58
+
61
59
  function getChildIndex(node: Element) {
62
60
  return Array.prototype.indexOf.call(node.parentElement!.childNodes, node);
63
61
  }
@@ -91,7 +89,7 @@ export class TableHandlesView<
91
89
  > implements PluginView
92
90
  {
93
91
  public state?: TableHandlesState<I, S>;
94
- public updateState: () => void;
92
+ public emitUpdate: () => void;
95
93
 
96
94
  public tableId: string | undefined;
97
95
  public tablePos: number | undefined;
@@ -101,16 +99,20 @@ export class TableHandlesView<
101
99
  public prevWasEditable: boolean | null = null;
102
100
 
103
101
  constructor(
104
- private readonly editor: BlockNoteEditor<BSchema, I, S>,
102
+ private readonly editor: BlockNoteEditor<
103
+ BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
104
+ I,
105
+ S
106
+ >,
105
107
  private readonly pmView: EditorView,
106
- updateState: (state: TableHandlesState<I, S>) => void
108
+ emitUpdate: (state: TableHandlesState<I, S>) => void
107
109
  ) {
108
- this.updateState = () => {
110
+ this.emitUpdate = () => {
109
111
  if (!this.state) {
110
112
  throw new Error("Attempting to update uninitialized image toolbar");
111
113
  }
112
114
 
113
- updateState(this.state);
115
+ emitUpdate(this.state);
114
116
  };
115
117
 
116
118
  pmView.dom.addEventListener("mousemove", this.mouseMoveHandler);
@@ -131,7 +133,7 @@ export class TableHandlesView<
131
133
  if (!target || !this.editor.isEditable) {
132
134
  if (this.state?.show) {
133
135
  this.state.show = false;
134
- this.updateState();
136
+ this.emitUpdate();
135
137
  }
136
138
  return;
137
139
  }
@@ -175,9 +177,9 @@ export class TableHandlesView<
175
177
 
176
178
  block = nodeToBlock(
177
179
  node,
178
- this.editor.blockSchema,
179
- this.editor.inlineContentSchema,
180
- this.editor.styleSchema,
180
+ this.editor.schema.blockSchema,
181
+ this.editor.schema.inlineContentSchema,
182
+ this.editor.schema.styleSchema,
181
183
  this.editor.blockCache
182
184
  );
183
185
  this.tablePos = pos + 1;
@@ -196,7 +198,7 @@ export class TableHandlesView<
196
198
 
197
199
  draggingState: undefined,
198
200
  };
199
- this.updateState();
201
+ this.emitUpdate();
200
202
 
201
203
  return false;
202
204
  };
@@ -286,7 +288,7 @@ export class TableHandlesView<
286
288
 
287
289
  // Emits a state update if any of the fields have changed.
288
290
  if (emitStateUpdate) {
289
- this.updateState();
291
+ this.emitUpdate();
290
292
  }
291
293
 
292
294
  // Dispatches a dummy transaction to force a decorations update if
@@ -327,7 +329,7 @@ export class TableHandlesView<
327
329
  type: "tableContent",
328
330
  rows: rows,
329
331
  },
330
- } as PartialBlock<BSchema, I, S>);
332
+ });
331
333
  };
332
334
 
333
335
  scrollHandler = () => {
@@ -343,7 +345,7 @@ export class TableHandlesView<
343
345
 
344
346
  this.state.referencePosTable = tableElement.getBoundingClientRect();
345
347
  this.state.referencePosCell = cellElement.getBoundingClientRect();
346
- this.updateState();
348
+ this.emitUpdate();
347
349
  }
348
350
  };
349
351
 
@@ -360,14 +362,25 @@ export class TableHandlesView<
360
362
  export const tableHandlesPluginKey = new PluginKey("TableHandlesPlugin");
361
363
 
362
364
  export class TableHandlesProsemirrorPlugin<
363
- BSchema extends BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
364
365
  I extends InlineContentSchema,
365
366
  S extends StyleSchema
366
367
  > extends EventEmitter<any> {
367
- private view: TableHandlesView<BSchema, I, S> | undefined;
368
+ private view:
369
+ | TableHandlesView<
370
+ BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
371
+ I,
372
+ S
373
+ >
374
+ | undefined;
368
375
  public readonly plugin: Plugin;
369
376
 
370
- constructor(private readonly editor: BlockNoteEditor<BSchema, I, S>) {
377
+ constructor(
378
+ private readonly editor: BlockNoteEditor<
379
+ BlockSchemaWithBlock<"table", DefaultBlockSchema["table"]>,
380
+ I,
381
+ S
382
+ >
383
+ ) {
371
384
  super();
372
385
  this.plugin = new Plugin({
373
386
  key: tableHandlesPluginKey,
@@ -531,7 +544,7 @@ export class TableHandlesProsemirrorPlugin<
531
544
  originalIndex: this.view!.state.colIndex,
532
545
  mousePos: event.clientX,
533
546
  };
534
- this.view!.updateState();
547
+ this.view!.emitUpdate();
535
548
 
536
549
  this.editor._tiptapEditor.view.dispatch(
537
550
  this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, {
@@ -567,7 +580,7 @@ export class TableHandlesProsemirrorPlugin<
567
580
  originalIndex: this.view!.state.rowIndex,
568
581
  mousePos: event.clientY,
569
582
  };
570
- this.view!.updateState();
583
+ this.view!.emitUpdate();
571
584
 
572
585
  this.editor._tiptapEditor.view.dispatch(
573
586
  this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, {
@@ -596,7 +609,7 @@ export class TableHandlesProsemirrorPlugin<
596
609
  }
597
610
 
598
611
  this.view!.state.draggingState = undefined;
599
- this.view!.updateState();
612
+ this.view!.emitUpdate();
600
613
 
601
614
  this.editor._tiptapEditor.view.dispatch(
602
615
  this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, null)
@@ -609,11 +622,15 @@ export class TableHandlesProsemirrorPlugin<
609
622
  * Freezes the drag handles. When frozen, they will stay attached to the same
610
623
  * cell regardless of which cell is hovered by the mouse cursor.
611
624
  */
612
- freezeHandles = () => (this.view!.menuFrozen = true);
625
+ freezeHandles = () => {
626
+ this.view!.menuFrozen = true;
627
+ };
613
628
 
614
629
  /**
615
630
  * Unfreezes the drag handles. When frozen, they will stay attached to the
616
631
  * same cell regardless of which cell is hovered by the mouse cursor.
617
632
  */
618
- unfreezeHandles = () => (this.view!.menuFrozen = false);
633
+ unfreezeHandles = () => {
634
+ this.view!.menuFrozen = false;
635
+ };
619
636
  }
@@ -0,0 +1,4 @@
1
+ export type UiElementPosition = {
2
+ show: boolean;
3
+ referencePos: DOMRect;
4
+ };
package/src/index.ts CHANGED
@@ -2,21 +2,21 @@ export * from "./api/exporters/html/externalHTMLExporter";
2
2
  export * from "./api/exporters/html/internalHTMLSerializer";
3
3
  export * from "./api/testUtil";
4
4
  export * from "./blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
5
+ export * from "./blocks/defaultBlockTypeGuards";
5
6
  export * from "./blocks/defaultBlocks";
6
7
  export * from "./blocks/defaultProps";
7
8
  export * from "./editor/BlockNoteEditor";
8
9
  export * from "./editor/BlockNoteExtensions";
10
+ export * from "./editor/BlockNoteSchema";
9
11
  export * from "./editor/selectionTypes";
10
- export * from "./extensions-shared/BaseUiElementTypes";
11
- export type { SuggestionItem } from "./extensions-shared/suggestion/SuggestionItem";
12
- export * from "./extensions-shared/suggestion/SuggestionPlugin";
12
+ export * from "./extensions-shared/UiElementPosition";
13
13
  export * from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
14
- export * from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
15
- export * from "./extensions/ImageToolbar/ImageToolbarPlugin";
14
+ export * from "./extensions/ImagePanel/ImageToolbarPlugin";
15
+ export * from "./extensions/LinkToolbar/LinkToolbarPlugin";
16
16
  export * from "./extensions/SideMenu/SideMenuPlugin";
17
- export * from "./extensions/SlashMenu/BaseSlashMenuItem";
18
- export * from "./extensions/SlashMenu/SlashMenuPlugin";
19
- export { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
17
+ export * from "./extensions/SuggestionMenu/DefaultSuggestionItem";
18
+ export * from "./extensions/SuggestionMenu/SuggestionPlugin";
19
+ export * from "./extensions/SuggestionMenu/getDefaultSlashMenuItems";
20
20
  export * from "./extensions/TableHandles/TableHandlesPlugin";
21
21
  export * from "./schema";
22
22
  export * from "./util/browser";
@@ -8,6 +8,7 @@ import {
8
8
  inlineContentToNodes,
9
9
  tableContentToNodes,
10
10
  } from "../api/nodeConversions/nodeConversions";
11
+ import { PartialBlock } from "../blocks/defaultBlocks";
11
12
  import type { BlockNoteEditor } from "../editor/BlockNoteEditor";
12
13
  import { NonEditableBlockPlugin } from "../extensions/NonEditableBlocks/NonEditableBlockPlugin";
13
14
  import { PreviousBlockTypePlugin } from "../extensions/PreviousBlockType/PreviousBlockTypePlugin";
@@ -15,7 +16,6 @@ import {
15
16
  BlockNoteDOMAttributes,
16
17
  BlockSchema,
17
18
  InlineContentSchema,
18
- PartialBlock,
19
19
  StyleSchema,
20
20
  } from "../schema";
21
21
  import { mergeCSSClasses } from "../util/browser";
@@ -109,7 +109,7 @@ export const BlockContainer = Node.create<{
109
109
  }
110
110
 
111
111
  const blockHTMLAttributes = {
112
- ...(this.options.domAttributes?.blockContainer || {}),
112
+ ...(this.options.domAttributes?.block || {}),
113
113
  ...HTMLAttributes,
114
114
  };
115
115
  const block = document.createElement("div");
@@ -183,7 +183,7 @@ export const BlockContainer = Node.create<{
183
183
  blockToNode(
184
184
  child,
185
185
  state.schema,
186
- this.options.editor.styleSchema
186
+ this.options.editor.schema.styleSchema
187
187
  )
188
188
  );
189
189
  }
@@ -223,13 +223,13 @@ export const BlockContainer = Node.create<{
223
223
  content = inlineContentToNodes(
224
224
  block.content,
225
225
  state.schema,
226
- this.options.editor.styleSchema
226
+ this.options.editor.schema.styleSchema
227
227
  );
228
228
  } else if (block.content.type === "tableContent") {
229
229
  content = tableContentToNodes(
230
230
  block.content,
231
231
  state.schema,
232
- this.options.editor.styleSchema
232
+ this.options.editor.schema.styleSchema
233
233
  );
234
234
  } else {
235
235
  throw new UnreachableCaseError(block.content.type);