@blocknote/core 0.13.0 → 0.13.3

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 (141) hide show
  1. package/README.md +6 -2
  2. package/dist/blocknote.js +5724 -2803
  3. package/dist/blocknote.js.map +1 -1
  4. package/dist/blocknote.umd.cjs +7 -7
  5. package/dist/blocknote.umd.cjs.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/dist/webpack-stats.json +1 -1
  8. package/package.json +2 -2
  9. package/src/api/exporters/html/__snapshots__/file/basic/external.html +1 -0
  10. package/src/api/exporters/html/__snapshots__/file/basic/internal.html +1 -0
  11. package/src/api/exporters/html/__snapshots__/file/button/external.html +1 -0
  12. package/src/api/exporters/html/__snapshots__/file/button/internal.html +1 -0
  13. package/src/api/exporters/html/__snapshots__/file/nested/external.html +1 -0
  14. package/src/api/exporters/html/__snapshots__/file/nested/internal.html +1 -0
  15. package/src/api/exporters/html/__snapshots__/file/noCaption/external.html +1 -0
  16. package/src/api/exporters/html/__snapshots__/file/noCaption/internal.html +1 -0
  17. package/src/api/exporters/html/__snapshots__/file/noName/external.html +1 -0
  18. package/src/api/exporters/html/__snapshots__/file/noName/internal.html +1 -0
  19. package/src/api/exporters/html/__snapshots__/image/basic/external.html +1 -1
  20. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -1
  21. package/src/api/exporters/html/__snapshots__/image/button/external.html +1 -1
  22. package/src/api/exporters/html/__snapshots__/image/button/internal.html +1 -1
  23. package/src/api/exporters/html/__snapshots__/image/nested/external.html +1 -1
  24. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -1
  25. package/src/api/exporters/html/__snapshots__/image/noCaption/external.html +1 -0
  26. package/src/api/exporters/html/__snapshots__/image/noCaption/internal.html +1 -0
  27. package/src/api/exporters/html/__snapshots__/image/noName/external.html +1 -0
  28. package/src/api/exporters/html/__snapshots__/image/noName/internal.html +1 -0
  29. package/src/api/exporters/html/__snapshots__/image/noPreview/external.html +1 -0
  30. package/src/api/exporters/html/__snapshots__/image/noPreview/internal.html +1 -0
  31. package/src/api/exporters/html/__snapshots__/simpleFile/basic/external.html +1 -0
  32. package/src/api/exporters/html/__snapshots__/simpleFile/basic/internal.html +1 -0
  33. package/src/api/exporters/html/__snapshots__/simpleFile/button/external.html +1 -0
  34. package/src/api/exporters/html/__snapshots__/simpleFile/button/internal.html +1 -0
  35. package/src/api/exporters/html/__snapshots__/simpleFile/nested/external.html +1 -0
  36. package/src/api/exporters/html/__snapshots__/simpleFile/nested/internal.html +1 -0
  37. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -1
  38. package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -1
  39. package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -1
  40. package/src/api/exporters/html/__snapshots__/simpleImage/button/internal.html +1 -1
  41. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -1
  42. package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -1
  43. package/src/api/exporters/html/__snapshots__/simpleImage/noCaption/external.html +1 -0
  44. package/src/api/exporters/html/__snapshots__/simpleImage/noCaption/internal.html +1 -0
  45. package/src/api/exporters/html/__snapshots__/simpleImage/noName/external.html +1 -0
  46. package/src/api/exporters/html/__snapshots__/simpleImage/noName/internal.html +1 -0
  47. package/src/api/exporters/html/__snapshots__/simpleImage/noPreview/external.html +1 -0
  48. package/src/api/exporters/html/__snapshots__/simpleImage/noPreview/internal.html +1 -0
  49. package/src/api/exporters/markdown/__snapshots__/file/basic/markdown.md +3 -0
  50. package/src/api/exporters/markdown/__snapshots__/file/button/markdown.md +1 -0
  51. package/src/api/exporters/markdown/__snapshots__/file/nested/markdown.md +7 -0
  52. package/src/api/exporters/markdown/__snapshots__/file/noCaption/markdown.md +1 -0
  53. package/src/api/exporters/markdown/__snapshots__/file/noName/markdown.md +3 -0
  54. package/src/api/exporters/markdown/__snapshots__/image/basic/markdown.md +1 -1
  55. package/src/api/exporters/markdown/__snapshots__/image/button/markdown.md +1 -1
  56. package/src/api/exporters/markdown/__snapshots__/image/nested/markdown.md +2 -2
  57. package/src/api/exporters/markdown/__snapshots__/image/noCaption/markdown.md +1 -0
  58. package/src/api/exporters/markdown/__snapshots__/image/noName/markdown.md +3 -0
  59. package/src/api/exporters/markdown/__snapshots__/image/noPreview/markdown.md +3 -0
  60. package/src/api/exporters/markdown/__snapshots__/simpleFile/basic/markdown.md +3 -0
  61. package/src/api/exporters/markdown/__snapshots__/simpleFile/button/markdown.md +1 -0
  62. package/src/api/exporters/markdown/__snapshots__/simpleFile/nested/markdown.md +7 -0
  63. package/src/api/exporters/markdown/__snapshots__/simpleImage/basic/markdown.md +3 -1
  64. package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +1 -0
  65. package/src/api/exporters/markdown/__snapshots__/simpleImage/nested/markdown.md +6 -2
  66. package/src/api/exporters/markdown/__snapshots__/simpleImage/noCaption/markdown.md +1 -0
  67. package/src/api/exporters/markdown/__snapshots__/simpleImage/noName/markdown.md +3 -0
  68. package/src/api/exporters/markdown/__snapshots__/simpleImage/noPreview/markdown.md +3 -0
  69. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +212 -4
  70. package/src/api/parsers/html/__snapshots__/paste/parse-basic-block-types.json +3 -1
  71. package/src/api/parsers/html/__snapshots__/paste/parse-fake-image-caption.json +3 -1
  72. package/src/api/testUtil/cases/customBlocks.ts +79 -33
  73. package/src/api/testUtil/cases/customInlineContent.ts +1 -1
  74. package/src/api/testUtil/cases/customStyles.ts +1 -1
  75. package/src/api/testUtil/cases/defaultSchema.ts +114 -4
  76. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +162 -0
  77. package/src/blocks/AudioBlockContent/audioBlockHelpers.ts +5 -0
  78. package/src/blocks/FileBlockContent/FileBlockContent.ts +121 -0
  79. package/src/blocks/FileBlockContent/fileBlockHelpers.ts +377 -0
  80. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +135 -356
  81. package/src/blocks/ImageBlockContent/imageBlockHelpers.ts +6 -0
  82. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +182 -0
  83. package/src/blocks/VideoBlockContent/videoBlockHelpers.ts +6 -0
  84. package/src/blocks/defaultBlockTypeGuards.ts +53 -1
  85. package/src/blocks/defaultBlocks.ts +8 -2
  86. package/src/editor/Block.css +67 -27
  87. package/src/editor/BlockNoteEditor.ts +14 -10
  88. package/src/editor/BlockNoteExtensions.ts +1 -1
  89. package/src/editor/BlockNoteSchema.ts +12 -3
  90. package/src/extensions/{ImagePanel/ImageToolbarPlugin.ts → FilePanel/FilePanelPlugin.ts} +22 -25
  91. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +14 -2
  92. package/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.ts +43 -12
  93. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +59 -2
  94. package/src/i18n/locales/en.ts +102 -11
  95. package/src/i18n/locales/fr.ts +289 -0
  96. package/src/i18n/locales/index.ts +8 -0
  97. package/src/i18n/locales/is.ts +288 -0
  98. package/src/i18n/locales/ja.ts +300 -0
  99. package/src/i18n/locales/ko.ts +292 -0
  100. package/src/i18n/locales/nl.ts +101 -8
  101. package/src/i18n/locales/pl.ts +280 -0
  102. package/src/i18n/locales/pt.ts +281 -0
  103. package/src/i18n/locales/vi.ts +281 -0
  104. package/src/i18n/locales/zh.ts +312 -0
  105. package/src/index.ts +9 -2
  106. package/src/pm-nodes/BlockContainer.ts +5 -3
  107. package/src/schema/blocks/createSpec.ts +1 -0
  108. package/src/schema/blocks/internal.ts +10 -0
  109. package/src/schema/blocks/types.ts +41 -5
  110. package/src/util/string.ts +12 -0
  111. package/types/src/api/testUtil/cases/customBlocks.d.ts +228 -42
  112. package/types/src/api/testUtil/cases/customInlineContent.d.ts +178 -4
  113. package/types/src/api/testUtil/cases/customStyles.d.ts +178 -4
  114. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +104 -0
  115. package/types/src/blocks/AudioBlockContent/audioBlockHelpers.d.ts +3 -0
  116. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +96 -0
  117. package/types/src/blocks/FileBlockContent/fileBlockHelpers.d.ts +30 -0
  118. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +53 -14
  119. package/types/src/blocks/ImageBlockContent/imageBlockHelpers.d.ts +4 -0
  120. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +132 -0
  121. package/types/src/blocks/VideoBlockContent/videoBlockHelpers.d.ts +4 -0
  122. package/types/src/blocks/defaultBlockTypeGuards.d.ts +6 -1
  123. package/types/src/blocks/defaultBlocks.d.ts +356 -8
  124. package/types/src/editor/BlockNoteEditor.d.ts +5 -5
  125. package/types/src/extensions/{ImagePanel/ImageToolbarPlugin.d.ts → FilePanel/FilePanelPlugin.d.ts} +9 -12
  126. package/types/src/i18n/locales/en.d.ts +49 -7
  127. package/types/src/i18n/locales/fr.d.ts +2 -0
  128. package/types/src/i18n/locales/index.d.ts +8 -0
  129. package/types/src/i18n/locales/is.d.ts +2 -0
  130. package/types/src/i18n/locales/ja.d.ts +2 -0
  131. package/types/src/i18n/locales/ko.d.ts +2 -0
  132. package/types/src/i18n/locales/pl.d.ts +2 -0
  133. package/types/src/i18n/locales/pt.d.ts +2 -0
  134. package/types/src/i18n/locales/vi.d.ts +2 -0
  135. package/types/src/i18n/locales/zh.d.ts +2 -0
  136. package/types/src/index.d.ts +8 -2
  137. package/types/src/schema/blocks/internal.d.ts +1 -1
  138. package/types/src/schema/blocks/types.d.ts +26 -1
  139. package/types/src/util/string.d.ts +1 -0
  140. /package/src/blocks/{ImageBlockContent → FileBlockContent}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  141. /package/types/src/blocks/{ImageBlockContent → FileBlockContent}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
