@blocknote/core 0.13.3 → 0.13.4

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 (84) hide show
  1. package/dist/blocknote.js +1038 -696
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +6 -6
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/dist/webpack-stats.json +1 -1
  7. package/package.json +2 -2
  8. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -1
  9. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -1
  10. package/src/api/exporters/html/__snapshots__/image/noCaption/internal.html +1 -1
  11. package/src/api/exporters/html/__snapshots__/image/noName/internal.html +1 -1
  12. package/src/api/exporters/html/__snapshots__/lists/basic/external.html +1 -0
  13. package/src/api/exporters/html/__snapshots__/lists/basic/internal.html +1 -0
  14. package/src/api/exporters/html/__snapshots__/lists/nested/external.html +1 -0
  15. package/src/api/exporters/html/__snapshots__/lists/nested/internal.html +1 -0
  16. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
  17. package/src/api/exporters/html/__snapshots__/simpleImage/basic/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/__snapshots__/simpleImage/noCaption/external.html +1 -1
  21. package/src/api/exporters/html/__snapshots__/simpleImage/noCaption/internal.html +1 -1
  22. package/src/api/exporters/html/__snapshots__/simpleImage/noName/external.html +1 -1
  23. package/src/api/exporters/html/__snapshots__/simpleImage/noName/internal.html +1 -1
  24. package/src/api/exporters/html/externalHTMLExporter.ts +4 -3
  25. package/src/api/exporters/html/util/simplifyBlocksRehypePlugin.ts +1 -1
  26. package/src/api/exporters/markdown/__snapshots__/lists/basic/markdown.md +8 -0
  27. package/src/api/exporters/markdown/__snapshots__/lists/nested/markdown.md +10 -0
  28. package/src/api/exporters/markdown/__snapshots__/simpleImage/basic/markdown.md +1 -1
  29. package/src/api/exporters/markdown/__snapshots__/simpleImage/nested/markdown.md +2 -2
  30. package/src/api/exporters/markdown/__snapshots__/simpleImage/noCaption/markdown.md +1 -1
  31. package/src/api/exporters/markdown/__snapshots__/simpleImage/noName/markdown.md +1 -1
  32. package/src/api/exporters/markdown/markdownExporter.ts +2 -0
  33. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +42 -0
  34. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +50 -0
  35. package/src/api/parsers/html/__snapshots__/paste/list-test.json +74 -2
  36. package/src/api/parsers/html/__snapshots__/paste/parse-mixed-nested-lists.json +135 -10
  37. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +132 -7
  38. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists.json +111 -3
  39. package/src/api/parsers/html/parseHTML.test.ts +166 -95
  40. package/src/api/testUtil/cases/customBlocks.ts +3 -0
  41. package/src/api/testUtil/cases/defaultSchema.ts +71 -0
  42. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +3 -2
  43. package/src/blocks/FileBlockContent/FileBlockContent.ts +1 -2
  44. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +3 -2
  45. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +3 -0
  46. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +266 -0
  47. package/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.ts +2 -1
  48. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +1 -0
  49. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -1
  50. package/src/blocks/defaultBlockTypeGuards.ts +1 -1
  51. package/src/blocks/defaultBlocks.ts +6 -3
  52. package/src/editor/Block.css +22 -0
  53. package/src/editor/BlockNoteEditor.ts +10 -0
  54. package/src/editor/transformPasted.ts +2 -1
  55. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +13 -0
  56. package/src/extensions/TableHandles/TableHandlesPlugin.ts +27 -27
  57. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +7 -1
  58. package/src/i18n/locales/en.ts +15 -0
  59. package/src/i18n/locales/fr.ts +14 -0
  60. package/src/i18n/locales/is.ts +7 -0
  61. package/src/i18n/locales/ja.ts +24 -1
  62. package/src/i18n/locales/ko.ts +15 -0
  63. package/src/i18n/locales/nl.ts +7 -0
  64. package/src/i18n/locales/pl.ts +7 -0
  65. package/src/i18n/locales/pt.ts +14 -0
  66. package/src/i18n/locales/vi.ts +16 -2
  67. package/src/i18n/locales/zh.ts +16 -0
  68. package/src/pm-nodes/BlockContainer.ts +16 -4
  69. package/src/schema/blocks/types.ts +0 -1
  70. package/types/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.d.ts +7 -0
  71. package/types/src/api/testUtil/cases/customBlocks.d.ts +74 -42
  72. package/types/src/api/testUtil/cases/customInlineContent.d.ts +74 -42
  73. package/types/src/api/testUtil/cases/customStyles.d.ts +74 -42
  74. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -3
  75. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -3
  76. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -3
  77. package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +55 -0
  78. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -3
  79. package/types/src/blocks/defaultBlocks.d.ts +141 -77
  80. package/types/src/editor/BlockNoteEditor.d.ts +7 -0
  81. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +1 -1
  82. package/types/src/i18n/locales/en.d.ts +7 -0
  83. package/types/src/pm-nodes/BlockContainer.d.ts +1 -1
  84. package/types/src/schema/blocks/types.d.ts +0 -1
