@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
@@ -3,56 +3,79 @@ import { Node } from "prosemirror-model";
3
3
  // import "./blocknote.css";
4
4
  import { Editor as TiptapEditor } from "@tiptap/core/dist/packages/core/src/Editor";
5
5
  import * as Y from "yjs";
6
- import { getBlockNoteExtensions } from "./BlockNoteExtensions";
7
6
  import {
8
7
  insertBlocks,
9
8
  removeBlocks,
10
9
  replaceBlocks,
11
10
  updateBlock,
12
- } from "./api/blockManipulation/blockManipulation";
13
- import {
14
- HTMLToBlocks,
15
- blocksToHTML,
16
- blocksToMarkdown,
17
- markdownToBlocks,
18
- } from "./api/formatConversions/formatConversions";
11
+ } from "../api/blockManipulation/blockManipulation";
12
+ import { createExternalHTMLExporter } from "../api/exporters/html/externalHTMLExporter";
13
+ import { blocksToMarkdown } from "../api/exporters/markdown/markdownExporter";
14
+ import { getBlockInfoFromPos } from "../api/getBlockInfoFromPos";
19
15
  import {
20
16
  blockToNode,
21
17
  nodeToBlock,
22
- } from "./api/nodeConversions/nodeConversions";
23
- import { getNodeById } from "./api/util/nodeUtil";
24
- import styles from "./editor.module.css";
18
+ } from "../api/nodeConversions/nodeConversions";
19
+ import { getNodeById } from "../api/nodeUtil";
20
+ import { HTMLToBlocks } from "../api/parsers/html/parseHTML";
21
+ import { markdownToBlocks } from "../api/parsers/markdown/parseMarkdown";
22
+ import {
23
+ DefaultBlockSchema,
24
+ DefaultInlineContentSchema,
25
+ DefaultStyleSchema,
26
+ defaultBlockSchema,
27
+ defaultBlockSpecs,
28
+ defaultInlineContentSpecs,
29
+ defaultStyleSpecs,
30
+ } from "../blocks/defaultBlocks";
31
+ import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin";
32
+ import { HyperlinkToolbarProsemirrorPlugin } from "../extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
33
+ import { ImageToolbarProsemirrorPlugin } from "../extensions/ImageToolbar/ImageToolbarPlugin";
34
+ import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin";
35
+ import { BaseSlashMenuItem } from "../extensions/SlashMenu/BaseSlashMenuItem";
36
+ import { SlashMenuProsemirrorPlugin } from "../extensions/SlashMenu/SlashMenuPlugin";
37
+ import { getDefaultSlashMenuItems } from "../extensions/SlashMenu/defaultSlashMenuItems";
38
+ import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin";
39
+ import { UniqueID } from "../extensions/UniqueID/UniqueID";
25
40
  import {
26
41
  Block,
27
42
  BlockIdentifier,
28
43
  BlockNoteDOMAttributes,
29
44
  BlockSchema,
45
+ BlockSchemaFromSpecs,
46
+ BlockSchemaWithBlock,
47
+ BlockSpecs,
48
+ InlineContentSchema,
49
+ InlineContentSchemaFromSpecs,
50
+ InlineContentSpecs,
30
51
  PartialBlock,
31
- } from "./extensions/Blocks/api/blockTypes";
32
- import { TextCursorPosition } from "./extensions/Blocks/api/cursorPositionTypes";
33
- import {
34
- DefaultBlockSchema,
35
- defaultBlockSchema,
36
- } from "./extensions/Blocks/api/defaultBlocks";
37
- import {
38
- ColorStyle,
52
+ StyleSchema,
53
+ StyleSchemaFromSpecs,
54
+ StyleSpecs,
39
55
  Styles,
40
- ToggledStyle,
41
- } from "./extensions/Blocks/api/inlineContentTypes";
42
- import { Selection } from "./extensions/Blocks/api/selectionTypes";
43
- import { getBlockInfoFromPos } from "./extensions/Blocks/helpers/getBlockInfoFromPos";
44
-
45
- import { FormattingToolbarProsemirrorPlugin } from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
46
- import { HyperlinkToolbarProsemirrorPlugin } from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
47
- import { ImageToolbarProsemirrorPlugin } from "./extensions/ImageToolbar/ImageToolbarPlugin";
48
- import { SideMenuProsemirrorPlugin } from "./extensions/SideMenu/SideMenuPlugin";
49
- import { BaseSlashMenuItem } from "./extensions/SlashMenu/BaseSlashMenuItem";
50
- import { SlashMenuProsemirrorPlugin } from "./extensions/SlashMenu/SlashMenuPlugin";
51
- import { getDefaultSlashMenuItems } from "./extensions/SlashMenu/defaultSlashMenuItems";
52
- import { UniqueID } from "./extensions/UniqueID/UniqueID";
53
- import { mergeCSSClasses } from "./shared/utils";
54
-
55
- export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
56
+ getBlockSchemaFromSpecs,
57
+ getInlineContentSchemaFromSpecs,
58
+ getStyleSchemaFromSpecs,
59
+ } from "../schema";
60
+ import { mergeCSSClasses } from "../util/browser";
61
+ import { UnreachableCaseError } from "../util/typescript";
62
+
63
+ import { getBlockNoteExtensions } from "./BlockNoteExtensions";
64
+ import { TextCursorPosition } from "./cursorPositionTypes";
65
+
66
+ import { Selection } from "./selectionTypes";
67
+ import { transformPasted } from "./transformPasted";
68
+
69
+ // CSS
70
+ import "prosemirror-tables/style/tables.css";
71
+ import "./Block.css";
72
+ import "./editor.css";
73
+
74
+ export type BlockNoteEditorOptions<
75
+ BSpecs extends BlockSpecs,
76
+ ISpecs extends InlineContentSpecs,
77
+ SSpecs extends StyleSpecs
78
+ > = {
56
79
  // TODO: Figure out if enableBlockNoteExtensions/disableHistoryExtension are needed and document them.
57
80
  enableBlockNoteExtensions: boolean;
58
81
  /**
@@ -61,7 +84,7 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
61
84
  *
62
85
  * @default defaultSlashMenuItems from `./extensions/SlashMenu`
63
86
  */
64
- slashMenuItems: BaseSlashMenuItem<any>[];
87
+ slashMenuItems: BaseSlashMenuItem<any, any, any>[];
65
88
 
66
89
  /**
67
90
  * The HTML element that should be used as the parent element for the editor.
@@ -78,15 +101,33 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
78
101
  /**
79
102
  * A callback function that runs when the editor is ready to be used.
80
103
  */
81
- onEditorReady: (editor: BlockNoteEditor<BSchema>) => void;
104
+ onEditorReady: (
105
+ editor: BlockNoteEditor<
106
+ BlockSchemaFromSpecs<BSpecs>,
107
+ InlineContentSchemaFromSpecs<ISpecs>,
108
+ StyleSchemaFromSpecs<SSpecs>
109
+ >
110
+ ) => void;
82
111
  /**
83
112
  * A callback function that runs whenever the editor's contents change.
84
113
  */
85
- onEditorContentChange: (editor: BlockNoteEditor<BSchema>) => void;
114
+ onEditorContentChange: (
115
+ editor: BlockNoteEditor<
116
+ BlockSchemaFromSpecs<BSpecs>,
117
+ InlineContentSchemaFromSpecs<ISpecs>,
118
+ StyleSchemaFromSpecs<SSpecs>
119
+ >
120
+ ) => void;
86
121
  /**
87
122
  * A callback function that runs whenever the text cursor position changes.
88
123
  */
89
- onTextCursorPositionChange: (editor: BlockNoteEditor<BSchema>) => void;
124
+ onTextCursorPositionChange: (
125
+ editor: BlockNoteEditor<
126
+ BlockSchemaFromSpecs<BSpecs>,
127
+ InlineContentSchemaFromSpecs<ISpecs>,
128
+ StyleSchemaFromSpecs<SSpecs>
129
+ >
130
+ ) => void;
90
131
  /**
91
132
  * Locks the editor from being editable by the user if set to `false`.
92
133
  */
@@ -94,7 +135,11 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
94
135
  /**
95
136
  * The content that should be in the editor when it's created, represented as an array of partial block objects.
96
137
  */
97
- initialContent: PartialBlock<BSchema>[];
138
+ initialContent: PartialBlock<
139
+ BlockSchemaFromSpecs<BSpecs>,
140
+ InlineContentSchemaFromSpecs<ISpecs>,
141
+ StyleSchemaFromSpecs<SSpecs>
142
+ >[];
98
143
  /**
99
144
  * Use default BlockNote font and reset the styles of <p> <li> <h1> elements etc., that are used in BlockNote.
100
145
  *
@@ -105,7 +150,11 @@ export type BlockNoteEditorOptions<BSchema extends BlockSchema> = {
105
150
  /**
106
151
  * A list of block types that should be available in the editor.
107
152
  */
108
- blockSchema: BSchema;
153
+ blockSpecs: BSpecs;
154
+
155
+ styleSpecs: SSpecs;
156
+
157
+ inlineContentSpecs: ISpecs;
109
158
 
110
159
  /**
111
160
  * A custom function to handle file uploads.
@@ -149,52 +198,115 @@ const blockNoteTipTapOptions = {
149
198
  enableCoreExtensions: false,
150
199
  };
151
200
 
152
- export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
201
+ export class BlockNoteEditor<
202
+ BSchema extends BlockSchema = DefaultBlockSchema,
203
+ ISchema extends InlineContentSchema = DefaultInlineContentSchema,
204
+ SSchema extends StyleSchema = DefaultStyleSchema
205
+ > {
153
206
  public readonly _tiptapEditor: TiptapEditor & { contentComponent: any };
154
- public blockCache = new WeakMap<Node, Block<BSchema>>();
155
- public readonly schema: BSchema;
207
+ public blockCache = new WeakMap<Node, Block<any, any, any>>();
208
+ public readonly blockSchema: BSchema;
209
+ public readonly inlineContentSchema: ISchema;
210
+ public readonly styleSchema: SSchema;
211
+
212
+ public readonly blockImplementations: BlockSpecs;
213
+ public readonly inlineContentImplementations: InlineContentSpecs;
214
+ public readonly styleImplementations: StyleSpecs;
215
+
156
216
  public ready = false;
157
217
 
158
- public readonly sideMenu: SideMenuProsemirrorPlugin<BSchema>;
159
- public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin<BSchema>;
160
- public readonly slashMenu: SlashMenuProsemirrorPlugin<BSchema, any>;
161
- public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<BSchema>;
162
- public readonly imageToolbar: ImageToolbarProsemirrorPlugin<BSchema>;
218
+ public readonly sideMenu: SideMenuProsemirrorPlugin<
219
+ BSchema,
220
+ ISchema,
221
+ SSchema
222
+ >;
223
+ public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin;
224
+ public readonly slashMenu: SlashMenuProsemirrorPlugin<
225
+ BSchema,
226
+ ISchema,
227
+ SSchema,
228
+ any
229
+ >;
230
+ public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<
231
+ BSchema,
232
+ ISchema,
233
+ SSchema
234
+ >;
235
+ public readonly imageToolbar: ImageToolbarProsemirrorPlugin<
236
+ BSchema,
237
+ ISchema,
238
+ SSchema
239
+ >;
240
+ public readonly tableHandles:
241
+ | TableHandlesProsemirrorPlugin<
242
+ BSchema extends BlockSchemaWithBlock<
243
+ "table",
244
+ DefaultBlockSchema["table"]
245
+ >
246
+ ? BSchema
247
+ : any,
248
+ ISchema,
249
+ SSchema
250
+ >
251
+ | undefined;
163
252
 
164
253
  public readonly uploadFile: ((file: File) => Promise<string>) | undefined;
165
254
 
166
- constructor(
167
- private readonly options: Partial<BlockNoteEditorOptions<BSchema>> = {}
255
+ public static create<
256
+ BSpecs extends BlockSpecs = typeof defaultBlockSpecs,
257
+ ISpecs extends InlineContentSpecs = typeof defaultInlineContentSpecs,
258
+ SSpecs extends StyleSpecs = typeof defaultStyleSpecs
259
+ >(options: Partial<BlockNoteEditorOptions<BSpecs, ISpecs, SSpecs>> = {}) {
260
+ return new BlockNoteEditor(options) as BlockNoteEditor<
261
+ BlockSchemaFromSpecs<BSpecs>,
262
+ InlineContentSchemaFromSpecs<ISpecs>,
263
+ StyleSchemaFromSpecs<SSpecs>
264
+ >;
265
+ }
266
+
267
+ private constructor(
268
+ private readonly options: Partial<BlockNoteEditorOptions<any, any, any>>
168
269
  ) {
169
270
  // apply defaults
170
- const newOptions: Omit<typeof options, "defaultStyles" | "blockSchema"> & {
171
- defaultStyles: boolean;
172
- blockSchema: BSchema;
173
- } = {
271
+ const newOptions = {
174
272
  defaultStyles: true,
175
- // TODO: There's a lot of annoying typing stuff to deal with here. If
176
- // BSchema is specified, then options.blockSchema should also be required.
177
- // If BSchema is not specified, then options.blockSchema should also not
178
- // be defined. Unfortunately, trying to implement these constraints seems
179
- // to be a huge pain, hence the `as any` casts.
180
- blockSchema: options.blockSchema || (defaultBlockSchema as any),
273
+ blockSpecs: options.blockSpecs || defaultBlockSpecs,
274
+ styleSpecs: options.styleSpecs || defaultStyleSpecs,
275
+ inlineContentSpecs:
276
+ options.inlineContentSpecs || defaultInlineContentSpecs,
181
277
  ...options,
182
278
  };
183
279
 
280
+ this.blockSchema = getBlockSchemaFromSpecs(newOptions.blockSpecs);
281
+ this.inlineContentSchema = getInlineContentSchemaFromSpecs(
282
+ newOptions.inlineContentSpecs
283
+ );
284
+ this.styleSchema = getStyleSchemaFromSpecs(newOptions.styleSpecs);
285
+ this.blockImplementations = newOptions.blockSpecs;
286
+ this.inlineContentImplementations = newOptions.inlineContentSpecs;
287
+ this.styleImplementations = newOptions.styleSpecs;
288
+
184
289
  this.sideMenu = new SideMenuProsemirrorPlugin(this);
185
290
  this.formattingToolbar = new FormattingToolbarProsemirrorPlugin(this);
186
291
  this.slashMenu = new SlashMenuProsemirrorPlugin(
187
292
  this,
188
293
  newOptions.slashMenuItems ||
189
- getDefaultSlashMenuItems(newOptions.blockSchema)
294
+ (getDefaultSlashMenuItems(this.blockSchema) as any)
190
295
  );
191
296
  this.hyperlinkToolbar = new HyperlinkToolbarProsemirrorPlugin(this);
192
297
  this.imageToolbar = new ImageToolbarProsemirrorPlugin(this);
193
298
 
194
- const extensions = getBlockNoteExtensions<BSchema>({
299
+ if (this.blockSchema.table === defaultBlockSchema.table) {
300
+ this.tableHandles = new TableHandlesProsemirrorPlugin(this as any);
301
+ }
302
+
303
+ const extensions = getBlockNoteExtensions({
195
304
  editor: this,
196
305
  domAttributes: newOptions.domAttributes || {},
197
- blockSchema: newOptions.blockSchema,
306
+ blockSchema: this.blockSchema,
307
+ blockSpecs: newOptions.blockSpecs,
308
+ styleSpecs: newOptions.styleSpecs,
309
+ inlineContentSpecs: newOptions.inlineContentSpecs,
198
310
  collaboration: newOptions.collaboration,
199
311
  });
200
312
 
@@ -208,15 +320,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
208
320
  this.slashMenu.plugin,
209
321
  this.hyperlinkToolbar.plugin,
210
322
  this.imageToolbar.plugin,
323
+ ...(this.tableHandles ? [this.tableHandles.plugin] : []),
211
324
  ];
212
325
  },
213
326
  });
214
327
  extensions.push(blockNoteUIExtension);
215
328
 
216
- this.schema = newOptions.blockSchema;
217
-
218
329
  this.uploadFile = newOptions.uploadFile;
219
330
 
331
+ if (newOptions.collaboration && newOptions.initialContent) {
332
+ console.warn(
333
+ "When using Collaboration, initialContent might cause conflicts, because changes should come from the collaboration provider"
334
+ );
335
+ }
336
+
220
337
  const initialContent =
221
338
  newOptions.initialContent ||
222
339
  (options.collaboration
@@ -227,26 +344,46 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
227
344
  id: UniqueID.options.generateID(),
228
345
  },
229
346
  ]);
347
+ const styleSchema = this.styleSchema;
230
348
 
231
349
  const tiptapOptions: Partial<EditorOptions> = {
232
350
  ...blockNoteTipTapOptions,
233
351
  ...newOptions._tiptapOptions,
234
352
  onBeforeCreate(editor) {
235
353
  newOptions._tiptapOptions?.onBeforeCreate?.(editor);
236
- if (!initialContent) {
237
- // when using collaboration
238
- return;
239
- }
240
-
241
354
  // We always set the initial content to a single paragraph block. This
242
355
  // allows us to easily replace it with the actual initial content once
243
356
  // the TipTap editor is initialized.
244
357
  const schema = editor.editor.schema;
358
+
359
+ // This is a hack to make "initial content detection" by y-prosemirror (and also tiptap isEmpty)
360
+ // properly detect whether or not the document has changed.
361
+ // We change the doc.createAndFill function to make sure the initial block id is set, instead of null
362
+ let cache: any;
363
+ const oldCreateAndFill = schema.nodes.doc.createAndFill;
364
+ (schema.nodes.doc as any).createAndFill = (...args: any) => {
365
+ if (cache) {
366
+ return cache;
367
+ }
368
+ const ret = oldCreateAndFill.apply(schema.nodes.doc, args);
369
+
370
+ // create a copy that we can mutate (otherwise, assigning attrs is not safe and corrupts the pm state)
371
+ const jsonNode = JSON.parse(JSON.stringify(ret!.toJSON()));
372
+ jsonNode.content[0].content[0].attrs.id = "initialBlockId";
373
+
374
+ cache = Node.fromJSON(schema, jsonNode);
375
+ return ret;
376
+ };
377
+
245
378
  const root = schema.node(
246
379
  "doc",
247
380
  undefined,
248
381
  schema.node("blockGroup", undefined, [
249
- blockToNode({ id: "initialBlock", type: "paragraph" }, schema),
382
+ blockToNode(
383
+ { id: "initialBlockId", type: "paragraph" },
384
+ schema,
385
+ styleSchema
386
+ ),
250
387
  ])
251
388
  );
252
389
  editor.editor.options.content = root.toJSON();
@@ -257,7 +394,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
257
394
  // initial content, as the schema may contain custom blocks which need
258
395
  // it to render.
259
396
  if (initialContent !== undefined) {
260
- this.replaceBlocks(this.topLevelBlocks, initialContent);
397
+ this.replaceBlocks(this.topLevelBlocks, initialContent as any);
261
398
  }
262
399
 
263
400
  newOptions.onEditorReady?.(this);
@@ -299,13 +436,13 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
299
436
  ...newOptions._tiptapOptions?.editorProps?.attributes,
300
437
  ...newOptions.domAttributes?.editor,
301
438
  class: mergeCSSClasses(
302
- styles.bnEditor,
303
- styles.bnRoot,
304
- newOptions.domAttributes?.editor?.class || "",
305
- newOptions.defaultStyles ? styles.defaultStyles : "",
439
+ "bn-root",
440
+ "bn-editor",
441
+ newOptions.defaultStyles ? "bn-default-styles" : "",
306
442
  newOptions.domAttributes?.editor?.class || ""
307
443
  ),
308
444
  },
445
+ transformPasted,
309
446
  },
310
447
  };
311
448
 
@@ -338,11 +475,19 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
338
475
  * Gets a snapshot of all top-level (non-nested) blocks in the editor.
339
476
  * @returns A snapshot of all top-level (non-nested) blocks in the editor.
340
477
  */
341
- public get topLevelBlocks(): Block<BSchema>[] {
342
- const blocks: Block<BSchema>[] = [];
478
+ public get topLevelBlocks(): Block<BSchema, ISchema, SSchema>[] {
479
+ const blocks: Block<BSchema, ISchema, SSchema>[] = [];
343
480
 
344
481
  this._tiptapEditor.state.doc.firstChild!.descendants((node) => {
345
- blocks.push(nodeToBlock(node, this.schema, this.blockCache));
482
+ blocks.push(
483
+ nodeToBlock(
484
+ node,
485
+ this.blockSchema,
486
+ this.inlineContentSchema,
487
+ this.styleSchema,
488
+ this.blockCache
489
+ )
490
+ );
346
491
 
347
492
  return false;
348
493
  });
@@ -357,12 +502,12 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
357
502
  */
358
503
  public getBlock(
359
504
  blockIdentifier: BlockIdentifier
360
- ): Block<BSchema> | undefined {
505
+ ): Block<BSchema, ISchema, SSchema> | undefined {
361
506
  const id =
362
507
  typeof blockIdentifier === "string"
363
508
  ? blockIdentifier
364
509
  : blockIdentifier.id;
365
- let newBlock: Block<BSchema> | undefined = undefined;
510
+ let newBlock: Block<BSchema, ISchema, SSchema> | undefined = undefined;
366
511
 
367
512
  this._tiptapEditor.state.doc.firstChild!.descendants((node) => {
368
513
  if (typeof newBlock !== "undefined") {
@@ -373,7 +518,13 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
373
518
  return true;
374
519
  }
375
520
 
376
- newBlock = nodeToBlock(node, this.schema, this.blockCache);
521
+ newBlock = nodeToBlock(
522
+ node,
523
+ this.blockSchema,
524
+ this.inlineContentSchema,
525
+ this.styleSchema,
526
+ this.blockCache
527
+ );
377
528
 
378
529
  return false;
379
530
  });
@@ -387,7 +538,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
387
538
  * @param reverse Whether the blocks should be traversed in reverse order.
388
539
  */
389
540
  public forEachBlock(
390
- callback: (block: Block<BSchema>) => boolean,
541
+ callback: (block: Block<BSchema, ISchema, SSchema>) => boolean,
391
542
  reverse = false
392
543
  ): void {
393
544
  const blocks = this.topLevelBlocks.slice();
@@ -396,7 +547,9 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
396
547
  blocks.reverse();
397
548
  }
398
549
 
399
- function traverseBlockArray(blockArray: Block<BSchema>[]): boolean {
550
+ function traverseBlockArray(
551
+ blockArray: Block<BSchema, ISchema, SSchema>[]
552
+ ): boolean {
400
553
  for (const block of blockArray) {
401
554
  if (!callback(block)) {
402
555
  return false;
@@ -437,7 +590,11 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
437
590
  * Gets a snapshot of the current text cursor position.
438
591
  * @returns A snapshot of the current text cursor position.
439
592
  */
440
- public getTextCursorPosition(): TextCursorPosition<BSchema> {
593
+ public getTextCursorPosition(): TextCursorPosition<
594
+ BSchema,
595
+ ISchema,
596
+ SSchema
597
+ > {
441
598
  const { node, depth, startPos, endPos } = getBlockInfoFromPos(
442
599
  this._tiptapEditor.state.doc,
443
600
  this._tiptapEditor.state.selection.from
@@ -465,15 +622,33 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
465
622
  }
466
623
 
467
624
  return {
468
- block: nodeToBlock(node, this.schema, this.blockCache),
625
+ block: nodeToBlock(
626
+ node,
627
+ this.blockSchema,
628
+ this.inlineContentSchema,
629
+ this.styleSchema,
630
+ this.blockCache
631
+ ),
469
632
  prevBlock:
470
633
  prevNode === undefined
471
634
  ? undefined
472
- : nodeToBlock(prevNode, this.schema, this.blockCache),
635
+ : nodeToBlock(
636
+ prevNode,
637
+ this.blockSchema,
638
+ this.inlineContentSchema,
639
+ this.styleSchema,
640
+ this.blockCache
641
+ ),
473
642
  nextBlock:
474
643
  nextNode === undefined
475
644
  ? undefined
476
- : nodeToBlock(nextNode, this.schema, this.blockCache),
645
+ : nodeToBlock(
646
+ nextNode,
647
+ this.blockSchema,
648
+ this.inlineContentSchema,
649
+ this.styleSchema,
650
+ this.blockCache
651
+ ),
477
652
  };
478
653
  }
479
654
 
@@ -495,25 +670,42 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
495
670
  posBeforeNode + 2
496
671
  )!;
497
672
 
498
- // For blocks without inline content
499
- if (contentNode.type.spec.content === "") {
673
+ const contentType: "none" | "inline" | "table" =
674
+ this.blockSchema[contentNode.type.name]!.content;
675
+
676
+ if (contentType === "none") {
500
677
  this._tiptapEditor.commands.setNodeSelection(startPos);
501
678
  return;
502
679
  }
503
680
 
504
- if (placement === "start") {
505
- this._tiptapEditor.commands.setTextSelection(startPos + 1);
681
+ if (contentType === "inline") {
682
+ if (placement === "start") {
683
+ this._tiptapEditor.commands.setTextSelection(startPos + 1);
684
+ } else {
685
+ this._tiptapEditor.commands.setTextSelection(
686
+ startPos + contentNode.nodeSize - 1
687
+ );
688
+ }
689
+ } else if (contentType === "table") {
690
+ if (placement === "start") {
691
+ // Need to offset the position as we have to get through the `tableRow`
692
+ // and `tableCell` nodes to get to the `tableParagraph` node we want to
693
+ // set the selection in.
694
+ this._tiptapEditor.commands.setTextSelection(startPos + 4);
695
+ } else {
696
+ this._tiptapEditor.commands.setTextSelection(
697
+ startPos + contentNode.nodeSize - 4
698
+ );
699
+ }
506
700
  } else {
507
- this._tiptapEditor.commands.setTextSelection(
508
- startPos + contentNode.nodeSize - 1
509
- );
701
+ throw new UnreachableCaseError(contentType);
510
702
  }
511
703
  }
512
704
 
513
705
  /**
514
706
  * Gets a snapshot of the current selection.
515
707
  */
516
- public getSelection(): Selection<BSchema> | undefined {
708
+ public getSelection(): Selection<BSchema, ISchema, SSchema> | undefined {
517
709
  // Either the TipTap selection is empty, or it's a node selection. In either
518
710
  // case, it only spans one block, so we return undefined.
519
711
  if (
@@ -524,8 +716,10 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
524
716
  return undefined;
525
717
  }
526
718
 
527
- const blocks: Block<BSchema>[] = [];
719
+ const blocks: Block<BSchema, ISchema, SSchema>[] = [];
528
720
 
721
+ // TODO: This adds all child blocks to the same array. Needs to find min
722
+ // depth and only add blocks at that depth.
529
723
  this._tiptapEditor.state.doc.descendants((node, pos) => {
530
724
  if (node.type.spec.group !== "blockContent") {
531
725
  return true;
@@ -541,7 +735,9 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
541
735
  blocks.push(
542
736
  nodeToBlock(
543
737
  this._tiptapEditor.state.doc.resolve(pos).node(),
544
- this.schema,
738
+ this.blockSchema,
739
+ this.inlineContentSchema,
740
+ this.styleSchema,
545
741
  this.blockCache
546
742
  )
547
743
  );
@@ -577,11 +773,11 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
577
773
  * `referenceBlock`. Inserts the blocks at the start of the existing block's children if "nested" is used.
578
774
  */
579
775
  public insertBlocks(
580
- blocksToInsert: PartialBlock<BSchema>[],
776
+ blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[],
581
777
  referenceBlock: BlockIdentifier,
582
778
  placement: "before" | "after" | "nested" = "before"
583
779
  ): void {
584
- insertBlocks(blocksToInsert, referenceBlock, placement, this._tiptapEditor);
780
+ insertBlocks(blocksToInsert, referenceBlock, placement, this);
585
781
  }
586
782
 
587
783
  /**
@@ -593,7 +789,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
593
789
  */
594
790
  public updateBlock(
595
791
  blockToUpdate: BlockIdentifier,
596
- update: PartialBlock<BSchema>
792
+ update: PartialBlock<BSchema, ISchema, SSchema>
597
793
  ) {
598
794
  updateBlock(blockToUpdate, update, this._tiptapEditor);
599
795
  }
@@ -615,32 +811,28 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
615
811
  */
616
812
  public replaceBlocks(
617
813
  blocksToRemove: BlockIdentifier[],
618
- blocksToInsert: PartialBlock<BSchema>[]
814
+ blocksToInsert: PartialBlock<BSchema, ISchema, SSchema>[]
619
815
  ) {
620
- replaceBlocks(blocksToRemove, blocksToInsert, this._tiptapEditor);
816
+ replaceBlocks(blocksToRemove, blocksToInsert, this);
621
817
  }
622
818
 
623
819
  /**
624
820
  * Gets the active text styles at the text cursor position or at the end of the current selection if it's active.
625
821
  */
626
822
  public getActiveStyles() {
627
- const styles: Styles = {};
823
+ const styles: Styles<SSchema> = {};
628
824
  const marks = this._tiptapEditor.state.selection.$to.marks();
629
825
 
630
- const toggleStyles = new Set<ToggledStyle>([
631
- "bold",
632
- "italic",
633
- "underline",
634
- "strike",
635
- "code",
636
- ]);
637
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
638
-
639
826
  for (const mark of marks) {
640
- if (toggleStyles.has(mark.type.name as ToggledStyle)) {
641
- styles[mark.type.name as ToggledStyle] = true;
642
- } else if (colorStyles.has(mark.type.name as ColorStyle)) {
643
- styles[mark.type.name as ColorStyle] = mark.attrs.color;
827
+ const config = this.styleSchema[mark.type.name];
828
+ if (!config) {
829
+ console.warn("mark not found in styleschema", mark.type.name);
830
+ continue;
831
+ }
832
+ if (config.propSchema === "boolean") {
833
+ (styles as any)[config.type] = true;
834
+ } else {
835
+ (styles as any)[config.type] = mark.attrs.stringValue;
644
836
  }
645
837
  }
646
838
 
@@ -651,23 +843,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
651
843
  * Adds styles to the currently selected content.
652
844
  * @param styles The styles to add.
653
845
  */
654
- public addStyles(styles: Styles) {
655
- const toggleStyles = new Set<ToggledStyle>([
656
- "bold",
657
- "italic",
658
- "underline",
659
- "strike",
660
- "code",
661
- ]);
662
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
663
-
846
+ public addStyles(styles: Styles<SSchema>) {
664
847
  this._tiptapEditor.view.focus();
665
848
 
666
849
  for (const [style, value] of Object.entries(styles)) {
667
- if (toggleStyles.has(style as ToggledStyle)) {
850
+ const config = this.styleSchema[style];
851
+ if (!config) {
852
+ throw new Error(`style ${style} not found in styleSchema`);
853
+ }
854
+ if (config.propSchema === "boolean") {
668
855
  this._tiptapEditor.commands.setMark(style);
669
- } else if (colorStyles.has(style as ColorStyle)) {
670
- this._tiptapEditor.commands.setMark(style, { color: value });
856
+ } else if (config.propSchema === "string") {
857
+ this._tiptapEditor.commands.setMark(style, { stringValue: value });
858
+ } else {
859
+ throw new UnreachableCaseError(config.propSchema);
671
860
  }
672
861
  }
673
862
  }
@@ -676,7 +865,7 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
676
865
  * Removes styles from the currently selected content.
677
866
  * @param styles The styles to remove.
678
867
  */
679
- public removeStyles(styles: Styles) {
868
+ public removeStyles(styles: Styles<SSchema>) {
680
869
  this._tiptapEditor.view.focus();
681
870
 
682
871
  for (const style of Object.keys(styles)) {
@@ -688,23 +877,20 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
688
877
  * Toggles styles on the currently selected content.
689
878
  * @param styles The styles to toggle.
690
879
  */
691
- public toggleStyles(styles: Styles) {
692
- const toggleStyles = new Set<ToggledStyle>([
693
- "bold",
694
- "italic",
695
- "underline",
696
- "strike",
697
- "code",
698
- ]);
699
- const colorStyles = new Set<ColorStyle>(["textColor", "backgroundColor"]);
700
-
880
+ public toggleStyles(styles: Styles<SSchema>) {
701
881
  this._tiptapEditor.view.focus();
702
882
 
703
883
  for (const [style, value] of Object.entries(styles)) {
704
- if (toggleStyles.has(style as ToggledStyle)) {
884
+ const config = this.styleSchema[style];
885
+ if (!config) {
886
+ throw new Error(`style ${style} not found in styleSchema`);
887
+ }
888
+ if (config.propSchema === "boolean") {
705
889
  this._tiptapEditor.commands.toggleMark(style);
706
- } else if (colorStyles.has(style as ColorStyle)) {
707
- this._tiptapEditor.commands.toggleMark(style, { color: value });
890
+ } else if (config.propSchema === "string") {
891
+ this._tiptapEditor.commands.toggleMark(style, { stringValue: value });
892
+ } else {
893
+ throw new UnreachableCaseError(config.propSchema);
708
894
  }
709
895
  }
710
896
  }
@@ -789,14 +975,21 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
789
975
  this._tiptapEditor.commands.liftListItem("blockContainer");
790
976
  }
791
977
 
978
+ // TODO: Fix when implementing HTML/Markdown import & export
792
979
  /**
793
980
  * Serializes blocks into an HTML string. To better conform to HTML standards, children of blocks which aren't list
794
981
  * items are un-nested in the output HTML.
795
982
  * @param blocks An array of blocks that should be serialized into HTML.
796
983
  * @returns The blocks, serialized as an HTML string.
797
984
  */
798
- public async blocksToHTML(blocks: Block<BSchema>[]): Promise<string> {
799
- return blocksToHTML(blocks, this._tiptapEditor.schema);
985
+ public async blocksToHTMLLossy(
986
+ blocks = this.topLevelBlocks
987
+ ): Promise<string> {
988
+ const exporter = createExternalHTMLExporter(
989
+ this._tiptapEditor.schema,
990
+ this
991
+ );
992
+ return exporter.exportBlocks(blocks);
800
993
  }
801
994
 
802
995
  /**
@@ -806,8 +999,16 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
806
999
  * @param html The HTML string to parse blocks from.
807
1000
  * @returns The blocks parsed from the HTML string.
808
1001
  */
809
- public async HTMLToBlocks(html: string): Promise<Block<BSchema>[]> {
810
- return HTMLToBlocks(html, this.schema, this._tiptapEditor.schema);
1002
+ public async tryParseHTMLToBlocks(
1003
+ html: string
1004
+ ): Promise<Block<BSchema, ISchema, SSchema>[]> {
1005
+ return HTMLToBlocks(
1006
+ html,
1007
+ this.blockSchema,
1008
+ this.inlineContentSchema,
1009
+ this.styleSchema,
1010
+ this._tiptapEditor.schema
1011
+ );
811
1012
  }
812
1013
 
813
1014
  /**
@@ -816,8 +1017,10 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
816
1017
  * @param blocks An array of blocks that should be serialized into Markdown.
817
1018
  * @returns The blocks, serialized as a Markdown string.
818
1019
  */
819
- public async blocksToMarkdown(blocks: Block<BSchema>[]): Promise<string> {
820
- return blocksToMarkdown(blocks, this._tiptapEditor.schema);
1020
+ public async blocksToMarkdownLossy(
1021
+ blocks: Block<BSchema, ISchema, SSchema>[] = this.topLevelBlocks
1022
+ ): Promise<string> {
1023
+ return blocksToMarkdown(blocks, this._tiptapEditor.schema, this);
821
1024
  }
822
1025
 
823
1026
  /**
@@ -827,8 +1030,16 @@ export class BlockNoteEditor<BSchema extends BlockSchema = DefaultBlockSchema> {
827
1030
  * @param markdown The Markdown string to parse blocks from.
828
1031
  * @returns The blocks parsed from the Markdown string.
829
1032
  */
830
- public async markdownToBlocks(markdown: string): Promise<Block<BSchema>[]> {
831
- return markdownToBlocks(markdown, this.schema, this._tiptapEditor.schema);
1033
+ public async tryParseMarkdownToBlocks(
1034
+ markdown: string
1035
+ ): Promise<Block<BSchema, ISchema, SSchema>[]> {
1036
+ return markdownToBlocks(
1037
+ markdown,
1038
+ this.blockSchema,
1039
+ this.inlineContentSchema,
1040
+ this.styleSchema,
1041
+ this._tiptapEditor.schema
1042
+ );
832
1043
  }
833
1044
 
834
1045
  /**