@@ -0,0 +1,312 @@
1
+ import type { Dictionary } from "../dictionary";
2
+
3
+ export const zh: Dictionary = {
4
+ slash_menu: {
5
+ heading: {
6
+ title: "一级标题",
7
+ subtext: "用于顶级标题",
8
+ aliases: ["h", "heading1", "h1", "标题", "一级标题"],
9
+ group: "标题",
10
+ },
11
+ heading_2: {
12
+ title: "二级标题",
13
+ subtext: "用于关键部分",
14
+ aliases: ["h2", "heading2", "subheading", "标题", "二级标题", "副标题"],
15
+ group: "标题",
16
+ },
17
+ heading_3: {
18
+ title: "三级标题",
19
+ subtext: "用于小节和分组标题",
20
+ aliases: ["h3", "heading3", "subheading", "标题", "三级标题"],
21
+ group: "标题",
22
+ },
23
+ numbered_list: {
24
+ title: "有序列表",
25
+ subtext: "用于显示有序列表",
26
+ aliases: [
27
+ "ol",
28
+ "li",
29
+ "list",
30
+ "numberedlist",
31
+ "numbered list",
32
+ "列表",
33
+ "有序列表",
34
+ ],
35
+ group: "基础",
36
+ },
37
+ bullet_list: {
38
+ title: "无序列表",
39
+ subtext: "用于显示无序列表",
40
+ aliases: [
41
+ "ul",
42
+ "li",
43
+ "list",
44
+ "bulletlist",
45
+ "bullet list",
46
+ "列表",
47
+ "无序列表",
48
+ ],
49
+ group: "基础",
50
+ },
51
+ paragraph: {
52
+ title: "段落",
53
+ subtext: "用于文档正文",
54
+ aliases: ["p", "paragraph", "text", "正文"],
55
+ group: "基础",
56
+ },
57
+ table: {
58
+ title: "表格",
59
+ subtext: "使用表格",
60
+ aliases: ["table", "表格"],
61
+ group: "高级功能",
62
+ },
63
+ image: {
64
+ title: "图片",
65
+ subtext: "插入图片",
66
+ aliases: [
67
+ "图片",
68
+ "上传图片",
69
+ "上传",
70
+ "image",
71
+ "img",
72
+ "相册",
73
+ "媒体",
74
+ "url",
75
+ ],
76
+ group: "媒体",
77
+ },
78
+ video: {
79
+ title: "视频",
80
+ subtext: "插入视频",
81
+ aliases: [
82
+ "视频",
83
+ "视频上传",
84
+ "上传",
85
+ "video",
86
+ "mp4",
87
+ "电影",
88
+ "媒体",
89
+ "url",
90
+ "驱动",
91
+ "dropbox",
92
+ ],
93
+ group: "媒体",
94
+ },
95
+ audio: {
96
+ title: "音频",
97
+ subtext: "插入音频",
98
+ aliases: [
99
+ "音频",
100
+ "音频上传",
101
+ "上传",
102
+ "audio",
103
+ "mp3",
104
+ "声音",
105
+ "媒体",
106
+ "url",
107
+ "驱动",
108
+ "dropbox",
109
+ ],
110
+ group: "媒体",
111
+ },
112
+ file: {
113
+ title: "文件",
114
+ subtext: "插入文件",
115
+ aliases: ["文件", "上传", "file", "嵌入", "媒体", "url"],
116
+ group: "媒体",
117
+ },
118
+ },
119
+ placeholders: {
120
+ default: "输入 '/' 以使用命令",
121
+ heading: "标题",
122
+ bulletListItem: "列表",
123
+ numberedListItem: "列表",
124
+ },
125
+ file_blocks: {
126
+ image: {
127
+ add_button_text: "添加图片",
128
+ },
129
+ video: {
130
+ add_button_text: "添加视频",
131
+ },
132
+ audio: {
133
+ add_button_text: "添加音频",
134
+ },
135
+ file: {
136
+ add_button_text: "添加文件",
137
+ },
138
+ },
139
+ // from react package:
140
+ side_menu: {
141
+ add_block_label: "添加块",
142
+ drag_handle_label: "打开菜单",
143
+ },
144
+ drag_handle: {
145
+ delete_menuitem: "删除",
146
+ colors_menuitem: "颜色",
147
+ },
148
+ table_handle: {
149
+ delete_column_menuitem: "删除列",
150
+ delete_row_menuitem: "删除行",
151
+ add_left_menuitem: "左侧添加列",
152
+ add_right_menuitem: "右侧添加列",
153
+ add_above_menuitem: "上方添加行",
154
+ add_below_menuitem: "下方添加行",
155
+ },
156
+ suggestion_menu: {
157
+ no_items_title: "无匹配项",
158
+ loading: "加载中…",
159
+ },
160
+ color_picker: {
161
+ text_title: "文本",
162
+ background_title: "背景色",
163
+ colors: {
164
+ default: "默认",
165
+ gray: "灰色",
166
+ brown: "棕色",
167
+ red: "红色",
168
+ orange: "橙色",
169
+ yellow: "黄色",
170
+ green: "绿色",
171
+ blue: "蓝色",
172
+ purple: "紫色",
173
+ pink: "粉色",
174
+ },
175
+ },
176
+
177
+ formatting_toolbar: {
178
+ bold: {
179
+ tooltip: "加粗",
180
+ secondary_tooltip: "Mod+B",
181
+ },
182
+ italic: {
183
+ tooltip: "斜体",
184
+ secondary_tooltip: "Mod+I",
185
+ },
186
+ underline: {
187
+ tooltip: "下划线",
188
+ secondary_tooltip: "Mod+U",
189
+ },
190
+ strike: {
191
+ tooltip: "删除线",
192
+ secondary_tooltip: "Mod+Shift+X",
193
+ },
194
+ code: {
195
+ tooltip: "代码标记",
196
+ secondary_tooltip: "",
197
+ },
198
+ colors: {
199
+ tooltip: "颜色",
200
+ },
201
+ link: {
202
+ tooltip: "添加链接",
203
+ secondary_tooltip: "Mod+K",
204
+ },
205
+ file_caption: {
206
+ tooltip: "编辑标题",
207
+ input_placeholder: "编辑标题",
208
+ },
209
+ file_replace: {
210
+ tooltip: {
211
+ image: "替换图片",
212
+ video: "替换视频",
213
+ audio: "替换音频",
214
+ file: "替换文件",
215
+ },
216
+ },
217
+ file_rename: {
218
+ tooltip: {
219
+ image: "重命名图片",
220
+ video: "重命名视频",
221
+ audio: "重命名音频",
222
+ file: "重命名文件",
223
+ },
224
+ input_placeholder: {
225
+ image: "重命名图片",
226
+ video: "重命名视频",
227
+ audio: "重命名音频",
228
+ file: "重命名文件",
229
+ },
230
+ },
231
+ file_download: {
232
+ tooltip: {
233
+ image: "下载图片",
234
+ video: "下载视频",
235
+ audio: "下载音频",
236
+ file: "下载文件",
237
+ },
238
+ },
239
+ file_delete: {
240
+ tooltip: {
241
+ image: "删除图片",
242
+ video: "删除视频",
243
+ audio: "删除音频",
244
+ file: "删除文件",
245
+ },
246
+ },
247
+ file_preview_toggle: {
248
+ tooltip: "切换预览",
249
+ },
250
+ nest: {
251
+ tooltip: "嵌套",
252
+ secondary_tooltip: "Tab",
253
+ },
254
+ unnest: {
255
+ tooltip: "取消嵌套",
256
+ secondary_tooltip: "Shift+Tab",
257
+ },
258
+ align_left: {
259
+ tooltip: "左对齐",
260
+ },
261
+ align_center: {
262
+ tooltip: "居中",
263
+ },
264
+ align_right: {
265
+ tooltip: "右对齐",
266
+ },
267
+ align_justify: {
268
+ tooltip: "文本对齐",
269
+ },
270
+ },
271
+ file_panel: {
272
+ upload: {
273
+ title: "上传",
274
+ file_placeholder: {
275
+ image: "上传图片",
276
+ video: "上传视频",
277
+ audio: "上传音频",
278
+ file: "上传文件",
279
+ },
280
+ upload_error: "Error:上传失败",
281
+ },
282
+ embed: {
283
+ title: "嵌入",
284
+ embed_button: {
285
+ image: "嵌入图片",
286
+ video: "嵌入视频",
287
+ audio: "嵌入音频",
288
+ file: "嵌入文件",
289
+ },
290
+ url_placeholder: "输入图片地址",
291
+ },
292
+ },
293
+ link_toolbar: {
294
+ delete: {
295
+ tooltip: "清除链接",
296
+ },
297
+ edit: {
298
+ text: "编辑链接",
299
+ tooltip: "编辑",
300
+ },
301
+ open: {
302
+ tooltip: "新窗口打开",
303
+ },
304
+ form: {
305
+ title_placeholder: "编辑标题",
306
+ url_placeholder: "编辑链接地址",
307
+ },
308
+ },
309
+ generic: {
310
+ ctrl_shortcut: "Ctrl",
311
+ },
312
+ };
package/src/index.ts CHANGED
@@ -2,7 +2,13 @@ import * as locales from "./i18n/locales";
2
2
  export * from "./api/exporters/html/externalHTMLExporter";