@@ -76,88 +76,147 @@ describe("Parse HTML", () => {
76
76
 
77
77
  it("list test", async () => {
78
78
  const html = `<ul>
79
- <li>First</li>
80
- <li>Second</li>
81
- <li>Third</li>
82
- <li>Five Parent
83
- <ul>
84
- <li>Child 1</li>
85
- <li>Child 2</li>
86
- </ul>
87
- </li>
88
- </ul>`;
79
+ <li>First</li>
80
+ <li>Second</li>
81
+ <li>Third</li>
82
+ <li>
83
+ <input type="checkbox">
84
+ Fourth
85
+ </li>
86
+ <li>
87
+ <input type="checkbox">
88
+ Fifth
89
+ </li>
90
+ <li>Five Parent
91
+ <ul>
92
+ <li>Child 1</li>
93
+ <li>Child 2</li>
94
+ <li>
95
+ <input type="checkbox">
96
+ Child 3
97
+ </li>
98
+ <li>
99
+ <input type="checkbox">
100
+ Child 4
101
+ </li>
102
+ </ul>
103
+ </li>
104
+ </ul>`;
89
105
  await parseHTMLAndCompareSnapshots(html, "list-test");
90
106
  });
91
107
 
92
108
  it("Parse nested lists", async () => {
93
109
  const html = `<ul>
94
110
  <li>Bullet List Item</li>
95
- <li>Bullet List Item</li>
96
- <ul>
97
- <li>
98
- Nested Bullet List Item
99
- </li>
100
- <li>
101
- Nested Bullet List Item
102
- </li>
103
- </ul>
104
- <li>
105
- Bullet List Item
106
- </li>
111
+ <li>Bullet List Item
112
+ <ul>
113
+ <li>Nested Bullet List Item</li>
114
+ <li>Nested Bullet List Item</li>
115
+ </ul>
116
+ </li>
117
+ <li>Bullet List Item</li>
107
118
  </ul>
108
119
  <ol>
109
- <li>
110
- Numbered List Item
111
- <ol>
112
- <li>
113
- Nested Numbered List Item
114
- </li>
115
- <li>
116
- Nested Numbered List Item
117
- </li>
118
- </ol>
119
- </li>
120
- <li>
121
- Numbered List Item
122
- </li>
123
- </ol>`;
120
+ <li>Numbered List Item</li>
121
+ <li>Numbered List Item
122
+ <ol>
123
+ <li>Nested Numbered List Item</li>
124
+ <li>Nested Numbered List Item</li>
125
+ </ol>
126
+ </li>
127
+ <li>Numbered List Item</li>
128
+ </ol>
129
+ <ul>
130
+ <li>
131
+ <input type="checkbox">
132
+ Check List Item
133
+ </li>
134
+ <li>
135
+ <input type="checkbox">
136
+ Check List Item
137
+ <ul>
138
+ <li>
139
+ <input type="checkbox">
140
+ Nested Check List Item
141
+ </li>
142
+ <li>
143
+ <input type="checkbox">
144
+ Nested Check List Item
145
+ </li>
146
+ </ul>
147
+ </li>
148
+ <li>
149
+ <input type="checkbox">
150
+ Nested Check List Item
151
+ </li>
152
+ </ul>`;
124
153
 
125
154
  await parseHTMLAndCompareSnapshots(html, "parse-nested-lists");
126
155
  });
127
156
 
128
157
  it("Parse nested lists with paragraphs", async () => {
129
158
  const html = `<ul>
130
- <li>
131
- <p>Bullet List Item</p>
132
- <ul>
133
- <li>
134
- <p>Nested Bullet List Item</p>
135
- </li>
136
- <li>
137
- <p>Nested Bullet List Item</p>
138
- </li>
139
- </ul>
140
- </li>
141
- <li>
142
- <p>Bullet List Item</p>
143
- </li>
159
+ <li>
160
+ <p>Bullet List Item</p>
161
+ </li>
162
+ <li>
163
+ <p>Bullet List Item</p>
164
+ <ul>
165
+ <li>
166
+ <p>Nested Bullet List Item</p>
167
+ </li>
168
+ <li>
169
+ <p>Nested Bullet List Item</p>
170
+ </li>
171
+ </ul>
172
+ </li>
173
+ <li>
174
+ <p>Bullet List Item</p>
175
+ </li>
144
176
  </ul>
145
177
  <ol>
146
- <li>
147
- <p>Numbered List Item</p>
148
- <ol>
149
- <li>
150
- <p>Nested Numbered List Item</p>
151
- </li>
152
- <li>
153
- <p>Nested Numbered List Item</p>
154
- </li>
155
- </ol>
156
- </li>
157
- <li>
158
- <p>Numbered List Item</p>
159
- </li>
160
- </ol>`;
178
+ <li>
179
+ <p>Numbered List Item</p>
180
+ </li>
181
+ <li>
182
+ <p>Numbered List Item</p>
183
+ <ol>
184
+ <li>
185
+ <p>Nested Numbered List Item</p>
186
+ </li>
187
+ <li>
188
+ <p>Nested Numbered List Item</p>
189
+ </li>
190
+ </ol>
191
+ </li>
192
+ <li>
193
+ <p>Numbered List Item</p>
194
+ </li>
195
+ </ol>
196
+ <ul>
197
+ <li>
198
+ <input type="checkbox">
199
+ <p>Checked List Item</p>
200
+ </li>
201
+ <li>
202
+ <input type="checkbox">
203
+ <p>Checked List Item</p>
204
+ <ul>
205
+ <li>
206
+ <input type="checkbox">
207
+ <p>Nested Checked List Item</p>
208
+ </li>
209
+ <li>
210
+ <label><input type="checkbox"></label>
211
+ <p>Nested Checked List Item</p>
212
+ </li>
213
+ </ul>
214
+ </li>
215
+ <li>
216
+ <input type="checkbox">
217
+ <p>Checked List Item</p>
218
+ </li>
219
+ </ul>`;
161
220
 
162
221
  await parseHTMLAndCompareSnapshots(
163
222
  html,
@@ -167,37 +226,49 @@ describe("Parse HTML", () => {
167
226
 
168
227
  it("Parse mixed nested lists", async () => {
169
228
  const html = `<ul>
170
- <li>
171
- Bullet List Item
172
- <ol>
173
- <li>
174
- Nested Numbered List Item
175
- </li>
176
- <li>
177
- Nested Numbered List Item
178
- </li>
179
- </ol>
180
- </li>
181
- <li>
182
- Bullet List Item
183
- </li>
229
+ <li>Bullet List Item</li>
230
+ <li>Bullet List Item
231
+ <ol>
232
+ <li>Nested Numbered List Item</li>
233
+ <li>Nested Numbered List Item</li>
234
+ </ol>
235
+ </li>
236
+ <li>Bullet List Item</li>
184
237
  </ul>
185
238
  <ol>
186
- <li>
187
- Numbered List Item
188
- <ul>
189
- <li>
190
- <p>Nested Bullet List Item</p>
191
- </li>
192
- <li>
193
- <p>Nested Bullet List Item</p>
194
- </li>
195
- </ul>
196
- </li>
197
- <li>
198
- Numbered List Item
199
- </li>
200
- </ol>`;
239
+ <li>Numbered List Item</li>
240
+ <li>Numbered List Item
241
+ <ul>
242
+ <li>
243
+ <input type="checkbox" checked>
244
+ Nested Check List Item
245
+ </li>
246
+ <li>
247
+ <input type="checkbox">
248
+ Nested Check List Item
249
+ </li>
250
+ </ul>
251
+ </li>
252
+ <li>Numbered List Item</li>
253
+ </ol>
254
+ <ul>
255
+ <li>
256
+ <input type="checkbox" checked>
257
+ Check List Item
258
+ </li>
259
+ <li>
260
+ <input type="checkbox">
261
+ Check List Item
262
+ <ul>
263
+ <li>Nested Bullet List Item</li>
264
+ <li>Nested Bullet List Item</li>
265
+ </ul>
266
+ </li>
267
+ <li>
268
+ <input type="checkbox" checked>
269
+ Nested Check List Item
270
+ </li>
271
+ </ul>`;
201
272
 
202
273
  await parseHTMLAndCompareSnapshots(html, "parse-mixed-nested-lists");
203
274
  });
@@ -98,6 +98,9 @@ export const customBlocksTestCases: EditorTestCases<
98
98
  });
