@blocknote/core 0.37.0 → 0.39.0

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 (271) hide show
  1. package/dist/BlockNoteSchema-DmZ6UQfY.cjs +11 -0
  2. package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +1 -0
  3. package/dist/BlockNoteSchema-oR047ACf.js +4275 -0
  4. package/dist/BlockNoteSchema-oR047ACf.js.map +1 -0
  5. package/dist/blocknote.cjs +4 -12
  6. package/dist/blocknote.cjs.map +1 -1
  7. package/dist/blocknote.js +3311 -7230
  8. package/dist/blocknote.js.map +1 -1
  9. package/dist/blocks.cjs +2 -0
  10. package/dist/blocks.cjs.map +1 -0
  11. package/dist/blocks.js +71 -0
  12. package/dist/blocks.js.map +1 -0
  13. package/dist/{en-CvDoFvhc.js → en-Bq3Es3Np.js} +6 -12
  14. package/dist/en-Bq3Es3Np.js.map +1 -0
  15. package/dist/en-D3B48eJ7.cjs +2 -0
  16. package/dist/en-D3B48eJ7.cjs.map +1 -0
  17. package/dist/locales.cjs +1 -1
  18. package/dist/locales.cjs.map +1 -1
  19. package/dist/locales.js +109 -229
  20. package/dist/locales.js.map +1 -1
  21. package/dist/style.css +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -0
  23. package/dist/webpack-stats.json +1 -1
  24. package/package.json +25 -22
  25. package/src/api/blockManipulation/commands/insertBlocks/insertBlocks.ts +1 -1
  26. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +2 -2
  27. package/src/api/blockManipulation/commands/splitBlock/splitBlock.ts +34 -25
  28. package/src/api/blockManipulation/setupTestEnv.ts +0 -1
  29. package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +4 -8
  30. package/src/api/clipboard/toClipboard/copyExtension.ts +1 -3
  31. package/src/api/exporters/html/externalHTMLExporter.ts +0 -1
  32. package/src/api/exporters/html/util/serializeBlocksExternalHTML.ts +128 -28
  33. package/src/api/exporters/html/util/serializeBlocksInternalHTML.ts +101 -41
  34. package/src/api/exporters/markdown/markdownExporter.ts +13 -22
  35. package/src/api/exporters/markdown/util/addSpacesToCheckboxesRehypePlugin.ts +2 -12
  36. package/src/api/parsers/html/parseHTML.ts +3 -2
  37. package/src/api/parsers/html/util/nestedLists.test.ts +8 -8
  38. package/src/api/parsers/markdown/parseMarkdown.ts +17 -14
  39. package/src/api/pmUtil.ts +1 -1
  40. package/src/api/positionMapping.test.ts +197 -33
  41. package/src/api/positionMapping.ts +4 -6
  42. package/src/blocks/Audio/block.ts +174 -0
  43. package/src/blocks/BlockNoteSchema.ts +59 -0
  44. package/src/blocks/Code/block.ts +303 -0
  45. package/src/blocks/Code/shiki.ts +73 -0
  46. package/src/blocks/File/block.ts +98 -0
  47. package/src/blocks/{FileBlockContent → File}/helpers/render/createAddFileButton.ts +8 -4
  48. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileBlockWrapper.ts +16 -13
  49. package/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.ts +15 -2
  50. package/src/blocks/{FileBlockContent → File}/helpers/render/createResizableFileBlockWrapper.ts +63 -19
  51. package/src/blocks/Heading/block.ts +138 -0
  52. package/src/blocks/Image/block.ts +190 -0
  53. package/src/blocks/ListItem/BulletListItem/block.ts +116 -0
  54. package/src/blocks/ListItem/CheckListItem/block.ts +175 -0
  55. package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +173 -0
  56. package/src/blocks/ListItem/NumberedListItem/block.ts +133 -0
  57. package/src/blocks/ListItem/ToggleListItem/block.ts +78 -0
  58. package/src/blocks/PageBreak/block.ts +72 -0
  59. package/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.ts +9 -7
  60. package/src/blocks/Paragraph/block.ts +80 -0
  61. package/src/blocks/Quote/block.ts +90 -0
  62. package/src/blocks/{TableBlockContent/TableBlockContent.ts → Table/block.ts} +169 -51
  63. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +1 -1
  64. package/src/blocks/Video/block.ts +143 -0
  65. package/src/blocks/defaultBlockHelpers.ts +2 -2
  66. package/src/blocks/defaultBlockTypeGuards.ts +143 -174
  67. package/src/blocks/defaultBlocks.ts +107 -35
  68. package/src/blocks/defaultProps.ts +145 -4
  69. package/src/blocks/index.ts +26 -0
  70. package/src/blocks/utils/listItemEnterHandler.ts +42 -0
  71. package/src/editor/Block.css +54 -18
  72. package/src/editor/BlockNoteEditor.ts +265 -230
  73. package/src/editor/BlockNoteExtension.ts +92 -0
  74. package/src/editor/BlockNoteExtensions.ts +20 -16
  75. package/src/editor/defaultColors.ts +2 -2
  76. package/src/exporter/Exporter.ts +1 -1
  77. package/src/exporter/mapping.ts +1 -1
  78. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +3 -20
  79. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +6 -8
  80. package/src/extensions/BlockChange/BlockChangePlugin.ts +2 -1
  81. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
  82. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
  83. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
  84. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
  85. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +52 -0
  86. package/src/extensions/Collaboration/schemaMigration/migrationRules/index.ts +4 -0
  87. package/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.ts +4 -0
  88. package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +78 -0
  89. package/src/extensions/Comments/CommentsPlugin.ts +2 -0
  90. package/src/extensions/FilePanel/FilePanelPlugin.ts +5 -10
  91. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +1 -1
  92. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +4 -3
  93. package/src/extensions/Placeholder/PlaceholderPlugin.ts +2 -2
  94. package/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.ts +1 -23
  95. package/src/extensions/SideMenu/SideMenuPlugin.ts +0 -2
  96. package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +0 -5
  97. package/src/extensions/SuggestionMenu/getDefaultEmojiPickerItems.ts +6 -2
  98. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +24 -17
  99. package/src/extensions/TableHandles/TableHandlesPlugin.ts +2 -2
  100. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +5 -11
  101. package/src/extensions/TextColor/TextColorExtension.ts +3 -17
  102. package/src/extensions/TextColor/TextColorMark.ts +4 -9
  103. package/src/extensions/UniqueID/UniqueID.ts +6 -13
  104. package/src/i18n/locales/ar.ts +6 -12
  105. package/src/i18n/locales/de.ts +6 -12
  106. package/src/i18n/locales/en.ts +6 -12
  107. package/src/i18n/locales/es.ts +6 -12
  108. package/src/i18n/locales/fr.ts +6 -12
  109. package/src/i18n/locales/he.ts +6 -12
  110. package/src/i18n/locales/hr.ts +6 -12
  111. package/src/i18n/locales/is.ts +6 -12
  112. package/src/i18n/locales/it.ts +6 -12
  113. package/src/i18n/locales/ja.ts +6 -12
  114. package/src/i18n/locales/ko.ts +6 -12
  115. package/src/i18n/locales/nl.ts +6 -12
  116. package/src/i18n/locales/no.ts +6 -12
  117. package/src/i18n/locales/pl.ts +6 -12
  118. package/src/i18n/locales/pt.ts +6 -12
  119. package/src/i18n/locales/ru.ts +6 -12
  120. package/src/i18n/locales/sk.ts +6 -12
  121. package/src/i18n/locales/uk.ts +6 -12
  122. package/src/i18n/locales/vi.ts +6 -12
  123. package/src/i18n/locales/zh-tw.ts +6 -12
  124. package/src/i18n/locales/zh.ts +6 -12
  125. package/src/index.ts +2 -29
  126. package/src/schema/blocks/createSpec.ts +342 -169
  127. package/src/schema/blocks/internal.ts +77 -138
  128. package/src/schema/blocks/types.ts +264 -94
  129. package/src/schema/index.ts +1 -0
  130. package/src/schema/inlineContent/createSpec.ts +99 -21
  131. package/src/schema/inlineContent/internal.ts +16 -7
  132. package/src/schema/inlineContent/types.ts +24 -2
  133. package/src/schema/propTypes.ts +15 -9
  134. package/src/schema/schema.ts +209 -0
  135. package/src/schema/styles/createSpec.ts +79 -31
  136. package/src/schema/styles/internal.ts +61 -2
  137. package/src/schema/styles/types.ts +17 -3
  138. package/src/util/topo-sort.test.ts +125 -0
  139. package/src/util/topo-sort.ts +160 -0
  140. package/types/src/api/blockManipulation/commands/splitBlock/splitBlock.d.ts +2 -1
  141. package/types/src/api/blockManipulation/selections/selection.d.ts +1 -1
  142. package/types/src/api/blockManipulation/setupTestEnv.d.ts +29 -543
  143. package/types/src/api/exporters/html/util/serializeBlocksExternalHTML.d.ts +1 -1
  144. package/types/src/api/exporters/html/util/serializeBlocksInternalHTML.d.ts +1 -1
  145. package/types/src/api/exporters/markdown/markdownExporter.d.ts +1 -1
  146. package/types/src/api/parsers/html/parseHTML.d.ts +1 -1
  147. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +2 -2
  148. package/types/src/api/pmUtil.d.ts +1 -1
  149. package/types/src/blocks/Audio/block.d.ts +58 -0
  150. package/types/src/blocks/BlockNoteSchema.d.ts +18 -0
  151. package/types/src/blocks/{CodeBlockContent/CodeBlockContent.d.ts → Code/block.d.ts} +25 -26
  152. package/types/src/blocks/Code/shiki.d.ts +4 -0
  153. package/types/src/blocks/File/block.d.ts +37 -0
  154. package/types/src/blocks/File/helpers/render/createAddFileButton.d.ts +6 -0
  155. package/types/src/blocks/File/helpers/render/createFileBlockWrapper.d.ts +25 -0
  156. package/types/src/blocks/{FileBlockContent → File}/helpers/render/createFileNameWithIcon.d.ts +6 -2
  157. package/types/src/blocks/File/helpers/render/createResizableFileBlockWrapper.d.ts +31 -0
  158. package/types/src/blocks/Heading/block.d.ts +71 -0
  159. package/types/src/blocks/Image/block.d.ts +102 -0
  160. package/types/src/blocks/ListItem/BulletListItem/block.d.ts +25 -0
  161. package/types/src/blocks/ListItem/CheckListItem/block.d.ts +33 -0
  162. package/types/src/blocks/ListItem/NumberedListItem/IndexingPlugin.d.ts +8 -0
  163. package/types/src/blocks/ListItem/NumberedListItem/block.d.ts +33 -0
  164. package/types/src/blocks/ListItem/ToggleListItem/block.d.ts +25 -0
  165. package/types/src/blocks/PageBreak/block.d.ts +11 -0
  166. package/types/src/blocks/{PageBreakBlockContent → PageBreak}/getPageBreakSlashMenuItems.d.ts +4 -2
  167. package/types/src/blocks/Paragraph/block.d.ts +25 -0
  168. package/types/src/blocks/Quote/block.d.ts +17 -0
  169. package/types/src/blocks/Table/block.d.ts +21 -0
  170. package/types/src/blocks/Video/block.d.ts +67 -0
  171. package/types/src/blocks/defaultBlockHelpers.d.ts +1 -1
  172. package/types/src/blocks/defaultBlockTypeGuards.d.ts +15 -36
  173. package/types/src/blocks/defaultBlocks.d.ts +221 -1060
  174. package/types/src/blocks/defaultProps.d.ts +17 -1
  175. package/types/src/blocks/index.d.ts +24 -0
  176. package/types/src/blocks/utils/listItemEnterHandler.d.ts +2 -0
  177. package/types/src/editor/BlockNoteEditor.d.ts +39 -75
  178. package/types/src/editor/BlockNoteExtension.d.ts +67 -0
  179. package/types/src/editor/BlockNoteExtensions.d.ts +2 -0
  180. package/types/src/editor/defaultColors.d.ts +8 -76
  181. package/types/src/exporter/Exporter.d.ts +1 -1
  182. package/types/src/exporter/mapping.d.ts +1 -1
  183. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +4 -1
  184. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +7 -0
  185. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/index.d.ts +3 -0
  186. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/migrationRule.d.ts +3 -0
  187. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.d.ts +2 -0
  188. package/types/src/extensions/Comments/CommentsPlugin.d.ts +3 -1
  189. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +4 -4
  190. package/types/src/extensions/TextColor/TextColorMark.d.ts +4 -1
  191. package/types/src/i18n/locales/en.d.ts +1 -12
  192. package/types/src/i18n/locales/sk.d.ts +1 -12
  193. package/types/src/index.d.ts +2 -26
  194. package/types/src/schema/blocks/createSpec.d.ts +16 -36
  195. package/types/src/schema/blocks/internal.d.ts +11 -33
  196. package/types/src/schema/blocks/types.d.ts +181 -57
  197. package/types/src/schema/index.d.ts +1 -0
  198. package/types/src/schema/inlineContent/createSpec.d.ts +36 -2
  199. package/types/src/schema/inlineContent/internal.d.ts +7 -15
  200. package/types/src/schema/inlineContent/types.d.ts +15 -1
  201. package/types/src/schema/propTypes.d.ts +4 -4
  202. package/types/src/schema/schema.d.ts +40 -0
  203. package/types/src/schema/styles/createSpec.d.ts +6 -4
  204. package/types/src/schema/styles/internal.d.ts +6 -3
  205. package/types/src/schema/styles/types.d.ts +11 -2
  206. package/types/src/util/topo-sort.d.ts +18 -0
  207. package/types/src/util/topo-sort.test.d.ts +1 -0
  208. package/dist/en-CvDoFvhc.js.map +0 -1
  209. package/dist/en-ub2yVBX0.cjs +0 -2
  210. package/dist/en-ub2yVBX0.cjs.map +0 -1
  211. package/src/blocks/AudioBlockContent/AudioBlockContent.ts +0 -145
  212. package/src/blocks/CodeBlockContent/CodeBlockContent.ts +0 -445
  213. package/src/blocks/FileBlockContent/FileBlockContent.ts +0 -100
  214. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +0 -159
  215. package/src/blocks/ImageBlockContent/ImageBlockContent.ts +0 -160
  216. package/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +0 -134
  217. package/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.ts +0 -299
  218. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +0 -86
  219. package/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +0 -172
  220. package/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.ts +0 -104
  221. package/src/blocks/PageBreakBlockContent/PageBreakBlockContent.ts +0 -49
  222. package/src/blocks/PageBreakBlockContent/schema.ts +0 -40
  223. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +0 -78
  224. package/src/blocks/QuoteBlockContent/QuoteBlockContent.ts +0 -121
  225. package/src/blocks/VideoBlockContent/VideoBlockContent.ts +0 -159
  226. package/src/editor/BlockNoteSchema.ts +0 -107
  227. package/src/editor/BlockNoteTipTapEditor.ts +0 -335
  228. package/src/util/esmDependencies.ts +0 -51
  229. package/types/src/blocks/AudioBlockContent/AudioBlockContent.d.ts +0 -99
  230. package/types/src/blocks/FileBlockContent/FileBlockContent.d.ts +0 -90
  231. package/types/src/blocks/FileBlockContent/helpers/render/createAddFileButton.d.ts +0 -6
  232. package/types/src/blocks/FileBlockContent/helpers/render/createFileBlockWrapper.d.ts +0 -9
  233. package/types/src/blocks/FileBlockContent/helpers/render/createResizableFileBlockWrapper.d.ts +0 -9
  234. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +0 -67
  235. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +0 -131
  236. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -46
  237. package/types/src/blocks/ListItemBlockContent/CheckListItemBlockContent/CheckListItemBlockContent.d.ts +0 -55
  238. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -2
  239. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -58
  240. package/types/src/blocks/ListItemBlockContent/ToggleListItemBlockContent/ToggleListItemBlockContent.d.ts +0 -46
  241. package/types/src/blocks/PageBreakBlockContent/PageBreakBlockContent.d.ts +0 -31
  242. package/types/src/blocks/PageBreakBlockContent/schema.d.ts +0 -86
  243. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -52
  244. package/types/src/blocks/QuoteBlockContent/QuoteBlockContent.d.ts +0 -52
  245. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +0 -39
  246. package/types/src/blocks/VideoBlockContent/VideoBlockContent.d.ts +0 -131
  247. package/types/src/editor/BlockNoteSchema.d.ts +0 -34
  248. package/types/src/editor/BlockNoteTipTapEditor.d.ts +0 -43
  249. package/types/src/util/esmDependencies.d.ts +0 -24
  250. /package/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.ts +0 -0
  251. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.ts +0 -0
  252. /package/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.ts +0 -0
  253. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.ts +0 -0
  254. /package/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.ts +0 -0
  255. /package/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  256. /package/src/blocks/{ImageBlockContent → Image}/parseImageElement.ts +0 -0
  257. /package/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.ts +0 -0
  258. /package/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.ts +0 -0
  259. /package/src/blocks/{TableBlockContent → Table}/TableExtension.ts +0 -0
  260. /package/src/blocks/{VideoBlockContent → Video}/parseVideoElement.ts +0 -0
  261. /package/types/src/blocks/{AudioBlockContent → Audio}/parseAudioElement.d.ts +0 -0
  262. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseEmbedElement.d.ts +0 -0
  263. /package/types/src/blocks/{FileBlockContent → File}/helpers/parse/parseFigureElement.d.ts +0 -0
  264. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createFigureWithCaption.d.ts +0 -0
  265. /package/types/src/blocks/{FileBlockContent → File}/helpers/toExternalHTML/createLinkWithCaption.d.ts +0 -0
  266. /package/types/src/blocks/{FileBlockContent → File/helpers}/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
  267. /package/types/src/blocks/{ImageBlockContent → Image}/parseImageElement.d.ts +0 -0
  268. /package/types/src/blocks/{ListItemBlockContent → ListItem}/ListItemKeyboardShortcuts.d.ts +0 -0
  269. /package/types/src/blocks/{ListItemBlockContent → ListItem}/getListItemContent.d.ts +0 -0
  270. /package/types/src/blocks/{TableBlockContent → Table}/TableExtension.d.ts +0 -0
  271. /package/types/src/blocks/{VideoBlockContent → Video}/parseVideoElement.d.ts +0 -0