3
3
  export * from "./api/exporters/html/internalHTMLSerializer";
4
4
  export * from "./api/testUtil";
5
- export * from "./blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
5
+ export * from "./blocks/FileBlockContent/FileBlockContent";
6
+ export * from "./blocks/ImageBlockContent/ImageBlockContent";
7
+ export * from "./blocks/VideoBlockContent/VideoBlockContent";
8
+ export * from "./blocks/AudioBlockContent/AudioBlockContent";
9
+
10
+ export * from "./blocks/FileBlockContent/fileBlockHelpers";
11
+ export * from "./blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
6
12
  export * from "./blocks/defaultBlockTypeGuards";
7
13
  export * from "./blocks/defaultBlocks";
8
14
  export * from "./blocks/defaultProps";
@@ -11,8 +17,8 @@ export * from "./editor/BlockNoteExtensions";
11
17
  export * from "./editor/BlockNoteSchema";
12
18
  export * from "./editor/selectionTypes";
13
19
  export * from "./extensions-shared/UiElementPosition";
20
+ export * from "./extensions/FilePanel/FilePanelPlugin";
14
21
  export * from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
15
- export * from "./extensions/ImagePanel/ImageToolbarPlugin";
16
22
  export * from "./extensions/LinkToolbar/LinkToolbarPlugin";
