@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
@@ -1,20 +1,37 @@
1
1
  import type { BlockNoteEditor } from "../../../../editor/BlockNoteEditor.js";
2
- import { BlockFromConfig, FileBlockConfig } from "../../../../schema/index.js";
2
+ import {
3
+ BlockConfig,
4
+ BlockFromConfigNoChildren,
5
+ } from "../../../../schema/index.js";
3
6
  import { createFileBlockWrapper } from "./createFileBlockWrapper.js";
4
7
 
5
8
  export const createResizableFileBlockWrapper = (
6
- block: BlockFromConfig<FileBlockConfig, any, any>,
9
+ block: BlockFromConfigNoChildren<
10
+ BlockConfig<
11
+ string,
12
+ {
13
+ backgroundColor: { default: "default" };
14
+ name: { default: "" };
15
+ url: { default: "" };
16
+ caption: { default: "" };
17
+ showPreview?: { default: true };
18
+ previewWidth?: { default: number };
19
+ textAlignment?: { default: "left" };
20
+ },
21
+ "none"
22
+ >,
23
+ any,
24
+ any
25
+ >,
7
26
  editor: BlockNoteEditor<any, any, any>,
8
27
  element: { dom: HTMLElement; destroy?: () => void },
9
28
  resizeHandlesContainerElement: HTMLElement,
10
- buttonText: string,
11
- buttonIcon: HTMLElement,
29
+ buttonIcon?: HTMLElement,
12
30
  ): { dom: HTMLElement; destroy: () => void } => {
13
31
  const { dom, destroy } = createFileBlockWrapper(
14
32
  block,
15
33
  editor,
16
34
  element,
17
- buttonText,
18
35
  buttonIcon,
19
36
  );
20
37
  const wrapper = dom;
@@ -56,7 +73,7 @@ export const createResizableFileBlockWrapper = (
56
73
 
57
74
  // Updates the element width with an updated width depending on the cursor X
58
75
  // offset from when the resize began, and which resize handle is being used.
59
- const windowMouseMoveHandler = (event: MouseEvent) => {
76
+ const windowMouseMoveHandler = (event: MouseEvent | TouchEvent) => {
60
77
  if (!resizeParams) {
61
78
  if (
62
79
  !editor.isEditable &&
@@ -72,27 +89,26 @@ export const createResizableFileBlockWrapper = (
72
89
 
73
90
  let newWidth: number;
74
91
 
92
+ const clientX =
93
+ "touches" in event ? event.touches[0].clientX : event.clientX;
94
+
75
95
  if (block.props.textAlignment === "center") {
76
96
  if (resizeParams.handleUsed === "left") {
77
97
  newWidth =
78
98
  resizeParams.initialWidth +
79
- (resizeParams.initialClientX - event.clientX) * 2;
99
+ (resizeParams.initialClientX - clientX) * 2;
80
100
  } else {
81
101
  newWidth =
82
102
  resizeParams.initialWidth +
83
- (event.clientX - resizeParams.initialClientX) * 2;
103
+ (clientX - resizeParams.initialClientX) * 2;
84
104
  }
85
105
  } else {
86
106
  if (resizeParams.handleUsed === "left") {
87
107
  newWidth =
88
- resizeParams.initialWidth +
89
- resizeParams.initialClientX -
90
- event.clientX;
108
+ resizeParams.initialWidth + resizeParams.initialClientX - clientX;
91
109
  } else {
92
110
  newWidth =
93
- resizeParams.initialWidth +
94
- event.clientX -
95
- resizeParams.initialClientX;
111
+ resizeParams.initialWidth + clientX - resizeParams.initialClientX;
96
112
  }
97
113
  }
98
114
 
@@ -109,7 +125,7 @@ export const createResizableFileBlockWrapper = (
109
125
  };
110
126
  // Stops mouse movements from resizing the element and updates the block's
111
127
  // `width` prop to the new value.
112
- const windowMouseUpHandler = (event: MouseEvent) => {
128
+ const windowMouseUpHandler = (event: MouseEvent | TouchEvent) => {
113
129
  // Hides the drag handles if the cursor is no longer over the element.
114
130
  if (
115
131
  (!event.target ||
@@ -172,62 +188,90 @@ export const createResizableFileBlockWrapper = (
172
188
 
173
189
  // Sets the resize params, allowing the user to begin resizing the element by
174
190
  // moving the cursor left or right.
175
- const leftResizeHandleMouseDownHandler = (event: MouseEvent) => {
191
+ const leftResizeHandleMouseDownHandler = (event: MouseEvent | TouchEvent) => {
176
192
  event.preventDefault();
177
193
 
178
194
  if (!wrapper.contains(eventCaptureElement)) {
179
195
  wrapper.appendChild(eventCaptureElement);
180
196
  }
181
197
 
198
+ const clientX =
199
+ "touches" in event ? event.touches[0].clientX : event.clientX;
200
+
182
201
  resizeParams = {
183
202
  handleUsed: "left",
184
203
  initialWidth: wrapper.clientWidth,
185
- initialClientX: event.clientX,
204
+ initialClientX: clientX,
186
205
  };
187
206
  };
188
- const rightResizeHandleMouseDownHandler = (event: MouseEvent) => {
207
+ const rightResizeHandleMouseDownHandler = (
208
+ event: MouseEvent | TouchEvent,
209
+ ) => {
189
210
  event.preventDefault();
190
211
 
191
212
  if (!wrapper.contains(eventCaptureElement)) {
192
213
  wrapper.appendChild(eventCaptureElement);
193
214
  }
194
215
 
216
+ const clientX =
217
+ "touches" in event ? event.touches[0].clientX : event.clientX;
218
+
195
219
  resizeParams = {
196
220
  handleUsed: "right",
197
221
  initialWidth: wrapper.clientWidth,
198
- initialClientX: event.clientX,
222
+ initialClientX: clientX,
199
223
  };
200
224
  };
201
225
 
202
226
  window.addEventListener("mousemove", windowMouseMoveHandler);
227
+ window.addEventListener("touchmove", windowMouseMoveHandler);
203
228
  window.addEventListener("mouseup", windowMouseUpHandler);
229
+ window.addEventListener("touchend", windowMouseUpHandler);
204
230
  wrapper.addEventListener("mouseenter", wrapperMouseEnterHandler);
205
231
  wrapper.addEventListener("mouseleave", wrapperMouseLeaveHandler);
206
232
  leftResizeHandle.addEventListener(
207
233
  "mousedown",
208
234
  leftResizeHandleMouseDownHandler,
209
235
  );
236
+ leftResizeHandle.addEventListener(
237
+ "touchstart",
238
+ leftResizeHandleMouseDownHandler,
239
+ );
210
240
  rightResizeHandle.addEventListener(
211
241
  "mousedown",
212
242
  rightResizeHandleMouseDownHandler,
213
243
  );
244
+ rightResizeHandle.addEventListener(
245
+ "touchstart",
246
+ rightResizeHandleMouseDownHandler,
247
+ );
214
248
 
215
249
  return {
216
250
  dom: wrapper,
217
251
  destroy: () => {
218
252
  destroy?.();
219
253
  window.removeEventListener("mousemove", windowMouseMoveHandler);
254
+ window.removeEventListener("touchmove", windowMouseMoveHandler);
220
255
  window.removeEventListener("mouseup", windowMouseUpHandler);
256
+ window.removeEventListener("touchend", windowMouseUpHandler);
221
257
  wrapper.removeEventListener("mouseenter", wrapperMouseEnterHandler);
222
258
  wrapper.removeEventListener("mouseleave", wrapperMouseLeaveHandler);
223
259
  leftResizeHandle.removeEventListener(
224
260
  "mousedown",
225
261
  leftResizeHandleMouseDownHandler,
226
262
  );
263
+ leftResizeHandle.removeEventListener(
264
+ "touchstart",
265
+ leftResizeHandleMouseDownHandler,
266
+ );
227
267
  rightResizeHandle.removeEventListener(
228
268
  "mousedown",
229
269
  rightResizeHandleMouseDownHandler,
230
270
  );
271
+ rightResizeHandle.removeEventListener(
272
+ "touchstart",
273
+ rightResizeHandleMouseDownHandler,
274
+ );
231
275
  },
232
276
  };
233
277
  };
@@ -0,0 +1,138 @@
1
+ import { createBlockConfig, createBlockSpec } from "../../schema/index.js";
2
+ import { createBlockNoteExtension } from "../../editor/BlockNoteExtension.js";
3
+ import {
4
+ addDefaultPropsExternalHTML,
5
+ defaultProps,
6
+ parseDefaultProps,
7
+ } from "../defaultProps.js";
8
+ import { createToggleWrapper } from "../ToggleWrapper/createToggleWrapper.js";
9
+
10
+ const HEADING_LEVELS = [1, 2, 3, 4, 5, 6] as const;
11
+
12
+ export interface HeadingOptions {
13
+ defaultLevel?: (typeof HEADING_LEVELS)[number];
14
+ levels?: readonly number[];
15
+ // TODO should probably use composition instead of this
16
+ allowToggleHeadings?: boolean;
17
+ }
18
+
19
+ export type HeadingBlockConfig = ReturnType<typeof createHeadingBlockConfig>;
20
+
21
+ export const createHeadingBlockConfig = createBlockConfig(
22
+ ({
23
+ defaultLevel = 1,
24
+ levels = HEADING_LEVELS,
25
+ allowToggleHeadings = true,
26
+ }: HeadingOptions = {}) =>
27
+ ({
28
+ type: "heading" as const,
29
+ propSchema: {
30
+ ...defaultProps,
31
+ level: { default: defaultLevel, values: levels },
32
+ ...(allowToggleHeadings
33
+ ? { isToggleable: { default: false, optional: true } as const }
34
+ : {}),
35
+ },
36
+ content: "inline",
37
+ }) as const,
38
+ );
39
+
40
+ export const createHeadingBlockSpec = createBlockSpec(
41
+ createHeadingBlockConfig,
42
+ ({ allowToggleHeadings = true }: HeadingOptions = {}) => ({
43
+ meta: {
44
+ isolating: false,
45
+ },
46
+ parse(e) {
47
+ let level: number;
48
+ switch (e.tagName) {
49
+ case "H1":
50
+ level = 1;
51
+ break;
52
+ case "H2":
53
+ level = 2;
54
+ break;
55
+ case "H3":
56
+ level = 3;
57
+ break;
58
+ case "H4":
59
+ level = 4;
60
+ break;
61
+ case "H5":
62
+ level = 5;
63
+ break;
64
+ case "H6":
65
+ level = 6;
66
+ break;
67
+ default:
68
+ return undefined;
69
+ }
70
+
71
+ return {
72
+ ...parseDefaultProps(e),
73
+ level,
74
+ };
75
+ },
76
+ render(block, editor) {
77
+ const dom = document.createElement(`h${block.props.level}`);
78
+
79
+ if (allowToggleHeadings) {
80
+ const toggleWrapper = createToggleWrapper(block, editor, dom);
81
+ return { ...toggleWrapper, contentDOM: dom };
82
+ }
83
+
84
+ return {
85
+ dom,
86
+ contentDOM: dom,
87
+ };
88
+ },
89
+ toExternalHTML(block) {
90
+ const dom = document.createElement(`h${block.props.level}`);
91
+ addDefaultPropsExternalHTML(block.props, dom);
92
+
93
+ return {
94
+ dom,
95
+ contentDOM: dom,
96
+ };
97
+ },
98
+ }),
99
+ ({ levels = HEADING_LEVELS }: HeadingOptions = {}) => [
100
+ createBlockNoteExtension({
101
+ key: "heading-shortcuts",
102
+ keyboardShortcuts: Object.fromEntries(
103
+ levels.map((level) => [
104
+ `Mod-Alt-${level}`,
105
+ ({ editor }) => {
106
+ const cursorPosition = editor.getTextCursorPosition();
107
+
108
+ if (
109
+ editor.schema.blockSchema[cursorPosition.block.type].content !==
110
+ "inline"
111
+ ) {
112
+ return false;
113
+ }
114
+
115
+ editor.updateBlock(cursorPosition.block, {
116
+ type: "heading",
117
+ props: {
118
+ level: level as any,
119
+ },
120
+ });
121
+ return true;
122
+ },
123
+ ]) ?? [],
124
+ ),
125
+ inputRules: levels.map((level) => ({
126
+ find: new RegExp(`^(#{${level}})\\s$`),
127
+ replace({ match }: { match: RegExpMatchArray }) {
128
+ return {
129
+ type: "heading",
130
+ props: {
131
+ level: match[1].length,
132
+ },
133
+ };
134
+ },
135
+ })),
136
+ }),
137
+ ],
138
+ );
@@ -0,0 +1,190 @@
1
+ import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
2
+ import {
3
+ BlockFromConfig,
4
+ createBlockConfig,
5
+ createBlockSpec,
6
+ } from "../../schema/index.js";
7
+ import { defaultProps, parseDefaultProps } from "../defaultProps.js";
8
+ import { parseFigureElement } from "../File/helpers/parse/parseFigureElement.js";
9
+ import { createResizableFileBlockWrapper } from "../File/helpers/render/createResizableFileBlockWrapper.js";
10
+ import { createFigureWithCaption } from "../File/helpers/toExternalHTML/createFigureWithCaption.js";
11
+ import { createLinkWithCaption } from "../File/helpers/toExternalHTML/createLinkWithCaption.js";
12
+ import { parseImageElement } from "./parseImageElement.js";
13
+
14
+ export const FILE_IMAGE_ICON_SVG =
15
+ '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5 11.1005L7 9.1005L12.5 14.6005L16 11.1005L19 14.1005V5H5V11.1005ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10Z"></path></svg>';
16
+
17
+ export interface ImageOptions {
18
+ icon?: string;
19
+ }
20
+
21
+ export type ImageBlockConfig = ReturnType<typeof createImageBlockConfig>;
22
+
23
+ export const createImageBlockConfig = createBlockConfig(
24
+ (_ctx: ImageOptions = {}) =>
25
+ ({
26
+ type: "image" as const,
27
+ propSchema: {
28
+ textAlignment: defaultProps.textAlignment,
29
+ backgroundColor: defaultProps.backgroundColor,
30
+ // File name.
31
+ name: {
32
+ default: "" as const,
33
+ },
34
+ // File url.
35
+ url: {
36
+ default: "" as const,
37
+ },
38
+ // File caption.
39
+ caption: {
40
+ default: "" as const,
41
+ },
42
+
43
+ showPreview: {
44
+ default: true,
45
+ },
46
+ // File preview width in px.
47
+ previewWidth: {
48
+ default: undefined,
49
+ type: "number" as const,
50
+ },
51
+ },
52
+ content: "none" as const,
53
+ }) as const,
54
+ );
55
+
56
+ export const imageParse =
57
+ (_config: ImageOptions = {}) =>
58
+ (element: HTMLElement) => {
59
+ if (element.tagName === "IMG") {
60
+ // Ignore if parent figure has already been parsed.
61
+ if (element.closest("figure")) {
62
+ return undefined;
63
+ }
64
+
65
+ const { backgroundColor } = parseDefaultProps(element);
66
+
67
+ return {
68
+ ...parseImageElement(element as HTMLImageElement),
69
+ backgroundColor,
70
+ };
71
+ }
72
+
73
+ if (element.tagName === "FIGURE") {
74
+ const parsedFigure = parseFigureElement(element, "img");
75
+ if (!parsedFigure) {
76
+ return undefined;
77
+ }
78
+
79
+ const { targetElement, caption } = parsedFigure;
80
+
81
+ const { backgroundColor } = parseDefaultProps(element);
82
+
83
+ return {
84
+ ...parseImageElement(targetElement as HTMLImageElement),
85
+ backgroundColor,
86
+ caption,
87
+ };
88
+ }
89
+
90
+ return undefined;
91
+ };
92
+
93
+ export const imageRender =
94
+ (config: ImageOptions = {}) =>
95
+ (
96
+ block: BlockFromConfig<ReturnType<typeof createImageBlockConfig>, any, any>,
97
+ editor: BlockNoteEditor<
98
+ Record<"image", ReturnType<typeof createImageBlockConfig>>,
99
+ any,
100
+ any
101
+ >,
102
+ ) => {
103
+ const icon = document.createElement("div");
104
+ icon.innerHTML = config.icon ?? FILE_IMAGE_ICON_SVG;
105
+
106
+ const imageWrapper = document.createElement("div");
107
+ imageWrapper.className = "bn-visual-media-wrapper";
108
+
109
+ const image = document.createElement("img");
110
+ image.className = "bn-visual-media";
111
+ if (editor.resolveFileUrl) {
112
+ editor.resolveFileUrl(block.props.url).then((downloadUrl) => {
113
+ image.src = downloadUrl;
114
+ });
115
+ } else {
116
+ image.src = block.props.url;
117
+ }
118
+
119
+ image.alt = block.props.name || block.props.caption || "BlockNote image";
120
+ image.contentEditable = "false";
121
+ image.draggable = false;
122
+ imageWrapper.appendChild(image);
123
+
124
+ return createResizableFileBlockWrapper(
125
+ block,
126
+ editor,
127
+ { dom: imageWrapper },
128
+ imageWrapper,
129
+ icon.firstElementChild as HTMLElement,
130
+ );
131
+ };
132
+
133
+ export const imageToExternalHTML =
134
+ (_config: ImageOptions = {}) =>
135
+ (
136
+ block: BlockFromConfig<ReturnType<typeof createImageBlockConfig>, any, any>,
137
+ _editor: BlockNoteEditor<
138
+ Record<"image", ReturnType<typeof createImageBlockConfig>>,
139
+ any,
140
+ any
141
+ >,
142
+ ) => {
143
+ if (!block.props.url) {
144
+ const div = document.createElement("p");
145
+ div.textContent = "Add image";
146
+
147
+ return {
148
+ dom: div,
149
+ };
150
+ }
151
+
152
+ let image;
153
+ if (block.props.showPreview) {
154
+ image = document.createElement("img");
155
+ image.src = block.props.url;
156
+ image.alt = block.props.name || block.props.caption || "BlockNote image";
157
+ if (block.props.previewWidth) {
158
+ image.width = block.props.previewWidth;
159
+ }
160
+ } else {
161
+ image = document.createElement("a");
162
+ image.href = block.props.url;
163
+ image.textContent = block.props.name || block.props.url;
164
+ }
165
+
166
+ if (block.props.caption) {
167
+ if (block.props.showPreview) {
168
+ return createFigureWithCaption(image, block.props.caption);
169
+ } else {
170
+ return createLinkWithCaption(image, block.props.caption);
171
+ }
172
+ }
173
+
174
+ return {
175
+ dom: image,
176
+ };
177
+ };
178
+
179
+ export const createImageBlockSpec = createBlockSpec(
180
+ createImageBlockConfig,
181
+ (config) => ({
182
+ meta: {
183
+ fileBlockAccept: ["image/*"],
184
+ },
185
+ parse: imageParse(config),
186
+ render: imageRender(config),
187
+ toExternalHTML: imageToExternalHTML(config),
188
+ runsBefore: ["file"],
189
+ }),
190
+ );
@@ -0,0 +1,116 @@
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
+ import { handleEnter } from "../../utils/listItemEnterHandler.js";
9
+ import { getListItemContent } from "../getListItemContent.js";
10
+
11
+ export type BulletListItemBlockConfig = ReturnType<
12
+ typeof createBulletListItemBlockConfig
13
+ >;
14
+
15
+ export const createBulletListItemBlockConfig = createBlockConfig(
16
+ () =>
17
+ ({
18
+ type: "bulletListItem" as const,
19
+ propSchema: {
20
+ ...defaultProps,
21
+ },
22
+ content: "inline",
23
+ }) as const,
24
+ );
25
+
26
+ export const createBulletListItemBlockSpec = createBlockSpec(
27
+ createBulletListItemBlockConfig,
28
+ {
29
+ meta: {
30
+ isolating: false,
31
+ },
32
+ parse(element) {
33
+ if (element.tagName !== "LI") {
34
+ return undefined;
35
+ }
36
+
37
+ const parent = element.parentElement;
38
+
39
+ if (parent === null) {
40
+ return undefined;
41
+ }
42
+
43
+ if (
44
+ parent.tagName === "UL" ||
45
+ (parent.tagName === "DIV" && parent.parentElement?.tagName === "UL")
46
+ ) {
47
+ return parseDefaultProps(element);
48
+ }
49
+
50
+ return undefined;
51
+ },
52
+ // As `li` elements can contain multiple paragraphs, we need to merge their contents
53
+ // into a single one so that ProseMirror can parse everything correctly.
54
+ parseContent: ({ el, schema }) =>
55
+ getListItemContent(el, schema, "bulletListItem"),
56
+ render() {
57
+ // We use a <p> tag, because for <li> tags we'd need a <ul> element to put
58
+ // them in to be semantically correct, which we can't have due to the
59
+ // schema.
60
+ const dom = document.createElement("p");
61
+
62
+ return {
63
+ dom,
64
+ contentDOM: dom,
65
+ };
66
+ },
67
+ toExternalHTML(block) {
68
+ const li = document.createElement("li");
69
+ const p = document.createElement("p");
70
+ addDefaultPropsExternalHTML(block.props, li);
71
+ li.appendChild(p);
72
+
73
+ return {
74
+ dom: li,
75
+ contentDOM: p,
76
+ };
77
+ },
78
+ },
79
+ [
80
+ createBlockNoteExtension({
81
+ key: "bullet-list-item-shortcuts",
82
+ keyboardShortcuts: {
83
+ Enter: ({ editor }) => {
84
+ return handleEnter(editor, "bulletListItem");
85
+ },
86
+ "Mod-Shift-8": ({ editor }) => {
87
+ const cursorPosition = editor.getTextCursorPosition();
88
+
89
+ if (
90
+ editor.schema.blockSchema[cursorPosition.block.type].content !==
91
+ "inline"
92
+ ) {
93
+ return false;
94
+ }
95
+
96
+ editor.updateBlock(cursorPosition.block, {
97
+ type: "bulletListItem",
98
+ props: {},
99
+ });
100
+ return true;
101
+ },
102
+ },
103
+ inputRules: [
104
+ {
105
+ find: new RegExp(`^[-+*]\\s$`),
106
+ replace() {
107
+ return {
108
+ type: "bulletListItem",
109
+ props: {},
110
+ };
111
+ },
112
+ },
113
+ ],
114
+ }),
115
+ ],
116
+ );