@blocknote/core 0.9.6 → 0.10.1

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 (347) hide show
  1. package/dist/blocknote.js +3696 -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 +11 -5
  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/nested/markdown.md +5 -0
  110. package/src/api/exporters/markdown/__snapshots__/paragraph/styled/markdown.md +1 -0
  111. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/basic/markdown.md +1 -0
  112. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/nested/markdown.md +5 -0
  113. package/src/api/exporters/markdown/__snapshots__/simpleCustomParagraph/styled/markdown.md +1 -0
  114. package/src/api/exporters/markdown/__snapshots__/simpleImage/basic/markdown.md +1 -0
  115. package/src/api/exporters/markdown/__snapshots__/simpleImage/button/markdown.md +1 -0
  116. package/src/api/exporters/markdown/__snapshots__/simpleImage/nested/markdown.md +3 -0
  117. package/src/api/exporters/markdown/__snapshots__/small/basic/markdown.md +1 -0
  118. package/src/api/exporters/markdown/__snapshots__/tag/basic/markdown.md +1 -0
  119. package/src/api/exporters/markdown/markdownExporter.test.ts +85 -0
  120. package/src/api/exporters/markdown/markdownExporter.ts +42 -0
  121. package/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap +486 -125
  122. package/src/api/nodeConversions/nodeConversions.test.ts +67 -498
  123. package/src/api/nodeConversions/nodeConversions.ts +311 -85
  124. package/src/api/parsers/html/__snapshots__/paste/list-test.json +105 -0
  125. package/src/api/parsers/html/__snapshots__/paste/parse-basic-block-types.json +140 -0
  126. package/src/api/parsers/html/__snapshots__/paste/parse-deep-nested-content.json +240 -0
  127. package/src/api/parsers/html/__snapshots__/paste/parse-div-with-inline-content.json +91 -0
  128. package/src/api/parsers/html/__snapshots__/paste/parse-divs.json +121 -0
  129. package/src/api/parsers/html/__snapshots__/paste/parse-fake-image-caption.json +31 -0
  130. package/src/api/parsers/html/__snapshots__/paste/parse-google-docs-html.json +476 -0
  131. package/src/api/parsers/html/__snapshots__/paste/parse-mixed-nested-lists.json +140 -0
  132. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists-with-paragraphs.json +140 -0
  133. package/src/api/parsers/html/__snapshots__/paste/parse-nested-lists.json +157 -0
  134. package/src/api/parsers/html/__snapshots__/paste/parse-notion-html.json +470 -0
  135. package/src/api/parsers/html/__snapshots__/paste/parse-two-divs.json +36 -0
  136. package/src/api/parsers/html/parseHTML.test.ts +440 -0
  137. package/src/api/parsers/html/parseHTML.ts +42 -0
  138. package/src/api/parsers/html/util/__snapshots__/nestedLists.test.ts.snap +129 -0
  139. package/src/api/parsers/html/util/nestedLists.test.ts +176 -0
  140. package/src/api/parsers/html/util/nestedLists.ts +113 -0
  141. package/src/api/parsers/markdown/__snapshots__/complex.json +353 -0
  142. package/src/api/parsers/markdown/__snapshots__/issue-226-1.json +71 -0
  143. package/src/api/parsers/markdown/__snapshots__/issue-226-2.json +144 -0
  144. package/src/api/parsers/markdown/__snapshots__/nested.json +72 -0
  145. package/src/api/parsers/markdown/__snapshots__/non-nested.json +71 -0
  146. package/src/api/parsers/markdown/__snapshots__/styled.json +58 -0
  147. package/src/api/parsers/markdown/parseMarkdown.test.ts +114 -0
  148. package/src/api/parsers/markdown/parseMarkdown.ts +84 -0
  149. package/src/api/parsers/pasteExtension.ts +59 -0
  150. package/src/api/testUtil/cases/customBlocks.ts +282 -0
  151. package/src/api/testUtil/cases/customInlineContent.ts +114 -0
  152. package/src/api/testUtil/cases/customStyles.ts +100 -0
  153. package/src/api/testUtil/cases/defaultSchema.ts +399 -0
  154. package/src/api/testUtil/index.ts +17 -0
  155. package/src/api/testUtil/partialBlockTestUtil.ts +127 -0
  156. package/src/blocks/HeadingBlockContent/HeadingBlockContent.ts +136 -0
  157. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/ImageBlockContent.ts +87 -31
  158. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +34 -47
  159. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/ListItemKeyboardShortcuts.ts +1 -1
  160. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.ts +1 -1
  161. package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +34 -56
  162. package/src/blocks/ParagraphBlockContent/ParagraphBlockContent.ts +43 -0
  163. package/src/blocks/README.md +3 -0
  164. package/src/blocks/TableBlockContent/TableBlockContent.ts +74 -0
  165. package/src/blocks/TableBlockContent/TableExtension.ts +63 -0
  166. package/src/blocks/defaultBlockHelpers.ts +95 -0
  167. package/src/blocks/defaultBlocks.ts +60 -0
  168. package/src/blocks/defaultProps.ts +24 -0
  169. package/src/{extensions/Blocks/nodes/Block.module.css → editor/Block.css} +69 -62
  170. package/src/{BlockNoteEditor.test.ts → editor/BlockNoteEditor.test.ts} +2 -2
  171. package/src/{BlockNoteEditor.ts → editor/BlockNoteEditor.ts} +363 -153
  172. package/src/{BlockNoteExtensions.ts → editor/BlockNoteExtensions.ts} +59 -40
  173. package/src/editor/README.md +3 -0
  174. package/src/editor/cursorPositionTypes.ts +16 -0
  175. package/src/{editor.module.css → editor/editor.css} +43 -15
  176. package/src/editor/selectionTypes.ts +14 -0
  177. package/src/editor/transformPasted.ts +58 -0
  178. package/src/extensions/BackgroundColor/BackgroundColorExtension.ts +1 -36
  179. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +12 -27
  180. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +16 -24
  181. package/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts +12 -10
  182. package/src/extensions/ImageToolbar/ImageToolbarPlugin.ts +35 -73
  183. package/src/extensions/Placeholder/PlaceholderExtension.ts +4 -4
  184. package/src/extensions/README.md +3 -0
  185. package/src/extensions/SideMenu/SideMenuPlugin.ts +66 -37
  186. package/src/extensions/SlashMenu/BaseSlashMenuItem.ts +7 -6
  187. package/src/extensions/SlashMenu/SlashMenuPlugin.ts +9 -7
  188. package/src/extensions/SlashMenu/defaultSlashMenuItems.ts +98 -35
  189. package/src/extensions/TableHandles/TableHandlesPlugin.ts +617 -0
  190. package/src/extensions/TextAlignment/TextAlignmentExtension.ts +3 -51
  191. package/src/extensions/TextColor/TextColorExtension.ts +1 -29
  192. package/src/extensions/TextColor/TextColorMark.ts +7 -27
  193. package/src/extensions/UniqueID/UniqueID.ts +28 -2
  194. package/src/extensions-shared/README.md +3 -0
  195. package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionPlugin.ts +19 -13
  196. package/src/index.ts +21 -15
  197. package/src/{extensions/Blocks/nodes → pm-nodes}/BlockContainer.ts +161 -96
  198. package/src/pm-nodes/BlockGroup.ts +54 -0
  199. package/src/pm-nodes/Doc.ts +7 -0
  200. package/src/pm-nodes/README.md +42 -0
  201. package/src/pm-nodes/index.ts +3 -0
  202. package/src/schema/README.md +3 -0
  203. package/src/schema/blocks/createSpec.ts +220 -0
  204. package/src/schema/blocks/internal.ts +253 -0
  205. package/src/schema/blocks/types.ts +252 -0
  206. package/src/schema/index.ts +10 -0
  207. package/src/schema/inlineContent/createSpec.ts +119 -0
  208. package/src/schema/inlineContent/internal.ts +105 -0
  209. package/src/schema/inlineContent/types.ts +144 -0
  210. package/src/schema/propTypes.ts +32 -0
  211. package/src/schema/styles/createSpec.ts +85 -0
  212. package/src/schema/styles/internal.ts +96 -0
  213. package/src/schema/styles/types.ts +42 -0
  214. package/src/util/README.md +3 -0
  215. package/src/{shared/utils.ts → util/browser.ts} +4 -8
  216. package/src/util/string.ts +3 -0
  217. package/src/util/typescript.ts +5 -0
  218. package/types/src/api/blockManipulation/blockManipulation.d.ts +5 -4
  219. package/types/src/api/exporters/copyExtension.d.ts +6 -0
  220. package/types/src/api/exporters/html/externalHTMLExporter.d.ts +8 -0
  221. package/types/src/api/exporters/html/internalHTMLSerializer.d.ts +8 -0
  222. package/types/src/api/exporters/html/util/sharedHTMLConversion.d.ts +7 -0
  223. package/types/src/api/exporters/markdown/markdownExporter.d.ts +5 -0
  224. package/types/src/api/nodeConversions/nodeConversions.d.ts +14 -6
  225. package/types/src/api/parsers/html/parseHTML.d.ts +3 -0
  226. package/types/src/api/parsers/html/parseHTML.test.d.ts +1 -0
  227. package/types/src/api/parsers/html/util/nestedLists.d.ts +1 -0
  228. package/types/src/api/parsers/html/util/nestedLists.test.d.ts +1 -0
  229. package/types/src/api/parsers/markdown/parseMarkdown.d.ts +3 -0
  230. package/types/src/api/parsers/markdown/parseMarkdown.test.d.ts +1 -0
  231. package/types/src/api/parsers/pasteExtension.d.ts +6 -0
  232. package/types/src/api/testUtil/cases/customBlocks.d.ts +345 -0
  233. package/types/src/api/testUtil/cases/customInlineContent.d.ts +29 -0
  234. package/types/src/api/testUtil/cases/customStyles.d.ts +64 -0
  235. package/types/src/api/testUtil/cases/defaultSchema.d.ts +3 -0
  236. package/types/src/api/testUtil/index.d.ts +12 -0
  237. package/types/src/api/testUtil/partialBlockTestUtil.d.ts +7 -0
  238. package/types/src/blocks/HeadingBlockContent/HeadingBlockContent.d.ts +58 -0
  239. package/types/src/blocks/ImageBlockContent/ImageBlockContent.d.ts +93 -0
  240. package/types/src/blocks/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +46 -0
  241. package/types/src/blocks/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +46 -0
  242. package/types/src/blocks/ParagraphBlockContent/ParagraphBlockContent.d.ts +52 -0
  243. package/types/src/blocks/TableBlockContent/TableBlockContent.d.ts +53 -0
  244. package/types/src/blocks/TableBlockContent/TableExtension.d.ts +2 -0
  245. package/types/src/blocks/defaultBlockHelpers.d.ts +10 -0
  246. package/types/src/blocks/defaultBlocks.d.ts +577 -0
  247. package/types/src/{extensions/Blocks/api → blocks}/defaultProps.d.ts +2 -1
  248. package/types/src/{BlockNoteEditor.d.ts → editor/BlockNoteEditor.d.ts} +54 -43
  249. package/types/src/editor/BlockNoteEditor.test.d.ts +1 -0
  250. package/types/src/{BlockNoteExtensions.d.ts → editor/BlockNoteExtensions.d.ts} +7 -4
  251. package/types/src/editor/cursorPositionTypes.d.ts +6 -0
  252. package/types/src/editor/selectionTypes.d.ts +4 -0
  253. package/types/src/editor/transformPasted.d.ts +12 -0
  254. package/types/src/extensions/BackgroundColor/BackgroundColorExtension.d.ts +0 -7
  255. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +7 -9
  256. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +8 -6
  257. package/types/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.d.ts +6 -6
  258. package/types/src/extensions/ImageToolbar/ImageToolbarPlugin.d.ts +11 -16
  259. package/types/src/extensions/SideMenu/SideMenuPlugin.d.ts +18 -11
  260. package/types/src/extensions/SlashMenu/BaseSlashMenuItem.d.ts +5 -6
  261. package/types/src/extensions/SlashMenu/SlashMenuPlugin.d.ts +6 -6
  262. package/types/src/extensions/SlashMenu/defaultSlashMenuItems.d.ts +2 -1
  263. package/types/src/extensions/TableHandles/TableHandlesPlugin.d.ts +74 -0
  264. package/types/src/extensions/TextAlignment/TextAlignmentExtension.d.ts +0 -7
  265. package/types/src/extensions/TextColor/TextColorExtension.d.ts +0 -7
  266. package/types/src/extensions/TextColor/TextColorMark.d.ts +7 -9
  267. package/types/src/extensions/UniqueID/UniqueID.d.ts +1 -1
  268. package/types/src/{shared/plugins → extensions-shared}/suggestion/SuggestionPlugin.d.ts +5 -4
  269. package/types/src/index.d.ts +20 -15
  270. package/types/src/{extensions/Blocks/nodes → pm-nodes}/BlockContainer.d.ts +5 -3
  271. package/types/src/pm-nodes/Doc.d.ts +2 -0
  272. package/types/src/pm-nodes/index.d.ts +3 -0
  273. package/types/src/schema/blocks/createSpec.d.ts +35 -0
  274. package/types/src/schema/blocks/internal.d.ts +45 -0
  275. package/types/src/schema/blocks/types.d.ts +107 -0
  276. package/types/src/schema/index.d.ts +10 -0
  277. package/types/src/schema/inlineContent/createSpec.d.ts +21 -0
  278. package/types/src/schema/inlineContent/internal.d.ts +28 -0
  279. package/types/src/schema/inlineContent/types.d.ts +62 -0
  280. package/types/src/schema/propTypes.d.ts +8 -0
  281. package/types/src/schema/styles/createSpec.d.ts +13 -0
  282. package/types/src/schema/styles/internal.d.ts +22 -0
  283. package/types/src/schema/styles/types.d.ts +21 -0
  284. package/types/src/{shared/utils.d.ts → util/browser.d.ts} +0 -3
  285. package/types/src/util/string.d.ts +1 -0
  286. package/types/src/util/typescript.d.ts +3 -0
  287. package/src/api/formatConversions/__snapshots__/formatConversions.test.ts.snap +0 -346
  288. package/src/api/formatConversions/formatConversions.test.ts +0 -753
  289. package/src/api/formatConversions/formatConversions.ts +0 -133
  290. package/src/api/nodeConversions/testUtil.ts +0 -65
  291. package/src/extensions/Blocks/api/block.ts +0 -307
  292. package/src/extensions/Blocks/api/blockTypes.ts +0 -249
  293. package/src/extensions/Blocks/api/cursorPositionTypes.ts +0 -7
  294. package/src/extensions/Blocks/api/defaultBlocks.ts +0 -16
  295. package/src/extensions/Blocks/api/defaultProps.ts +0 -16
  296. package/src/extensions/Blocks/api/inlineContentTypes.ts +0 -36
  297. package/src/extensions/Blocks/api/selectionTypes.ts +0 -5
  298. package/src/extensions/Blocks/api/serialization.ts +0 -29
  299. package/src/extensions/Blocks/helpers/findBlock.ts +0 -5
  300. package/src/extensions/Blocks/index.ts +0 -8
  301. package/src/extensions/Blocks/nodes/BlockAttributes.ts +0 -10
  302. package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +0 -142
  303. package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +0 -62
  304. package/src/extensions/Blocks/nodes/BlockGroup.ts +0 -53
  305. package/types/src/api/formatConversions/formatConversions.d.ts +0 -6
  306. package/types/src/api/nodeConversions/testUtil.d.ts +0 -2
  307. package/types/src/extensions/Blocks/api/block.d.ts +0 -20
  308. package/types/src/extensions/Blocks/api/blockTypes.d.ts +0 -103
  309. package/types/src/extensions/Blocks/api/cursorPositionTypes.d.ts +0 -6
  310. package/types/src/extensions/Blocks/api/defaultBlocks.d.ts +0 -117
  311. package/types/src/extensions/Blocks/api/inlineContentTypes.d.ts +0 -30
  312. package/types/src/extensions/Blocks/api/selectionTypes.d.ts +0 -4
  313. package/types/src/extensions/Blocks/api/serialization.d.ts +0 -2
  314. package/types/src/extensions/Blocks/helpers/findBlock.d.ts +0 -6
  315. package/types/src/extensions/Blocks/index.d.ts +0 -4
  316. package/types/src/extensions/Blocks/nodes/BlockAttributes.d.ts +0 -2
  317. package/types/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.d.ts +0 -43
  318. package/types/src/extensions/Blocks/nodes/BlockContent/ImageBlockContent/ImageBlockContent.d.ts +0 -37
  319. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.d.ts +0 -35
  320. package/types/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.d.ts +0 -35
  321. package/types/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.d.ts +0 -44
  322. /package/src/{shared/EditorElement.ts → api/exporters/markdown/__snapshots__/hardbreak/only/markdown.md} +0 -0
  323. /package/{types/src/shared/EditorElement.d.ts → src/api/exporters/markdown/__snapshots__/paragraph/empty/markdown.md} +0 -0
  324. /package/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.ts +0 -0
  325. /package/src/{extensions/Blocks/helpers → api}/getBlockInfoFromPos.ts +0 -0
  326. /package/src/api/{util/nodeUtil.ts → nodeUtil.ts} +0 -0
  327. /package/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.ts +0 -0
  328. /package/src/extensions/{Blocks → NonEditableBlocks}/NonEditableBlockPlugin.ts +0 -0
  329. /package/src/extensions/{Blocks → PreviousBlockType}/PreviousBlockTypePlugin.ts +0 -0
  330. /package/src/{shared → extensions-shared}/BaseUiElementTypes.ts +0 -0
  331. /package/src/{shared/plugins → extensions-shared}/suggestion/SuggestionItem.ts +0 -0
  332. /package/src/{shared → util}/EventEmitter.ts +0 -0
  333. /package/types/src/{BlockNoteEditor.test.d.ts → api/exporters/html/htmlConversion.test.d.ts} +0 -0
  334. /package/types/src/api/{formatConversions → exporters/html/util}/simplifyBlocksRehypePlugin.d.ts +0 -0
  335. /package/types/src/api/{formatConversions/formatConversions.test.d.ts → exporters/markdown/markdownExporter.test.d.ts} +0 -0
  336. /package/types/src/api/{formatConversions → exporters/markdown}/removeUnderlinesRehypePlugin.d.ts +0 -0
  337. /package/types/src/{extensions/Blocks/helpers → api}/getBlockInfoFromPos.d.ts +0 -0
  338. /package/types/src/api/{util/nodeUtil.d.ts → nodeUtil.d.ts} +0 -0
  339. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ImageBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.d.ts +0 -0
  340. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/ListItemKeyboardShortcuts.d.ts +0 -0
  341. /package/types/src/{extensions/Blocks/nodes/BlockContent → blocks}/ListItemBlockContent/NumberedListItemBlockContent/NumberedListIndexingPlugin.d.ts +0 -0
  342. /package/types/src/extensions/{Blocks → NonEditableBlocks}/NonEditableBlockPlugin.d.ts +0 -0
  343. /package/types/src/extensions/{Blocks → PreviousBlockType}/PreviousBlockTypePlugin.d.ts +0 -0
  344. /package/types/src/{shared → extensions-shared}/BaseUiElementTypes.d.ts +0 -0
  345. /package/types/src/{shared/plugins → extensions-shared}/suggestion/SuggestionItem.d.ts +0 -0
  346. /package/types/src/{extensions/Blocks/nodes → pm-nodes}/BlockGroup.d.ts +0 -0
  347. /package/types/src/{shared → util}/EventEmitter.d.ts +0 -0