@@ -0,0 +1,80 @@
1
+ import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
2
+ import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
3
+ import {
4
+ addDefaultPropsExternalHTML,
5
+ defaultProps,
6
+ parseDefaultProps,
7
+ } from "../defaultProps.js";
8
+
9
+ export type ParagraphBlockConfig = ReturnType<
10
+ typeof createParagraphBlockConfig
11
+ >;
12
+
13
+ export const createParagraphBlockConfig = createBlockConfig(
14
+ () =>
15
+ ({
16
+ type: "paragraph" as const,
17
+ propSchema: defaultProps,
18
+ content: "inline" as const,
19
+ }) as const,
20
+ );
21
+
22
+ export const createParagraphBlockSpec = createBlockSpec(
23
+ createParagraphBlockConfig,
24
+ {
25
+ meta: {
26
+ isolating: false,
27
+ },
28
+ parse: (e) => {
29
+ if (e.tagName !== "P") {
30
+ return undefined;
31
+ }
32
+
33
+ // Edge case for things like images directly inside paragraph.
34
+ if (!e.textContent?.trim()) {
35
+ return undefined;
36
+ }
37
+
38
+ return parseDefaultProps(e);
39
+ },
40
+ render: () => {
41
+ const dom = document.createElement("p");
42
+ return {
43
+ dom,
44
+ contentDOM: dom,
45
+ };
46
+ },
47
+ toExternalHTML: (block) => {
48
+ const dom = document.createElement("p");
49
+ addDefaultPropsExternalHTML(block.props, dom);
50
+ return {
51
+ dom,
52
+ contentDOM: dom,
53
+ };
54
+ },
55
+ runsBefore: ["default"],
56
+ },
57
+ [
58
+ createBlockNoteExtension({
59
+ key: "paragraph-shortcuts",
60
+ keyboardShortcuts: {
61
+ "Mod-Alt-0": ({ editor }) => {
62
+ const cursorPosition = editor.getTextCursorPosition();
63
+
64
+ if (
65
+ editor.schema.blockSchema[cursorPosition.block.type].content !==
66
+ "inline"
67
+ ) {
68
+ return false;
69
+ }
70
+
71
+ editor.updateBlock(cursorPosition.block, {
72
+ type: "paragraph",
73
+ props: {},
74
+ });
75
+ return true;
76
+ },
77
+ },
78
+ }),
79
+ ],
80
+ );
@@ -0,0 +1,90 @@
1
+ import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
2
+ import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
3
+ import {
4
+ addDefaultPropsExternalHTML,
5
+ defaultProps,
6
+ parseDefaultProps,
7
+ } from "../defaultProps.js";
8
+
9
+ export type QuoteBlockConfig = ReturnType<typeof createQuoteBlockConfig>;
10
+
11
+ export const createQuoteBlockConfig = createBlockConfig(
12
+ () =>
13
+ ({
14
+ type: "quote" as const,
15
+ propSchema: {
16
+ backgroundColor: defaultProps.backgroundColor,
17
+ textColor: defaultProps.textColor,
18
+ },
19
+ content: "inline" as const,
20
+ }) as const,
21
+ );
22
+
23
+ export const createQuoteBlockSpec = createBlockSpec(
24
+ createQuoteBlockConfig,
25
+ {
26
+ meta: {
27
+ isolating: false,
28
+ },
29
+ parse(element) {
30
+ if (element.tagName === "BLOCKQUOTE") {
31
+ const { backgroundColor, textColor } = parseDefaultProps(element);
32
+
33
+ return { backgroundColor, textColor };
34
+ }
35
+
36
+ return undefined;
37
+ },
38
+ render() {
39
+ const quote = document.createElement("blockquote");
40
+
41
+ return {
42
+ dom: quote,
43
+ contentDOM: quote,
44
+ };
45
+ },
46
+ toExternalHTML(block) {
47
+ const quote = document.createElement("blockquote");
48
+ addDefaultPropsExternalHTML(block.props, quote);
49
+
50
+ return {
51
+ dom: quote,
52
+ contentDOM: quote,
53
+ };
54
+ },
55
+ },
56
+ [
57
+ createBlockNoteExtension({
58
+ key: "quote-block-shortcuts",
59
+ keyboardShortcuts: {
60
+ "Mod-Alt-q": ({ editor }) => {
61
+ const cursorPosition = editor.getTextCursorPosition();
62
+
63
+ if (
64
+ editor.schema.blockSchema[cursorPosition.block.type].content !==
65
+ "inline"
66
+ ) {
67
+ return false;
68
+ }
69
+
70
+ editor.updateBlock(cursorPosition.block, {
71
+ type: "quote",
72
+ props: {},
73
+ });
74
+ return true;
75
+ },
76
+ },
77
+ inputRules: [
78
+ {
79
+ find: new RegExp(`^>\\s$`),
80
+ replace() {
81
+ return {
82
+ type: "quote",
83
+ props: {},
84
+ };
85
+ },
86
+ },
87
+ ],
88
+ }),
89
+ ],
90
+ );
@@ -1,12 +1,11 @@
1
1
  import { Node, mergeAttributes } from "@tiptap/core";
