@blocknote/core 0.9.6 → 0.10.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 (367) hide show
  1. package/dist/blocknote.js +3697 -2609
  2. package/dist/blocknote.js.map +1 -1
  3. package/dist/blocknote.umd.cjs +7 -7
  4. package/dist/blocknote.umd.cjs.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/dist/webpack-stats.json +1 -0
  7. package/package.json +8 -4
  8. package/src/api/README.md +8 -0
  9. package/src/api/blockManipulation/blockManipulation.test.ts +72 -10
  10. package/src/api/blockManipulation/blockManipulation.ts +38 -18
  11. package/src/api/exporters/copyExtension.ts +68 -0
  12. package/src/api/exporters/html/__snapshots__/complex/misc/external.html +1 -0
  13. package/src/api/exporters/html/__snapshots__/complex/misc/internal.html +1 -0
  14. package/src/api/exporters/html/__snapshots__/customParagraph/basic/external.html +1 -0
  15. package/src/api/exporters/html/__snapshots__/customParagraph/basic/internal.html +1 -0
  16. package/src/api/exporters/html/__snapshots__/customParagraph/nested/external.html +1 -0
  17. package/src/api/exporters/html/__snapshots__/customParagraph/nested/internal.html +1 -0
  18. package/src/api/exporters/html/__snapshots__/customParagraph/styled/external.html +1 -0
  19. package/src/api/exporters/html/__snapshots__/customParagraph/styled/internal.html +1 -0
  20. package/src/api/exporters/html/__snapshots__/fontSize/basic/external.html +1 -0
  21. package/src/api/exporters/html/__snapshots__/fontSize/basic/internal.html +1 -0
  22. package/src/api/exporters/html/__snapshots__/hardbreak/basic/external.html +1 -0
  23. package/src/api/exporters/html/__snapshots__/hardbreak/basic/internal.html +1 -0
  24. package/src/api/exporters/html/__snapshots__/hardbreak/between-links/external.html +1 -0
  25. package/src/api/exporters/html/__snapshots__/hardbreak/between-links/internal.html +1 -0
  26. package/src/api/exporters/html/__snapshots__/hardbreak/end/external.html +1 -0
  27. package/src/api/exporters/html/__snapshots__/hardbreak/end/internal.html +1 -0
  28. package/src/api/exporters/html/__snapshots__/hardbreak/link/external.html +1 -0
  29. package/src/api/exporters/html/__snapshots__/hardbreak/link/internal.html +1 -0
  30. package/src/api/exporters/html/__snapshots__/hardbreak/multiple/external.html +1 -0
  31. package/src/api/exporters/html/__snapshots__/hardbreak/multiple/internal.html +1 -0
  32. package/src/api/exporters/html/__snapshots__/hardbreak/only/external.html +1 -0
  33. package/src/api/exporters/html/__snapshots__/hardbreak/only/internal.html +1 -0
  34. package/src/api/exporters/html/__snapshots__/hardbreak/start/external.html +1 -0
  35. package/src/api/exporters/html/__snapshots__/hardbreak/start/internal.html +1 -0
  36. package/src/api/exporters/html/__snapshots__/hardbreak/styles/external.html +1 -0
  37. package/src/api/exporters/html/__snapshots__/hardbreak/styles/internal.html +1 -0
  38. package/src/api/exporters/html/__snapshots__/image/basic/external.html +1 -0
  39. package/src/api/exporters/html/__snapshots__/image/basic/internal.html +1 -0
  40. package/src/api/exporters/html/__snapshots__/image/button/external.html +1 -0
  41. package/src/api/exporters/html/__snapshots__/image/button/internal.html +1 -0
  42. package/src/api/exporters/html/__snapshots__/image/nested/external.html +1 -0
  43. package/src/api/exporters/html/__snapshots__/image/nested/internal.html +1 -0
  44. package/src/api/exporters/html/__snapshots__/link/adjacent/external.html +1 -0
  45. package/src/api/exporters/html/__snapshots__/link/adjacent/internal.html +1 -0
  46. package/src/api/exporters/html/__snapshots__/link/basic/external.html +1 -0
  47. package/src/api/exporters/html/__snapshots__/link/basic/internal.html +1 -0
  48. package/src/api/exporters/html/__snapshots__/link/styled/external.html +1 -0
  49. package/src/api/exporters/html/__snapshots__/link/styled/internal.html +1 -0
  50. package/src/api/exporters/html/__snapshots__/mention/basic/external.html +1 -0
  51. package/src/api/exporters/html/__snapshots__/mention/basic/internal.html +1 -0
  52. package/src/api/exporters/html/__snapshots__/paragraph/basic/external.html +1 -0
  53. package/src/api/exporters/html/__snapshots__/paragraph/basic/internal.html +1 -0
  54. package/src/api/exporters/html/__snapshots__/paragraph/empty/external.html +1 -0
  55. package/src/api/exporters/html/__snapshots__/paragraph/empty/internal.html +1 -0
  56. package/src/api/exporters/html/__snapshots__/paragraph/nested/external.html +1 -0
  57. package/src/api/exporters/html/__snapshots__/paragraph/nested/internal.html +1 -0
  58. package/src/api/exporters/html/__snapshots__/paragraph/styled/external.html +1 -0
  59. package/src/api/exporters/html/__snapshots__/paragraph/styled/internal.html +1 -0
  60. package/src/api/exporters/html/__snapshots__/paste/parse-basic-block-types.json +140 -0
  61. package/src/api/exporters/html/__snapshots__/paste/parse-deep-nested-content.json +240 -0
  62. package/src/api/exporters/html/__snapshots__/paste/parse-div-with-inline-content.json +91 -0
  63. package/src/api/exporters/html/__snapshots__/paste/parse-divs.json +19 -0
  64. package/src/api/exporters/html/__snapshots__/paste/parse-fake-image-caption.json +31 -0
  65. package/src/api/exporters/html/__snapshots__/paste/parse-mixed-nested-lists.json +70 -0
  66. package/src/api/exporters/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +70 -0
  67. package/src/api/exporters/html/__snapshots__/paste/parse-nested-lists.json +70 -0
  68. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/basic/external.html +1 -0
  69. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/basic/internal.html +1 -0
  70. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/nested/external.html +1 -0
  71. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/nested/internal.html +1 -0
  72. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/styled/external.html +1 -0
  73. package/src/api/exporters/html/__snapshots__/simpleCustomParagraph/styled/internal.html +1 -0
  74. package/src/api/exporters/html/__snapshots__/simpleImage/basic/external.html +1 -0
  75. package/src/api/exporters/html/__snapshots__/simpleImage/basic/internal.html +1 -0
  76. package/src/api/exporters/html/__snapshots__/simpleImage/button/external.html +1 -0
  77. package/src/api/exporters/html/__snapshots__/simpleImage/button/internal.html +1 -0
  78. package/src/api/exporters/html/__snapshots__/simpleImage/nested/external.html +1 -0
  79. package/src/api/exporters/html/__snapshots__/simpleImage/nested/internal.html +1 -0
  80. package/src/api/exporters/html/__snapshots__/small/basic/external.html +1 -0
  81. package/src/api/exporters/html/__snapshots__/small/basic/internal.html +1 -0
  82. package/src/api/exporters/html/__snapshots__/tag/basic/external.html +1 -0
  83. package/src/api/exporters/html/__snapshots__/tag/basic/internal.html +1 -0
  84. package/src/api/exporters/html/externalHTMLExporter.ts +98 -0
  85. package/src/api/exporters/html/htmlConversion.test.ts +100 -0
  86. package/src/api/exporters/html/internalHTMLSerializer.ts +80 -0
  87. package/src/api/exporters/html/util/sharedHTMLConversion.ts +128 -0
  88. package/src/api/{formatConversions → exporters/html/util}/simplifyBlocksRehypePlugin.ts +13 -0
  89. package/src/api/exporters/markdown/__snapshots__/complex/misc/markdown.md +5 -0
  90. package/src/api/exporters/markdown/__snapshots__/customParagraph/basic/markdown.md +1 -0
  91. package/src/api/exporters/markdown/__snapshots__/customParagraph/nested/markdown.md +5 -0
  92. package/src/api/exporters/markdown/__snapshots__/customParagraph/styled/markdown.md +1 -0
  93. package/src/api/exporters/markdown/__snapshots__/fontSize/basic/markdown.md +1 -0
  94. package/src/api/exporters/markdown/__snapshots__/hardbreak/basic/markdown.md +2 -0
  95. package/src/api/exporters/markdown/__snapshots__/hardbreak/between-links/markdown.md +2 -0
  96. package/src/api/exporters/markdown/__snapshots__/hardbreak/end/markdown.md +1 -0
  97. package/src/api/exporters/markdown/__snapshots__/hardbreak/link/markdown.md +2 -0
  98. package/src/api/exporters/markdown/__snapshots__/hardbreak/multiple/markdown.md +3 -0
  99. package/src/api/exporters/markdown/__snapshots__/hardbreak/start/markdown.md +1 -0
  100. package/src/api/exporters/markdown/__snapshots__/hardbreak/styles/markdown.md +2 -0
  101. package/src/api/exporters/markdown/__snapshots__/image/basic/markdown.md +3 -0
  102. package/src/api/exporters/markdown/__snapshots__/image/button/markdown.md +1 -0
  103. package/src/api/exporters/markdown/__snapshots__/image/nested/markdown.md +7 -0
  104. package/src/api/exporters/markdown/__snapshots__/link/adjacent/markdown.md +1 -0
  105. package/src/api/exporters/markdown/__snapshots__/link/basic/markdown.md +1 -0
  106. package/src/api/exporters/markdown/__snapshots__/link/styled/markdown.md +1 -0
  107. package/src/api/exporters/markdown/__snapshots__/mention/basic/markdown.md +1 -0
  108. package/src/api/exporters/markdown/__snapshots__/paragraph/basic/markdown.md +1 -0
  109. package/src/api/exporters/markdown/__snapshots__/paragraph/empty/markdown.md +0 -0
  110. package/src/api/exporters/markdown/__snapshots__/paragraph/nested/markdown.md +5 -0
  111. package/src/api/exporters/markdown/__snapshots__/paragraph/styled/markdown.md +1 -0
  112. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/basic/markdown.md +1 -0
  113. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/nested/markdown.md +5 -0
  114. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/styled/markdown.md +1 -0
  115. package/src/api/exporters/markdown/__snapshots__/simpleImage/basic/markdown.md +1 -0
  116. package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +1 -0
  117. package/src/api/exporters/markdown/__snapshots__/simpleImage/nested/markdown.md +3 -0
  118. package/src/api/exporters/markdown/__snapshots__/small/basic/markdown.md +1 -0
  119. package/src/api/exporters/markdown/__snapshots__/tag/basic/markdown.md +1 -0
  120. package/src/api/exporters/markdown/markdownExporter.test.ts +85 -0
  121. package/src/api/exporters/markdown/markdownExporter.ts +42 -0
  122. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +486 -125
  123. package/src/api/nodeConversions/nodeConversions.test.ts +67 -498
  124. package/src/api/nodeConversions/nodeConversions.ts +311 -85
  125. package/src/api/parsers/html/__snapshots__/paste/list-test.json +105 -0
  126. package/src/api/parsers/html/__snapshots__/paste/parse-basic-block-types.json +140 -0
  127. package/src/api/parsers/html/__snapshots__/paste/parse-deep-nested-content.json +240 -0
  128. package/src/api/parsers/html/__snapshots__/paste/parse-div-with-inline-content.json +91 -0
  129. package/src/api/parsers/html/__snapshots__/paste/parse-divs.json +121 -0
  130. package/src/api/parsers/html/__snapshots__/paste/parse-fake-image-caption.json +31 -0
  131. package/src/api/parsers/html/__snapshots__/paste/parse-google-docs-html.json +476 -0
  132. package/src/api/parsers/html/__snapshots__/paste/parse-mixed-nested-lists.json +140 -0
  133. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +140 -0
  134. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists.json +157 -0
  135. package/src/api/parsers/html/__snapshots__/paste/parse-notion-html.json +470 -0
  136. package/src/api/parsers/html/__snapshots__/paste/parse-two-divs.json +36 -0
  137. package/src/api/parsers/html/parseHTML.test.ts +440 -0
  138. package/src/api/parsers/html/parseHTML.ts +42 -0
  139. package/src/api/parsers/html/util/__snapshots__/nestedLists.test.ts.snap +129 -0
  140. package/src/api/parsers/html/util/nestedLists.test.ts +176 -0
  141. package/src/api/parsers/html/util/nestedLists.ts +113 -0
  142. package/src/api/parsers/markdown/__snapshots__/complex.json +353 -0
  143. package/src/api/parsers/markdown/__snapshots__/issue-226-1.json +71 -0
  144. package/src/api/parsers/markdown/__snapshots__/issue-226-2.json +144 -0
  145. package/src/api/parsers/markdown/__snapshots__/nested.json +72 -0
  146. package/src/api/parsers/markdown/__snapshots__/non-nested.json +71 -0
  147. package/src/api/parsers/markdown/__snapshots__/styled.json +58 -0
  148. package/src/api/parsers/markdown/parseMarkdown.test.ts +114 -0
  149. package/src/api/parsers/markdown/parseMarkdown.ts +84 -0
  150. package/src/api/parsers/pasteExtension.ts +59 -0
  151. package/src/api/testUtil/cases/customBlocks.ts +282 -0
  152. package/src/api/testUtil/cases/customInlineContent.ts +114 -0
  153. package/src/api/testUtil/cases/customStyles.ts +100 -0
  154. package/src/api/testUtil/cases/defaultSchema.ts +399 -0
  155. package/src/api/testUtil/index.ts +17 -0
  156. package/src/api/testUtil/partialBlockTestUtil.ts +127 -0
  157. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +136 -0
  158. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/ImageBlockContent.ts +87 -31
  159. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +34 -47
  160. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  161. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  162. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +34 -56
  163. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +43 -0
  164. package/src/blocks/README.md +3 -0
  165. package/src/blocks/TableBlockContent/TableBlockContent.ts +74 -0
  166. package/src/blocks/TableBlockContent/TableExtension.ts +63 -0
  167. package/src/blocks/defaultBlockHelpers.ts +95 -0
  168. package/src/blocks/defaultBlocks.ts +60 -0
  169. package/src/blocks/defaultProps.ts +24 -0
  170. package/src/{extensions/Blocks/nodes/Block.module.css → editor/Block.css} +69 -62
  171. package/src/{BlockNoteEditor.test.ts → editor/BlockNoteEditor.test.ts} +2 -2
  172. package/src/{BlockNoteEditor.ts → editor/BlockNoteEditor.ts} +364 -153
  173. package/src/{BlockNoteExtensions.ts → editor/BlockNoteExtensions.ts} +59 -40
  174. package/src/editor/README.md +3 -0
  175. package/src/editor/cursorPositionTypes.ts +16 -0
  176. package/src/{editor.module.css → editor/editor.css} +42 -15
  177. package/src/editor/selectionTypes.ts +14 -0
  178. package/src/editor/transformPasted.ts +58 -0
  179. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +1 -36
  180. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +12 -27
  181. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +16 -24
  182. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +12 -10
  183. package/src/extensions/ImageToolbar/ImageToolbarPlugin.ts +35 -73
  184. package/src/extensions/Placeholder/PlaceholderExtension.ts +4 -4
  185. package/src/extensions/README.md +3 -0
  186. package/src/extensions/SideMenu/SideMenuPlugin.ts +66 -37
  187. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +7 -6
  188. package/src/extensions/SlashMenu/SlashMenuPlugin.ts +9 -7
  189. package/src/extensions/SlashMenu/defaultSlashMenuItems.ts +98 -35
  190. package/src/extensions/TableHandles/TableHandlesPlugin.ts +617 -0
  191. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +3 -51
  192. package/src/extensions/TextColor/TextColorExtension.ts +1 -29
  193. package/src/extensions/TextColor/TextColorMark.ts +7 -27
  194. package/src/extensions/UniqueID/UniqueID.ts +28 -2
  195. package/src/extensions-shared/README.md +3 -0
  196. package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionPlugin.ts +19 -13
  197. package/src/index.ts +21 -15
  198. package/src/{extensions/Blocks/nodes → pm-nodes}/BlockContainer.ts +161 -96
  199. package/src/pm-nodes/BlockGroup.ts +54 -0
  200. package/src/pm-nodes/Doc.ts +7 -0
  201. package/src/pm-nodes/README.md +42 -0
  202. package/src/pm-nodes/index.ts +3 -0
  203. package/src/schema/README.md +3 -0
  204. package/src/schema/blocks/createSpec.ts +220 -0
  205. package/src/schema/blocks/internal.ts +253 -0
  206. package/src/schema/blocks/types.ts +252 -0
  207. package/src/schema/index.ts +10 -0
  208. package/src/schema/inlineContent/createSpec.ts +119 -0
  209. package/src/schema/inlineContent/internal.ts +105 -0
  210. package/src/schema/inlineContent/types.ts +144 -0
  211. package/src/schema/propTypes.ts +32 -0
  212. package/src/schema/styles/createSpec.ts +85 -0
  213. package/src/schema/styles/internal.ts +96 -0
  214. package/src/schema/styles/types.ts +42 -0
  215. package/src/util/README.md +3 -0
  216. package/src/{shared/utils.ts → util/browser.ts} +4 -8
  217. package/src/util/string.ts +3 -0
  218. package/src/util/typescript.ts +5 -0
  219. package/types/src/BlockNoteEditor.d.ts +49 -36
  220. package/types/src/BlockNoteExtensions.d.ts +8 -3
  221. package/types/src/api/blockManipulation/blockManipulation.d.ts +5 -4
  222. package/types/src/api/exporters/copyExtension.d.ts +6 -0
  223. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +8 -0
  224. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +8 -0
  225. package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +7 -0
  226. package/types/src/api/exporters/markdown/markdownExporter.d.ts +5 -0
  227. package/types/src/api/exporters/markdown/markdownExporter.test.d.ts +1 -0
  228. package/types/src/api/getBlockInfoFromPos.d.ts +27 -0
  229. package/types/src/api/nodeConversions/nodeConversions.d.ts +14 -6
  230. package/types/src/api/nodeConversions/testUtil.d.ts +7 -2
  231. package/types/src/api/nodeUtil.d.ts +8 -0
  232. package/types/src/api/parsers/html/parseHTML.d.ts +3 -0
  233. package/types/src/api/parsers/html/parseHTML.test.d.ts +1 -0
  234. package/types/src/api/parsers/html/util/nestedLists.d.ts +1 -0
  235. package/types/src/api/parsers/html/util/nestedLists.test.d.ts +1 -0
  236. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +3 -0
  237. package/types/src/api/parsers/markdown/parseMarkdown.test.d.ts +1 -0
  238. package/types/src/api/parsers/pasteExtension.d.ts +6 -0
  239. package/types/src/api/testCases/cases/customBlocks.d.ts +345 -0
  240. package/types/src/api/testCases/cases/customInlineContent.d.ts +29 -0
  241. package/types/src/api/testCases/cases/customStyles.d.ts +64 -0
  242. package/types/src/api/testCases/cases/defaultSchema.d.ts +3 -0
  243. package/types/src/api/testCases/index.d.ts +12 -0
  244. package/types/src/api/testUtil/cases/customBlocks.d.ts +345 -0
  245. package/types/src/api/testUtil/cases/customInlineContent.d.ts +29 -0
  246. package/types/src/api/testUtil/cases/customStyles.d.ts +64 -0
  247. package/types/src/api/testUtil/cases/defaultSchema.d.ts +3 -0
  248. package/types/src/api/testUtil/index.d.ts +12 -0
  249. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +7 -0
  250. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +58 -0
  251. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +93 -0
  252. package/types/src/blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +1 -0
  253. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +46 -0
  254. package/types/src/blocks/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +2 -0
  255. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +2 -0
  256. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +46 -0
  257. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +52 -0
  258. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +53 -0
  259. package/types/src/blocks/TableBlockContent/TableExtension.d.ts +2 -0
  260. package/types/src/blocks/defaultBlockHelpers.d.ts +10 -0
  261. package/types/src/blocks/defaultBlocks.d.ts +577 -0
  262. package/types/src/blocks/defaultProps.d.ts +15 -0
  263. package/types/src/editor/BlockNoteEditor.d.ts +299 -0
  264. package/types/src/editor/BlockNoteEditor.test.d.ts +1 -0
  265. package/types/src/editor/BlockNoteExtensions.d.ts +24 -0
  266. package/types/src/editor/cursorPositionTypes.d.ts +6 -0
  267. package/types/src/editor/selectionTypes.d.ts +4 -0
  268. package/types/src/editor/transformPasted.d.ts +12 -0
  269. package/types/src/extensions/BackgroundColor/BackgroundColorExtension.d.ts +0 -7
  270. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +7 -9
  271. package/types/src/extensions/Blocks/api/blocks/createSpec.d.ts +35 -0
  272. package/types/src/extensions/Blocks/api/blocks/internal.d.ts +45 -0
  273. package/types/src/extensions/Blocks/api/blocks/types.d.ts +114 -0
  274. package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +7 -5
  275. package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +573 -113
  276. package/types/src/extensions/Blocks/api/defaultProps.d.ts +2 -1
  277. package/types/src/extensions/Blocks/api/inlineContent/createSpec.d.ts +21 -0
  278. package/types/src/extensions/Blocks/api/inlineContent/internal.d.ts +25 -0
  279. package/types/src/extensions/Blocks/api/inlineContent/types.d.ts +62 -0
  280. package/types/src/extensions/Blocks/api/selectionTypes.d.ts +5 -3
  281. package/types/src/extensions/Blocks/api/styles/createSpec.d.ts +13 -0
  282. package/types/src/extensions/Blocks/api/styles/internal.d.ts +22 -0
  283. package/types/src/extensions/Blocks/api/styles/types.d.ts +21 -0
  284. package/types/src/extensions/Blocks/nodes/BlockContainer.d.ts +8 -4
  285. package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +38 -23
  286. package/types/src/extensions/Blocks/nodes/BlockContent/ImageBlockContent/ImageBlockContent.d.ts +75 -17
  287. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +30 -19
  288. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +30 -19
  289. package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +36 -28
  290. package/types/src/extensions/Blocks/nodes/BlockContent/TableBlockContent/TableBlockContent.d.ts +53 -0
  291. package/types/src/extensions/Blocks/nodes/BlockContent/TableBlockContent/TableExtension.d.ts +2 -0
  292. package/types/src/extensions/Blocks/nodes/BlockContent/defaultBlockHelpers.d.ts +12 -0
  293. package/types/src/extensions/Blocks/nodes/BlockGroup.d.ts +1 -1
  294. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +8 -6
  295. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +6 -6
  296. package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +11 -16
  297. package/types/src/extensions/NonEditableBlocks/NonEditableBlockPlugin.d.ts +2 -0
  298. package/types/src/extensions/PreviousBlockType/PreviousBlockTypePlugin.d.ts +14 -0
  299. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +18 -11
  300. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +5 -6
  301. package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +6 -6
  302. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +2 -1
  303. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +74 -0
  304. package/types/src/extensions/TextAlignment/TextAlignmentExtension.d.ts +0 -7
  305. package/types/src/extensions/TextColor/TextColorExtension.d.ts +0 -7
  306. package/types/src/extensions/TextColor/TextColorMark.d.ts +7 -9
  307. package/types/src/extensions/UniqueID/UniqueID.d.ts +1 -1
  308. package/types/src/extensions-shared/BaseUiElementTypes.d.ts +7 -0
  309. package/types/src/extensions-shared/suggestion/SuggestionItem.d.ts +3 -0
  310. package/types/src/extensions-shared/suggestion/SuggestionPlugin.d.ts +36 -0
  311. package/types/src/index.d.ts +20 -15
  312. package/types/src/pm-nodes/BlockContainer.d.ts +28 -0
  313. package/types/src/pm-nodes/BlockGroup.d.ts +10 -0
  314. package/types/src/pm-nodes/Doc.d.ts +2 -0
  315. package/types/src/pm-nodes/index.d.ts +3 -0
  316. package/types/src/schema/blocks/createSpec.d.ts +35 -0
  317. package/types/src/schema/blocks/internal.d.ts +45 -0
  318. package/types/src/schema/blocks/types.d.ts +107 -0
  319. package/types/src/schema/index.d.ts +10 -0
  320. package/types/src/schema/inlineContent/createSpec.d.ts +21 -0
  321. package/types/src/schema/inlineContent/internal.d.ts +28 -0
  322. package/types/src/schema/inlineContent/types.d.ts +62 -0
  323. package/types/src/schema/propTypes.d.ts +8 -0
  324. package/types/src/schema/styles/createSpec.d.ts +13 -0
  325. package/types/src/schema/styles/internal.d.ts +22 -0
  326. package/types/src/schema/styles/types.d.ts +21 -0
  327. package/types/src/shared/plugins/suggestion/SuggestionPlugin.d.ts +4 -2
  328. package/types/src/util/EventEmitter.d.ts +11 -0
  329. package/types/src/util/browser.d.ts +3 -0
  330. package/types/src/util/string.d.ts +1 -0
  331. package/types/src/util/typescript.d.ts +3 -0
  332. package/src/api/formatConversions/__snapshots__/formatConversions.test.ts.snap +0 -346
  333. package/src/api/formatConversions/formatConversions.test.ts +0 -753
  334. package/src/api/formatConversions/formatConversions.ts +0 -133
  335. package/src/api/nodeConversions/testUtil.ts +0 -65
  336. package/src/extensions/Blocks/api/block.ts +0 -307
  337. package/src/extensions/Blocks/api/blockTypes.ts +0 -249
  338. package/src/extensions/Blocks/api/cursorPositionTypes.ts +0 -7
  339. package/src/extensions/Blocks/api/defaultBlocks.ts +0 -16
  340. package/src/extensions/Blocks/api/defaultProps.ts +0 -16
  341. package/src/extensions/Blocks/api/inlineContentTypes.ts +0 -36
  342. package/src/extensions/Blocks/api/selectionTypes.ts +0 -5
  343. package/src/extensions/Blocks/api/serialization.ts +0 -29
  344. package/src/extensions/Blocks/helpers/findBlock.ts +0 -5
  345. package/src/extensions/Blocks/index.ts +0 -8
  346. package/src/extensions/Blocks/nodes/BlockAttributes.ts +0 -10
  347. package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +0 -142
  348. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +0 -62
  349. package/src/extensions/Blocks/nodes/BlockGroup.ts +0 -53
  350. package/types/src/api/formatConversions/formatConversions.d.ts +0 -6
  351. package/types/src/extensions/Blocks/api/block.d.ts +0 -20
  352. package/types/src/extensions/Blocks/api/blockTypes.d.ts +0 -103
  353. package/types/src/extensions/Blocks/api/inlineContentTypes.d.ts +0 -30
  354. package/types/src/extensions/Blocks/api/serialization.d.ts +0 -2
  355. /package/src/{shared/EditorElement.ts → api/exporters/markdown/__snapshots__/hardbreak/only/markdown.md} +0 -0
  356. /package/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.ts +0 -0
  357. /package/src/{extensions/Blocks/helpers → api}/getBlockInfoFromPos.ts +0 -0
  358. /package/src/api/{util/nodeUtil.ts → nodeUtil.ts} +0 -0
  359. /package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  360. /package/src/extensions/{Blocks → NonEditableBlocks}/NonEditableBlockPlugin.ts +0 -0
  361. /package/src/extensions/{Blocks → PreviousBlockType}/PreviousBlockTypePlugin.ts +0 -0
  362. /package/src/{shared → extensions-shared}/BaseUiElementTypes.ts +0 -0
  363. /package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionItem.ts +0 -0
  364. /package/src/{shared → util}/EventEmitter.ts +0 -0
  365. /package/types/src/api/{formatConversions/formatConversions.test.d.ts → exporters/html/htmlConversion.test.d.ts} +0 -0
  366. /package/types/src/api/{formatConversions → exporters/html/util}/simplifyBlocksRehypePlugin.d.ts +0 -0
  367. /package/types/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.d.ts +0 -0