@@ -1,48 +1,44 @@
1
- import { Node as PMNode } from "prosemirror-model";
2
1
  import { EditorState, Plugin, PluginKey } from "prosemirror-state";
3
2
  import { EditorView } from "prosemirror-view";
3
+
4
+ import { EventEmitter } from "../../util/EventEmitter";
5
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
4
6
  import {
5
- BaseUiElementCallbacks,
6
- BaseUiElementState,
7
- BlockNoteEditor,
8
7
  BlockSchema,
9
- BlockSpec,
8
+ InlineContentSchema,
10
9
  SpecificBlock,
11
- } from "../..";
12
- import { EventEmitter } from "../../shared/EventEmitter";
13
-
10
+ StyleSchema,
11
+ } from "../../schema";
12
+ import {
13
+ BaseUiElementCallbacks,
14
+ BaseUiElementState,
15
+ } from "../../extensions-shared/BaseUiElementTypes";
14
16
  export type ImageToolbarCallbacks = BaseUiElementCallbacks;
15
17
 
16
- export type ImageToolbarState = BaseUiElementState & {
17
- block: SpecificBlock<
18
- BlockSchema & {
19
- image: BlockSpec<
20
- "image",
21
- {
22
- src: { default: string };
23
- },
24
- false
25
- >;
26
- },
27
- "image"
28
- >;
18
+ export type ImageToolbarState<
19
+ B extends BlockSchema,
20
+ I extends InlineContentSchema,
21
+ S extends StyleSchema = StyleSchema
22
+ > = BaseUiElementState & {
23
+ block: SpecificBlock<B, "image", I, S>;
29
24
  };
30
25
 
31
- export class ImageToolbarView {
32
- private imageToolbarState?: ImageToolbarState;
26
+ export class ImageToolbarView<
27
+ BSchema extends BlockSchema,
28
+ I extends InlineContentSchema,
29
+ S extends StyleSchema
30
+ > {
31
+ private imageToolbarState?: ImageToolbarState<BSchema, I, S>;
33
32
  public updateImageToolbar: () => void;
34
33
 
35
34
  public prevWasEditable: boolean | null = null;
36
35
 
37
- public shouldShow: (state: EditorState) => boolean = (state) =>
38
- "node" in state.selection &&
39
- (state.selection.node as PMNode).type.name === "image" &&
40
- (state.selection.node as PMNode).attrs.src === "";
41
-
42
36
  constructor(
43
37
  private readonly pluginKey: PluginKey,
44
38
  private readonly pmView: EditorView,
45
- updateImageToolbar: (imageToolbarState: ImageToolbarState) => void
39
+ updateImageToolbar: (
40
+ imageToolbarState: ImageToolbarState<BSchema, I, S>
41
+ ) => void
46
42
  ) {
47
43
  this.updateImageToolbar = () => {
48
44
  if (!this.imageToolbarState) {
@@ -112,18 +108,7 @@ export class ImageToolbarView {
112
108
 
113
109
  update(view: EditorView, prevState: EditorState) {
114
110
  const pluginState: {
115
- block: SpecificBlock<
116
- BlockSchema & {
117
- image: BlockSpec<
118
- "image",
119
- {
120
- src: { default: string };
121
- },
122
- false
123
- >;
124
- },
125
- "image"
126
- >;
111
+ block: SpecificBlock<BSchema, "image", I, S>;
127
112
  } = this.pluginKey.getState(view.state);
128
113
 
129
114
  if (!this.imageToolbarState?.show && pluginState.block) {
@@ -168,28 +153,17 @@ export class ImageToolbarView {
168
153
  export const imageToolbarPluginKey = new PluginKey("ImageToolbarPlugin");
169
154
 
170
155
  export class ImageToolbarProsemirrorPlugin<
171
- BSchema extends BlockSchema
156
+ BSchema extends BlockSchema,
157
+ I extends InlineContentSchema,
158
+ S extends StyleSchema
172
159
  > extends EventEmitter<any> {
173
- private view: ImageToolbarView | undefined;
160
+ private view: ImageToolbarView<BSchema, I, S> | undefined;
174
161
  public readonly plugin: Plugin;
175
162
 
176
- constructor(_editor: BlockNoteEditor<BSchema>) {
163
+ constructor(_editor: BlockNoteEditor<BSchema, I, S>) {
177
164
  super();
178
165
  this.plugin = new Plugin<{
179
- block:
180
- | SpecificBlock<
181
- BlockSchema & {
182
- image: BlockSpec<
183
- "image",
184
- {
185
- src: { default: string };
186
- },
187
- false
188
- >;
189
- },
190
- "image"
191
- >
192
- | undefined;
166
+ block: SpecificBlock<BSchema, "image", I, S> | undefined;
193
167
  }>({
194
168
  key: imageToolbarPluginKey,
195
169
  view: (editorView) => {
@@ -210,20 +184,8 @@ export class ImageToolbarProsemirrorPlugin<
210
184
  };
211
185
  },
212
186
  apply: (transaction) => {
213
- const block:
214
- | SpecificBlock<
215
- BlockSchema & {
216
- image: BlockSpec<
217
- "image",
218
- {
219
- src: { default: string };
220
- },
221
- false
222
- >;
223
- },
224
- "image"
225
- >
226
- | undefined = transaction.getMeta(imageToolbarPluginKey)?.block;
187
+ const block: SpecificBlock<BSchema, "image", I, S> | undefined =
188
+ transaction.getMeta(imageToolbarPluginKey)?.block;
227
189
 
228
190
  return {
229
191
  block,
@@ -233,7 +195,7 @@ export class ImageToolbarProsemirrorPlugin<
233
195
  });
234
196
  }
235
197
 
236
- public onUpdate(callback: (state: ImageToolbarState) => void) {
198
+ public onUpdate(callback: (state: ImageToolbarState<BSchema, I, S>) => void) {
237
199
  return this.on("update", callback);
238
200
  }
239
201
  }
@@ -36,10 +36,10 @@ export const Placeholder = Extension.create<PlaceholderOptions>({
36
36
 
37
37
  addOptions() {
38
38
  return {
39
- emptyEditorClass: "is-editor-empty",
40
- emptyNodeClass: "is-empty",
41
- isFilterClass: "is-filter",
42
- hasAnchorClass: "has-anchor",
39
+ emptyEditorClass: "bn-is-editor-empty",
40
+ emptyNodeClass: "bn-is-empty",
41
+ isFilterClass: "bn-is-filter",
42
+ hasAnchorClass: "bn-has-anchor",
43
43
  placeholder: "Write something …",
44
44
  showOnlyWhenEditable: true,
45
45
  showOnlyCurrent: true,
@@ -0,0 +1,3 @@
1
+ ### @blocknote/core/src/extensions
2
+
3
+ All extra extensions for TipTap / Prosemirror needed to implement the Prosemirror UX and editor behavior.
@@ -1,28 +1,35 @@
1
1
  import { PluginView } from "@tiptap/pm/state";
2
2
  import { Node } from "prosemirror-model";
3
3
  import { NodeSelection, Plugin, PluginKey, Selection } from "prosemirror-state";
4
- import * as pv from "prosemirror-view";
5
4
  import { EditorView } from "prosemirror-view";
6
- import { BlockNoteEditor } from "../../BlockNoteEditor";
7
- import styles from "../../editor.module.css";
8
- import { BaseUiElementState } from "../../shared/BaseUiElementTypes";
9
- import { EventEmitter } from "../../shared/EventEmitter";
10
- import { Block, BlockSchema } from "../Blocks/api/blockTypes";
11
- import { getBlockInfoFromPos } from "../Blocks/helpers/getBlockInfoFromPos";
5
+ import { createExternalHTMLExporter } from "../../api/exporters/html/externalHTMLExporter";
6
+ import { createInternalHTMLSerializer } from "../../api/exporters/html/internalHTMLSerializer";
7
+ import { cleanHTMLToMarkdown } from "../../api/exporters/markdown/markdownExporter";
8
+ import { getBlockInfoFromPos } from "../../api/getBlockInfoFromPos";
9
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
10
+ import { BaseUiElementState } from "../../extensions-shared/BaseUiElementTypes";
11
+ import {
12
+ Block,
13
+ BlockSchema,
14
+ InlineContentSchema,
15
+ StyleSchema,
16
+ } from "../../schema";
17
+ import { EventEmitter } from "../../util/EventEmitter";
12
18
  import { slashMenuPluginKey } from "../SlashMenu/SlashMenuPlugin";
13
19
  import { MultipleNodeSelection } from "./MultipleNodeSelection";
14
20
 
15
- const serializeForClipboard = (pv as any).__serializeForClipboard;
16
- // code based on https://github.com/ueberdosis/tiptap/issues/323#issuecomment-506637799
17
-
18
21
  let dragImageElement: Element | undefined;
19
22
 
20
- export type SideMenuState<BSchema extends BlockSchema> = BaseUiElementState & {
23
+ export type SideMenuState<
24
+ BSchema extends BlockSchema,
25
+ I extends InlineContentSchema,
26
+ S extends StyleSchema
27
+ > = BaseUiElementState & {
21
28
  // The block that the side menu is attached to.
22
- block: Block<BSchema>;
29
+ block: Block<BSchema, I, S>;
23
30
  };
24
31
 
25
- function getDraggableBlockFromCoords(
32
+ export function getDraggableBlockFromCoords(
26
33
  coords: { left: number; top: number },
27
34
  view: EditorView
28
35
  ) {
@@ -153,18 +160,14 @@ function setDragImage(view: EditorView, from: number, to = from) {
153
160
  const inheritedClasses = classes
154
161
  .filter(
155
162
  (className) =>
156
- !className.includes("bn") &&
157
- !className.includes("ProseMirror") &&
158
- !className.includes("editor")
163
+ className !== "ProseMirror" &&
164
+ className !== "bn-root" &&
165
+ className !== "bn-editor"
159
166
  )
160
167
  .join(" ");
161
168
 
162
169
  dragImageElement.className =
163
- dragImageElement.className +
164
- " " +
165
- styles.dragPreview +
166
- " " +
167
- inheritedClasses;
170
+ dragImageElement.className + " bn-drag-preview " + inheritedClasses;
168
171
 
169
172
  document.body.appendChild(dragImageElement);
170
173
  }
@@ -176,14 +179,20 @@ function unsetDragImage() {
176
179
  }
177
180
  }
178
181
 
179
- function dragStart(
182
+ function dragStart<
183
+ BSchema extends BlockSchema,
184
+ I extends InlineContentSchema,
185
+ S extends StyleSchema
186
+ >(
180
187
  e: { dataTransfer: DataTransfer | null; clientY: number },
181
- view: EditorView
188
+ editor: BlockNoteEditor<BSchema, I, S>
182
189
  ) {
183
190
  if (!e.dataTransfer) {
184
191
  return;
185
192
  }
186
193
 
194
+ const view = editor.prosemirrorView;
195
+
187
196
  const editorBoundingBox = view.dom.getBoundingClientRect();
188
197
 
189
198
  const coords = {
@@ -215,20 +224,38 @@ function dragStart(
215
224
  setDragImage(view, pos);
216
225
  }
217
226
 
218
- const slice = view.state.selection.content();
219
- const { dom, text } = serializeForClipboard(view, slice);
227
+ const selectedSlice = view.state.selection.content();
228
+ const schema = editor._tiptapEditor.schema;
229
+
230
+ const internalHTMLSerializer = createInternalHTMLSerializer(schema, editor);
231
+ const internalHTML = internalHTMLSerializer.serializeProseMirrorFragment(
232
+ selectedSlice.content
233
+ );
234
+
235
+ const externalHTMLExporter = createExternalHTMLExporter(schema, editor);
236
+ const externalHTML = externalHTMLExporter.exportProseMirrorFragment(
237
+ selectedSlice.content
238
+ );
239
+
240
+ const plainText = cleanHTMLToMarkdown(externalHTML);
220
241
 
221
242
  e.dataTransfer.clearData();
222
- e.dataTransfer.setData("text/html", dom.innerHTML);
223
- e.dataTransfer.setData("text/plain", text);
243
+ e.dataTransfer.setData("blocknote/html", internalHTML);
244
+ e.dataTransfer.setData("text/html", externalHTML);
245
+ e.dataTransfer.setData("text/plain", plainText);
224
246
  e.dataTransfer.effectAllowed = "move";
225
247
  e.dataTransfer.setDragImage(dragImageElement!, 0, 0);
226
- view.dragging = { slice, move: true };
248
+ view.dragging = { slice: selectedSlice, move: true };
227
249
  }
228
250
  }
229
251
 
230
- export class SideMenuView<BSchema extends BlockSchema> implements PluginView {
231
- private sideMenuState?: SideMenuState<BSchema>;
252
+ export class SideMenuView<
253
+ BSchema extends BlockSchema,
254
+ I extends InlineContentSchema,
255
+ S extends StyleSchema
256
+ > implements PluginView
257
+ {
258
+ private sideMenuState?: SideMenuState<BSchema, I, S>;
232
259
 
233
260
  // When true, the drag handle with be anchored at the same level as root elements
234
261
  // When false, the drag handle with be just to the left of the element
@@ -244,10 +271,10 @@ export class SideMenuView<BSchema extends BlockSchema> implements PluginView {
244
271
  public menuFrozen = false;
245
272
 
246
273
  constructor(
247
- private readonly editor: BlockNoteEditor<BSchema>,
274
+ private readonly editor: BlockNoteEditor<BSchema, I, S>,
248
275
  private readonly pmView: EditorView,
249
276
  private readonly updateSideMenu: (
250
- sideMenuState: SideMenuState<BSchema>
277
+ sideMenuState: SideMenuState<BSchema, I, S>
251
278
  ) => void
252
279
  ) {
253
280
  this.horizontalPosAnchoredAtRoot = true;
@@ -552,12 +579,14 @@ export class SideMenuView<BSchema extends BlockSchema> implements PluginView {
552
579
  export const sideMenuPluginKey = new PluginKey("SideMenuPlugin");
553
580
 
554
581
  export class SideMenuProsemirrorPlugin<
555
- BSchema extends BlockSchema
582
+ BSchema extends BlockSchema,
583
+ I extends InlineContentSchema,
584
+ S extends StyleSchema
556
585
  > extends EventEmitter<any> {
557
- private sideMenuView: SideMenuView<BSchema> | undefined;
586
+ private sideMenuView: SideMenuView<BSchema, I, S> | undefined;
558
587
  public readonly plugin: Plugin;
559
588
 
560
- constructor(private readonly editor: BlockNoteEditor<BSchema>) {
589
+ constructor(private readonly editor: BlockNoteEditor<BSchema, I, S>) {
561
590
  super();
562
591
  this.plugin = new Plugin({
563
592
  key: sideMenuPluginKey,
@@ -574,7 +603,7 @@ export class SideMenuProsemirrorPlugin<
574
603
  });
575
604
  }
576
605
 
577
- public onUpdate(callback: (state: SideMenuState<BSchema>) => void) {
606
+ public onUpdate(callback: (state: SideMenuState<BSchema, I, S>) => void) {
578
607
  return this.on("update", callback);
579
608
  }
580
609
 
@@ -592,7 +621,7 @@ export class SideMenuProsemirrorPlugin<
592
621
  clientY: number;
593
622
  }) => {
594
623
  this.sideMenuView!.isDragging = true;
595
- dragStart(event, this.editor.prosemirrorView);
624
+ dragStart(event, this.editor);
596
625
  };
597
626
 
598
627
  /**
@@ -1,11 +1,12 @@
1
- import { SuggestionItem } from "../../shared/plugins/suggestion/SuggestionItem";
2
- import { BlockNoteEditor } from "../../BlockNoteEditor";
3
- import { BlockSchema } from "../Blocks/api/blockTypes";
4
- import { DefaultBlockSchema } from "../Blocks/api/defaultBlocks";
1
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
2
+ import { SuggestionItem } from "../../extensions-shared/suggestion/SuggestionItem";
3
+ import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
5
4
 
6
5
  export type BaseSlashMenuItem<
7
- BSchema extends BlockSchema = DefaultBlockSchema
6
+ BSchema extends BlockSchema,
7
+ I extends InlineContentSchema,
8
+ S extends StyleSchema
8
9
  > = SuggestionItem & {
9
- execute: (editor: BlockNoteEditor<BSchema>) => void;
10
+ execute: (editor: BlockNoteEditor<BSchema, I, S>) => void;
10
11
  aliases?: string[];
11
12
  };
@@ -1,26 +1,28 @@
1
1
  import { Plugin, PluginKey } from "prosemirror-state";
2
2
 
3
- import { BlockNoteEditor } from "../../BlockNoteEditor";
4
- import { EventEmitter } from "../../shared/EventEmitter";
3
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
5
4
  import {
6
5
  SuggestionsMenuState,
7
6
  setupSuggestionsMenu,
8
- } from "../../shared/plugins/suggestion/SuggestionPlugin";
9
- import { BlockSchema } from "../Blocks/api/blockTypes";
7
+ } from "../../extensions-shared/suggestion/SuggestionPlugin";
8
+ import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
9
+ import { EventEmitter } from "../../util/EventEmitter";
10
10
  import { BaseSlashMenuItem } from "./BaseSlashMenuItem";
11
11
 
12
12
  export const slashMenuPluginKey = new PluginKey("SlashMenuPlugin");
13
13
 
14
14
  export class SlashMenuProsemirrorPlugin<
15
15
  BSchema extends BlockSchema,
16
- SlashMenuItem extends BaseSlashMenuItem<BSchema>
16
+ I extends InlineContentSchema,
17
+ S extends StyleSchema,
18
+ SlashMenuItem extends BaseSlashMenuItem<BSchema, I, S>
17
19
  > extends EventEmitter<any> {
18
20
  public readonly plugin: Plugin;
19
21
  public readonly itemCallback: (item: SlashMenuItem) => void;
20
22
 
21
- constructor(editor: BlockNoteEditor<BSchema>, items: SlashMenuItem[]) {
23
+ constructor(editor: BlockNoteEditor<BSchema, I, S>, items: SlashMenuItem[]) {
22
24
  super();
23
- const suggestions = setupSuggestionsMenu<SlashMenuItem, BSchema>(
25
+ const suggestions = setupSuggestionsMenu<SlashMenuItem, BSchema, I, S>(
24
26
  editor,
25
27
  (state) => {
26
28
  this.emit("update", state);
@@ -1,42 +1,87 @@
1
- import { BlockNoteEditor } from "../../BlockNoteEditor";
2
- import { BlockSchema, PartialBlock } from "../Blocks/api/blockTypes";
3
- import { BaseSlashMenuItem } from "./BaseSlashMenuItem";
4
- import { defaultBlockSchema } from "../Blocks/api/defaultBlocks";
1
+ import { defaultBlockSchema } from "../../blocks/defaultBlocks";
2
+ import type { BlockNoteEditor } from "../../editor/BlockNoteEditor";
3
+ import {
4
+ Block,
5
+ BlockSchema,
6
+ InlineContentSchema,
7
+ PartialBlock,
8
+ StyleSchema,
9
+ isStyledTextInlineContent,
10
+ } from "../../schema";
5
11
  import { imageToolbarPluginKey } from "../ImageToolbar/ImageToolbarPlugin";
12
+ import { BaseSlashMenuItem } from "./BaseSlashMenuItem";
13
+
14
+ // Sets the editor's text cursor position to the next content editable block,
15
+ // so either a block with inline content or a table. The last block is always a
16
+ // paragraph, so this function won't try to set the cursor position past the
17
+ // last block.
18
+ function setSelectionToNextContentEditableBlock<
19
+ BSchema extends BlockSchema,
20
+ I extends InlineContentSchema,
21
+ S extends StyleSchema
22
+ >(editor: BlockNoteEditor<BSchema, I, S>) {
23
+ let block = editor.getTextCursorPosition().block;
24
+ let contentType = editor.blockSchema[block.type].content;
25
+
26
+ while (contentType === "none") {
27
+ block = editor.getTextCursorPosition().nextBlock!;
28
+ contentType = editor.blockSchema[block.type].content as
29
+ | "inline"
30
+ | "table"
31
+ | "none";
32
+ editor.setTextCursorPosition(block, "end");
33
+ }
34
+ }
6
35
 
7
- function insertOrUpdateBlock<BSchema extends BlockSchema>(
8
- editor: BlockNoteEditor<BSchema>,
9
- block: PartialBlock<BSchema>
10
- ) {
36
+ // Checks if the current block is empty or only contains a slash, and if so,
37
+ // updates the current block instead of inserting a new one below. If the new
38
+ // block doesn't contain editable content, the cursor is moved to the next block
39
+ // that does.
40
+ function insertOrUpdateBlock<
41
+ BSchema extends BlockSchema,
42
+ I extends InlineContentSchema,
43
+ S extends StyleSchema
44
+ >(
45
+ editor: BlockNoteEditor<BSchema, I, S>,
46
+ block: PartialBlock<BSchema, I, S>
47
+ ): Block<BSchema, I, S> {
11
48
  const currentBlock = editor.getTextCursorPosition().block;
12
49
 
13
50
  if (currentBlock.content === undefined) {
14
- throw new Error(
15
- "Slash Menu open in a block that doesn't contain inline content."
16
- );
51
+ throw new Error("Slash Menu open in a block that doesn't contain content.");
17
52
  }
18
53
 
19
54
  if (
20
- (currentBlock.content.length === 1 &&
55
+ Array.isArray(currentBlock.content) &&
56
+ ((currentBlock.content.length === 1 &&
57
+ isStyledTextInlineContent(currentBlock.content[0]) &&
21
58
  currentBlock.content[0].type === "text" &&
22
59
  currentBlock.content[0].text === "/") ||
23
- currentBlock.content.length === 0
60
+ currentBlock.content.length === 0)
24
61
  ) {
25
62
  editor.updateBlock(currentBlock, block);
26
63
  } else {
27
64
  editor.insertBlocks([block], currentBlock, "after");
28
- editor.setTextCursorPosition(editor.getTextCursorPosition().nextBlock!);
65
+ editor.setTextCursorPosition(
66
+ editor.getTextCursorPosition().nextBlock!,
67
+ "end"
68
+ );
29
69
  }
70
+
71
+ const insertedBlock = editor.getTextCursorPosition().block;
72
+ setSelectionToNextContentEditableBlock(editor);
73
+
74
+ return insertedBlock;
30
75
  }
31
76
 
32
- export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
33
- // This type casting is weird, but it's the best way of doing it, as it allows
34
- // the schema type to be automatically inferred if it is defined, or be
35
- // inferred as any if it is not defined. I don't think it's possible to make it
36
- // infer to DefaultBlockSchema if it is not defined.
77
+ export const getDefaultSlashMenuItems = <
78
+ BSchema extends BlockSchema,
79
+ I extends InlineContentSchema,
80
+ S extends StyleSchema
81
+ >(
37
82
  schema: BSchema = defaultBlockSchema as unknown as BSchema
38
83
  ) => {
39
- const slashMenuItems: BaseSlashMenuItem<BSchema>[] = [];
84
+ const slashMenuItems: BaseSlashMenuItem<BSchema, I, S>[] = [];
40
85
 
41
86
  if ("heading" in schema && "level" in schema.heading.propSchema) {
42
87
  // Command for creating a level 1 heading
@@ -48,7 +93,7 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
48
93
  insertOrUpdateBlock(editor, {
49
94
  type: "heading",
50
95
  props: { level: 1 },
51
- } as PartialBlock<BSchema>),
96
+ } as PartialBlock<BSchema, I, S>),
52
97
  });
53
98
  }
54
99
 
@@ -61,7 +106,7 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
61
106
  insertOrUpdateBlock(editor, {
62
107
  type: "heading",
63
108
  props: { level: 2 },
64
- } as PartialBlock<BSchema>),
109
+ } as PartialBlock<BSchema, I, S>),
65
110
  });
66
111
  }
67
112
 
@@ -74,7 +119,7 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
74
119
  insertOrUpdateBlock(editor, {
75
120
  type: "heading",
76
121
  props: { level: 3 },
77
- } as PartialBlock<BSchema>),
122
+ } as PartialBlock<BSchema, I, S>),
78
123
  });
79
124
  }
80
125
  }
@@ -86,7 +131,7 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
86
131
  execute: (editor) =>
87
132
  insertOrUpdateBlock(editor, {
88
133
  type: "bulletListItem",
89
- } as PartialBlock<BSchema>),
134
+ }),
90
135
  });
91
136
  }
92
137
 
@@ -97,7 +142,7 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
97
142
  execute: (editor) =>
98
143
  insertOrUpdateBlock(editor, {
99
144
  type: "numberedListItem",
100
- } as PartialBlock<BSchema>),
145
+ }),
101
146
  });
102
147
  }
103
148
 
@@ -108,7 +153,30 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
108
153
  execute: (editor) =>
109
154
  insertOrUpdateBlock(editor, {
110
155
  type: "paragraph",
111
- } as PartialBlock<BSchema>),
156
+ }),
157
+ });
158
+ }
159
+
160
+ if ("table" in schema) {
161
+ slashMenuItems.push({
162
+ name: "Table",
163
+ aliases: ["table"],
164
+ execute: (editor) => {
165
+ insertOrUpdateBlock(editor, {
166
+ type: "table",
167
+ content: {
168
+ type: "tableContent",
169
+ rows: [
170
+ {
171
+ cells: ["", "", ""],
172
+ },
173
+ {
174
+ cells: ["", "", ""],
175
+ },
176
+ ],
177
+ },
178
+ } as PartialBlock<BSchema, I, S>);
179
+ },
112
180
  });
113
181
  }
114
182
 
@@ -127,19 +195,14 @@ export const getDefaultSlashMenuItems = <BSchema extends BlockSchema>(
127
195
  "dropbox",
128
196
  ],
129
197
  execute: (editor) => {
130
- insertOrUpdateBlock(editor, {
198
+ const insertedBlock = insertOrUpdateBlock(editor, {
131
199
  type: "image",
132
- } as PartialBlock<BSchema>);
133
- // Don't want to select the add image button, instead select the block
134
- // below it
135
- editor.setTextCursorPosition(
136
- editor.getTextCursorPosition().nextBlock!,
137
- "start"
138
- );
200
+ });
201
+
139
202
  // Immediately open the image toolbar
140
203
  editor._tiptapEditor.view.dispatch(
141
204
  editor._tiptapEditor.state.tr.setMeta(imageToolbarPluginKey, {
142
- block: editor.getTextCursorPosition().prevBlock,
205
+ block: insertedBlock,
143
206
  })
144
207
  );
145
208
  },