99
99
  },
100
100
  documents: [
101
+ // Because images need to fetch the download URL async, their output HTML is
102
+ // initially rendered without a `src` attribute, which is reflected in the
103
+ // tests.
101
104
  {
102
105
  name: "simpleImage/button",
103
106
  blocks: [
@@ -98,6 +98,74 @@ export const defaultSchemaTestCases: EditorTestCases<
98
98
  },
99
99
  ],
100
100
  },
101
+ {
102
+ name: "lists/basic",
103
+ blocks: [
104
+ {
105
+ type: "bulletListItem",
106
+ content: "Bullet List Item 1",
107
+ },
108
+ {
109
+ type: "bulletListItem",
110
+ content: "Bullet List Item 2",
111
+ },
112
+ {
113
+ type: "numberedListItem",
114
+ content: "Numbered List Item 1",
115
+ },
116
+ {
117
+ type: "numberedListItem",
118
+ content: "Numbered List Item 2",
119
+ },
120
+ {
121
+ type: "checkListItem",
122
+ content: "Check List Item 1",
123
+ },
124
+ {
125
+ type: "checkListItem",
126
+ props: {
127
+ checked: true,
128
+ },
129
+ content: "Check List Item 2",
130
+ },
131
+ ],
132
+ },
133
+ {
134
+ name: "lists/nested",
135
+ blocks: [
136
+ {
137
+ type: "bulletListItem",
138
+ content: "Bullet List Item 1",
139
+ },
140
+ {
141
+ type: "bulletListItem",
142
+ content: "Bullet List Item 2",
143
+ children: [
144
+ {
145
+ type: "numberedListItem",
146
+ content: "Numbered List Item 1",
147
+ },
148
+ {
149
+ type: "numberedListItem",
150
+ content: "Numbered List Item 2",
151
+ children: [
152
+ {
153
+ type: "checkListItem",
154
+ content: "Check List Item 1",
155
+ },
156
+ {
157
+ type: "checkListItem",
158
+ props: {
159
+ checked: true,
160
+ },
161
+ content: "Check List Item 2",
162
+ },
163
+ ],
164
+ },
165
+ ],
166
+ },
167
+ ],
168
+ },
101
169
  {
102
170
  name: "file/button",
103
171
  blocks: [
@@ -166,6 +234,9 @@ export const defaultSchemaTestCases: EditorTestCases<
166
234
  },
167
235
  ],