17
23
  export * from "./extensions/SideMenu/SideMenuPlugin";
18
24
  export * from "./extensions/SuggestionMenu/DefaultSuggestionItem";
@@ -29,3 +35,4 @@ export * from "./extensions/UniqueID/UniqueID";
29
35
  export * from "./i18n/dictionary";
30
36
  export { UnreachableCaseError, assertEmpty } from "./util/typescript";
31
37
  export { locales };
38
+ export { parseImageElement } from "./blocks/ImageBlockContent/imageBlockHelpers";
@@ -139,7 +139,7 @@ export const BlockContainer = Node.create<{
139
139
  state.schema.nodes["blockContainer"].createAndFill()!;
140
140
 
141
141
  if (dispatch) {
142
- state.tr.insert(pos, newBlock);
142
+ state.tr.insert(pos, newBlock).scrollIntoView();
143
143
  }
144
144
 
145
145
  return true;
@@ -470,6 +470,8 @@ export const BlockContainer = Node.create<{
470
470
  )
471
471
  : undefined
472
472
  );
473
+
474
+ state.tr.scrollIntoView();
473
475
  }
474
476
 
475
477
  return true;
@@ -689,7 +691,7 @@ export const BlockContainer = Node.create<{
689
691
  if (
690
692
  this.options.editor.formattingToolbar?.shown ||
691
693
  this.options.editor.linkToolbar?.shown ||
692
- this.options.editor.imagePanel?.shown
694
+ this.options.editor.filePanel?.shown
693
695
  ) {
694
696
  // don't handle tabs if a toolbar is shown, so we can tab into / out of it
695
697
  return false;
@@ -701,7 +703,7 @@ export const BlockContainer = Node.create<{
701
703
  if (
702
704
  this.options.editor.formattingToolbar?.shown ||
703
705
  this.options.editor.linkToolbar?.shown ||
704
- this.options.editor.imagePanel?.shown
706
+ this.options.editor.filePanel?.shown
705
707
  ) {
706
708
  // don't handle tabs if a toolbar is shown, so we can tab into / out of it
707
709
  return false;
@@ -193,6 +193,7 @@ export function createBlockSpec<
193
193
  block.type,
194
194
  block.props,
195
195
  blockConfig.propSchema,
196
+ blockConfig.isFileBlock,
196
197
  blockContentDOMAttributes
197
198
  );
198
199
  },
@@ -109,6 +109,11 @@ export function getBlockFromPos<
109
109
  const blockContainer = tipTapEditor.state.doc.resolve(pos!).node();
110
110
  // Gets block identifier
111
111
  const blockIdentifier = blockContainer.attrs.id;
112
+
113
+ if (!blockIdentifier) {
114
+ throw new Error("Block doesn't have id");
115
+ }
116
+
112
117
  // Gets the block
113
118
  const block = editor.getBlock(blockIdentifier)! as SpecificBlock<
114
119
  BSchema,
@@ -139,6 +144,7 @@ export function wrapInBlockStructure<
139
144
  blockType: BType,
140
145
  blockProps: Props<PSchema>,
141
146
  propSchema: PSchema,
147
+ isFileBlock = false,
142
148
  domAttributes?: Record<string, string>
143
149
  ): {
144
150
  dom: HTMLElement;
@@ -171,6 +177,10 @@ export function wrapInBlockStructure<
171
177
  blockContent.setAttribute(camelToDataKebab(prop), value);
172
178
  }
173
179
  }