@@ -1,14 +1,5 @@
1
1
  import { Extension } from "@tiptap/core";
2
- import { getBlockInfoFromPos } from "../Blocks/helpers/getBlockInfoFromPos";
3
- import { defaultProps } from "../Blocks/api/defaultProps";
4
-
5
- declare module "@tiptap/core" {
6
- interface Commands<ReturnType> {
7
- blockTextColor: {
8
- setBlockTextColor: (posInBlock: number, color: string) => ReturnType;
9
- };
10
- }
11
- }
2
+ import { defaultProps } from "../../blocks/defaultProps";
12
3
 
13
4
  export const TextColorExtension = Extension.create({
14
5
  name: "blockTextColor",
@@ -33,23 +24,4 @@ export const TextColorExtension = Extension.create({
33
24
  },
34
25
  ];
35
26
  },
36
-
37
- addCommands() {
38
- return {
39
- setBlockTextColor:
40
- (posInBlock, color) =>
41
- ({ state, view }) => {
42
- const blockInfo = getBlockInfoFromPos(state.doc, posInBlock);
43
- if (blockInfo === undefined) {
44
- return false;
45
- }
46
-
47
- state.tr.setNodeAttribute(blockInfo.startPos - 1, "textColor", color);
48
-
49
- view.focus();
50
-
51
- return true;
52
- },
53
- };
54
- },
55
27
  });