168
236
  },
237
+ // Because images need to fetch the download URL async, their internal HTML
238
+ // is initially rendered without a `src` attribute, which is reflected in
239
+ // the tests.
169
240
  {
170
241
  name: "image/button",
171
242
  blocks: [
@@ -43,7 +43,6 @@ export const audioBlockConfig = {
43
43
  propSchema: audioPropSchema,
44
44
  content: "none",
45
45
  isFileBlock: true,
46
- isFileBlockPlaceholder: (block: any) => !block.props.url,
47
46
  fileBlockAcceptMimeTypes: ["audio/*"],
48
47
  } satisfies FileBlockConfig;
49
48
 
@@ -82,7 +81,9 @@ export const audioRender = (
82
81
  } else {
83
82
  const audio = document.createElement("audio");
84
83
  audio.className = "bn-audio";
85
- audio.src = block.props.url;
84
+ editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
85
+ audio.src = downloadUrl;
86
+ });
86
87
  audio.controls = true;
87
88
  audio.contentEditable = "false";
88
89
  audio.draggable = false;
@@ -10,9 +10,9 @@ import {
10
10
  createAddFileButton,
11
11
  createDefaultFilePreview,
12
12
  createFileAndCaptionWrapper,
13
+ createLinkWithCaption,
13
14
  parseEmbedElement,
14
15
  parseFigureElement,
15
- createLinkWithCaption,
16
16
  } from "./fileBlockHelpers";
17
17
 
18
18
  export const filePropSchema = {
@@ -36,7 +36,6 @@ export const fileBlockConfig = {
36
36
  propSchema: filePropSchema,
37
37
  content: "none",
38
38
  isFileBlock: true,
39
- isFileBlockPlaceholder: (block: any) => !block.props.url,
40
39
  } satisfies FileBlockConfig;
41
40
 
42
41
  export const fileRender = (
@@ -49,7 +49,6 @@ export const imageBlockConfig = {
49
49
  propSchema: imagePropSchema,
50
50
  content: "none",
51
51
  isFileBlock: true,
52
- isFileBlockPlaceholder: (block: any) => !block.props.url,
53
52
  fileBlockAcceptMimeTypes: ["image/*"],
54
53
  } satisfies FileBlockConfig;
55
54
 
@@ -88,7 +87,9 @@ export const imageRender = (
88
87
  } else {
89
88
  const image = document.createElement("img");
90
89
  image.className = "bn-visual-media";
91
- image.src = block.props.url;
90
+ editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
91
+ image.src = downloadUrl;
92
+ });
92
93
  image.alt = block.props.name || block.props.caption || "BlockNote image";
93
94
  image.contentEditable = "false";
94
95
  image.draggable = false;
@@ -17,6 +17,9 @@ const BulletListItemBlockContent = createStronglyTypedTiptapNode({
17
17
  name: "bulletListItem",
18
18
  content: "inline*",
19
19
  group: "blockContent",
20
+ // This is to make sure that check list parse rules run before, since they
21
+ // both parse `li` elements but check lists are more specific.
22
+ priority: 90,
20
23
  addInputRules() {
21
24
  return [
22
25
  // Creates an unordered list when starting with "-", "+", or "*".