180
+ // Adds file block attribute
181
+ if (isFileBlock) {
182
+ blockContent.setAttribute("data-file-block", "");
183
+ }
174
184
 
175
185
  blockContent.appendChild(element.dom);
176
186
 
@@ -21,14 +21,50 @@ export type BlockNoteDOMAttributes = Partial<{
21
21
  [DOMElement in BlockNoteDOMElement]: Record<string, string>;
22
22
  }>;
23
23
 
24
- // BlockConfig contains the "schema" info about a Block type
25
- // i.e. what props it supports, what content it supports, etc.
26
- export type BlockConfig = {
24
+ export type FileBlockConfig = {
27
25
  type: string;
28
- readonly propSchema: PropSchema;
29
- content: "inline" | "none" | "table";
26
+ readonly propSchema: PropSchema & {
27
+ caption: {
28
+ default: "";
29
+ };
30
+ name: {
31
+ default: "";
32
+ };
33
+
34
+ // URL is optional, as we also want to accept files with no URL, but for example ids
35
+ // (ids can be used for files that are resolved on the backend)
36
+ url?: {
37
+ default: "";
38
+ };
39
+
40
+ // Whether to show the file preview or the name only.
41
+ // This is useful for some file blocks, but not all
42
+ // (e.g.: not relevant for default "file" block which doesn;'t show previews)
43
+ showPreview?: {
44
+ default: boolean;
45
+ };
46
+ // File preview width in px.
47
+ previewWidth?: {
48
+ default: number;
49
+ };
50
+ };
51
+ content: "none";
52
+ isFileBlock: true;
53
+ isFileBlockPlaceholder: (block: any) => boolean;
54
+ fileBlockAcceptMimeTypes?: string[];
30
55
  };
31
56
 
57
+ // BlockConfig contains the "schema" info about a Block type
58
+ // i.e. what props it supports, what content it supports, etc.
59
+ export type BlockConfig =
60
+ | {
61
+ type: string;
62
+ readonly propSchema: PropSchema;
63
+ content: "inline" | "none" | "table";
64
+ isFileBlock?: false;
65
+ }
66
+ | FileBlockConfig;
67
+
32
68
  // Block implementation contains the "implementation" info about a Block
33
69
  // such as the functions / Nodes required to render and / or serialize it
34
70
  export type TiptapBlockImplementation<
@@ -1,3 +1,15 @@
1
1
  export function camelToDataKebab(str: string): string {
2
2
  return "data-" + str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
3
3
  }
4
+
5
+ export function filenameFromURL(url: string): string {
6
+ const parts = url.split("/");
7
+ if (
8
+ !parts.length || // invalid?
9
+ parts[parts.length - 1] === "" // for example, URL ends in a directory-like trailing slash
10
+ ) {
11
+ // in this case just return the original url
12
+ return url;
13
+ }
14
+ return parts[parts.length - 1];
15
+ }