@multiplatform.one/rich-text 6.1.0 → 6.4.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 (691) hide show
  1. package/README.md +60 -0
  2. package/dist/cjs/RichEditor.cjs +89 -9
  3. package/dist/cjs/RichEditor.native.js +444 -35
  4. package/dist/cjs/RichEditor.native.js.map +1 -1
  5. package/dist/cjs/RichTextEditor/index.cjs +20 -2
  6. package/dist/cjs/RichTextEditor/index.native.js +20 -2
  7. package/dist/cjs/RichTextEditor/index.native.js.map +1 -1
  8. package/dist/cjs/constants.cjs +52 -29
  9. package/dist/cjs/constants.native.js +59 -29
  10. package/dist/cjs/constants.native.js.map +1 -1
  11. package/dist/cjs/editor/BlockDragHandle.cjs +22 -7
  12. package/dist/cjs/editor/BlockDragHandle.native.js +41 -7
  13. package/dist/cjs/editor/BlockDragHandle.native.js.map +1 -1
  14. package/dist/cjs/editor/SlashCommands.cjs +257 -294
  15. package/dist/cjs/editor/SlashCommands.native.js +320 -341
  16. package/dist/cjs/editor/SlashCommands.native.js.map +1 -1
  17. package/dist/cjs/editor/TentapEditor.native.js +59 -12
  18. package/dist/cjs/editor/TentapEditor.native.js.map +1 -1
  19. package/dist/cjs/editor/TiptapEditor.cjs +143 -240
  20. package/dist/cjs/editor/TiptapEditor.native.js +163 -289
  21. package/dist/cjs/editor/TiptapEditor.native.js.map +1 -1
  22. package/dist/cjs/editor/blockAnchor.cjs +43 -0
  23. package/dist/cjs/editor/blockAnchor.native.js +68 -0
  24. package/dist/cjs/editor/blockAnchor.native.js.map +1 -0
  25. package/dist/cjs/editor/capabilities.cjs +37 -0
  26. package/dist/cjs/editor/capabilities.native.js +41 -0
  27. package/dist/cjs/editor/capabilities.native.js.map +1 -0
  28. package/dist/cjs/editor/codeBlockPreview.cjs +230 -0
  29. package/dist/cjs/editor/codeBlockPreview.native.js +265 -0
  30. package/dist/cjs/editor/codeBlockPreview.native.js.map +1 -0
  31. package/dist/cjs/editor/editorStyles.cjs +203 -34
  32. package/dist/cjs/editor/editorStyles.native.js +203 -34
  33. package/dist/cjs/editor/editorStyles.native.js.map +1 -1
  34. package/dist/cjs/editor/emoji.cjs +128 -0
  35. package/dist/cjs/editor/emoji.native.js +184 -0
  36. package/dist/cjs/editor/emoji.native.js.map +1 -0
  37. package/dist/cjs/editor/extensions.cjs +275 -0
  38. package/dist/cjs/editor/extensions.native.js +328 -0
  39. package/dist/cjs/editor/extensions.native.js.map +1 -0
  40. package/dist/cjs/editor/lazyKatex.cjs +78 -0
  41. package/dist/cjs/editor/lazyKatex.native.js +117 -0
  42. package/dist/cjs/editor/lazyKatex.native.js.map +1 -0
  43. package/dist/cjs/editor/markdown.cjs +216 -0
  44. package/dist/cjs/editor/markdown.native.js +278 -0
  45. package/dist/cjs/editor/markdown.native.js.map +1 -0
  46. package/dist/cjs/editor/mathematics.cjs +168 -0
  47. package/dist/cjs/editor/mathematics.native.js +202 -0
  48. package/dist/cjs/editor/mathematics.native.js.map +1 -0
  49. package/dist/cjs/editor/media.cjs +138 -0
  50. package/dist/cjs/editor/media.native.js +172 -0
  51. package/dist/cjs/editor/media.native.js.map +1 -0
  52. package/dist/cjs/editor/mentions.cjs +73 -0
  53. package/dist/cjs/editor/mentions.native.js +84 -0
  54. package/dist/cjs/editor/mentions.native.js.map +1 -0
  55. package/dist/cjs/editor/pasteCleanup.cjs +83 -0
  56. package/dist/cjs/editor/pasteCleanup.native.js +175 -0
  57. package/dist/cjs/editor/pasteCleanup.native.js.map +1 -0
  58. package/dist/cjs/editor/suggestionPopup.cjs +297 -0
  59. package/dist/cjs/editor/suggestionPopup.native.js +327 -0
  60. package/dist/cjs/editor/suggestionPopup.native.js.map +1 -0
  61. package/dist/cjs/index.cjs +5 -2
  62. package/dist/cjs/index.native.js +4 -1
  63. package/dist/cjs/index.native.js.map +1 -1
  64. package/dist/cjs/preview.cjs +263 -0
  65. package/dist/cjs/preview.native.js +294 -0
  66. package/dist/cjs/preview.native.js.map +1 -0
  67. package/dist/cjs/shared/t.cjs +53 -0
  68. package/dist/cjs/shared/t.native.js +56 -0
  69. package/dist/cjs/shared/t.native.js.map +1 -0
  70. package/dist/cjs/shared/url.cjs +35 -0
  71. package/dist/cjs/shared/url.native.js +38 -0
  72. package/dist/cjs/shared/url.native.js.map +1 -0
  73. package/dist/cjs/styled.cjs +13 -6
  74. package/dist/cjs/styled.native.js +13 -6
  75. package/dist/cjs/styled.native.js.map +1 -1
  76. package/dist/cjs/toolbar/BubbleToolbar.cjs +19 -14
  77. package/dist/cjs/toolbar/BubbleToolbar.native.js +22 -15
  78. package/dist/cjs/toolbar/BubbleToolbar.native.js.map +1 -1
  79. package/dist/cjs/toolbar/CodeBlockBubble.cjs +59 -23
  80. package/dist/cjs/toolbar/CodeBlockBubble.native.js +71 -25
  81. package/dist/cjs/toolbar/CodeBlockBubble.native.js.map +1 -1
  82. package/dist/cjs/toolbar/ColorPicker.cjs +19 -54
  83. package/dist/cjs/toolbar/ColorPicker.native.js +81 -179
  84. package/dist/cjs/toolbar/ColorPicker.native.js.map +1 -1
  85. package/dist/cjs/toolbar/FixedToolbar.cjs +39 -13
  86. package/dist/cjs/toolbar/FixedToolbar.native.js +46 -54
  87. package/dist/cjs/toolbar/FixedToolbar.native.js.map +1 -1
  88. package/dist/cjs/toolbar/HeadingPicker.cjs +32 -39
  89. package/dist/cjs/toolbar/HeadingPicker.native.js +61 -51
  90. package/dist/cjs/toolbar/HeadingPicker.native.js.map +1 -1
  91. package/dist/cjs/toolbar/ImageBubble.cjs +20 -43
  92. package/dist/cjs/toolbar/ImageBubble.native.js +20 -43
  93. package/dist/cjs/toolbar/ImageBubble.native.js.map +1 -1
  94. package/dist/cjs/toolbar/ImageDialog.cjs +5 -4
  95. package/dist/cjs/toolbar/ImageDialog.native.js +76 -65
  96. package/dist/cjs/toolbar/ImageDialog.native.js.map +1 -1
  97. package/dist/cjs/toolbar/LinkBubble.cjs +23 -70
  98. package/dist/cjs/toolbar/LinkBubble.native.js +23 -70
  99. package/dist/cjs/toolbar/LinkBubble.native.js.map +1 -1
  100. package/dist/cjs/toolbar/LinkDialog.cjs +19 -18
  101. package/dist/cjs/toolbar/LinkDialog.native.js +86 -83
  102. package/dist/cjs/toolbar/LinkDialog.native.js.map +1 -1
  103. package/dist/cjs/toolbar/ListPicker.cjs +32 -43
  104. package/dist/cjs/toolbar/ListPicker.native.js +43 -44
  105. package/dist/cjs/toolbar/ListPicker.native.js.map +1 -1
  106. package/dist/cjs/toolbar/MathBubble.cjs +159 -0
  107. package/dist/cjs/toolbar/MathBubble.native.js +169 -0
  108. package/dist/cjs/toolbar/MathBubble.native.js.map +1 -0
  109. package/dist/cjs/toolbar/MoreDropdown.cjs +54 -93
  110. package/dist/cjs/toolbar/MoreDropdown.native.js +80 -93
  111. package/dist/cjs/toolbar/MoreDropdown.native.js.map +1 -1
  112. package/dist/cjs/toolbar/StatusBar.cjs +19 -10
  113. package/dist/cjs/toolbar/StatusBar.native.js +19 -10
  114. package/dist/cjs/toolbar/StatusBar.native.js.map +1 -1
  115. package/dist/cjs/toolbar/TableBubble.cjs +91 -96
  116. package/dist/cjs/toolbar/TableBubble.native.js +90 -73
  117. package/dist/cjs/toolbar/TableBubble.native.js.map +1 -1
  118. package/dist/cjs/toolbar/ToolbarButton.cjs +86 -21
  119. package/dist/cjs/toolbar/ToolbarButton.native.js +14 -4
  120. package/dist/cjs/toolbar/ToolbarButton.native.js.map +1 -1
  121. package/dist/cjs/toolbar/icons.cjs +111 -468
  122. package/dist/cjs/toolbar/shortcuts.cjs +73 -24
  123. package/dist/cjs/toolbar/shortcuts.native.js +73 -24
  124. package/dist/cjs/toolbar/shortcuts.native.js.map +1 -1
  125. package/dist/cjs/toolbar/useHorizontalScroll.cjs +25 -5
  126. package/dist/cjs/toolbar/useHorizontalScroll.native.js +25 -5
  127. package/dist/cjs/toolbar/useHorizontalScroll.native.js.map +1 -1
  128. package/dist/cjs/toolbar/useRovingFocus.cjs +80 -0
  129. package/dist/cjs/toolbar/useRovingFocus.native.js +113 -0
  130. package/dist/cjs/toolbar/useRovingFocus.native.js.map +1 -0
  131. package/dist/cjs/types.native.js.map +1 -1
  132. package/dist/esm/RichEditor.mjs +90 -10
  133. package/dist/esm/RichEditor.mjs.map +1 -1
  134. package/dist/esm/RichEditor.native.js +447 -38
  135. package/dist/esm/RichEditor.native.js.map +1 -1
  136. package/dist/esm/RichTextEditor/index.mjs +20 -2
  137. package/dist/esm/RichTextEditor/index.mjs.map +1 -1
  138. package/dist/esm/RichTextEditor/index.native.js +20 -2
  139. package/dist/esm/RichTextEditor/index.native.js.map +1 -1
  140. package/dist/esm/constants.mjs +47 -29
  141. package/dist/esm/constants.mjs.map +1 -1
  142. package/dist/esm/constants.native.js +54 -29
  143. package/dist/esm/constants.native.js.map +1 -1
  144. package/dist/esm/editor/BlockDragHandle.mjs +22 -7
  145. package/dist/esm/editor/BlockDragHandle.mjs.map +1 -1
  146. package/dist/esm/editor/BlockDragHandle.native.js +41 -7
  147. package/dist/esm/editor/BlockDragHandle.native.js.map +1 -1
  148. package/dist/esm/editor/SlashCommands.mjs +258 -295
  149. package/dist/esm/editor/SlashCommands.mjs.map +1 -1
  150. package/dist/esm/editor/SlashCommands.native.js +321 -342
  151. package/dist/esm/editor/SlashCommands.native.js.map +1 -1
  152. package/dist/esm/editor/TentapEditor.native.js +60 -13
  153. package/dist/esm/editor/TentapEditor.native.js.map +1 -1
  154. package/dist/esm/editor/TiptapEditor.mjs +145 -231
  155. package/dist/esm/editor/TiptapEditor.mjs.map +1 -1
  156. package/dist/esm/editor/TiptapEditor.native.js +165 -280
  157. package/dist/esm/editor/TiptapEditor.native.js.map +1 -1
  158. package/dist/esm/editor/blockAnchor.mjs +18 -0
  159. package/dist/esm/editor/blockAnchor.mjs.map +1 -0
  160. package/dist/esm/editor/blockAnchor.native.js +40 -0
  161. package/dist/esm/editor/blockAnchor.native.js.map +1 -0
  162. package/dist/esm/editor/capabilities.mjs +10 -0
  163. package/dist/esm/editor/capabilities.mjs.map +1 -0
  164. package/dist/esm/editor/capabilities.native.js +11 -0
  165. package/dist/esm/editor/capabilities.native.js.map +1 -0
  166. package/dist/esm/editor/codeBlockPreview.mjs +190 -0
  167. package/dist/esm/editor/codeBlockPreview.mjs.map +1 -0
  168. package/dist/esm/editor/codeBlockPreview.native.js +222 -0
  169. package/dist/esm/editor/codeBlockPreview.native.js.map +1 -0
  170. package/dist/esm/editor/editorStyles.mjs +203 -34
  171. package/dist/esm/editor/editorStyles.mjs.map +1 -1
  172. package/dist/esm/editor/editorStyles.native.js +203 -34
  173. package/dist/esm/editor/editorStyles.native.js.map +1 -1
  174. package/dist/esm/editor/emoji.mjs +88 -0
  175. package/dist/esm/editor/emoji.mjs.map +1 -0
  176. package/dist/esm/editor/emoji.native.js +141 -0
  177. package/dist/esm/editor/emoji.native.js.map +1 -0
  178. package/dist/esm/editor/extensions.mjs +236 -0
  179. package/dist/esm/editor/extensions.mjs.map +1 -0
  180. package/dist/esm/editor/extensions.native.js +286 -0
  181. package/dist/esm/editor/extensions.native.js.map +1 -0
  182. package/dist/esm/editor/lazyKatex.mjs +40 -0
  183. package/dist/esm/editor/lazyKatex.mjs.map +1 -0
  184. package/dist/esm/editor/lazyKatex.native.js +76 -0
  185. package/dist/esm/editor/lazyKatex.native.js.map +1 -0
  186. package/dist/esm/editor/markdown.mjs +179 -0
  187. package/dist/esm/editor/markdown.mjs.map +1 -0
  188. package/dist/esm/editor/markdown.native.js +238 -0
  189. package/dist/esm/editor/markdown.native.js.map +1 -0
  190. package/dist/esm/editor/mathematics.mjs +142 -0
  191. package/dist/esm/editor/mathematics.mjs.map +1 -0
  192. package/dist/esm/editor/mathematics.native.js +173 -0
  193. package/dist/esm/editor/mathematics.native.js.map +1 -0
  194. package/dist/esm/editor/media.mjs +113 -0
  195. package/dist/esm/editor/media.mjs.map +1 -0
  196. package/dist/esm/editor/media.native.js +144 -0
  197. package/dist/esm/editor/media.native.js.map +1 -0
  198. package/dist/esm/editor/mentions.mjs +37 -0
  199. package/dist/esm/editor/mentions.mjs.map +1 -0
  200. package/dist/esm/editor/mentions.native.js +45 -0
  201. package/dist/esm/editor/mentions.native.js.map +1 -0
  202. package/dist/esm/editor/pasteCleanup.mjs +57 -0
  203. package/dist/esm/editor/pasteCleanup.mjs.map +1 -0
  204. package/dist/esm/editor/pasteCleanup.native.js +146 -0
  205. package/dist/esm/editor/pasteCleanup.native.js.map +1 -0
  206. package/dist/esm/editor/suggestionPopup.mjs +268 -0
  207. package/dist/esm/editor/suggestionPopup.mjs.map +1 -0
  208. package/dist/esm/editor/suggestionPopup.native.js +295 -0
  209. package/dist/esm/editor/suggestionPopup.native.js.map +1 -0
  210. package/dist/esm/index.mjs +2 -1
  211. package/dist/esm/index.mjs.map +1 -1
  212. package/dist/esm/index.native.js +2 -1
  213. package/dist/esm/index.native.js.map +1 -1
  214. package/dist/esm/preview.mjs +236 -0
  215. package/dist/esm/preview.mjs.map +1 -0
  216. package/dist/esm/preview.native.js +264 -0
  217. package/dist/esm/preview.native.js.map +1 -0
  218. package/dist/esm/shared/t.mjs +17 -0
  219. package/dist/esm/shared/t.mjs.map +1 -0
  220. package/dist/esm/shared/t.native.js +17 -0
  221. package/dist/esm/shared/t.native.js.map +1 -0
  222. package/dist/esm/shared/url.mjs +10 -0
  223. package/dist/esm/shared/url.mjs.map +1 -0
  224. package/dist/esm/shared/url.native.js +10 -0
  225. package/dist/esm/shared/url.native.js.map +1 -0
  226. package/dist/esm/styled.mjs +13 -6
  227. package/dist/esm/styled.mjs.map +1 -1
  228. package/dist/esm/styled.native.js +13 -6
  229. package/dist/esm/styled.native.js.map +1 -1
  230. package/dist/esm/toolbar/BubbleToolbar.mjs +20 -15
  231. package/dist/esm/toolbar/BubbleToolbar.mjs.map +1 -1
  232. package/dist/esm/toolbar/BubbleToolbar.native.js +23 -16
  233. package/dist/esm/toolbar/BubbleToolbar.native.js.map +1 -1
  234. package/dist/esm/toolbar/CodeBlockBubble.mjs +60 -24
  235. package/dist/esm/toolbar/CodeBlockBubble.mjs.map +1 -1
  236. package/dist/esm/toolbar/CodeBlockBubble.native.js +72 -26
  237. package/dist/esm/toolbar/CodeBlockBubble.native.js.map +1 -1
  238. package/dist/esm/toolbar/ColorPicker.mjs +21 -56
  239. package/dist/esm/toolbar/ColorPicker.mjs.map +1 -1
  240. package/dist/esm/toolbar/ColorPicker.native.js +82 -180
  241. package/dist/esm/toolbar/ColorPicker.native.js.map +1 -1
  242. package/dist/esm/toolbar/FixedToolbar.mjs +40 -14
  243. package/dist/esm/toolbar/FixedToolbar.mjs.map +1 -1
  244. package/dist/esm/toolbar/FixedToolbar.native.js +47 -55
  245. package/dist/esm/toolbar/FixedToolbar.native.js.map +1 -1
  246. package/dist/esm/toolbar/HeadingPicker.mjs +34 -41
  247. package/dist/esm/toolbar/HeadingPicker.mjs.map +1 -1
  248. package/dist/esm/toolbar/HeadingPicker.native.js +63 -53
  249. package/dist/esm/toolbar/HeadingPicker.native.js.map +1 -1
  250. package/dist/esm/toolbar/ImageBubble.mjs +20 -43
  251. package/dist/esm/toolbar/ImageBubble.mjs.map +1 -1
  252. package/dist/esm/toolbar/ImageBubble.native.js +20 -43
  253. package/dist/esm/toolbar/ImageBubble.native.js.map +1 -1
  254. package/dist/esm/toolbar/ImageDialog.mjs +5 -4
  255. package/dist/esm/toolbar/ImageDialog.mjs.map +1 -1
  256. package/dist/esm/toolbar/ImageDialog.native.js +75 -64
  257. package/dist/esm/toolbar/ImageDialog.native.js.map +1 -1
  258. package/dist/esm/toolbar/LinkBubble.mjs +23 -70
  259. package/dist/esm/toolbar/LinkBubble.mjs.map +1 -1
  260. package/dist/esm/toolbar/LinkBubble.native.js +23 -70
  261. package/dist/esm/toolbar/LinkBubble.native.js.map +1 -1
  262. package/dist/esm/toolbar/LinkDialog.mjs +17 -16
  263. package/dist/esm/toolbar/LinkDialog.mjs.map +1 -1
  264. package/dist/esm/toolbar/LinkDialog.native.js +84 -80
  265. package/dist/esm/toolbar/LinkDialog.native.js.map +1 -1
  266. package/dist/esm/toolbar/ListPicker.mjs +33 -44
  267. package/dist/esm/toolbar/ListPicker.mjs.map +1 -1
  268. package/dist/esm/toolbar/ListPicker.native.js +44 -45
  269. package/dist/esm/toolbar/ListPicker.native.js.map +1 -1
  270. package/dist/esm/toolbar/MathBubble.mjs +134 -0
  271. package/dist/esm/toolbar/MathBubble.mjs.map +1 -0
  272. package/dist/esm/toolbar/MathBubble.native.js +141 -0
  273. package/dist/esm/toolbar/MathBubble.native.js.map +1 -0
  274. package/dist/esm/toolbar/MoreDropdown.mjs +53 -92
  275. package/dist/esm/toolbar/MoreDropdown.mjs.map +1 -1
  276. package/dist/esm/toolbar/MoreDropdown.native.js +79 -92
  277. package/dist/esm/toolbar/MoreDropdown.native.js.map +1 -1
  278. package/dist/esm/toolbar/StatusBar.mjs +19 -10
  279. package/dist/esm/toolbar/StatusBar.mjs.map +1 -1
  280. package/dist/esm/toolbar/StatusBar.native.js +19 -10
  281. package/dist/esm/toolbar/StatusBar.native.js.map +1 -1
  282. package/dist/esm/toolbar/TableBubble.mjs +91 -96
  283. package/dist/esm/toolbar/TableBubble.mjs.map +1 -1
  284. package/dist/esm/toolbar/TableBubble.native.js +90 -73
  285. package/dist/esm/toolbar/TableBubble.native.js.map +1 -1
  286. package/dist/esm/toolbar/ToolbarButton.mjs +87 -22
  287. package/dist/esm/toolbar/ToolbarButton.mjs.map +1 -1
  288. package/dist/esm/toolbar/ToolbarButton.native.js +14 -4
  289. package/dist/esm/toolbar/ToolbarButton.native.js.map +1 -1
  290. package/dist/esm/toolbar/icons.mjs +109 -469
  291. package/dist/esm/toolbar/icons.mjs.map +1 -1
  292. package/dist/esm/toolbar/shortcuts.mjs +73 -24
  293. package/dist/esm/toolbar/shortcuts.mjs.map +1 -1
  294. package/dist/esm/toolbar/shortcuts.native.js +73 -24
  295. package/dist/esm/toolbar/shortcuts.native.js.map +1 -1
  296. package/dist/esm/toolbar/useHorizontalScroll.mjs +25 -6
  297. package/dist/esm/toolbar/useHorizontalScroll.mjs.map +1 -1
  298. package/dist/esm/toolbar/useHorizontalScroll.native.js +25 -6
  299. package/dist/esm/toolbar/useHorizontalScroll.native.js.map +1 -1
  300. package/dist/esm/toolbar/useRovingFocus.mjs +55 -0
  301. package/dist/esm/toolbar/useRovingFocus.mjs.map +1 -0
  302. package/dist/esm/toolbar/useRovingFocus.native.js +85 -0
  303. package/dist/esm/toolbar/useRovingFocus.native.js.map +1 -0
  304. package/dist/esm/types.mjs.map +1 -1
  305. package/dist/esm/types.native.js.map +1 -1
  306. package/dist/jsx/RichEditor.mjs +90 -10
  307. package/dist/jsx/RichEditor.mjs.map +1 -1
  308. package/dist/jsx/RichEditor.native.js +444 -35
  309. package/dist/jsx/RichEditor.native.js.map +1 -1
  310. package/dist/jsx/RichTextEditor/index.mjs +20 -2
  311. package/dist/jsx/RichTextEditor/index.mjs.map +1 -1
  312. package/dist/jsx/RichTextEditor/index.native.js +20 -2
  313. package/dist/jsx/RichTextEditor/index.native.js.map +1 -1
  314. package/dist/jsx/constants.mjs +47 -29
  315. package/dist/jsx/constants.mjs.map +1 -1
  316. package/dist/jsx/constants.native.js +59 -29
  317. package/dist/jsx/constants.native.js.map +1 -1
  318. package/dist/jsx/editor/BlockDragHandle.mjs +22 -7
  319. package/dist/jsx/editor/BlockDragHandle.mjs.map +1 -1
  320. package/dist/jsx/editor/BlockDragHandle.native.js +41 -7
  321. package/dist/jsx/editor/BlockDragHandle.native.js.map +1 -1
  322. package/dist/jsx/editor/SlashCommands.mjs +258 -295
  323. package/dist/jsx/editor/SlashCommands.mjs.map +1 -1
  324. package/dist/jsx/editor/SlashCommands.native.js +320 -341
  325. package/dist/jsx/editor/SlashCommands.native.js.map +1 -1
  326. package/dist/jsx/editor/TentapEditor.native.js +59 -12
  327. package/dist/jsx/editor/TentapEditor.native.js.map +1 -1
  328. package/dist/jsx/editor/TiptapEditor.mjs +145 -231
  329. package/dist/jsx/editor/TiptapEditor.mjs.map +1 -1
  330. package/dist/jsx/editor/TiptapEditor.native.js +163 -289
  331. package/dist/jsx/editor/TiptapEditor.native.js.map +1 -1
  332. package/dist/jsx/editor/blockAnchor.mjs +18 -0
  333. package/dist/jsx/editor/blockAnchor.mjs.map +1 -0
  334. package/dist/jsx/editor/blockAnchor.native.js +68 -0
  335. package/dist/jsx/editor/blockAnchor.native.js.map +1 -0
  336. package/dist/jsx/editor/capabilities.mjs +10 -0
  337. package/dist/jsx/editor/capabilities.mjs.map +1 -0
  338. package/dist/jsx/editor/capabilities.native.js +41 -0
  339. package/dist/jsx/editor/capabilities.native.js.map +1 -0
  340. package/dist/jsx/editor/codeBlockPreview.mjs +190 -0
  341. package/dist/jsx/editor/codeBlockPreview.mjs.map +1 -0
  342. package/dist/jsx/editor/codeBlockPreview.native.js +265 -0
  343. package/dist/jsx/editor/codeBlockPreview.native.js.map +1 -0
  344. package/dist/jsx/editor/editorStyles.mjs +203 -34
  345. package/dist/jsx/editor/editorStyles.mjs.map +1 -1
  346. package/dist/jsx/editor/editorStyles.native.js +203 -34
  347. package/dist/jsx/editor/editorStyles.native.js.map +1 -1
  348. package/dist/jsx/editor/emoji.mjs +88 -0
  349. package/dist/jsx/editor/emoji.mjs.map +1 -0
  350. package/dist/jsx/editor/emoji.native.js +184 -0
  351. package/dist/jsx/editor/emoji.native.js.map +1 -0
  352. package/dist/jsx/editor/extensions.mjs +236 -0
  353. package/dist/jsx/editor/extensions.mjs.map +1 -0
  354. package/dist/jsx/editor/extensions.native.js +328 -0
  355. package/dist/jsx/editor/extensions.native.js.map +1 -0
  356. package/dist/jsx/editor/lazyKatex.mjs +40 -0
  357. package/dist/jsx/editor/lazyKatex.mjs.map +1 -0
  358. package/dist/jsx/editor/lazyKatex.native.js +117 -0
  359. package/dist/jsx/editor/lazyKatex.native.js.map +1 -0
  360. package/dist/jsx/editor/markdown.mjs +179 -0
  361. package/dist/jsx/editor/markdown.mjs.map +1 -0
  362. package/dist/jsx/editor/markdown.native.js +278 -0
  363. package/dist/jsx/editor/markdown.native.js.map +1 -0
  364. package/dist/jsx/editor/mathematics.mjs +142 -0
  365. package/dist/jsx/editor/mathematics.mjs.map +1 -0
  366. package/dist/jsx/editor/mathematics.native.js +202 -0
  367. package/dist/jsx/editor/mathematics.native.js.map +1 -0
  368. package/dist/jsx/editor/media.mjs +113 -0
  369. package/dist/jsx/editor/media.mjs.map +1 -0
  370. package/dist/jsx/editor/media.native.js +172 -0
  371. package/dist/jsx/editor/media.native.js.map +1 -0
  372. package/dist/jsx/editor/mentions.mjs +37 -0
  373. package/dist/jsx/editor/mentions.mjs.map +1 -0
  374. package/dist/jsx/editor/mentions.native.js +84 -0
  375. package/dist/jsx/editor/mentions.native.js.map +1 -0
  376. package/dist/jsx/editor/pasteCleanup.mjs +57 -0
  377. package/dist/jsx/editor/pasteCleanup.mjs.map +1 -0
  378. package/dist/jsx/editor/pasteCleanup.native.js +175 -0
  379. package/dist/jsx/editor/pasteCleanup.native.js.map +1 -0
  380. package/dist/jsx/editor/suggestionPopup.mjs +268 -0
  381. package/dist/jsx/editor/suggestionPopup.mjs.map +1 -0
  382. package/dist/jsx/editor/suggestionPopup.native.js +327 -0
  383. package/dist/jsx/editor/suggestionPopup.native.js.map +1 -0
  384. package/dist/jsx/index.js +2 -1
  385. package/dist/jsx/index.js.map +1 -1
  386. package/dist/jsx/index.mjs +2 -1
  387. package/dist/jsx/index.mjs.map +1 -1
  388. package/dist/jsx/index.native.js +4 -1
  389. package/dist/jsx/index.native.js.map +1 -1
  390. package/dist/jsx/preview.mjs +236 -0
  391. package/dist/jsx/preview.mjs.map +1 -0
  392. package/dist/jsx/preview.native.js +294 -0
  393. package/dist/jsx/preview.native.js.map +1 -0
  394. package/dist/jsx/shared/t.mjs +17 -0
  395. package/dist/jsx/shared/t.mjs.map +1 -0
  396. package/dist/jsx/shared/t.native.js +56 -0
  397. package/dist/jsx/shared/t.native.js.map +1 -0
  398. package/dist/jsx/shared/url.mjs +10 -0
  399. package/dist/jsx/shared/url.mjs.map +1 -0
  400. package/dist/jsx/shared/url.native.js +38 -0
  401. package/dist/jsx/shared/url.native.js.map +1 -0
  402. package/dist/jsx/styled.mjs +13 -6
  403. package/dist/jsx/styled.mjs.map +1 -1
  404. package/dist/jsx/styled.native.js +13 -6
  405. package/dist/jsx/styled.native.js.map +1 -1
  406. package/dist/jsx/toolbar/BubbleToolbar.mjs +20 -15
  407. package/dist/jsx/toolbar/BubbleToolbar.mjs.map +1 -1
  408. package/dist/jsx/toolbar/BubbleToolbar.native.js +22 -15
  409. package/dist/jsx/toolbar/BubbleToolbar.native.js.map +1 -1
  410. package/dist/jsx/toolbar/CodeBlockBubble.mjs +60 -24
  411. package/dist/jsx/toolbar/CodeBlockBubble.mjs.map +1 -1
  412. package/dist/jsx/toolbar/CodeBlockBubble.native.js +71 -25
  413. package/dist/jsx/toolbar/CodeBlockBubble.native.js.map +1 -1
  414. package/dist/jsx/toolbar/ColorPicker.mjs +21 -56
  415. package/dist/jsx/toolbar/ColorPicker.mjs.map +1 -1
  416. package/dist/jsx/toolbar/ColorPicker.native.js +81 -179
  417. package/dist/jsx/toolbar/ColorPicker.native.js.map +1 -1
  418. package/dist/jsx/toolbar/FixedToolbar.mjs +40 -14
  419. package/dist/jsx/toolbar/FixedToolbar.mjs.map +1 -1
  420. package/dist/jsx/toolbar/FixedToolbar.native.js +46 -54
  421. package/dist/jsx/toolbar/FixedToolbar.native.js.map +1 -1
  422. package/dist/jsx/toolbar/HeadingPicker.mjs +34 -41
  423. package/dist/jsx/toolbar/HeadingPicker.mjs.map +1 -1
  424. package/dist/jsx/toolbar/HeadingPicker.native.js +61 -51
  425. package/dist/jsx/toolbar/HeadingPicker.native.js.map +1 -1
  426. package/dist/jsx/toolbar/ImageBubble.mjs +20 -43
  427. package/dist/jsx/toolbar/ImageBubble.mjs.map +1 -1
  428. package/dist/jsx/toolbar/ImageBubble.native.js +20 -43
  429. package/dist/jsx/toolbar/ImageBubble.native.js.map +1 -1
  430. package/dist/jsx/toolbar/ImageDialog.mjs +5 -4
  431. package/dist/jsx/toolbar/ImageDialog.mjs.map +1 -1
  432. package/dist/jsx/toolbar/ImageDialog.native.js +76 -65
  433. package/dist/jsx/toolbar/ImageDialog.native.js.map +1 -1
  434. package/dist/jsx/toolbar/LinkBubble.mjs +23 -70
  435. package/dist/jsx/toolbar/LinkBubble.mjs.map +1 -1
  436. package/dist/jsx/toolbar/LinkBubble.native.js +23 -70
  437. package/dist/jsx/toolbar/LinkBubble.native.js.map +1 -1
  438. package/dist/jsx/toolbar/LinkDialog.mjs +17 -16
  439. package/dist/jsx/toolbar/LinkDialog.mjs.map +1 -1
  440. package/dist/jsx/toolbar/LinkDialog.native.js +86 -83
  441. package/dist/jsx/toolbar/LinkDialog.native.js.map +1 -1
  442. package/dist/jsx/toolbar/ListPicker.mjs +33 -44
  443. package/dist/jsx/toolbar/ListPicker.mjs.map +1 -1
  444. package/dist/jsx/toolbar/ListPicker.native.js +43 -44
  445. package/dist/jsx/toolbar/ListPicker.native.js.map +1 -1
  446. package/dist/jsx/toolbar/MathBubble.mjs +134 -0
  447. package/dist/jsx/toolbar/MathBubble.mjs.map +1 -0
  448. package/dist/jsx/toolbar/MathBubble.native.js +169 -0
  449. package/dist/jsx/toolbar/MathBubble.native.js.map +1 -0
  450. package/dist/jsx/toolbar/MoreDropdown.mjs +53 -92
  451. package/dist/jsx/toolbar/MoreDropdown.mjs.map +1 -1
  452. package/dist/jsx/toolbar/MoreDropdown.native.js +80 -93
  453. package/dist/jsx/toolbar/MoreDropdown.native.js.map +1 -1
  454. package/dist/jsx/toolbar/StatusBar.mjs +19 -10
  455. package/dist/jsx/toolbar/StatusBar.mjs.map +1 -1
  456. package/dist/jsx/toolbar/StatusBar.native.js +19 -10
  457. package/dist/jsx/toolbar/StatusBar.native.js.map +1 -1
  458. package/dist/jsx/toolbar/TableBubble.mjs +91 -96
  459. package/dist/jsx/toolbar/TableBubble.mjs.map +1 -1
  460. package/dist/jsx/toolbar/TableBubble.native.js +90 -73
  461. package/dist/jsx/toolbar/TableBubble.native.js.map +1 -1
  462. package/dist/jsx/toolbar/ToolbarButton.mjs +87 -22
  463. package/dist/jsx/toolbar/ToolbarButton.mjs.map +1 -1
  464. package/dist/jsx/toolbar/ToolbarButton.native.js +14 -4
  465. package/dist/jsx/toolbar/ToolbarButton.native.js.map +1 -1
  466. package/dist/jsx/toolbar/icons.mjs +109 -469
  467. package/dist/jsx/toolbar/icons.mjs.map +1 -1
  468. package/dist/jsx/toolbar/shortcuts.mjs +73 -24
  469. package/dist/jsx/toolbar/shortcuts.mjs.map +1 -1
  470. package/dist/jsx/toolbar/shortcuts.native.js +73 -24
  471. package/dist/jsx/toolbar/shortcuts.native.js.map +1 -1
  472. package/dist/jsx/toolbar/useHorizontalScroll.mjs +25 -6
  473. package/dist/jsx/toolbar/useHorizontalScroll.mjs.map +1 -1
  474. package/dist/jsx/toolbar/useHorizontalScroll.native.js +25 -5
  475. package/dist/jsx/toolbar/useHorizontalScroll.native.js.map +1 -1
  476. package/dist/jsx/toolbar/useRovingFocus.mjs +55 -0
  477. package/dist/jsx/toolbar/useRovingFocus.mjs.map +1 -0
  478. package/dist/jsx/toolbar/useRovingFocus.native.js +113 -0
  479. package/dist/jsx/toolbar/useRovingFocus.native.js.map +1 -0
  480. package/dist/jsx/types.mjs.map +1 -1
  481. package/dist/jsx/types.native.js.map +1 -1
  482. package/package.json +28 -13
  483. package/src/RichEditor.native.tsx +471 -49
  484. package/src/RichEditor.stories.tsx +190 -0
  485. package/src/RichEditor.tsx +126 -7
  486. package/src/RichTextEditor/index.tsx +54 -3
  487. package/src/RichTextEditor/richTextEditor.spec.tsx +11 -4
  488. package/src/constants.ts +86 -24
  489. package/src/editor/BlockDragHandle.ts +30 -5
  490. package/src/editor/SlashCommands.tsx +238 -293
  491. package/src/editor/TentapEditor.native.tsx +81 -17
  492. package/src/editor/TiptapEditor.tsx +202 -265
  493. package/src/editor/blockAnchor.spec.ts +70 -0
  494. package/src/editor/blockAnchor.ts +42 -0
  495. package/src/editor/capabilities.spec.ts +190 -0
  496. package/src/editor/capabilities.ts +76 -0
  497. package/src/editor/codeBlockPreview.spec.ts +144 -0
  498. package/src/editor/codeBlockPreview.ts +266 -0
  499. package/src/editor/css.d.ts +2 -0
  500. package/src/editor/details.spec.ts +48 -0
  501. package/src/editor/editorStyles.spec.ts +25 -0
  502. package/src/editor/editorStyles.ts +218 -34
  503. package/src/editor/emoji.spec.ts +88 -0
  504. package/src/editor/emoji.ts +147 -0
  505. package/src/editor/emojilib.d.ts +16 -0
  506. package/src/editor/extensions.ts +315 -0
  507. package/src/editor/lazyKatex.spec.ts +38 -0
  508. package/src/editor/lazyKatex.ts +68 -0
  509. package/src/editor/markdown.spec.ts +196 -0
  510. package/src/editor/markdown.ts +249 -0
  511. package/src/editor/mathematics.spec.ts +97 -0
  512. package/src/editor/mathematics.ts +179 -0
  513. package/src/editor/media.spec.ts +121 -0
  514. package/src/editor/media.ts +133 -0
  515. package/src/editor/mentions.spec.ts +41 -0
  516. package/src/editor/mentions.ts +55 -0
  517. package/src/editor/pasteCleanup.spec.ts +84 -0
  518. package/src/editor/pasteCleanup.ts +124 -0
  519. package/src/editor/suggestionPopup.spec.tsx +105 -0
  520. package/src/editor/suggestionPopup.tsx +414 -0
  521. package/src/editor/tiptapEditor.spec.tsx +15 -8
  522. package/src/exports.spec.ts +4 -2
  523. package/src/index.ts +10 -1
  524. package/src/integration.spec.tsx +38 -9
  525. package/src/preview.spec.ts +130 -0
  526. package/src/preview.ts +287 -0
  527. package/src/richEditor.spec.tsx +10 -3
  528. package/src/shared/t.ts +25 -0
  529. package/src/shared/url.ts +16 -0
  530. package/src/styled.ts +13 -6
  531. package/src/toolbar/BubbleToolbar.tsx +48 -33
  532. package/src/toolbar/CodeBlockBubble.tsx +66 -28
  533. package/src/toolbar/ColorPicker.native.tsx +126 -0
  534. package/src/toolbar/ColorPicker.tsx +23 -67
  535. package/src/toolbar/FixedToolbar.native.tsx +51 -51
  536. package/src/toolbar/FixedToolbar.tsx +73 -21
  537. package/src/toolbar/HeadingPicker.tsx +46 -38
  538. package/src/toolbar/ImageBubble.tsx +26 -44
  539. package/src/toolbar/ImageDialog.native.tsx +97 -0
  540. package/src/toolbar/ImageDialog.tsx +5 -4
  541. package/src/toolbar/LinkBubble.tsx +27 -64
  542. package/src/toolbar/LinkDialog.native.tsx +117 -0
  543. package/src/toolbar/LinkDialog.tsx +28 -24
  544. package/src/toolbar/ListPicker.tsx +47 -43
  545. package/src/toolbar/MathBubble.tsx +140 -0
  546. package/src/toolbar/MoreDropdown.tsx +79 -62
  547. package/src/toolbar/StatusBar.tsx +13 -8
  548. package/src/toolbar/TableBubble.tsx +136 -95
  549. package/src/toolbar/ToolbarButton.native.tsx +14 -4
  550. package/src/toolbar/ToolbarButton.tsx +98 -19
  551. package/src/toolbar/bubbleToolbar.spec.tsx +2 -1
  552. package/src/toolbar/fixedToolbar.spec.tsx +4 -2
  553. package/src/toolbar/icons.tsx +113 -323
  554. package/src/toolbar/shortcuts.ts +77 -24
  555. package/src/toolbar/toolbarPrimitives.spec.tsx +29 -1
  556. package/src/toolbar/toolbarSubComponents.spec.tsx +4 -2
  557. package/src/toolbar/useHorizontalScroll.spec.ts +67 -0
  558. package/src/toolbar/useHorizontalScroll.tsx +39 -12
  559. package/src/toolbar/useRovingFocus.spec.tsx +100 -0
  560. package/src/toolbar/useRovingFocus.ts +82 -0
  561. package/src/types.spec.ts +40 -1
  562. package/src/types.ts +56 -1
  563. package/types/RichEditor.d.ts +51 -0
  564. package/types/RichEditor.d.ts.map +1 -0
  565. package/types/RichEditor.native.d.ts +59 -0
  566. package/types/RichEditor.native.d.ts.map +1 -0
  567. package/types/RichTextEditor/index.d.ts +77 -0
  568. package/types/RichTextEditor/index.d.ts.map +1 -0
  569. package/types/constants.d.ts +49 -0
  570. package/types/constants.d.ts.map +1 -0
  571. package/types/context.d.ts +10 -0
  572. package/types/context.d.ts.map +1 -0
  573. package/types/editor/BlockDragHandle.d.ts +8 -0
  574. package/types/editor/BlockDragHandle.d.ts.map +1 -0
  575. package/types/editor/MarkdownPaste.d.ts +8 -0
  576. package/types/editor/MarkdownPaste.d.ts.map +1 -0
  577. package/types/editor/SlashCommands.d.ts +24 -0
  578. package/types/editor/SlashCommands.d.ts.map +1 -0
  579. package/types/editor/TentapEditor.native.d.ts +21 -0
  580. package/types/editor/TentapEditor.native.d.ts.map +1 -0
  581. package/types/editor/TiptapEditor.d.ts +24 -0
  582. package/types/editor/TiptapEditor.d.ts.map +1 -0
  583. package/types/editor/blockAnchor.d.ts +25 -0
  584. package/types/editor/blockAnchor.d.ts.map +1 -0
  585. package/types/editor/capabilities.d.ts +29 -0
  586. package/types/editor/capabilities.d.ts.map +1 -0
  587. package/types/editor/codeBlockPreview.d.ts +51 -0
  588. package/types/editor/codeBlockPreview.d.ts.map +1 -0
  589. package/types/editor/editorStyles.d.ts +25 -0
  590. package/types/editor/editorStyles.d.ts.map +1 -0
  591. package/types/editor/emoji.d.ts +45 -0
  592. package/types/editor/emoji.d.ts.map +1 -0
  593. package/types/editor/extensions.d.ts +41 -0
  594. package/types/editor/extensions.d.ts.map +1 -0
  595. package/types/editor/index.d.ts +11 -0
  596. package/types/editor/index.d.ts.map +1 -0
  597. package/types/editor/lazyKatex.d.ts +33 -0
  598. package/types/editor/lazyKatex.d.ts.map +1 -0
  599. package/types/editor/markdown.d.ts +24 -0
  600. package/types/editor/markdown.d.ts.map +1 -0
  601. package/types/editor/mathematics.d.ts +44 -0
  602. package/types/editor/mathematics.d.ts.map +1 -0
  603. package/types/editor/media.d.ts +32 -0
  604. package/types/editor/media.d.ts.map +1 -0
  605. package/types/editor/mentions.d.ts +15 -0
  606. package/types/editor/mentions.d.ts.map +1 -0
  607. package/types/editor/pasteCleanup.d.ts +24 -0
  608. package/types/editor/pasteCleanup.d.ts.map +1 -0
  609. package/types/editor/suggestionPopup.d.ts +113 -0
  610. package/types/editor/suggestionPopup.d.ts.map +1 -0
  611. package/types/editor/types.d.ts +80 -0
  612. package/types/editor/types.d.ts.map +1 -0
  613. package/types/editor/useEditorState.d.ts +19 -0
  614. package/types/editor/useEditorState.d.ts.map +1 -0
  615. package/types/index.d.ts +12 -0
  616. package/types/index.d.ts.map +1 -0
  617. package/types/preview.d.ts +44 -0
  618. package/types/preview.d.ts.map +1 -0
  619. package/types/shared/t.d.ts +10 -0
  620. package/types/shared/t.d.ts.map +1 -0
  621. package/types/shared/url.d.ts +9 -0
  622. package/types/shared/url.d.ts.map +1 -0
  623. package/types/styled.d.ts +40 -0
  624. package/types/styled.d.ts.map +1 -0
  625. package/types/toolbar/BubbleToolbar.d.ts +25 -0
  626. package/types/toolbar/BubbleToolbar.d.ts.map +1 -0
  627. package/types/toolbar/CodeBlockBubble.d.ts +10 -0
  628. package/types/toolbar/CodeBlockBubble.d.ts.map +1 -0
  629. package/types/toolbar/ColorPicker.d.ts +15 -0
  630. package/types/toolbar/ColorPicker.d.ts.map +1 -0
  631. package/types/toolbar/ColorPicker.native.d.ts +20 -0
  632. package/types/toolbar/ColorPicker.native.d.ts.map +1 -0
  633. package/types/toolbar/FixedToolbar.d.ts +34 -0
  634. package/types/toolbar/FixedToolbar.d.ts.map +1 -0
  635. package/types/toolbar/FixedToolbar.native.d.ts +30 -0
  636. package/types/toolbar/FixedToolbar.native.d.ts.map +1 -0
  637. package/types/toolbar/HeadingPicker.d.ts +14 -0
  638. package/types/toolbar/HeadingPicker.d.ts.map +1 -0
  639. package/types/toolbar/ImageBubble.d.ts +10 -0
  640. package/types/toolbar/ImageBubble.d.ts.map +1 -0
  641. package/types/toolbar/ImageDialog.d.ts +12 -0
  642. package/types/toolbar/ImageDialog.d.ts.map +1 -0
  643. package/types/toolbar/ImageDialog.native.d.ts +15 -0
  644. package/types/toolbar/ImageDialog.native.d.ts.map +1 -0
  645. package/types/toolbar/LinkBubble.d.ts +10 -0
  646. package/types/toolbar/LinkBubble.d.ts.map +1 -0
  647. package/types/toolbar/LinkDialog.d.ts +20 -0
  648. package/types/toolbar/LinkDialog.d.ts.map +1 -0
  649. package/types/toolbar/LinkDialog.native.d.ts +18 -0
  650. package/types/toolbar/LinkDialog.native.d.ts.map +1 -0
  651. package/types/toolbar/ListPicker.d.ts +14 -0
  652. package/types/toolbar/ListPicker.d.ts.map +1 -0
  653. package/types/toolbar/MathBubble.d.ts +11 -0
  654. package/types/toolbar/MathBubble.d.ts.map +1 -0
  655. package/types/toolbar/MoreDropdown.d.ts +15 -0
  656. package/types/toolbar/MoreDropdown.d.ts.map +1 -0
  657. package/types/toolbar/ResizeHandle.d.ts +11 -0
  658. package/types/toolbar/ResizeHandle.d.ts.map +1 -0
  659. package/types/toolbar/StatusBar.d.ts +11 -0
  660. package/types/toolbar/StatusBar.d.ts.map +1 -0
  661. package/types/toolbar/TableBubble.d.ts +13 -0
  662. package/types/toolbar/TableBubble.d.ts.map +1 -0
  663. package/types/toolbar/ToolbarButton.d.ts +35 -0
  664. package/types/toolbar/ToolbarButton.d.ts.map +1 -0
  665. package/types/toolbar/ToolbarButton.native.d.ts +30 -0
  666. package/types/toolbar/ToolbarButton.native.d.ts.map +1 -0
  667. package/types/toolbar/ToolbarGroup.d.ts +14 -0
  668. package/types/toolbar/ToolbarGroup.d.ts.map +1 -0
  669. package/types/toolbar/icons.d.ts +52 -0
  670. package/types/toolbar/icons.d.ts.map +1 -0
  671. package/types/toolbar/icons.native.d.ts +41 -0
  672. package/types/toolbar/icons.native.d.ts.map +1 -0
  673. package/types/toolbar/shortcuts.d.ts +34 -0
  674. package/types/toolbar/shortcuts.d.ts.map +1 -0
  675. package/types/toolbar/useHorizontalScroll.d.ts +43 -0
  676. package/types/toolbar/useHorizontalScroll.d.ts.map +1 -0
  677. package/types/toolbar/useRovingFocus.d.ts +10 -0
  678. package/types/toolbar/useRovingFocus.d.ts.map +1 -0
  679. package/types/types.d.ts +147 -0
  680. package/types/types.d.ts.map +1 -0
  681. package/dist/cjs/RichEditor.stories.cjs +0 -327
  682. package/dist/cjs/RichEditor.stories.native.js +0 -342
  683. package/dist/cjs/RichEditor.stories.native.js.map +0 -1
  684. package/dist/esm/RichEditor.stories.mjs +0 -291
  685. package/dist/esm/RichEditor.stories.mjs.map +0 -1
  686. package/dist/esm/RichEditor.stories.native.js +0 -303
  687. package/dist/esm/RichEditor.stories.native.js.map +0 -1
  688. package/dist/jsx/RichEditor.stories.mjs +0 -291
  689. package/dist/jsx/RichEditor.stories.mjs.map +0 -1
  690. package/dist/jsx/RichEditor.stories.native.js +0 -342
  691. package/dist/jsx/RichEditor.stories.native.js.map +0 -1
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Canonical HTML <-> Markdown conversion for the rich text editor (web).
3
+ *
4
+ * One implementation (LC-16) shared by the markdown source mode toggle and
5
+ * the markdown paste handler. GFM coverage beyond turndown's defaults:
6
+ * strikethrough, task lists (Tiptap's label-nested checkbox markup), and
7
+ * pipe tables. Marks with no markdown syntax (underline, sub/superscript,
8
+ * highlight, text color spans) survive as inline HTML so the
9
+ * rich -> markdown -> rich round-trip is lossless for every toolbar feature.
10
+ *
11
+ * GitLab-flavored extras (round-trip lossless):
12
+ * - `$x$` inline math <-> `<span data-type="inline-math" data-latex>`
13
+ * - `$$ ... $$` block math <-> code block with language "math"
14
+ * (``` math fences parse to the same node; `$$` is the canonical output)
15
+ * - ```mermaid fences <-> code block with language "mermaid" (turndown's
16
+ * fenced rule + marked's language classes handle this natively)
17
+ * - `<details>` collapsible sections stay raw HTML in markdown, exactly
18
+ * like GitLab renders them
19
+ */
20
+
21
+ import TurndownService from "turndown";
22
+ import { Marked } from "marked";
23
+
24
+ // ===========================================================================
25
+ // HTML -> Markdown (turndown + GFM rules)
26
+ // ===========================================================================
27
+
28
+ function cellMarkdown(cell: HTMLElement, inline: TurndownService): string {
29
+ const md = inline.turndown(cell.innerHTML || "");
30
+ // GFM cells are single-line: collapse block breaks and escape pipes
31
+ return md.replace(/\n+/g, " ").replace(/\|/g, "\\|").trim();
32
+ }
33
+
34
+ function createTurndown(): TurndownService {
35
+ const service = new TurndownService({
36
+ headingStyle: "atx",
37
+ codeBlockStyle: "fenced",
38
+ bulletListMarker: "-",
39
+ });
40
+
41
+ // Marks markdown cannot express stay as inline HTML (round-trip lossless):
42
+ // underline, sub/superscript, highlight, and color-carrying spans.
43
+ // Collapsible <details> sections are raw HTML in markdown (GitLab
44
+ // behavior) — kept whole, children included.
45
+ service.keep((node) => {
46
+ const name = node.nodeName;
47
+ if (name === "U" || name === "SUB" || name === "SUP" || name === "MARK") return true;
48
+ if (name === "DETAILS") return true;
49
+ if (name === "SPAN") {
50
+ const style = (node as HTMLElement).getAttribute("style") ?? "";
51
+ return style.includes("color");
52
+ }
53
+ return false;
54
+ });
55
+
56
+ service.addRule("strikethrough", {
57
+ filter: ["del", "s"],
58
+ replacement: (content) => `~~${content}~~`,
59
+ });
60
+
61
+ // Inline math node -> `$latex$` (GitLab-flavored markdown dollar math)
62
+ service.addRule("inlineMath", {
63
+ filter: (node) =>
64
+ node.nodeName === "SPAN" && (node as HTMLElement).getAttribute("data-type") === "inline-math",
65
+ replacement: (_content, node) => `$${(node as HTMLElement).getAttribute("data-latex") ?? ""}$`,
66
+ });
67
+
68
+ // Math code block -> `$$` delimited block (canonical GLFM display math)
69
+ service.addRule("mathBlock", {
70
+ filter: (node) =>
71
+ node.nodeName === "PRE" &&
72
+ (node.firstChild as HTMLElement | null)?.nodeName === "CODE" &&
73
+ ((node.firstChild as HTMLElement).getAttribute("class") ?? "").includes("language-math"),
74
+ replacement: (_content, node) => {
75
+ const code = (node.firstChild as HTMLElement).textContent ?? "";
76
+ return `\n\n$$\n${code.replace(/\n$/, "")}\n$$\n\n`;
77
+ },
78
+ });
79
+
80
+ // Tiptap task item: <li data-type="taskItem" data-checked="true">
81
+ // <label><input type="checkbox"><span></span></label><div><p>text</p></div>
82
+ service.addRule("taskListItem", {
83
+ filter: (node) =>
84
+ node.nodeName === "LI" && (node as HTMLElement).getAttribute("data-type") === "taskItem",
85
+ replacement: (content, node) => {
86
+ const checked = (node as HTMLElement).getAttribute("data-checked") === "true";
87
+ const text = content.replace(/^\s+|\s+$/g, "").replace(/\n{2,}/g, "\n");
88
+ return `- [${checked ? "x" : " "}] ${text}\n`;
89
+ },
90
+ });
91
+
92
+ // The checkbox control inside the task item label contributes no text
93
+ service.addRule("taskListCheckbox", {
94
+ filter: (node) =>
95
+ (node.nodeName === "INPUT" && (node as HTMLInputElement).type === "checkbox") ||
96
+ (node.nodeName === "LABEL" && node.parentElement?.getAttribute("data-type") === "taskItem"),
97
+ replacement: () => "",
98
+ });
99
+
100
+ // GFM pipe tables (simple grid: no colspan/rowspan)
101
+ service.addRule("table", {
102
+ filter: "table",
103
+ replacement: (_content, node) => {
104
+ const table = node as HTMLTableElement;
105
+ const rows = Array.from(table.querySelectorAll("tr"));
106
+ if (rows.length === 0) return "";
107
+ const inline = createInlineTurndown();
108
+ const grid = rows.map((row) =>
109
+ Array.from(row.querySelectorAll("th, td")).map((cell) =>
110
+ cellMarkdown(cell as HTMLElement, inline),
111
+ ),
112
+ );
113
+ const cols = Math.max(...grid.map((r) => r.length));
114
+ const pad = (r: string[]) => {
115
+ const filled = [...r];
116
+ while (filled.length < cols) filled.push("");
117
+ return filled;
118
+ };
119
+ const line = (cells: string[]) => `| ${pad(cells).join(" | ")} |`;
120
+ const header = line(grid[0]!);
121
+ const divider = `| ${Array.from({ length: cols }, () => "---").join(" | ")} |`;
122
+ const body = grid.slice(1).map(line);
123
+ return `\n\n${[header, divider, ...body].join("\n")}\n\n`;
124
+ },
125
+ });
126
+
127
+ return service;
128
+ }
129
+
130
+ /** Inline-only converter for table cells (tables cannot nest in GFM cells) */
131
+ function createInlineTurndown(): TurndownService {
132
+ const service = new TurndownService({ codeBlockStyle: "fenced" });
133
+ service.keep((node) => {
134
+ const name = node.nodeName;
135
+ if (name === "U" || name === "SUB" || name === "SUP" || name === "MARK") return true;
136
+ if (name === "SPAN")
137
+ return ((node as HTMLElement).getAttribute("style") ?? "").includes("color");
138
+ return false;
139
+ });
140
+ service.addRule("strikethrough", {
141
+ filter: ["del", "s"],
142
+ replacement: (content) => `~~${content}~~`,
143
+ });
144
+ return service;
145
+ }
146
+
147
+ let turndownSingleton: TurndownService | null = null;
148
+
149
+ /** Convert editor HTML to GFM markdown */
150
+ export function htmlToMarkdown(html: string): string {
151
+ if (!turndownSingleton) turndownSingleton = createTurndown();
152
+ return turndownSingleton.turndown(html);
153
+ }
154
+
155
+ // ===========================================================================
156
+ // Markdown -> HTML (marked + math extensions + Tiptap task list upgrade)
157
+ // ===========================================================================
158
+
159
+ function escapeHtml(value: string): string {
160
+ return value
161
+ .replace(/&/g, "&amp;")
162
+ .replace(/</g, "&lt;")
163
+ .replace(/>/g, "&gt;")
164
+ .replace(/"/g, "&quot;");
165
+ }
166
+
167
+ /**
168
+ * `$$ ... $$` display math -> math code block. Accepts the delimiters on
169
+ * their own lines (canonical GLFM) or a single `$$x$$` line; both re-enter
170
+ * the editor as a code block with language "math".
171
+ */
172
+ const blockMathExtension = {
173
+ name: "blockMath",
174
+ level: "block" as const,
175
+ start: (src: string) => src.match(/^\$\$/m)?.index,
176
+ tokenizer(src: string) {
177
+ const match =
178
+ src.match(/^\$\$[ \t]*\n([\s\S]*?)\n[ \t]*\$\$[ \t]*(?:\n+|$)/) ??
179
+ src.match(/^\$\$([^\n$]+?)\$\$[ \t]*(?:\n+|$)/);
180
+ if (!match) return undefined;
181
+ return { type: "blockMath", raw: match[0], latex: (match[1] ?? "").trim() };
182
+ },
183
+ renderer(token: { latex: string }) {
184
+ return `<pre><code class="language-math">${escapeHtml(token.latex)}</code></pre>\n`;
185
+ },
186
+ };
187
+
188
+ /**
189
+ * `$x^2$` inline math -> inline-math span. Content must not start or end
190
+ * with whitespace and cannot span lines, so prose like "$5 and $10" never
191
+ * false-positives (same heuristic GitLab/Pandoc use for dollar math).
192
+ */
193
+ const inlineMathExtension = {
194
+ name: "inlineMath",
195
+ level: "inline" as const,
196
+ start: (src: string) => src.indexOf("$"),
197
+ tokenizer(src: string) {
198
+ const match = src.match(/^\$([^$\n])\$/) ?? src.match(/^\$([^$\n \t][^$\n]*?[^$\n \t])\$/);
199
+ if (!match) return undefined;
200
+ return { type: "inlineMath", raw: match[0], latex: match[1] ?? "" };
201
+ },
202
+ renderer(token: { latex: string }) {
203
+ const escaped = escapeHtml(token.latex);
204
+ return `<span data-type="inline-math" data-latex="${escaped}">${escaped}</span>`;
205
+ },
206
+ };
207
+
208
+ let markedSingleton: Marked | null = null;
209
+
210
+ /** Local marked instance so math extensions never leak into the global */
211
+ function getMarked(): Marked {
212
+ if (!markedSingleton) {
213
+ markedSingleton = new Marked({ gfm: true });
214
+ markedSingleton.use({ extensions: [blockMathExtension, inlineMathExtension] });
215
+ }
216
+ return markedSingleton;
217
+ }
218
+
219
+ /**
220
+ * marked emits GFM task items as `<li><input type="checkbox" checked>`;
221
+ * Tiptap's TaskList/TaskItem parse `ul[data-type="taskList"] >
222
+ * li[data-type="taskItem"][data-checked]`. Upgrade in the DOM so the
223
+ * round-trip re-enters the editor as real task items.
224
+ */
225
+ function upgradeTaskLists(html: string): string {
226
+ if (typeof document === "undefined" || !html.includes("checkbox")) return html;
227
+ const doc = new DOMParser().parseFromString(html, "text/html");
228
+ for (const input of Array.from(
229
+ doc.querySelectorAll<HTMLInputElement>('li input[type="checkbox"]'),
230
+ )) {
231
+ const li = input.closest("li");
232
+ if (!li) continue;
233
+ li.setAttribute("data-type", "taskItem");
234
+ li.setAttribute(
235
+ "data-checked",
236
+ input.checked || input.hasAttribute("checked") ? "true" : "false",
237
+ );
238
+ input.remove();
239
+ const list = li.closest("ul, ol");
240
+ if (list) list.setAttribute("data-type", "taskList");
241
+ }
242
+ return doc.body.innerHTML;
243
+ }
244
+
245
+ /** Convert GFM markdown to HTML the Tiptap schema can ingest */
246
+ export function markdownToHtml(markdown: string): string {
247
+ const html = getMarked().parse(markdown, { async: false }) as string;
248
+ return upgradeTaskLists(html);
249
+ }
@@ -0,0 +1,97 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { Editor } from "@tiptap/core";
3
+ import StarterKit from "@tiptap/starter-kit";
4
+ import { INLINE_MATH_INPUT_RULE, InlineMath } from "./mathematics";
5
+
6
+ function createEditor(content = "<p></p>") {
7
+ return new Editor({
8
+ element: document.createElement("div"),
9
+ extensions: [StarterKit, InlineMath],
10
+ content,
11
+ });
12
+ }
13
+
14
+ async function waitFor(check: () => boolean, timeoutMs = 3000): Promise<void> {
15
+ const start = Date.now();
16
+ while (!check()) {
17
+ if (Date.now() - start > timeoutMs) throw new Error("waitFor timed out");
18
+ await new Promise((resolve) => setTimeout(resolve, 25));
19
+ }
20
+ }
21
+
22
+ describe("INLINE_MATH_INPUT_RULE", () => {
23
+ const matches = (text: string) => text.match(INLINE_MATH_INPUT_RULE);
24
+
25
+ it("matches dollar math at the end of typed text", () => {
26
+ const match = matches("energy $E=mc^2$");
27
+ expect(match?.[2]).toBe("E=mc^2");
28
+ const startOfLine = matches("$x^2$");
29
+ expect(startOfLine?.[2]).toBe("x^2");
30
+ const singleChar = matches("$x$");
31
+ expect(singleChar?.[2]).toBe("x");
32
+ });
33
+
34
+ it("rejects price-like text and padded content", () => {
35
+ expect(matches("costs $5 and $10")).toBeNull();
36
+ expect(matches("$ x$")).toBeNull();
37
+ expect(matches("$x $")).toBeNull();
38
+ expect(matches("$$")).toBeNull();
39
+ // `$$x$$` is block math, not inline
40
+ expect(matches("$$x$$")).toBeNull();
41
+ });
42
+ });
43
+
44
+ describe("InlineMath node", () => {
45
+ it("parses and serializes data-latex spans losslessly", () => {
46
+ const editor = createEditor(
47
+ '<p>see <span data-type="inline-math" data-latex="E=mc^2">E=mc^2</span></p>',
48
+ );
49
+ expect(editor.getHTML()).toContain('data-type="inline-math"');
50
+ expect(editor.getHTML()).toContain('data-latex="E=mc^2"');
51
+ editor.destroy();
52
+ });
53
+
54
+ it("insertInlineMath inserts and selects the node (bubble opens)", () => {
55
+ const editor = createEditor();
56
+ editor.chain().focus().insertInlineMath({ latex: "a+b" }).run();
57
+ expect(editor.isActive("inlineMath")).toBe(true);
58
+ expect(editor.getAttributes("inlineMath").latex).toBe("a+b");
59
+ editor.destroy();
60
+ });
61
+
62
+ it("updateInlineMath rewrites the selected node's latex", () => {
63
+ const editor = createEditor();
64
+ editor.chain().focus().insertInlineMath({ latex: "a" }).run();
65
+ expect(editor.commands.updateInlineMath({ latex: "b^2" })).toBe(true);
66
+ expect(editor.getAttributes("inlineMath").latex).toBe("b^2");
67
+ expect(editor.getHTML()).toContain('data-latex="b^2"');
68
+ editor.destroy();
69
+ });
70
+
71
+ it("updateInlineMath is a no-op without a selected math node", () => {
72
+ const editor = createEditor("<p>plain</p>");
73
+ expect(editor.commands.updateInlineMath({ latex: "x" })).toBe(false);
74
+ editor.destroy();
75
+ });
76
+
77
+ it("node view renders KaTeX markup for valid TeX", async () => {
78
+ const editor = createEditor('<p><span data-type="inline-math" data-latex="x^2">x^2</span></p>');
79
+ const chip = editor.view.dom.querySelector(".rt-math-inline");
80
+ expect(chip).not.toBeNull();
81
+ await waitFor(() => chip!.querySelector(".katex") !== null);
82
+ expect(chip!.getAttribute("aria-label")).toBe("x^2");
83
+ editor.destroy();
84
+ });
85
+
86
+ it("node view shows the error state for invalid TeX", async () => {
87
+ const editor = createEditor(
88
+ '<p><span data-type="inline-math" data-latex="\\nope{">x</span></p>',
89
+ );
90
+ const chip = editor.view.dom.querySelector(".rt-math-inline");
91
+ await waitFor(() => chip!.classList.contains("rt-math-error"));
92
+ // raw source stays visible; the parse error rides the title
93
+ expect(chip!.textContent).toBe("\\nope{");
94
+ expect(chip!.getAttribute("title")).toMatch(/parse error/i);
95
+ editor.destroy();
96
+ });
97
+ });
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Inline math node (`$x^2$`) rendered with lazy-loaded KaTeX — GitLab
3
+ * parity for dollar math in the rich text editor.
4
+ *
5
+ * - Typing `$latex$` converts to a rendered formula (input rule; prices
6
+ * like "$5 and $10" never convert — content cannot start/end with
7
+ * whitespace).
8
+ * - The node is an inline atom carrying the raw TeX in `data-latex`; the
9
+ * MathBubble edits it in place (updateInlineMath command).
10
+ * - Invalid TeX shows the raw source in an error style with the KaTeX
11
+ * parse message (Axiom 6: show the error, never blank).
12
+ * - Block math (`$$ ... $$`) is a code block with language "math" — see
13
+ * codeBlockPreview.ts — matching GitLab's ```math fence model.
14
+ *
15
+ * Serialization: `<span data-type="inline-math" data-latex="...">` <->
16
+ * `$...$` (editor/markdown.ts), so the source toggle is lossless.
17
+ */
18
+
19
+ import { Node, mergeAttributes, nodeInputRule } from "@tiptap/core";
20
+ import { NodeSelection } from "@tiptap/pm/state";
21
+ import { t } from "../shared/t";
22
+ import { mountKatexHtml, renderKatexHtml } from "./lazyKatex";
23
+
24
+ export interface InlineMathOptions {
25
+ HTMLAttributes: Record<string, any>;
26
+ }
27
+
28
+ declare module "@tiptap/core" {
29
+ interface Commands<ReturnType> {
30
+ inlineMath: {
31
+ /** Inserts an inline math node and selects it (opens the MathBubble) */
32
+ insertInlineMath: (attributes?: { latex?: string }) => ReturnType;
33
+ /** Updates the latex of the selected inline math node */
34
+ updateInlineMath: (attributes: { latex: string }) => ReturnType;
35
+ };
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Matches `$...$` as the last thing typed. match[1] is the dollar span
41
+ * (what the node replaces), match[2] the TeX. The character before the
42
+ * opening `$` must not be another `$` (that is block math), and content
43
+ * cannot start/end with whitespace or contain `$`/newlines.
44
+ */
45
+ export const INLINE_MATH_INPUT_RULE = /(?:^|[^$])(\$([^$\n \t](?:[^$\n]*[^$\n \t])?)\$)$/;
46
+
47
+ export const InlineMath = Node.create<InlineMathOptions>({
48
+ name: "inlineMath",
49
+ inline: true,
50
+ group: "inline",
51
+ atom: true,
52
+ marks: "",
53
+
54
+ addOptions() {
55
+ return { HTMLAttributes: {} };
56
+ },
57
+
58
+ addAttributes() {
59
+ return {
60
+ latex: {
61
+ default: "",
62
+ parseHTML: (element) => element.getAttribute("data-latex") ?? element.textContent ?? "",
63
+ renderHTML: (attributes) => ({ "data-latex": attributes.latex }),
64
+ },
65
+ };
66
+ },
67
+
68
+ parseHTML() {
69
+ return [{ tag: 'span[data-type="inline-math"]' }];
70
+ },
71
+
72
+ renderHTML({ node, HTMLAttributes }) {
73
+ // raw TeX as text content: non-web surfaces (native preview, plain
74
+ // parsers) degrade to readable source
75
+ return [
76
+ "span",
77
+ mergeAttributes({ "data-type": "inline-math" }, this.options.HTMLAttributes, HTMLAttributes),
78
+ node.attrs.latex,
79
+ ];
80
+ },
81
+
82
+ addCommands() {
83
+ return {
84
+ insertInlineMath:
85
+ (attributes) =>
86
+ ({ tr, dispatch }) => {
87
+ if (dispatch) {
88
+ const pos = tr.selection.from;
89
+ tr.replaceSelectionWith(this.type.create({ latex: attributes?.latex ?? "" }), false);
90
+ tr.setSelection(NodeSelection.create(tr.doc, pos));
91
+ tr.scrollIntoView();
92
+ }
93
+ return true;
94
+ },
95
+ updateInlineMath:
96
+ (attributes) =>
97
+ ({ tr, dispatch }) => {
98
+ const { selection } = tr;
99
+ if (!(selection instanceof NodeSelection) || selection.node.type !== this.type) {
100
+ return false;
101
+ }
102
+ if (dispatch) {
103
+ const pos = selection.from;
104
+ tr.setNodeMarkup(pos, undefined, { latex: attributes.latex });
105
+ tr.setSelection(NodeSelection.create(tr.doc, pos));
106
+ }
107
+ return true;
108
+ },
109
+ };
110
+ },
111
+
112
+ addInputRules() {
113
+ return [
114
+ nodeInputRule({
115
+ find: INLINE_MATH_INPUT_RULE,
116
+ type: this.type,
117
+ getAttributes: (match) => ({ latex: match[2] ?? "" }),
118
+ }),
119
+ ];
120
+ },
121
+
122
+ addNodeView() {
123
+ return ({ node }) => {
124
+ const dom = document.createElement("span");
125
+ dom.className = "rt-math-inline";
126
+ dom.setAttribute("data-type", "inline-math");
127
+ dom.contentEditable = "false";
128
+
129
+ let currentLatex: string | null = null;
130
+ let destroyed = false;
131
+
132
+ const render = (latex: string) => {
133
+ if (destroyed || latex === currentLatex) return;
134
+ currentLatex = latex;
135
+ dom.setAttribute("data-latex", latex);
136
+ if (!latex.trim()) {
137
+ dom.classList.add("rt-math-empty");
138
+ dom.classList.remove("rt-math-error");
139
+ dom.removeAttribute("title");
140
+ dom.textContent = t("math");
141
+ return;
142
+ }
143
+ dom.classList.remove("rt-math-empty");
144
+ // raw TeX stays visible while KaTeX loads (first render only)
145
+ dom.textContent = latex;
146
+ void renderKatexHtml(latex).then((result) => {
147
+ if (destroyed || currentLatex !== latex) return;
148
+ if (result.ok) {
149
+ mountKatexHtml(dom, result.html);
150
+ dom.classList.remove("rt-math-error");
151
+ dom.removeAttribute("title");
152
+ dom.setAttribute("role", "img");
153
+ dom.setAttribute("aria-label", latex);
154
+ } else {
155
+ // Axiom 6: raw source + parse message, never a blank chip
156
+ dom.textContent = latex;
157
+ dom.classList.add("rt-math-error");
158
+ dom.title = result.error;
159
+ }
160
+ });
161
+ };
162
+
163
+ render((node.attrs.latex as string) ?? "");
164
+
165
+ return {
166
+ dom,
167
+ update: (updatedNode) => {
168
+ if (updatedNode.type.name !== "inlineMath") return false;
169
+ render((updatedNode.attrs.latex as string) ?? "");
170
+ return true;
171
+ },
172
+ ignoreMutation: () => true,
173
+ destroy: () => {
174
+ destroyed = true;
175
+ },
176
+ };
177
+ };
178
+ },
179
+ });
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Media paste/drop upload behavior against a headless Tiptap editor.
3
+ */
4
+
5
+ import { describe, expect, it, vi } from "vitest";
6
+ import { Editor } from "@tiptap/core";
7
+ import StarterKit from "@tiptap/starter-kit";
8
+ import Image from "@tiptap/extension-image";
9
+ import { MediaUpload } from "./media";
10
+
11
+ function createEditor() {
12
+ return new Editor({
13
+ element: document.createElement("div"),
14
+ extensions: [StarterKit, Image.configure({ inline: true, allowBase64: true }), MediaUpload],
15
+ content: "<p>start</p>",
16
+ });
17
+ }
18
+
19
+ function firePaste(editor: Editor, files: File[]) {
20
+ const event = {
21
+ clipboardData: { files, types: ["Files"], getData: () => "" },
22
+ preventDefault: vi.fn(),
23
+ } as unknown as ClipboardEvent;
24
+ // someProp mirrors ProseMirror dispatch: handlers run in order until one
25
+ // claims the event by returning truthy
26
+ const handled = !!editor.view.someProp("handlePaste", (fn) =>
27
+ fn(editor.view, event, editor.state.tr.doc.slice(0)),
28
+ );
29
+ return { handled, event };
30
+ }
31
+
32
+ async function waitFor(check: () => boolean, timeoutMs = 2000) {
33
+ const start = Date.now();
34
+ while (!check()) {
35
+ if (Date.now() - start > timeoutMs) throw new Error("waitFor timed out");
36
+ await new Promise((r) => setTimeout(r, 10));
37
+ }
38
+ }
39
+
40
+ describe("MediaUpload", () => {
41
+ it("inserts an uploaded image URL when onImageUpload is wired", async () => {
42
+ const editor = createEditor();
43
+ const onImageUpload = vi.fn(async () => "https://cdn.example.com/pic.png");
44
+ editor.storage.mediaUpload.handlers = { onImageUpload };
45
+
46
+ const file = new File(["binary"], "pic.png", { type: "image/png" });
47
+ const { handled, event } = firePaste(editor, [file]);
48
+
49
+ expect(handled).toBe(true);
50
+ expect(event.preventDefault).toHaveBeenCalled();
51
+ await waitFor(() => editor.getHTML().includes("<img"));
52
+ expect(onImageUpload).toHaveBeenCalledWith(file);
53
+ expect(editor.getHTML()).toContain('src="https://cdn.example.com/pic.png"');
54
+ expect(editor.getHTML()).toContain('alt="pic"');
55
+ editor.destroy();
56
+ });
57
+
58
+ it("falls back to base64 data URI without an image handler", async () => {
59
+ const editor = createEditor();
60
+ const file = new File(["binary"], "photo.jpg", { type: "image/jpeg" });
61
+ const { handled } = firePaste(editor, [file]);
62
+
63
+ expect(handled).toBe(true);
64
+ await waitFor(() => editor.getHTML().includes("<img"));
65
+ expect(editor.getHTML()).toContain('src="data:');
66
+ editor.destroy();
67
+ });
68
+
69
+ it("inserts an attachment chip link for non-image files via onFileUpload", async () => {
70
+ const editor = createEditor();
71
+ const onFileUpload = vi.fn(async () => ({
72
+ url: "https://cdn.example.com/report.pdf",
73
+ name: "report.pdf",
74
+ }));
75
+ editor.storage.mediaUpload.handlers = { onFileUpload };
76
+
77
+ const file = new File(["%PDF"], "report.pdf", { type: "application/pdf" });
78
+ const { handled } = firePaste(editor, [file]);
79
+
80
+ expect(handled).toBe(true);
81
+ await waitFor(() => editor.getHTML().includes("<a"));
82
+ const html = editor.getHTML();
83
+ expect(html).toContain('href="https://cdn.example.com/report.pdf"');
84
+ expect(html).toContain("rt-attachment");
85
+ expect(html).toContain("report.pdf");
86
+ editor.destroy();
87
+ });
88
+
89
+ it("ignores non-image files without a file handler (honest no-op)", () => {
90
+ const editor = createEditor();
91
+ const file = new File(["%PDF"], "report.pdf", { type: "application/pdf" });
92
+ const { handled } = firePaste(editor, [file]);
93
+ expect(handled).toBe(false);
94
+ expect(editor.getHTML()).not.toContain("<a");
95
+ editor.destroy();
96
+ });
97
+
98
+ it("does not intercept text-only pastes", () => {
99
+ const editor = createEditor();
100
+ const { handled } = firePaste(editor, []);
101
+ expect(handled).toBeFalsy();
102
+ editor.destroy();
103
+ });
104
+
105
+ it("survives a failing upload without crashing", async () => {
106
+ const editor = createEditor();
107
+ const onImageUpload = vi.fn(async () => {
108
+ throw new Error("upload broke");
109
+ });
110
+ editor.storage.mediaUpload.handlers = { onImageUpload };
111
+ const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
112
+
113
+ const file = new File(["binary"], "pic.png", { type: "image/png" });
114
+ const { handled } = firePaste(editor, [file]);
115
+ expect(handled).toBe(true);
116
+ await waitFor(() => warn.mock.calls.length > 0);
117
+ expect(editor.getHTML()).not.toContain("<img");
118
+ warn.mockRestore();
119
+ editor.destroy();
120
+ });
121
+ });