2
- import { TableCell } from "@tiptap/extension-table-cell";
3
- import { TableHeader } from "@tiptap/extension-table-header";
4
2
  import { DOMParser, Fragment, Node as PMNode, Schema } from "prosemirror-model";
5
3
  import { TableView } from "prosemirror-tables";
6
4
  import { NodeView } from "prosemirror-view";
5
+ import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
7
6
  import {
8
- createBlockSpecFromStronglyTypedTiptapNode,
9
- createStronglyTypedTiptapNode,
7
+ BlockConfig,
8
+ createBlockSpecFromTiptapNode,
10
9
  } from "../../schema/index.js";
11
10
  import { mergeCSSClasses } from "../../util/browser.js";
12
11
  import { createDefaultBlockDOMOutputSpec } from "../defaultBlockHelpers.js";
@@ -17,7 +16,134 @@ export const tablePropSchema = {
17
16
  textColor: defaultProps.textColor,
18
17
  };
19
18
 
20
- export const TableBlockContent = createStronglyTypedTiptapNode({
19
+ const TiptapTableHeader = Node.create<{
20
+ HTMLAttributes: Record<string, any>;
21
+ }>({
22
+ name: "tableHeader",
23
+
24
+ addOptions() {
25
+ return {
26
+ HTMLAttributes: {},
27
+ };
28
+ },
29
+
30
+ /**
31
+ * We allow table headers and cells to have multiple tableContent nodes because
32
+ * when merging cells, prosemirror-tables will concat the contents of the cells naively.
33
+ * This would cause that content to overflow into other cells when prosemirror tries to enforce the cell structure.
34
+ *
35
+ * So, we manually fix this up when reading back in the `nodeToBlock` and only ever place a single tableContent back into the cell.
36
+ */
37
+ content: "tableContent+",
38
+
39
+ addAttributes() {
40
+ return {
41
+ colspan: {
42
+ default: 1,
43
+ },
44
+ rowspan: {
45
+ default: 1,
46
+ },
47
+ colwidth: {
48
+ default: null,
49
+ parseHTML: (element) => {
50
+ const colwidth = element.getAttribute("colwidth");
51
+ const value = colwidth
52
+ ? colwidth.split(",").map((width) => parseInt(width, 10))
53
+ : null;
54
+
55
+ return value;
56
+ },
57
+ },
58
+ };
59
+ },
60
+
61
+ tableRole: "header_cell",
62
+
63
+ isolating: true,
64
+
65
+ parseHTML() {
66
+ return [
67
+ {
68
+ tag: "th",
69
+ // As `th` elements can contain multiple paragraphs, we need to merge their contents
70
+ // into a single one so that ProseMirror can parse everything correctly.
71
+ getContent: (node, schema) =>
72
+ parseTableContent(node as HTMLElement, schema),
73
+ },
74
+ ];
75
+ },
76
+
77
+ renderHTML({ HTMLAttributes }) {
78
+ return [
79
+ "th",
80
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
81
+ 0,
82
+ ];
83
+ },
84
+ });
85
+
86
+ const TiptapTableCell = Node.create<{
87
+ HTMLAttributes: Record<string, any>;
88
+ }>({
89
+ name: "tableCell",
90
+
91
+ addOptions() {
92
+ return {
93
+ HTMLAttributes: {},
94
+ };
95
+ },
96
+
97
+ content: "tableContent+",
98
+
99
+ addAttributes() {
100
+ return {
101
+ colspan: {
102
+ default: 1,
103
+ },
104
+ rowspan: {
105
+ default: 1,
106
+ },
107
+ colwidth: {
108
+ default: null,
109
+ parseHTML: (element) => {
110
+ const colwidth = element.getAttribute("colwidth");
111
+ const value = colwidth
112
+ ? colwidth.split(",").map((width) => parseInt(width, 10))
113
+ : null;
114
+
115
+ return value;
116
+ },
117
+ },
118
+ };
119
+ },
120
+
121
+ tableRole: "cell",
122
+
123
+ isolating: true,
124
+
125
+ parseHTML() {
126
+ return [
127
+ {
128
+ tag: "td",
129
+ // As `td` elements can contain multiple paragraphs, we need to merge their contents
130
+ // into a single one so that ProseMirror can parse everything correctly.
131
+ getContent: (node, schema) =>
132
+ parseTableContent(node as HTMLElement, schema),
133
+ },
134
+ ];
135
+ },
136
+
137
+ renderHTML({ HTMLAttributes }) {
138
+ return [
139
+ "td",
140
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
141
+ 0,
142
+ ];
143
+ },
144
+ });
145
+
146
+ const TiptapTableNode = Node.create({
21
147
  name: "table",
22
148
  content: "tableRow+",
23
149
  group: "blockContent",
@@ -134,7 +260,7 @@ export const TableBlockContent = createStronglyTypedTiptapNode({
134
260
  },
135
261
  });
136
262
 
137
- const TableParagraph = createStronglyTypedTiptapNode({
263
+ const TiptapTableParagraph = Node.create({
138
264
  name: "tableParagraph",
139
265
  group: "tableContent",
140
266
  content: "inline*",
@@ -179,7 +305,9 @@ const TableParagraph = createStronglyTypedTiptapNode({
179
305
  * This extension allows you to create table rows.
180
306
  * @see https://www.tiptap.dev/api/nodes/table-row
181
307
  */
182
- export const TableRow = Node.create<{ HTMLAttributes: Record<string, any> }>({
308
+ const TiptapTableRow = Node.create<{
309
+ HTMLAttributes: Record<string, any>;
310
+ }>({
183
311
  name: "tableRow",
184
312
 
185
313
  addOptions() {
@@ -241,47 +369,37 @@ function parseTableContent(node: HTMLElement, schema: Schema) {
241
369
  return Fragment.fromArray(extractedContent);
242
370
  }
243
371
 
244
- export const Table = createBlockSpecFromStronglyTypedTiptapNode(
245
- TableBlockContent,
246
- tablePropSchema,
247
- [
248
- TableExtension,
249
- TableParagraph,
250
- TableHeader.extend({
251
- /**
252
- * We allow table headers and cells to have multiple tableContent nodes because
253
- * when merging cells, prosemirror-tables will concat the contents of the cells naively.
254
- * This would cause that content to overflow into other cells when prosemirror tries to enforce the cell structure.
255
- *
256
- * So, we manually fix this up when reading back in the `nodeToBlock` and only ever place a single tableContent back into the cell.
257
- */
258
- content: "tableContent+",
259
- parseHTML() {
260
- return [
261
- {
262
- tag: "th",
263
- // As `th` elements can contain multiple paragraphs, we need to merge their contents
264
- // into a single one so that ProseMirror can parse everything correctly.
265
- getContent: (node, schema) =>
266
- parseTableContent(node as HTMLElement, schema),
267
- },
268
- ];
269
- },
270
- }),
271
- TableCell.extend({
272
- content: "tableContent+",
273
- parseHTML() {
274
- return [
275
- {
276
- tag: "td",
277
- // As `td` elements can contain multiple paragraphs, we need to merge their contents
278
- // into a single one so that ProseMirror can parse everything correctly.
279
- getContent: (node, schema) =>
280
- parseTableContent(node as HTMLElement, schema),
281
- },
282
- ];
283
- },
284
- }),
285
- TableRow,
286
- ],
287
- );
372
+ export type TableBlockConfig = BlockConfig<
373
+ "table",
374
+ {
375
+ textColor: {
376
+ default: "default";
377
+ };
378
+ },
379
+ "table"
380
+ >;
381
+
382
+ export const createTableBlockSpec = () =>
383
+ createBlockSpecFromTiptapNode(
384
+ { node: TiptapTableNode, type: "table", content: "table" },
385
+ tablePropSchema,
386
+ [
387
+ createBlockNoteExtension({
388
+ key: "table-extensions",
389
+ tiptapExtensions: [
390
+ TableExtension,
391
+ TiptapTableParagraph,
392
+ TiptapTableHeader,
393
+ TiptapTableCell,
394
+ TiptapTableRow,
395
+ ],
396
+ }),
397
+ ],
398
+ );
399
+
400
+ // We need to declare this here because we aren't using the table extensions from tiptap, so the types are not automatically inferred.
401
+ declare module "@tiptap/core" {
402
+ interface NodeConfig {
403
+ tableRole?: string;
404
+ }
405
+ }
@@ -28,7 +28,7 @@ export const createToggleWrapper = (
28
28
  ignoreMutation?: (mutation: ViewMutationRecord) => boolean;
29
29
  destroy?: () => void;
30
30
  } => {
31
- if ("isToggleable" in block.props && !block.props.isToggleable) {
31
+ if (!("isToggleable" in block.props) || !block.props.isToggleable) {
32
32
  return {
33
33
  dom: renderedElement,
34
34
  };
@@ -0,0 +1,143 @@
1
+ import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
2
+ import { defaultProps, parseDefaultProps } from "../defaultProps.js";
3
+ import { parseFigureElement } from "../File/helpers/parse/parseFigureElement.js";
4
+ import { createResizableFileBlockWrapper } from "../File/helpers/render/createResizableFileBlockWrapper.js";
5
+ import { createFigureWithCaption } from "../File/helpers/toExternalHTML/createFigureWithCaption.js";
6
+ import { createLinkWithCaption } from "../File/helpers/toExternalHTML/createLinkWithCaption.js";
7
+ import { parseVideoElement } from "./parseVideoElement.js";
8
+
9
+ export const FILE_VIDEO_ICON_SVG =
10
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M2 3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934ZM8 5V19H16V5H8ZM4 5V7H6V5H4ZM18 5V7H20V5H18ZM4 9V11H6V9H4ZM18 9V11H20V9H18ZM4 13V15H6V13H4ZM18 13V15H20V13H18ZM4 17V19H6V17H4ZM18 17V19H20V17H18Z"></path></svg>';
11
+
12
+ export interface VideoOptions {
13
+ icon?: string;
14
+ }
15
+
16
+ export type VideoBlockConfig = ReturnType<typeof createVideoBlockConfig>;
17
+
18
+ export const createVideoBlockConfig = createBlockConfig(
19
+ (_ctx: VideoOptions) => ({
20
+ type: "video" as const,
21
+ propSchema: {
22
+ textAlignment: defaultProps.textAlignment,
23
+ backgroundColor: defaultProps.backgroundColor,
24
+ name: { default: "" as const },
25
+ url: { default: "" as const },
26
+ caption: { default: "" as const },
27
+ showPreview: { default: true },
28
+ previewWidth: { default: undefined, type: "number" as const },
29
+ },
30
+ content: "none" as const,
31
+ }),
32
+ );
33
+
34
+ export const videoParse = (_config: VideoOptions) => (element: HTMLElement) => {
35
+ if (element.tagName === "VIDEO") {
36
+ // Ignore if parent figure has already been parsed.
37
+ if (element.closest("figure")) {
38
+ return undefined;
39
+ }
40
+
41
+ const { backgroundColor } = parseDefaultProps(element);
42
+
43
+ return {
44
+ ...parseVideoElement(element as HTMLVideoElement),
45
+ backgroundColor,
46
+ };
47
+ }
48
+
49
+ if (element.tagName === "FIGURE") {
50
+ const parsedFigure = parseFigureElement(element, "video");
51
+ if (!parsedFigure) {
52
+ return undefined;
53
+ }
54
+
55
+ const { targetElement, caption } = parsedFigure;
56
+
57
+ const { backgroundColor } = parseDefaultProps(element);
58
+
59
+ return {
60
+ ...parseVideoElement(targetElement as HTMLVideoElement),
61
+ backgroundColor,
62
+ caption,
63
+ };
64
+ }
65
+
66
+ return undefined;
67
+ };
68
+
69
+ export const createVideoBlockSpec = createBlockSpec(
70
+ createVideoBlockConfig,
71
+ (config) => ({
72
+ meta: {
73
+ fileBlockAccept: ["video/*"],
74
+ },
75
+ parse: videoParse(config),
76
+ render(block, editor) {
77
+ const icon = document.createElement("div");
78
+ icon.innerHTML = config.icon ?? FILE_VIDEO_ICON_SVG;
79
+
80
+ const videoWrapper = document.createElement("div");
81
+ videoWrapper.className = "bn-visual-media-wrapper";
82
+
83
+ const video = document.createElement("video");
84
+ video.className = "bn-visual-media";
85
+ if (editor.resolveFileUrl) {
86
+ editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
87
+ video.src = downloadUrl;
88
+ });
89
+ } else {
90
+ video.src = block.props.url;
91
+ }
92
+ video.controls = true;
93
+ video.contentEditable = "false";
94
+ video.draggable = false;
95
+ video.width = block.props.previewWidth;
96
+ videoWrapper.appendChild(video);
97
+
98
+ return createResizableFileBlockWrapper(
99
+ block,
100
+ editor,
101
+ { dom: videoWrapper },
102
+ videoWrapper,
103
+ icon.firstElementChild as HTMLElement,
104
+ );
105
+ },
106
+ toExternalHTML(block) {
107
+ if (!block.props.url) {
108
+ const div = document.createElement("p");
109
+ div.textContent = "Add video";
110
+
111
+ return {
112
+ dom: div,
113
+ };
114
+ }
115
+
116
+ let video;
117
+ if (block.props.showPreview) {
118
+ video = document.createElement("video");
119
+ video.src = block.props.url;
120
+ if (block.props.previewWidth) {
121
+ video.width = block.props.previewWidth;
122
+ }
123
+ } else {
124
+ video = document.createElement("a");
125
+ video.href = block.props.url;
126
+ video.textContent = block.props.name || block.props.url;
127
+ }
128
+
129
+ if (block.props.caption) {
130
+ if (block.props.showPreview) {
131
+ return createFigureWithCaption(video, block.props.caption);
132
+ } else {
133
+ return createLinkWithCaption(video, block.props.caption);
134
+ }
135
+ }
136
+
137
+ return {
138
+ dom: video,
139
+ };
140
+ },
141
+ runsBefore: ["file"],
142
+ }),
143
+ );
@@ -100,13 +100,13 @@ export const defaultBlockToHTML = <
100
100
  // This is used when parsing blocks like list items and table cells, as they may
101
101
  // contain multiple paragraphs that ProseMirror will not be able to handle
102
102
  // properly.
103
- export function mergeParagraphs(element: HTMLElement) {
103
+ export function mergeParagraphs(element: HTMLElement, separator = "<br>") {
104
104
  const paragraphs = element.querySelectorAll("p");
105
105
  if (paragraphs.length > 1) {
106
106
  const firstParagraph = paragraphs[0];
107
107
  for (let i = 1; i < paragraphs.length; i++) {
108
108
  const paragraph = paragraphs[i];
109
- firstParagraph.innerHTML += "<br>" + paragraph.innerHTML;
109
+ firstParagraph.innerHTML += separator + paragraph.innerHTML;
110
110
  paragraph.remove();
111
111
  }
112
112
  }