@@ -1,24 +1,16 @@
1
1
  import { Mark } from "@tiptap/core";
2
- import { defaultProps } from "../Blocks/api/defaultProps";
2
+ import { createStyleSpecFromTipTapMark } from "../../schema";
3
3
 
4
- declare module "@tiptap/core" {
5
- interface Commands<ReturnType> {
6
- textColor: {
7
- setTextColor: (color: string) => ReturnType;
8
- };
9
- }
10
- }
11
-
12
- export const TextColorMark = Mark.create({
4
+ const TextColorMark = Mark.create({
13
5
  name: "textColor",
14
6
 
15
7
  addAttributes() {
16
8
  return {
17
- color: {
9
+ stringValue: {
18
10
  default: undefined,
19
11
  parseHTML: (element) => element.getAttribute("data-text-color"),
20
12
  renderHTML: (attributes) => ({
21
- "data-text-color": attributes.color,
13
+ "data-text-color": attributes.stringValue,
22
14
  }),
23
15
  },
24
16
  };
@@ -34,7 +26,7 @@ export const TextColorMark = Mark.create({
34
26
  }
35
27
 
36
28
  if (element.hasAttribute("data-text-color")) {
37
- return { color: element.getAttribute("data-text-color") };
29
+ return { stringValue: element.getAttribute("data-text-color") };
38
30
  }
39
31
 
40
32
  return false;
@@ -46,18 +38,6 @@ export const TextColorMark = Mark.create({
46
38
  renderHTML({ HTMLAttributes }) {
47
39
  return ["span", HTMLAttributes, 0];
48
40
  },
49
-
50
- addCommands() {
51
- return {
52
- setTextColor:
53
- (color) =>
54
- ({ commands }) => {
55
- if (color !== defaultProps.textColor.default) {
56
- return commands.setMark(this.name, { color: color });
57
- }
58
-
59
- return commands.unsetMark(this.name);
60
- },
61
- };
62
- },
63
41
  });
42
+
43
+ export const TextColor = createStyleSpecFromTipTapMark(TextColorMark, "string");
@@ -172,6 +172,33 @@ const UniqueID = Extension.create({
172
172
  ? void 0
173
173
  : _a.attrs[attributeName];
174
174
  if (id === null) {
175
+ // edge case, when using collaboration, yjs will set the id to null in `_forceRerender`
176
+ // when loading the editor
177
+ // this checks for this case and keeps it at initialBlockId so there will be no change
178
+ const initialDoc = oldState.doc.type.createAndFill()!.content;
179
+ const wasInitial =
180
+ oldState.doc.content.findDiffStart(initialDoc) === null;
181
+
182
+ if (wasInitial) {
183
+ // the old state was the "initial content"
184
+ const jsonNode = JSON.parse(
185
+ JSON.stringify(newState.doc.toJSON())
186
+ );
187
+ jsonNode.content[0].content[0].attrs.id = "initialBlockId";
188
+ // would the new state with the fix also be the "initial content"?
189
+ if (
190
+ JSON.stringify(jsonNode.content) ===
191
+ JSON.stringify(initialDoc.toJSON())
192
+ ) {
193
+ // yes, apply the fix
194
+ tr.setNodeMarkup(pos, undefined, {
195
+ ...node.attrs,
196
+ [attributeName]: "initialBlockId",
197
+ });
198
+ return;
199
+ }
200
+ }
201
+
175
202
  tr.setNodeMarkup(pos, undefined, {
176
203
  ...node.attrs,
177
204
  [attributeName]: generateID(),
@@ -285,5 +312,4 @@ const UniqueID = Extension.create({
285
312
  },
286
313
  });
287
314
 
288
- export { UniqueID, UniqueID as default };
289
- //# sourceMappingURL=tiptap-extension-unique-id.esm.js.map
315
+ export { UniqueID as default, UniqueID };
@@ -0,0 +1,3 @@
1
+ ### @blocknote/core/src/extensions-shared
2
+
3
+ Helper functions / base plugins for @blocknote/core/src/extensions
@@ -1,11 +1,13 @@
1
+ import { findParentNode } from "@tiptap/core";
1
2
  import { EditorState, Plugin, PluginKey } from "prosemirror-state";
2
3
  import { Decoration, DecorationSet, EditorView } from "prosemirror-view";
3
- import { BlockNoteEditor } from "../../../BlockNoteEditor";
4
- import { BlockSchema } from "../../../extensions/Blocks/api/blockTypes";
5
- import { findBlock } from "../../../extensions/Blocks/helpers/findBlock";
6
- import { BaseUiElementState } from "../../BaseUiElementTypes";
4
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
5
+ import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
6
+ import { BaseUiElementState } from "../BaseUiElementTypes";
7
7
  import { SuggestionItem } from "./SuggestionItem";
8
8
 
9
+ const findBlock = findParentNode((node) => node.type.name === "blockContainer");
10
+
9
11
  export type SuggestionsMenuState<T extends SuggestionItem> =
10
12
  BaseUiElementState & {
11
13
  // The suggested items to display.
@@ -16,7 +18,9 @@ export type SuggestionsMenuState<T extends SuggestionItem> =
16
18
 
17
19
  class SuggestionsMenuView<
18
20
  T extends SuggestionItem,
19
- BSchema extends BlockSchema
21
+ BSchema extends BlockSchema,
22
+ I extends InlineContentSchema,
23
+ S extends StyleSchema
20
24
  > {
21
25
  private suggestionsMenuState?: SuggestionsMenuState<T>;
22
26
  public updateSuggestionsMenu: () => void;
@@ -24,7 +28,7 @@ class SuggestionsMenuView<
24
28
  pluginState: SuggestionPluginState<T>;
25
29
 
26
30
  constructor(
27
- private readonly editor: BlockNoteEditor<BSchema>,
31
+ private readonly editor: BlockNoteEditor<BSchema, I, S>,
28
32
  private readonly pluginKey: PluginKey,
29
33
  updateSuggestionsMenu: (
30
34
  suggestionsMenuState: SuggestionsMenuState<T>
@@ -147,9 +151,11 @@ function getDefaultPluginState<
147
151
  */
148
152
  export const setupSuggestionsMenu = <
149
153
  T extends SuggestionItem,
150
- BSchema extends BlockSchema
154
+ BSchema extends BlockSchema,
155
+ I extends InlineContentSchema,
156
+ S extends StyleSchema
151
157
  >(
152
- editor: BlockNoteEditor<BSchema>,
158
+ editor: BlockNoteEditor<BSchema, I, S>,
153
159
  updateSuggestionsMenu: (
154
160
  suggestionsMenuState: SuggestionsMenuState<T>
155
161
  ) => void,
@@ -159,7 +165,7 @@ export const setupSuggestionsMenu = <
159
165
  items: (query: string) => T[] = () => [],
160
166
  onSelectItem: (props: {
161
167
  item: T;
162
- editor: BlockNoteEditor<BSchema>;
168
+ editor: BlockNoteEditor<BSchema, I, S>;
163
169
  }) => void = () => {
164
170
  // noop
165
171
  }
@@ -169,7 +175,7 @@ export const setupSuggestionsMenu = <
169
175
  throw new Error("'char' should be a single character");
170
176
  }
171
177
 
172
- let suggestionsPluginView: SuggestionsMenuView<T, BSchema>;
178
+ let suggestionsPluginView: SuggestionsMenuView<T, BSchema, I, S>;
173
179
 
174
180
  const deactivate = (view: EditorView) => {
175
181
  view.dispatch(view.state.tr.setMeta(pluginKey, { deactivate: true }));
@@ -180,7 +186,7 @@ export const setupSuggestionsMenu = <
180
186
  key: pluginKey,
181
187
 
182
188
  view: () => {
183
- suggestionsPluginView = new SuggestionsMenuView<T, BSchema>(
189
+ suggestionsPluginView = new SuggestionsMenuView<T, BSchema, I, S>(
184
190
  editor,
185
191
  pluginKey,
186
192
 
@@ -398,7 +404,7 @@ export const setupSuggestionsMenu = <
398
404
  blockNode.pos + blockNode.node.nodeSize,
399
405
  {
400
406
  nodeName: "span",
401
- class: "suggestion-decorator",
407
+ class: "bn-suggestion-decorator",
402
408
  "data-decoration-id": decorationId,
403
409
  }
404
410
  ),
@@ -412,7 +418,7 @@ export const setupSuggestionsMenu = <
412
418
  queryStartPos,
413
419
  {
414
420
  nodeName: "span",
415
- class: "suggestion-decorator",
421
+ class: "bn-suggestion-decorator",
416
422
  "data-decoration-id": decorationId,
417
423
  }
418
424
  ),
package/src/index.ts CHANGED
@@ -1,14 +1,15 @@
1
- export * from "./BlockNoteEditor";
2
- export * from "./BlockNoteExtensions";
3
- export * from "./extensions/Blocks/api/block";
4
- export * from "./extensions/Blocks/api/blockTypes";
5
- export * from "./extensions/Blocks/api/defaultProps";
6
- export * from "./extensions/Blocks/api/defaultBlocks";
7
- export * from "./extensions/Blocks/api/inlineContentTypes";
8
- export * from "./extensions/Blocks/api/selectionTypes";
9
- export * from "./extensions/Blocks/api/serialization";
10
- export * as blockStyles from "./extensions/Blocks/nodes/Block.module.css";
11
- export * from "./extensions/Blocks/nodes/BlockContent/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
1
+ export * from "./api/exporters/html/externalHTMLExporter";
2
+ export * from "./api/exporters/html/internalHTMLSerializer";
3
+ export * from "./api/testUtil";
4
+ export * from "./blocks/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY";
5
+ export * from "./blocks/defaultBlocks";
6
+ export * from "./blocks/defaultProps";
7
+ export * from "./editor/BlockNoteEditor";
8
+ export * from "./editor/BlockNoteExtensions";
9
+ export * from "./editor/selectionTypes";
10
+ export * from "./extensions-shared/BaseUiElementTypes";
11
+ export type { SuggestionItem } from "./extensions-shared/suggestion/SuggestionItem";
12
+ export * from "./extensions-shared/suggestion/SuggestionPlugin";
12
13
  export * from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
13
14
  export * from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
14
15
  export * from "./extensions/ImageToolbar/ImageToolbarPlugin";
@@ -16,7 +17,12 @@ export * from "./extensions/SideMenu/SideMenuPlugin";
16
17
  export * from "./extensions/SlashMenu/BaseSlashMenuItem";
17
18
  export * from "./extensions/SlashMenu/SlashMenuPlugin";
18
19
  export { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
19
- export * from "./shared/BaseUiElementTypes";
20
- export type { SuggestionItem } from "./shared/plugins/suggestion/SuggestionItem";
21
- export * from "./shared/plugins/suggestion/SuggestionPlugin";
22
- export * from "./shared/utils";
20
+ export * from "./extensions/TableHandles/TableHandlesPlugin";
21
+ export * from "./schema";
22
+ export * from "./util/browser";
23
+ export * from "./util/string";
24
+ // for testing from react (TODO: move):
25
+ export * from "./api/nodeConversions/nodeConversions";
26
+ export * from "./api/testUtil/partialBlockTestUtil";
27
+ export * from "./extensions/UniqueID/UniqueID";
28
+ export { UnreachableCaseError } from "./util/typescript";
@@ -1,22 +1,34 @@
1
- import { mergeAttributes, Node } from "@tiptap/core";
1
+ import { Node } from "@tiptap/core";
2
2
  import { Fragment, Node as PMNode, Slice } from "prosemirror-model";
3
3
  import { NodeSelection, TextSelection } from "prosemirror-state";
4
+
5
+ import { getBlockInfoFromPos } from "../api/getBlockInfoFromPos";
4
6
  import {
5
7
  blockToNode,
6
8
  inlineContentToNodes,
7
- } from "../../../api/nodeConversions/nodeConversions";
8
-
9
+ tableContentToNodes,
10
+ } from "../api/nodeConversions/nodeConversions";
11
+ import type { BlockNoteEditor } from "../editor/BlockNoteEditor";
12
+ import { NonEditableBlockPlugin } from "../extensions/NonEditableBlocks/NonEditableBlockPlugin";
13
+ import { PreviousBlockTypePlugin } from "../extensions/PreviousBlockType/PreviousBlockTypePlugin";
9
14
  import {
10
15
  BlockNoteDOMAttributes,
11
16
  BlockSchema,
17
+ InlineContentSchema,
12
18
  PartialBlock,
13
- } from "../api/blockTypes";
14
- import { getBlockInfoFromPos } from "../helpers/getBlockInfoFromPos";
15
- import { PreviousBlockTypePlugin } from "../PreviousBlockTypePlugin";
16
- import styles from "./Block.module.css";
17
- import BlockAttributes from "./BlockAttributes";
18
- import { mergeCSSClasses } from "../../../shared/utils";
19
- import { NonEditableBlockPlugin } from "../NonEditableBlockPlugin";
19
+ StyleSchema,
20
+ } from "../schema";
21
+ import { mergeCSSClasses } from "../util/browser";
22
+ import { UnreachableCaseError } from "../util/typescript";
23
+
24
+ // Object containing all possible block attributes.
25
+ const BlockAttributes: Record<string, string> = {
26
+ blockColor: "data-block-color",
27
+ blockStyle: "data-block-style",
28
+ id: "data-id",
29
+ depth: "data-depth",
30
+ depthChange: "data-depth-change",
31
+ };
20
32
 
21
33
  declare module "@tiptap/core" {
22
34
  interface Commands<ReturnType> {
@@ -25,13 +37,21 @@ declare module "@tiptap/core" {
25
37
  BNDeleteBlock: (posInBlock: number) => ReturnType;
26
38
  BNMergeBlocks: (posBetweenBlocks: number) => ReturnType;
27
39
  BNSplitBlock: (posInBlock: number, keepType: boolean) => ReturnType;
28
- BNUpdateBlock: <BSchema extends BlockSchema>(
40
+ BNUpdateBlock: <
41
+ BSchema extends BlockSchema,
42
+ I extends InlineContentSchema,
43
+ S extends StyleSchema
44
+ >(
29
45
  posInBlock: number,
30
- block: PartialBlock<BSchema>
46
+ block: PartialBlock<BSchema, I, S>
31
47
  ) => ReturnType;
32
- BNCreateOrUpdateBlock: <BSchema extends BlockSchema>(
48
+ BNCreateOrUpdateBlock: <
49
+ BSchema extends BlockSchema,
50
+ I extends InlineContentSchema,
51
+ S extends StyleSchema
52
+ >(
33
53
  posInBlock: number,
34
- block: PartialBlock<BSchema>
54
+ block: PartialBlock<BSchema, I, S>
35
55
  ) => ReturnType;
36
56
  };
37
57
  }
@@ -42,6 +62,7 @@ declare module "@tiptap/core" {
42
62
  */
43
63
  export const BlockContainer = Node.create<{
44
64
  domAttributes?: BlockNoteDOMAttributes;
65
+ editor: BlockNoteEditor<BlockSchema, InlineContentSchema, StyleSchema>;
45
66
  }>({
46
67
  name: "blockContainer",
47
68
  group: "blockContainer",
@@ -78,27 +99,34 @@ export const BlockContainer = Node.create<{
78
99
  },
79
100
 
80
101
  renderHTML({ HTMLAttributes }) {
81
- const domAttributes = this.options.domAttributes?.blockContainer || {};
102
+ const blockOuter = document.createElement("div");
103
+ blockOuter.className = "bn-block-outer";
104
+ blockOuter.setAttribute("data-node-type", "blockOuter");
105
+ for (const [attribute, value] of Object.entries(HTMLAttributes)) {
106
+ if (attribute !== "class") {
107
+ blockOuter.setAttribute(attribute, value);
108
+ }
109
+ }
110
+
111
+ const blockHTMLAttributes = {
112
+ ...(this.options.domAttributes?.blockContainer || {}),
113
+ ...HTMLAttributes,
114
+ };
115
+ const block = document.createElement("div");
116
+ block.className = mergeCSSClasses("bn-block", blockHTMLAttributes.class);
117
+ block.setAttribute("data-node-type", this.name);
118
+ for (const [attribute, value] of Object.entries(blockHTMLAttributes)) {
119
+ if (attribute !== "class") {
120
+ block.setAttribute(attribute, value);
121
+ }
122
+ }
82
123
 
83
- return [
84
- "div",
85
- mergeAttributes(HTMLAttributes, {
86
- class: styles.blockOuter,
87
- "data-node-type": "block-outer",
88
- }),
89
- [
90
- "div",
91
- mergeAttributes(
92
- {
93
- ...domAttributes,
94
- class: mergeCSSClasses(styles.block, domAttributes.class),
95
- "data-node-type": this.name,
96
- },
97
- HTMLAttributes
98
- ),
99
- 0,
100
- ],
101
- ];
124
+ blockOuter.appendChild(block);
125
+
126
+ return {
127
+ dom: blockOuter,
128
+ contentDOM: block,
129
+ };
102
130
  },
103
131
 
104
132
  addCommands() {
@@ -151,7 +179,13 @@ export const BlockContainer = Node.create<{
151
179
 
152
180
  // Creates ProseMirror nodes for each child block, including their descendants.
153
181
  for (const child of block.children) {
154
- childNodes.push(blockToNode(child, state.schema));
182
+ childNodes.push(
183
+ blockToNode(
184
+ child,
185
+ state.schema,
186
+ this.options.editor.styleSchema
187
+ )
188
+ );
155
189
  }
156
190
 
157
191
  // Checks if a blockGroup node already exists.
@@ -171,59 +205,63 @@ export const BlockContainer = Node.create<{
171
205
  }
172
206
  }
173
207
 
174
- // Replaces the blockContent node's content if necessary.
175
- if (block.content !== undefined) {
176
- let content: PMNode[] = [];
208
+ const oldType = contentNode.type.name;
209
+ const newType = block.type || oldType;
210
+
211
+ // The code below determines the new content of the block.
212
+ // or "keep" to keep as-is
213
+ let content: PMNode[] | "keep" = "keep";
177
214
 
178
- // Checks if the provided content is a string or InlineContent[] type.
215
+ // Has there been any custom content provided?
216
+ if (block.content) {
179
217
  if (typeof block.content === "string") {
180
218
  // Adds a single text node with no marks to the content.
181
- content.push(state.schema.text(block.content));
219
+ content = [state.schema.text(block.content)];
220
+ } else if (Array.isArray(block.content)) {
221
+ // Adds a text node with the provided styles converted into marks to the content,
222
+ // for each InlineContent object.
223
+ content = inlineContentToNodes(
224
+ block.content,
225
+ state.schema,
226
+ this.options.editor.styleSchema
227
+ );
228
+ } else if (block.content.type === "tableContent") {
229
+ content = tableContentToNodes(
230
+ block.content,
231
+ state.schema,
232
+ this.options.editor.styleSchema
233
+ );
182
234
  } else {
183
- // Adds a text node with the provided styles converted into marks to the content, for each InlineContent
184
- // object.
185
- content = inlineContentToNodes(block.content, state.schema);
235
+ throw new UnreachableCaseError(block.content.type);
236
+ }
237
+ } else {
238
+ // no custom content has been provided, use existing content IF possible
239
+
240
+ // Since some block types contain inline content and others don't,
241
+ // we either need to call setNodeMarkup to just update type &
242
+ // attributes, or replaceWith to replace the whole blockContent.
243
+ const oldContentType = state.schema.nodes[oldType].spec.content;
244
+ const newContentType = state.schema.nodes[newType].spec.content;
245
+
246
+ if (oldContentType === "") {
247
+ // keep old content, because it's empty anyway and should be compatible with
248
+ // any newContentType
249
+ } else if (newContentType !== oldContentType) {
250
+ // the content type changed, replace the previous content
251
+ content = [];
252
+ } else {
253
+ // keep old content, because the content type is the same and should be compatible
186
254
  }
187
-
188
- // Replaces the contents of the blockContent node with the previously created text node(s).
189
- state.tr.replace(
190
- startPos + 1,
191
- startPos + contentNode.nodeSize - 1,
192
- new Slice(Fragment.from(content), 0, 0)
193
- );
194
255
  }
195
256
 
196
- // Since some block types contain inline content and others don't,
197
- // we either need to call setNodeMarkup to just update type &
198
- // attributes, or replaceWith to replace the whole blockContent.
199
- const oldType = contentNode.type.name;
200
- const newType = block.type || oldType;
201
-
202
- const oldContentType = state.schema.nodes[oldType].spec.content;
203
- const newContentType = state.schema.nodes[newType].spec.content;
204
-
205
- if (oldContentType === "inline*" && newContentType === "") {
206
- // Replaces the blockContent node with one of the new type and
207
- // adds the provided props as attributes. Also preserves all
208
- // existing attributes that are compatible with the new type.
209
- // Need to reset the selection since replacing the block content
210
- // sets it to the next block.
211
- state.tr
212
- .replaceWith(
213
- startPos,
214
- endPos,
215
- state.schema.nodes[newType].create({
216
- ...contentNode.attrs,
217
- ...block.props,
218
- })
219
- )
220
- .setSelection(
221
- new NodeSelection(state.tr.doc.resolve(startPos))
222
- );
223
- } else {
224
- // Changes the blockContent node type and adds the provided props
225
- // as attributes. Also preserves all existing attributes that are
226
- // compatible with the new type.
257
+ // Now, changes the blockContent node type and adds the provided props
258
+ // as attributes. Also preserves all existing attributes that are
259
+ // compatible with the new type.
260
+ //
261
+ // Use either setNodeMarkup or replaceWith depending on whether the
262
+ // content is being replaced or not.
263
+ if (content === "keep") {
264
+ // use setNodeMarkup to only update the type and attributes
227
265
  state.tr.setNodeMarkup(
228
266
  startPos,
229
267
  block.type === undefined
@@ -234,6 +272,35 @@ export const BlockContainer = Node.create<{
234
272
  ...block.props,
235
273
  }
236
274
  );
275
+ } else {
276
+ // use replaceWith to replace the content and the block itself
277
+ // also reset the selection since replacing the block content
278
+ // sets it to the next block.
279
+ state.tr
280
+ .replaceWith(
281
+ startPos,
282
+ endPos,
283
+ state.schema.nodes[newType].create(
284
+ {
285
+ ...contentNode.attrs,
286
+ ...block.props,
287
+ },
288
+ content
289
+ )
290
+ )
291
+ // If the node doesn't contain editable content, we want to
292
+ // select the whole node. But if it does have editable content,
293
+ // we want to set the selection to the start of it.
294
+ .setSelection(
295
+ state.schema.nodes[newType].spec.content === ""
296
+ ? new NodeSelection(state.tr.doc.resolve(startPos))
297
+ : state.schema.nodes[newType].spec.content === "inline*"
298
+ ? new TextSelection(state.tr.doc.resolve(startPos))
299
+ : // Need to offset the position as we have to get through the
300
+ // `tableRow` and `tableCell` nodes to get to the
301
+ // `tableParagraph` node we want to set the selection in.
302
+ new TextSelection(state.tr.doc.resolve(startPos + 4))
303
+ );
237
304
  }
238
305
 
239
306
  // Adds all provided props as attributes to the parent blockContainer node too, and also preserves existing
@@ -425,13 +492,12 @@ export const BlockContainer = Node.create<{
425
492
  // Reverts block content type to a paragraph if the selection is at the start of the block.
426
493
  () =>
427
494
  commands.command(({ state }) => {
428
- const { contentType } = getBlockInfoFromPos(
495
+ const { contentType, startPos } = getBlockInfoFromPos(
429
496
  state.doc,
430
497
  state.selection.from
431
498
  )!;
432
499
 
433
- const selectionAtBlockStart =
434
- state.selection.$anchor.parentOffset === 0;
500
+ const selectionAtBlockStart = state.selection.from === startPos + 1;
435
501
  const isParagraph = contentType.name === "paragraph";
436
502
 
437
503
  if (selectionAtBlockStart && !isParagraph) {
@@ -446,8 +512,12 @@ export const BlockContainer = Node.create<{
446
512
  // Removes a level of nesting if the block is indented if the selection is at the start of the block.
447
513
  () =>
448
514
  commands.command(({ state }) => {
449
- const selectionAtBlockStart =
450
- state.selection.$anchor.parentOffset === 0;
515
+ const { startPos } = getBlockInfoFromPos(
516
+ state.doc,
517
+ state.selection.from
518
+ )!;
519
+
520
+ const selectionAtBlockStart = state.selection.from === startPos + 1;
451
521
 
452
522
  if (selectionAtBlockStart) {
453
523
  return commands.liftListItem("blockContainer");
@@ -464,10 +534,8 @@ export const BlockContainer = Node.create<{
464
534
  state.selection.from
465
535
  )!;
466
536
 
467
- const selectionAtBlockStart =
468
- state.selection.$anchor.parentOffset === 0;
469
- const selectionEmpty =
470
- state.selection.anchor === state.selection.head;
537
+ const selectionAtBlockStart = state.selection.from === startPos + 1;
538
+ const selectionEmpty = state.selection.empty;
471
539
  const blockAtDocStart = startPos === 2;
472
540
 
473
541
  const posBetweenBlocks = startPos - 1;
@@ -494,17 +562,14 @@ export const BlockContainer = Node.create<{
494
562
  // end of the block.
495
563
  () =>
496
564
  commands.command(({ state }) => {
497
- const { node, contentNode, depth, endPos } = getBlockInfoFromPos(
565
+ const { node, depth, endPos } = getBlockInfoFromPos(
498
566
  state.doc,
499
567
  state.selection.from
500
568
  )!;
501
569
 
502
570
  const blockAtDocEnd = false;
503
- const selectionAtBlockEnd =
504
- state.selection.$anchor.parentOffset ===
505
- contentNode.firstChild!.nodeSize;
506
- const selectionEmpty =
507
- state.selection.anchor === state.selection.head;
571
+ const selectionAtBlockEnd = state.selection.from === endPos - 1;
572
+ const selectionEmpty = state.selection.empty;
508
573
  const hasChildBlocks = node.childCount === 2;
509
574
 
510
575
  if (