@multiplatform.one/rich-text 6.1.0 → 6.3.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 (649) hide show
  1. package/README.md +60 -0
  2. package/dist/cjs/RichEditor.cjs +84 -9
  3. package/dist/cjs/RichEditor.native.js +422 -35
  4. package/dist/cjs/RichEditor.native.js.map +1 -1
  5. package/dist/cjs/RichTextEditor/index.cjs +18 -2
  6. package/dist/cjs/RichTextEditor/index.native.js +18 -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 +249 -293
  15. package/dist/cjs/editor/SlashCommands.native.js +306 -340
  16. package/dist/cjs/editor/SlashCommands.native.js.map +1 -1
  17. package/dist/cjs/editor/TentapEditor.native.js +44 -12
  18. package/dist/cjs/editor/TentapEditor.native.js.map +1 -1
  19. package/dist/cjs/editor/TiptapEditor.cjs +140 -33
  20. package/dist/cjs/editor/TiptapEditor.native.js +153 -33
  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/codeBlockPreview.cjs +230 -0
  26. package/dist/cjs/editor/codeBlockPreview.native.js +265 -0
  27. package/dist/cjs/editor/codeBlockPreview.native.js.map +1 -0
  28. package/dist/cjs/editor/editorStyles.cjs +203 -34
  29. package/dist/cjs/editor/editorStyles.native.js +203 -34
  30. package/dist/cjs/editor/editorStyles.native.js.map +1 -1
  31. package/dist/cjs/editor/emoji.cjs +128 -0
  32. package/dist/cjs/editor/emoji.native.js +184 -0
  33. package/dist/cjs/editor/emoji.native.js.map +1 -0
  34. package/dist/cjs/editor/lazyKatex.cjs +78 -0
  35. package/dist/cjs/editor/lazyKatex.native.js +117 -0
  36. package/dist/cjs/editor/lazyKatex.native.js.map +1 -0
  37. package/dist/cjs/editor/markdown.cjs +216 -0
  38. package/dist/cjs/editor/markdown.native.js +278 -0
  39. package/dist/cjs/editor/markdown.native.js.map +1 -0
  40. package/dist/cjs/editor/mathematics.cjs +168 -0
  41. package/dist/cjs/editor/mathematics.native.js +202 -0
  42. package/dist/cjs/editor/mathematics.native.js.map +1 -0
  43. package/dist/cjs/editor/media.cjs +138 -0
  44. package/dist/cjs/editor/media.native.js +172 -0
  45. package/dist/cjs/editor/media.native.js.map +1 -0
  46. package/dist/cjs/editor/mentions.cjs +73 -0
  47. package/dist/cjs/editor/mentions.native.js +84 -0
  48. package/dist/cjs/editor/mentions.native.js.map +1 -0
  49. package/dist/cjs/editor/pasteCleanup.cjs +83 -0
  50. package/dist/cjs/editor/pasteCleanup.native.js +175 -0
  51. package/dist/cjs/editor/pasteCleanup.native.js.map +1 -0
  52. package/dist/cjs/editor/suggestionPopup.cjs +297 -0
  53. package/dist/cjs/editor/suggestionPopup.native.js +327 -0
  54. package/dist/cjs/editor/suggestionPopup.native.js.map +1 -0
  55. package/dist/cjs/preview.cjs +263 -0
  56. package/dist/cjs/preview.native.js +294 -0
  57. package/dist/cjs/preview.native.js.map +1 -0
  58. package/dist/cjs/shared/t.cjs +53 -0
  59. package/dist/cjs/shared/t.native.js +56 -0
  60. package/dist/cjs/shared/t.native.js.map +1 -0
  61. package/dist/cjs/shared/url.cjs +35 -0
  62. package/dist/cjs/shared/url.native.js +38 -0
  63. package/dist/cjs/shared/url.native.js.map +1 -0
  64. package/dist/cjs/styled.cjs +13 -6
  65. package/dist/cjs/styled.native.js +13 -6
  66. package/dist/cjs/styled.native.js.map +1 -1
  67. package/dist/cjs/toolbar/BubbleToolbar.cjs +10 -8
  68. package/dist/cjs/toolbar/BubbleToolbar.native.js +10 -8
  69. package/dist/cjs/toolbar/BubbleToolbar.native.js.map +1 -1
  70. package/dist/cjs/toolbar/CodeBlockBubble.cjs +59 -23
  71. package/dist/cjs/toolbar/CodeBlockBubble.native.js +71 -25
  72. package/dist/cjs/toolbar/CodeBlockBubble.native.js.map +1 -1
  73. package/dist/cjs/toolbar/ColorPicker.cjs +19 -54
  74. package/dist/cjs/toolbar/ColorPicker.native.js +81 -179
  75. package/dist/cjs/toolbar/ColorPicker.native.js.map +1 -1
  76. package/dist/cjs/toolbar/FixedToolbar.cjs +33 -10
  77. package/dist/cjs/toolbar/FixedToolbar.native.js +46 -54
  78. package/dist/cjs/toolbar/FixedToolbar.native.js.map +1 -1
  79. package/dist/cjs/toolbar/HeadingPicker.cjs +32 -39
  80. package/dist/cjs/toolbar/HeadingPicker.native.js +61 -51
  81. package/dist/cjs/toolbar/HeadingPicker.native.js.map +1 -1
  82. package/dist/cjs/toolbar/ImageBubble.cjs +20 -43
  83. package/dist/cjs/toolbar/ImageBubble.native.js +20 -43
  84. package/dist/cjs/toolbar/ImageBubble.native.js.map +1 -1
  85. package/dist/cjs/toolbar/ImageDialog.cjs +5 -4
  86. package/dist/cjs/toolbar/ImageDialog.native.js +76 -65
  87. package/dist/cjs/toolbar/ImageDialog.native.js.map +1 -1
  88. package/dist/cjs/toolbar/LinkBubble.cjs +23 -70
  89. package/dist/cjs/toolbar/LinkBubble.native.js +23 -70
  90. package/dist/cjs/toolbar/LinkBubble.native.js.map +1 -1
  91. package/dist/cjs/toolbar/LinkDialog.cjs +19 -18
  92. package/dist/cjs/toolbar/LinkDialog.native.js +86 -83
  93. package/dist/cjs/toolbar/LinkDialog.native.js.map +1 -1
  94. package/dist/cjs/toolbar/ListPicker.cjs +32 -43
  95. package/dist/cjs/toolbar/ListPicker.native.js +43 -44
  96. package/dist/cjs/toolbar/ListPicker.native.js.map +1 -1
  97. package/dist/cjs/toolbar/MathBubble.cjs +159 -0
  98. package/dist/cjs/toolbar/MathBubble.native.js +169 -0
  99. package/dist/cjs/toolbar/MathBubble.native.js.map +1 -0
  100. package/dist/cjs/toolbar/MoreDropdown.cjs +51 -98
  101. package/dist/cjs/toolbar/MoreDropdown.native.js +73 -98
  102. package/dist/cjs/toolbar/MoreDropdown.native.js.map +1 -1
  103. package/dist/cjs/toolbar/StatusBar.cjs +19 -10
  104. package/dist/cjs/toolbar/StatusBar.native.js +19 -10
  105. package/dist/cjs/toolbar/StatusBar.native.js.map +1 -1
  106. package/dist/cjs/toolbar/TableBubble.cjs +77 -95
  107. package/dist/cjs/toolbar/TableBubble.native.js +73 -71
  108. package/dist/cjs/toolbar/TableBubble.native.js.map +1 -1
  109. package/dist/cjs/toolbar/ToolbarButton.cjs +86 -21
  110. package/dist/cjs/toolbar/ToolbarButton.native.js +14 -4
  111. package/dist/cjs/toolbar/ToolbarButton.native.js.map +1 -1
  112. package/dist/cjs/toolbar/icons.cjs +111 -468
  113. package/dist/cjs/toolbar/shortcuts.cjs +73 -24
  114. package/dist/cjs/toolbar/shortcuts.native.js +73 -24
  115. package/dist/cjs/toolbar/shortcuts.native.js.map +1 -1
  116. package/dist/cjs/toolbar/useHorizontalScroll.cjs +25 -5
  117. package/dist/cjs/toolbar/useHorizontalScroll.native.js +25 -5
  118. package/dist/cjs/toolbar/useHorizontalScroll.native.js.map +1 -1
  119. package/dist/cjs/toolbar/useRovingFocus.cjs +80 -0
  120. package/dist/cjs/toolbar/useRovingFocus.native.js +113 -0
  121. package/dist/cjs/toolbar/useRovingFocus.native.js.map +1 -0
  122. package/dist/cjs/types.native.js.map +1 -1
  123. package/dist/esm/RichEditor.mjs +85 -10
  124. package/dist/esm/RichEditor.mjs.map +1 -1
  125. package/dist/esm/RichEditor.native.js +425 -38
  126. package/dist/esm/RichEditor.native.js.map +1 -1
  127. package/dist/esm/RichTextEditor/index.mjs +18 -2
  128. package/dist/esm/RichTextEditor/index.mjs.map +1 -1
  129. package/dist/esm/RichTextEditor/index.native.js +18 -2
  130. package/dist/esm/RichTextEditor/index.native.js.map +1 -1
  131. package/dist/esm/constants.mjs +47 -29
  132. package/dist/esm/constants.mjs.map +1 -1
  133. package/dist/esm/constants.native.js +54 -29
  134. package/dist/esm/constants.native.js.map +1 -1
  135. package/dist/esm/editor/BlockDragHandle.mjs +22 -7
  136. package/dist/esm/editor/BlockDragHandle.mjs.map +1 -1
  137. package/dist/esm/editor/BlockDragHandle.native.js +41 -7
  138. package/dist/esm/editor/BlockDragHandle.native.js.map +1 -1
  139. package/dist/esm/editor/SlashCommands.mjs +250 -294
  140. package/dist/esm/editor/SlashCommands.mjs.map +1 -1
  141. package/dist/esm/editor/SlashCommands.native.js +307 -341
  142. package/dist/esm/editor/SlashCommands.native.js.map +1 -1
  143. package/dist/esm/editor/TentapEditor.native.js +45 -13
  144. package/dist/esm/editor/TentapEditor.native.js.map +1 -1
  145. package/dist/esm/editor/TiptapEditor.mjs +142 -35
  146. package/dist/esm/editor/TiptapEditor.mjs.map +1 -1
  147. package/dist/esm/editor/TiptapEditor.native.js +155 -35
  148. package/dist/esm/editor/TiptapEditor.native.js.map +1 -1
  149. package/dist/esm/editor/blockAnchor.mjs +18 -0
  150. package/dist/esm/editor/blockAnchor.mjs.map +1 -0
  151. package/dist/esm/editor/blockAnchor.native.js +40 -0
  152. package/dist/esm/editor/blockAnchor.native.js.map +1 -0
  153. package/dist/esm/editor/codeBlockPreview.mjs +190 -0
  154. package/dist/esm/editor/codeBlockPreview.mjs.map +1 -0
  155. package/dist/esm/editor/codeBlockPreview.native.js +222 -0
  156. package/dist/esm/editor/codeBlockPreview.native.js.map +1 -0
  157. package/dist/esm/editor/editorStyles.mjs +203 -34
  158. package/dist/esm/editor/editorStyles.mjs.map +1 -1
  159. package/dist/esm/editor/editorStyles.native.js +203 -34
  160. package/dist/esm/editor/editorStyles.native.js.map +1 -1
  161. package/dist/esm/editor/emoji.mjs +88 -0
  162. package/dist/esm/editor/emoji.mjs.map +1 -0
  163. package/dist/esm/editor/emoji.native.js +141 -0
  164. package/dist/esm/editor/emoji.native.js.map +1 -0
  165. package/dist/esm/editor/lazyKatex.mjs +40 -0
  166. package/dist/esm/editor/lazyKatex.mjs.map +1 -0
  167. package/dist/esm/editor/lazyKatex.native.js +76 -0
  168. package/dist/esm/editor/lazyKatex.native.js.map +1 -0
  169. package/dist/esm/editor/markdown.mjs +179 -0
  170. package/dist/esm/editor/markdown.mjs.map +1 -0
  171. package/dist/esm/editor/markdown.native.js +238 -0
  172. package/dist/esm/editor/markdown.native.js.map +1 -0
  173. package/dist/esm/editor/mathematics.mjs +142 -0
  174. package/dist/esm/editor/mathematics.mjs.map +1 -0
  175. package/dist/esm/editor/mathematics.native.js +173 -0
  176. package/dist/esm/editor/mathematics.native.js.map +1 -0
  177. package/dist/esm/editor/media.mjs +113 -0
  178. package/dist/esm/editor/media.mjs.map +1 -0
  179. package/dist/esm/editor/media.native.js +144 -0
  180. package/dist/esm/editor/media.native.js.map +1 -0
  181. package/dist/esm/editor/mentions.mjs +37 -0
  182. package/dist/esm/editor/mentions.mjs.map +1 -0
  183. package/dist/esm/editor/mentions.native.js +45 -0
  184. package/dist/esm/editor/mentions.native.js.map +1 -0
  185. package/dist/esm/editor/pasteCleanup.mjs +57 -0
  186. package/dist/esm/editor/pasteCleanup.mjs.map +1 -0
  187. package/dist/esm/editor/pasteCleanup.native.js +146 -0
  188. package/dist/esm/editor/pasteCleanup.native.js.map +1 -0
  189. package/dist/esm/editor/suggestionPopup.mjs +268 -0
  190. package/dist/esm/editor/suggestionPopup.mjs.map +1 -0
  191. package/dist/esm/editor/suggestionPopup.native.js +295 -0
  192. package/dist/esm/editor/suggestionPopup.native.js.map +1 -0
  193. package/dist/esm/preview.mjs +236 -0
  194. package/dist/esm/preview.mjs.map +1 -0
  195. package/dist/esm/preview.native.js +264 -0
  196. package/dist/esm/preview.native.js.map +1 -0
  197. package/dist/esm/shared/t.mjs +17 -0
  198. package/dist/esm/shared/t.mjs.map +1 -0
  199. package/dist/esm/shared/t.native.js +17 -0
  200. package/dist/esm/shared/t.native.js.map +1 -0
  201. package/dist/esm/shared/url.mjs +10 -0
  202. package/dist/esm/shared/url.mjs.map +1 -0
  203. package/dist/esm/shared/url.native.js +10 -0
  204. package/dist/esm/shared/url.native.js.map +1 -0
  205. package/dist/esm/styled.mjs +13 -6
  206. package/dist/esm/styled.mjs.map +1 -1
  207. package/dist/esm/styled.native.js +13 -6
  208. package/dist/esm/styled.native.js.map +1 -1
  209. package/dist/esm/toolbar/BubbleToolbar.mjs +11 -9
  210. package/dist/esm/toolbar/BubbleToolbar.mjs.map +1 -1
  211. package/dist/esm/toolbar/BubbleToolbar.native.js +11 -9
  212. package/dist/esm/toolbar/BubbleToolbar.native.js.map +1 -1
  213. package/dist/esm/toolbar/CodeBlockBubble.mjs +60 -24
  214. package/dist/esm/toolbar/CodeBlockBubble.mjs.map +1 -1
  215. package/dist/esm/toolbar/CodeBlockBubble.native.js +72 -26
  216. package/dist/esm/toolbar/CodeBlockBubble.native.js.map +1 -1
  217. package/dist/esm/toolbar/ColorPicker.mjs +21 -56
  218. package/dist/esm/toolbar/ColorPicker.mjs.map +1 -1
  219. package/dist/esm/toolbar/ColorPicker.native.js +82 -180
  220. package/dist/esm/toolbar/ColorPicker.native.js.map +1 -1
  221. package/dist/esm/toolbar/FixedToolbar.mjs +34 -11
  222. package/dist/esm/toolbar/FixedToolbar.mjs.map +1 -1
  223. package/dist/esm/toolbar/FixedToolbar.native.js +47 -55
  224. package/dist/esm/toolbar/FixedToolbar.native.js.map +1 -1
  225. package/dist/esm/toolbar/HeadingPicker.mjs +34 -41
  226. package/dist/esm/toolbar/HeadingPicker.mjs.map +1 -1
  227. package/dist/esm/toolbar/HeadingPicker.native.js +63 -53
  228. package/dist/esm/toolbar/HeadingPicker.native.js.map +1 -1
  229. package/dist/esm/toolbar/ImageBubble.mjs +20 -43
  230. package/dist/esm/toolbar/ImageBubble.mjs.map +1 -1
  231. package/dist/esm/toolbar/ImageBubble.native.js +20 -43
  232. package/dist/esm/toolbar/ImageBubble.native.js.map +1 -1
  233. package/dist/esm/toolbar/ImageDialog.mjs +5 -4
  234. package/dist/esm/toolbar/ImageDialog.mjs.map +1 -1
  235. package/dist/esm/toolbar/ImageDialog.native.js +75 -64
  236. package/dist/esm/toolbar/ImageDialog.native.js.map +1 -1
  237. package/dist/esm/toolbar/LinkBubble.mjs +23 -70
  238. package/dist/esm/toolbar/LinkBubble.mjs.map +1 -1
  239. package/dist/esm/toolbar/LinkBubble.native.js +23 -70
  240. package/dist/esm/toolbar/LinkBubble.native.js.map +1 -1
  241. package/dist/esm/toolbar/LinkDialog.mjs +17 -16
  242. package/dist/esm/toolbar/LinkDialog.mjs.map +1 -1
  243. package/dist/esm/toolbar/LinkDialog.native.js +84 -80
  244. package/dist/esm/toolbar/LinkDialog.native.js.map +1 -1
  245. package/dist/esm/toolbar/ListPicker.mjs +33 -44
  246. package/dist/esm/toolbar/ListPicker.mjs.map +1 -1
  247. package/dist/esm/toolbar/ListPicker.native.js +44 -45
  248. package/dist/esm/toolbar/ListPicker.native.js.map +1 -1
  249. package/dist/esm/toolbar/MathBubble.mjs +134 -0
  250. package/dist/esm/toolbar/MathBubble.mjs.map +1 -0
  251. package/dist/esm/toolbar/MathBubble.native.js +141 -0
  252. package/dist/esm/toolbar/MathBubble.native.js.map +1 -0
  253. package/dist/esm/toolbar/MoreDropdown.mjs +50 -97
  254. package/dist/esm/toolbar/MoreDropdown.mjs.map +1 -1
  255. package/dist/esm/toolbar/MoreDropdown.native.js +72 -97
  256. package/dist/esm/toolbar/MoreDropdown.native.js.map +1 -1
  257. package/dist/esm/toolbar/StatusBar.mjs +19 -10
  258. package/dist/esm/toolbar/StatusBar.mjs.map +1 -1
  259. package/dist/esm/toolbar/StatusBar.native.js +19 -10
  260. package/dist/esm/toolbar/StatusBar.native.js.map +1 -1
  261. package/dist/esm/toolbar/TableBubble.mjs +77 -95
  262. package/dist/esm/toolbar/TableBubble.mjs.map +1 -1
  263. package/dist/esm/toolbar/TableBubble.native.js +73 -71
  264. package/dist/esm/toolbar/TableBubble.native.js.map +1 -1
  265. package/dist/esm/toolbar/ToolbarButton.mjs +87 -22
  266. package/dist/esm/toolbar/ToolbarButton.mjs.map +1 -1
  267. package/dist/esm/toolbar/ToolbarButton.native.js +14 -4
  268. package/dist/esm/toolbar/ToolbarButton.native.js.map +1 -1
  269. package/dist/esm/toolbar/icons.mjs +109 -469
  270. package/dist/esm/toolbar/icons.mjs.map +1 -1
  271. package/dist/esm/toolbar/shortcuts.mjs +73 -24
  272. package/dist/esm/toolbar/shortcuts.mjs.map +1 -1
  273. package/dist/esm/toolbar/shortcuts.native.js +73 -24
  274. package/dist/esm/toolbar/shortcuts.native.js.map +1 -1
  275. package/dist/esm/toolbar/useHorizontalScroll.mjs +25 -6
  276. package/dist/esm/toolbar/useHorizontalScroll.mjs.map +1 -1
  277. package/dist/esm/toolbar/useHorizontalScroll.native.js +25 -6
  278. package/dist/esm/toolbar/useHorizontalScroll.native.js.map +1 -1
  279. package/dist/esm/toolbar/useRovingFocus.mjs +55 -0
  280. package/dist/esm/toolbar/useRovingFocus.mjs.map +1 -0
  281. package/dist/esm/toolbar/useRovingFocus.native.js +85 -0
  282. package/dist/esm/toolbar/useRovingFocus.native.js.map +1 -0
  283. package/dist/esm/types.mjs.map +1 -1
  284. package/dist/esm/types.native.js.map +1 -1
  285. package/dist/jsx/RichEditor.mjs +85 -10
  286. package/dist/jsx/RichEditor.mjs.map +1 -1
  287. package/dist/jsx/RichEditor.native.js +422 -35
  288. package/dist/jsx/RichEditor.native.js.map +1 -1
  289. package/dist/jsx/RichTextEditor/index.mjs +18 -2
  290. package/dist/jsx/RichTextEditor/index.mjs.map +1 -1
  291. package/dist/jsx/RichTextEditor/index.native.js +18 -2
  292. package/dist/jsx/RichTextEditor/index.native.js.map +1 -1
  293. package/dist/jsx/constants.mjs +47 -29
  294. package/dist/jsx/constants.mjs.map +1 -1
  295. package/dist/jsx/constants.native.js +59 -29
  296. package/dist/jsx/constants.native.js.map +1 -1
  297. package/dist/jsx/editor/BlockDragHandle.mjs +22 -7
  298. package/dist/jsx/editor/BlockDragHandle.mjs.map +1 -1
  299. package/dist/jsx/editor/BlockDragHandle.native.js +41 -7
  300. package/dist/jsx/editor/BlockDragHandle.native.js.map +1 -1
  301. package/dist/jsx/editor/SlashCommands.mjs +250 -294
  302. package/dist/jsx/editor/SlashCommands.mjs.map +1 -1
  303. package/dist/jsx/editor/SlashCommands.native.js +306 -340
  304. package/dist/jsx/editor/SlashCommands.native.js.map +1 -1
  305. package/dist/jsx/editor/TentapEditor.native.js +44 -12
  306. package/dist/jsx/editor/TentapEditor.native.js.map +1 -1
  307. package/dist/jsx/editor/TiptapEditor.mjs +142 -35
  308. package/dist/jsx/editor/TiptapEditor.mjs.map +1 -1
  309. package/dist/jsx/editor/TiptapEditor.native.js +153 -33
  310. package/dist/jsx/editor/TiptapEditor.native.js.map +1 -1
  311. package/dist/jsx/editor/blockAnchor.mjs +18 -0
  312. package/dist/jsx/editor/blockAnchor.mjs.map +1 -0
  313. package/dist/jsx/editor/blockAnchor.native.js +68 -0
  314. package/dist/jsx/editor/blockAnchor.native.js.map +1 -0
  315. package/dist/jsx/editor/codeBlockPreview.mjs +190 -0
  316. package/dist/jsx/editor/codeBlockPreview.mjs.map +1 -0
  317. package/dist/jsx/editor/codeBlockPreview.native.js +265 -0
  318. package/dist/jsx/editor/codeBlockPreview.native.js.map +1 -0
  319. package/dist/jsx/editor/editorStyles.mjs +203 -34
  320. package/dist/jsx/editor/editorStyles.mjs.map +1 -1
  321. package/dist/jsx/editor/editorStyles.native.js +203 -34
  322. package/dist/jsx/editor/editorStyles.native.js.map +1 -1
  323. package/dist/jsx/editor/emoji.mjs +88 -0
  324. package/dist/jsx/editor/emoji.mjs.map +1 -0
  325. package/dist/jsx/editor/emoji.native.js +184 -0
  326. package/dist/jsx/editor/emoji.native.js.map +1 -0
  327. package/dist/jsx/editor/lazyKatex.mjs +40 -0
  328. package/dist/jsx/editor/lazyKatex.mjs.map +1 -0
  329. package/dist/jsx/editor/lazyKatex.native.js +117 -0
  330. package/dist/jsx/editor/lazyKatex.native.js.map +1 -0
  331. package/dist/jsx/editor/markdown.mjs +179 -0
  332. package/dist/jsx/editor/markdown.mjs.map +1 -0
  333. package/dist/jsx/editor/markdown.native.js +278 -0
  334. package/dist/jsx/editor/markdown.native.js.map +1 -0
  335. package/dist/jsx/editor/mathematics.mjs +142 -0
  336. package/dist/jsx/editor/mathematics.mjs.map +1 -0
  337. package/dist/jsx/editor/mathematics.native.js +202 -0
  338. package/dist/jsx/editor/mathematics.native.js.map +1 -0
  339. package/dist/jsx/editor/media.mjs +113 -0
  340. package/dist/jsx/editor/media.mjs.map +1 -0
  341. package/dist/jsx/editor/media.native.js +172 -0
  342. package/dist/jsx/editor/media.native.js.map +1 -0
  343. package/dist/jsx/editor/mentions.mjs +37 -0
  344. package/dist/jsx/editor/mentions.mjs.map +1 -0
  345. package/dist/jsx/editor/mentions.native.js +84 -0
  346. package/dist/jsx/editor/mentions.native.js.map +1 -0
  347. package/dist/jsx/editor/pasteCleanup.mjs +57 -0
  348. package/dist/jsx/editor/pasteCleanup.mjs.map +1 -0
  349. package/dist/jsx/editor/pasteCleanup.native.js +175 -0
  350. package/dist/jsx/editor/pasteCleanup.native.js.map +1 -0
  351. package/dist/jsx/editor/suggestionPopup.mjs +268 -0
  352. package/dist/jsx/editor/suggestionPopup.mjs.map +1 -0
  353. package/dist/jsx/editor/suggestionPopup.native.js +327 -0
  354. package/dist/jsx/editor/suggestionPopup.native.js.map +1 -0
  355. package/dist/jsx/preview.mjs +236 -0
  356. package/dist/jsx/preview.mjs.map +1 -0
  357. package/dist/jsx/preview.native.js +294 -0
  358. package/dist/jsx/preview.native.js.map +1 -0
  359. package/dist/jsx/shared/t.mjs +17 -0
  360. package/dist/jsx/shared/t.mjs.map +1 -0
  361. package/dist/jsx/shared/t.native.js +56 -0
  362. package/dist/jsx/shared/t.native.js.map +1 -0
  363. package/dist/jsx/shared/url.mjs +10 -0
  364. package/dist/jsx/shared/url.mjs.map +1 -0
  365. package/dist/jsx/shared/url.native.js +38 -0
  366. package/dist/jsx/shared/url.native.js.map +1 -0
  367. package/dist/jsx/styled.mjs +13 -6
  368. package/dist/jsx/styled.mjs.map +1 -1
  369. package/dist/jsx/styled.native.js +13 -6
  370. package/dist/jsx/styled.native.js.map +1 -1
  371. package/dist/jsx/toolbar/BubbleToolbar.mjs +11 -9
  372. package/dist/jsx/toolbar/BubbleToolbar.mjs.map +1 -1
  373. package/dist/jsx/toolbar/BubbleToolbar.native.js +10 -8
  374. package/dist/jsx/toolbar/BubbleToolbar.native.js.map +1 -1
  375. package/dist/jsx/toolbar/CodeBlockBubble.mjs +60 -24
  376. package/dist/jsx/toolbar/CodeBlockBubble.mjs.map +1 -1
  377. package/dist/jsx/toolbar/CodeBlockBubble.native.js +71 -25
  378. package/dist/jsx/toolbar/CodeBlockBubble.native.js.map +1 -1
  379. package/dist/jsx/toolbar/ColorPicker.mjs +21 -56
  380. package/dist/jsx/toolbar/ColorPicker.mjs.map +1 -1
  381. package/dist/jsx/toolbar/ColorPicker.native.js +81 -179
  382. package/dist/jsx/toolbar/ColorPicker.native.js.map +1 -1
  383. package/dist/jsx/toolbar/FixedToolbar.mjs +34 -11
  384. package/dist/jsx/toolbar/FixedToolbar.mjs.map +1 -1
  385. package/dist/jsx/toolbar/FixedToolbar.native.js +46 -54
  386. package/dist/jsx/toolbar/FixedToolbar.native.js.map +1 -1
  387. package/dist/jsx/toolbar/HeadingPicker.mjs +34 -41
  388. package/dist/jsx/toolbar/HeadingPicker.mjs.map +1 -1
  389. package/dist/jsx/toolbar/HeadingPicker.native.js +61 -51
  390. package/dist/jsx/toolbar/HeadingPicker.native.js.map +1 -1
  391. package/dist/jsx/toolbar/ImageBubble.mjs +20 -43
  392. package/dist/jsx/toolbar/ImageBubble.mjs.map +1 -1
  393. package/dist/jsx/toolbar/ImageBubble.native.js +20 -43
  394. package/dist/jsx/toolbar/ImageBubble.native.js.map +1 -1
  395. package/dist/jsx/toolbar/ImageDialog.mjs +5 -4
  396. package/dist/jsx/toolbar/ImageDialog.mjs.map +1 -1
  397. package/dist/jsx/toolbar/ImageDialog.native.js +76 -65
  398. package/dist/jsx/toolbar/ImageDialog.native.js.map +1 -1
  399. package/dist/jsx/toolbar/LinkBubble.mjs +23 -70
  400. package/dist/jsx/toolbar/LinkBubble.mjs.map +1 -1
  401. package/dist/jsx/toolbar/LinkBubble.native.js +23 -70
  402. package/dist/jsx/toolbar/LinkBubble.native.js.map +1 -1
  403. package/dist/jsx/toolbar/LinkDialog.mjs +17 -16
  404. package/dist/jsx/toolbar/LinkDialog.mjs.map +1 -1
  405. package/dist/jsx/toolbar/LinkDialog.native.js +86 -83
  406. package/dist/jsx/toolbar/LinkDialog.native.js.map +1 -1
  407. package/dist/jsx/toolbar/ListPicker.mjs +33 -44
  408. package/dist/jsx/toolbar/ListPicker.mjs.map +1 -1
  409. package/dist/jsx/toolbar/ListPicker.native.js +43 -44
  410. package/dist/jsx/toolbar/ListPicker.native.js.map +1 -1
  411. package/dist/jsx/toolbar/MathBubble.mjs +134 -0
  412. package/dist/jsx/toolbar/MathBubble.mjs.map +1 -0
  413. package/dist/jsx/toolbar/MathBubble.native.js +169 -0
  414. package/dist/jsx/toolbar/MathBubble.native.js.map +1 -0
  415. package/dist/jsx/toolbar/MoreDropdown.mjs +50 -97
  416. package/dist/jsx/toolbar/MoreDropdown.mjs.map +1 -1
  417. package/dist/jsx/toolbar/MoreDropdown.native.js +73 -98
  418. package/dist/jsx/toolbar/MoreDropdown.native.js.map +1 -1
  419. package/dist/jsx/toolbar/StatusBar.mjs +19 -10
  420. package/dist/jsx/toolbar/StatusBar.mjs.map +1 -1
  421. package/dist/jsx/toolbar/StatusBar.native.js +19 -10
  422. package/dist/jsx/toolbar/StatusBar.native.js.map +1 -1
  423. package/dist/jsx/toolbar/TableBubble.mjs +77 -95
  424. package/dist/jsx/toolbar/TableBubble.mjs.map +1 -1
  425. package/dist/jsx/toolbar/TableBubble.native.js +73 -71
  426. package/dist/jsx/toolbar/TableBubble.native.js.map +1 -1
  427. package/dist/jsx/toolbar/ToolbarButton.mjs +87 -22
  428. package/dist/jsx/toolbar/ToolbarButton.mjs.map +1 -1
  429. package/dist/jsx/toolbar/ToolbarButton.native.js +14 -4
  430. package/dist/jsx/toolbar/ToolbarButton.native.js.map +1 -1
  431. package/dist/jsx/toolbar/icons.mjs +109 -469
  432. package/dist/jsx/toolbar/icons.mjs.map +1 -1
  433. package/dist/jsx/toolbar/shortcuts.mjs +73 -24
  434. package/dist/jsx/toolbar/shortcuts.mjs.map +1 -1
  435. package/dist/jsx/toolbar/shortcuts.native.js +73 -24
  436. package/dist/jsx/toolbar/shortcuts.native.js.map +1 -1
  437. package/dist/jsx/toolbar/useHorizontalScroll.mjs +25 -6
  438. package/dist/jsx/toolbar/useHorizontalScroll.mjs.map +1 -1
  439. package/dist/jsx/toolbar/useHorizontalScroll.native.js +25 -5
  440. package/dist/jsx/toolbar/useHorizontalScroll.native.js.map +1 -1
  441. package/dist/jsx/toolbar/useRovingFocus.mjs +55 -0
  442. package/dist/jsx/toolbar/useRovingFocus.mjs.map +1 -0
  443. package/dist/jsx/toolbar/useRovingFocus.native.js +113 -0
  444. package/dist/jsx/toolbar/useRovingFocus.native.js.map +1 -0
  445. package/dist/jsx/types.mjs.map +1 -1
  446. package/dist/jsx/types.native.js.map +1 -1
  447. package/package.json +28 -13
  448. package/src/RichEditor.native.tsx +451 -49
  449. package/src/RichEditor.stories.tsx +158 -0
  450. package/src/RichEditor.tsx +121 -7
  451. package/src/RichTextEditor/index.tsx +41 -3
  452. package/src/RichTextEditor/richTextEditor.spec.tsx +11 -4
  453. package/src/constants.ts +86 -24
  454. package/src/editor/BlockDragHandle.ts +30 -5
  455. package/src/editor/SlashCommands.tsx +228 -293
  456. package/src/editor/TentapEditor.native.tsx +68 -17
  457. package/src/editor/TiptapEditor.tsx +187 -22
  458. package/src/editor/blockAnchor.spec.ts +70 -0
  459. package/src/editor/blockAnchor.ts +42 -0
  460. package/src/editor/codeBlockPreview.spec.ts +144 -0
  461. package/src/editor/codeBlockPreview.ts +266 -0
  462. package/src/editor/css.d.ts +2 -0
  463. package/src/editor/details.spec.ts +48 -0
  464. package/src/editor/editorStyles.spec.ts +25 -0
  465. package/src/editor/editorStyles.ts +218 -34
  466. package/src/editor/emoji.spec.ts +88 -0
  467. package/src/editor/emoji.ts +147 -0
  468. package/src/editor/emojilib.d.ts +16 -0
  469. package/src/editor/lazyKatex.spec.ts +38 -0
  470. package/src/editor/lazyKatex.ts +68 -0
  471. package/src/editor/markdown.spec.ts +196 -0
  472. package/src/editor/markdown.ts +249 -0
  473. package/src/editor/mathematics.spec.ts +97 -0
  474. package/src/editor/mathematics.ts +179 -0
  475. package/src/editor/media.spec.ts +121 -0
  476. package/src/editor/media.ts +133 -0
  477. package/src/editor/mentions.spec.ts +41 -0
  478. package/src/editor/mentions.ts +55 -0
  479. package/src/editor/pasteCleanup.spec.ts +84 -0
  480. package/src/editor/pasteCleanup.ts +124 -0
  481. package/src/editor/suggestionPopup.spec.tsx +105 -0
  482. package/src/editor/suggestionPopup.tsx +414 -0
  483. package/src/editor/tiptapEditor.spec.tsx +15 -8
  484. package/src/exports.spec.ts +4 -2
  485. package/src/index.ts +7 -1
  486. package/src/integration.spec.tsx +38 -9
  487. package/src/preview.spec.ts +130 -0
  488. package/src/preview.ts +287 -0
  489. package/src/richEditor.spec.tsx +10 -3
  490. package/src/shared/t.ts +25 -0
  491. package/src/shared/url.ts +16 -0
  492. package/src/styled.ts +13 -6
  493. package/src/toolbar/BubbleToolbar.tsx +11 -8
  494. package/src/toolbar/CodeBlockBubble.tsx +66 -28
  495. package/src/toolbar/ColorPicker.native.tsx +126 -0
  496. package/src/toolbar/ColorPicker.tsx +23 -67
  497. package/src/toolbar/FixedToolbar.native.tsx +51 -51
  498. package/src/toolbar/FixedToolbar.tsx +54 -10
  499. package/src/toolbar/HeadingPicker.tsx +46 -38
  500. package/src/toolbar/ImageBubble.tsx +26 -44
  501. package/src/toolbar/ImageDialog.native.tsx +97 -0
  502. package/src/toolbar/ImageDialog.tsx +5 -4
  503. package/src/toolbar/LinkBubble.tsx +27 -64
  504. package/src/toolbar/LinkDialog.native.tsx +117 -0
  505. package/src/toolbar/LinkDialog.tsx +28 -24
  506. package/src/toolbar/ListPicker.tsx +47 -43
  507. package/src/toolbar/MathBubble.tsx +140 -0
  508. package/src/toolbar/MoreDropdown.tsx +53 -60
  509. package/src/toolbar/StatusBar.tsx +13 -8
  510. package/src/toolbar/TableBubble.tsx +82 -94
  511. package/src/toolbar/ToolbarButton.native.tsx +14 -4
  512. package/src/toolbar/ToolbarButton.tsx +98 -19
  513. package/src/toolbar/bubbleToolbar.spec.tsx +2 -1
  514. package/src/toolbar/fixedToolbar.spec.tsx +4 -2
  515. package/src/toolbar/icons.tsx +113 -323
  516. package/src/toolbar/shortcuts.ts +77 -24
  517. package/src/toolbar/toolbarPrimitives.spec.tsx +29 -1
  518. package/src/toolbar/toolbarSubComponents.spec.tsx +4 -2
  519. package/src/toolbar/useHorizontalScroll.spec.ts +67 -0
  520. package/src/toolbar/useHorizontalScroll.tsx +39 -12
  521. package/src/toolbar/useRovingFocus.spec.tsx +100 -0
  522. package/src/toolbar/useRovingFocus.ts +82 -0
  523. package/src/types.spec.ts +40 -1
  524. package/src/types.ts +28 -0
  525. package/types/RichEditor.d.ts +51 -0
  526. package/types/RichEditor.d.ts.map +1 -0
  527. package/types/RichEditor.native.d.ts +59 -0
  528. package/types/RichEditor.native.d.ts.map +1 -0
  529. package/types/RichTextEditor/index.d.ts +71 -0
  530. package/types/RichTextEditor/index.d.ts.map +1 -0
  531. package/types/constants.d.ts +49 -0
  532. package/types/constants.d.ts.map +1 -0
  533. package/types/context.d.ts +10 -0
  534. package/types/context.d.ts.map +1 -0
  535. package/types/editor/BlockDragHandle.d.ts +8 -0
  536. package/types/editor/BlockDragHandle.d.ts.map +1 -0
  537. package/types/editor/MarkdownPaste.d.ts +8 -0
  538. package/types/editor/MarkdownPaste.d.ts.map +1 -0
  539. package/types/editor/SlashCommands.d.ts +24 -0
  540. package/types/editor/SlashCommands.d.ts.map +1 -0
  541. package/types/editor/TentapEditor.native.d.ts +21 -0
  542. package/types/editor/TentapEditor.native.d.ts.map +1 -0
  543. package/types/editor/TiptapEditor.d.ts +24 -0
  544. package/types/editor/TiptapEditor.d.ts.map +1 -0
  545. package/types/editor/blockAnchor.d.ts +25 -0
  546. package/types/editor/blockAnchor.d.ts.map +1 -0
  547. package/types/editor/codeBlockPreview.d.ts +51 -0
  548. package/types/editor/codeBlockPreview.d.ts.map +1 -0
  549. package/types/editor/editorStyles.d.ts +25 -0
  550. package/types/editor/editorStyles.d.ts.map +1 -0
  551. package/types/editor/emoji.d.ts +45 -0
  552. package/types/editor/emoji.d.ts.map +1 -0
  553. package/types/editor/index.d.ts +11 -0
  554. package/types/editor/index.d.ts.map +1 -0
  555. package/types/editor/lazyKatex.d.ts +33 -0
  556. package/types/editor/lazyKatex.d.ts.map +1 -0
  557. package/types/editor/markdown.d.ts +24 -0
  558. package/types/editor/markdown.d.ts.map +1 -0
  559. package/types/editor/mathematics.d.ts +44 -0
  560. package/types/editor/mathematics.d.ts.map +1 -0
  561. package/types/editor/media.d.ts +32 -0
  562. package/types/editor/media.d.ts.map +1 -0
  563. package/types/editor/mentions.d.ts +15 -0
  564. package/types/editor/mentions.d.ts.map +1 -0
  565. package/types/editor/pasteCleanup.d.ts +24 -0
  566. package/types/editor/pasteCleanup.d.ts.map +1 -0
  567. package/types/editor/suggestionPopup.d.ts +113 -0
  568. package/types/editor/suggestionPopup.d.ts.map +1 -0
  569. package/types/editor/types.d.ts +80 -0
  570. package/types/editor/types.d.ts.map +1 -0
  571. package/types/editor/useEditorState.d.ts +19 -0
  572. package/types/editor/useEditorState.d.ts.map +1 -0
  573. package/types/index.d.ts +11 -0
  574. package/types/index.d.ts.map +1 -0
  575. package/types/preview.d.ts +44 -0
  576. package/types/preview.d.ts.map +1 -0
  577. package/types/shared/t.d.ts +10 -0
  578. package/types/shared/t.d.ts.map +1 -0
  579. package/types/shared/url.d.ts +9 -0
  580. package/types/shared/url.d.ts.map +1 -0
  581. package/types/styled.d.ts +40 -0
  582. package/types/styled.d.ts.map +1 -0
  583. package/types/toolbar/BubbleToolbar.d.ts +23 -0
  584. package/types/toolbar/BubbleToolbar.d.ts.map +1 -0
  585. package/types/toolbar/CodeBlockBubble.d.ts +10 -0
  586. package/types/toolbar/CodeBlockBubble.d.ts.map +1 -0
  587. package/types/toolbar/ColorPicker.d.ts +15 -0
  588. package/types/toolbar/ColorPicker.d.ts.map +1 -0
  589. package/types/toolbar/ColorPicker.native.d.ts +20 -0
  590. package/types/toolbar/ColorPicker.native.d.ts.map +1 -0
  591. package/types/toolbar/FixedToolbar.d.ts +32 -0
  592. package/types/toolbar/FixedToolbar.d.ts.map +1 -0
  593. package/types/toolbar/FixedToolbar.native.d.ts +30 -0
  594. package/types/toolbar/FixedToolbar.native.d.ts.map +1 -0
  595. package/types/toolbar/HeadingPicker.d.ts +14 -0
  596. package/types/toolbar/HeadingPicker.d.ts.map +1 -0
  597. package/types/toolbar/ImageBubble.d.ts +10 -0
  598. package/types/toolbar/ImageBubble.d.ts.map +1 -0
  599. package/types/toolbar/ImageDialog.d.ts +12 -0
  600. package/types/toolbar/ImageDialog.d.ts.map +1 -0
  601. package/types/toolbar/ImageDialog.native.d.ts +15 -0
  602. package/types/toolbar/ImageDialog.native.d.ts.map +1 -0
  603. package/types/toolbar/LinkBubble.d.ts +10 -0
  604. package/types/toolbar/LinkBubble.d.ts.map +1 -0
  605. package/types/toolbar/LinkDialog.d.ts +20 -0
  606. package/types/toolbar/LinkDialog.d.ts.map +1 -0
  607. package/types/toolbar/LinkDialog.native.d.ts +18 -0
  608. package/types/toolbar/LinkDialog.native.d.ts.map +1 -0
  609. package/types/toolbar/ListPicker.d.ts +14 -0
  610. package/types/toolbar/ListPicker.d.ts.map +1 -0
  611. package/types/toolbar/MathBubble.d.ts +11 -0
  612. package/types/toolbar/MathBubble.d.ts.map +1 -0
  613. package/types/toolbar/MoreDropdown.d.ts +13 -0
  614. package/types/toolbar/MoreDropdown.d.ts.map +1 -0
  615. package/types/toolbar/ResizeHandle.d.ts +11 -0
  616. package/types/toolbar/ResizeHandle.d.ts.map +1 -0
  617. package/types/toolbar/StatusBar.d.ts +11 -0
  618. package/types/toolbar/StatusBar.d.ts.map +1 -0
  619. package/types/toolbar/TableBubble.d.ts +10 -0
  620. package/types/toolbar/TableBubble.d.ts.map +1 -0
  621. package/types/toolbar/ToolbarButton.d.ts +35 -0
  622. package/types/toolbar/ToolbarButton.d.ts.map +1 -0
  623. package/types/toolbar/ToolbarButton.native.d.ts +30 -0
  624. package/types/toolbar/ToolbarButton.native.d.ts.map +1 -0
  625. package/types/toolbar/ToolbarGroup.d.ts +14 -0
  626. package/types/toolbar/ToolbarGroup.d.ts.map +1 -0
  627. package/types/toolbar/icons.d.ts +52 -0
  628. package/types/toolbar/icons.d.ts.map +1 -0
  629. package/types/toolbar/icons.native.d.ts +41 -0
  630. package/types/toolbar/icons.native.d.ts.map +1 -0
  631. package/types/toolbar/shortcuts.d.ts +34 -0
  632. package/types/toolbar/shortcuts.d.ts.map +1 -0
  633. package/types/toolbar/useHorizontalScroll.d.ts +43 -0
  634. package/types/toolbar/useHorizontalScroll.d.ts.map +1 -0
  635. package/types/toolbar/useRovingFocus.d.ts +10 -0
  636. package/types/toolbar/useRovingFocus.d.ts.map +1 -0
  637. package/types/types.d.ts +125 -0
  638. package/types/types.d.ts.map +1 -0
  639. package/dist/cjs/RichEditor.stories.cjs +0 -327
  640. package/dist/cjs/RichEditor.stories.native.js +0 -342
  641. package/dist/cjs/RichEditor.stories.native.js.map +0 -1
  642. package/dist/esm/RichEditor.stories.mjs +0 -291
  643. package/dist/esm/RichEditor.stories.mjs.map +0 -1
  644. package/dist/esm/RichEditor.stories.native.js +0 -303
  645. package/dist/esm/RichEditor.stories.native.js.map +0 -1
  646. package/dist/jsx/RichEditor.stories.mjs +0 -291
  647. package/dist/jsx/RichEditor.stories.mjs.map +0 -1
  648. package/dist/jsx/RichEditor.stories.native.js +0 -342
  649. package/dist/jsx/RichEditor.stories.native.js.map +0 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Paste sanitizer for HTML clipboard payloads from Google Docs and
3
+ * Microsoft Word/Outlook.
4
+ *
5
+ * Both sources wrap content in junk that either breaks ProseMirror parsing
6
+ * or smuggles presentation into the document:
7
+ * - Google Docs wraps the entire fragment in
8
+ * `<b style="font-weight:normal" id="docs-internal-guid-...">` (which
9
+ * ProseMirror would read as bold) and inlines font/size styles on spans.
10
+ * - Word ships `<o:p>` tags, `Mso*` classes, `mso-*` style declarations,
11
+ * XML islands, and conditional comments.
12
+ *
13
+ * The cleanup keeps semantics (b/strong/i/em/u/lists/headings/links and
14
+ * color/background-color styles the editor actually supports) and drops
15
+ * the rest. Non-office HTML passes through untouched.
16
+ */
17
+
18
+ const OFFICE_SIGNATURES = [
19
+ "docs-internal-guid",
20
+ "urn:schemas-microsoft-com",
21
+ "MsoNormal",
22
+ "mso-",
23
+ "<o:p>",
24
+ "office:office",
25
+ ];
26
+
27
+ /** True when the clipboard HTML comes from Google Docs or Microsoft Office */
28
+ export function isOfficeHtml(html: string): boolean {
29
+ return OFFICE_SIGNATURES.some((sig) => html.includes(sig));
30
+ }
31
+
32
+ /** Style declarations the editor supports (everything else is junk) */
33
+ const KEPT_STYLES = new Set([
34
+ "color",
35
+ "background-color",
36
+ // Docs/Word mark bold/italic/underline/strike with span styles rather
37
+ // than semantic tags; ProseMirror parses these into real marks.
38
+ "font-weight",
39
+ "font-style",
40
+ "text-decoration",
41
+ "text-decoration-line",
42
+ ]);
43
+
44
+ function cleanElement(el: Element): void {
45
+ // Word XML-namespaced elements (<o:p>, <w:sdt>, ...) contribute nothing
46
+ if (el.tagName.includes(":")) {
47
+ el.remove();
48
+ return;
49
+ }
50
+
51
+ if (el.hasAttribute("class")) el.removeAttribute("class");
52
+ if (el.hasAttribute("lang")) el.removeAttribute("lang");
53
+ if (el.hasAttribute("id")) el.removeAttribute("id");
54
+
55
+ if (el.hasAttribute("style")) {
56
+ // Parse the attribute text directly (not CSSStyleDeclaration) so the
57
+ // result is identical across browsers and DOM test environments.
58
+ const declarations = (el.getAttribute("style") ?? "")
59
+ .split(";")
60
+ .map((decl) => decl.trim())
61
+ .filter((decl) => decl.includes(":"));
62
+ const kept: string[] = [];
63
+ for (const decl of declarations) {
64
+ const colon = decl.indexOf(":");
65
+ const prop = decl.slice(0, colon).trim().toLowerCase();
66
+ const value = decl.slice(colon + 1).trim();
67
+ if (!KEPT_STYLES.has(prop)) continue;
68
+ // Office emits default inks explicitly; dropping them keeps content
69
+ // on theme text color instead of hardcoded near-black
70
+ if (prop === "color" && /^(rgb\(0,\s*0,\s*0\)|#000000|#000|windowtext)$/i.test(value)) {
71
+ continue;
72
+ }
73
+ if (
74
+ prop === "background-color" &&
75
+ /^(transparent|#ffffff|#fff|rgb\(255,\s*255,\s*255\))$/i.test(value)
76
+ ) {
77
+ continue;
78
+ }
79
+ // Non-emphasis values are the office default state, not authored marks
80
+ if (prop === "font-weight" && !/^(bold(er)?|[5-9]\d\d)$/i.test(value)) continue;
81
+ if (prop === "font-style" && !/^(italic|oblique)/i.test(value)) continue;
82
+ if (
83
+ (prop === "text-decoration" || prop === "text-decoration-line") &&
84
+ !/(underline|line-through)/i.test(value)
85
+ ) {
86
+ continue;
87
+ }
88
+ kept.push(`${prop}: ${value}`);
89
+ }
90
+ if (kept.length > 0) el.setAttribute("style", kept.join("; "));
91
+ else el.removeAttribute("style");
92
+ }
93
+
94
+ for (const child of Array.from(el.children)) cleanElement(child);
95
+ }
96
+
97
+ /**
98
+ * Sanitize office-suite clipboard HTML. Non-office HTML is returned as-is
99
+ * (regular web copy already parses cleanly).
100
+ */
101
+ export function cleanPastedHtml(html: string): string {
102
+ if (typeof document === "undefined" || !isOfficeHtml(html)) return html;
103
+
104
+ // Strip XML islands and conditional comments before parsing
105
+ const source = html
106
+ .replace(/<xml>[\s\S]*?<\/xml>/gi, "")
107
+ .replace(/<!--\[if[\s\S]*?<!\[endif\]-->/gi, "")
108
+ .replace(/<!--StartFragment-->|<!--EndFragment-->/gi, "");
109
+
110
+ const doc = new DOMParser().parseFromString(source, "text/html");
111
+ doc.querySelectorAll("style, meta, link, script, title").forEach((el) => el.remove());
112
+
113
+ // Google Docs: unwrap the non-bold <b> guid wrapper so content is not bold
114
+ for (const b of Array.from(doc.body.querySelectorAll("b"))) {
115
+ const weight = (b as HTMLElement).style.fontWeight;
116
+ if (weight === "normal" || weight === "400") {
117
+ b.replaceWith(...Array.from(b.childNodes));
118
+ }
119
+ }
120
+
121
+ for (const child of Array.from(doc.body.children)) cleanElement(child);
122
+
123
+ return doc.body.innerHTML;
124
+ }
@@ -0,0 +1,105 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { act, createRef } from "react";
3
+ import { render } from "@testing-library/react";
4
+ import {
5
+ SuggestionList,
6
+ fallbackSuggestionChrome,
7
+ getSuggestionChrome,
8
+ type SuggestionListRef,
9
+ type SuggestionRow,
10
+ } from "./suggestionPopup";
11
+
12
+ const rows: SuggestionRow[] = [
13
+ { key: "a", title: "Alpha", description: "first" },
14
+ { key: "b", title: "Beta", description: "second" },
15
+ { key: "c", title: "Gamma", description: "third" },
16
+ ];
17
+
18
+ const chrome = { ...fallbackSuggestionChrome, rowPaddingX: 12 };
19
+
20
+ function renderList(onSelect = vi.fn()) {
21
+ const ref = createRef<SuggestionListRef>();
22
+ const utils = render(
23
+ <SuggestionList
24
+ ref={ref}
25
+ rows={rows}
26
+ chrome={chrome}
27
+ emptyLabel="No results"
28
+ onSelect={onSelect}
29
+ />,
30
+ );
31
+ return { ref, onSelect, ...utils };
32
+ }
33
+
34
+ describe("SuggestionList", () => {
35
+ it("renders one option per row with LC-16 menu-row geometry", () => {
36
+ const { container } = renderList();
37
+ const options = container.querySelectorAll('[role="option"]');
38
+ expect(options.length).toBe(3);
39
+ const style = (options[0] as HTMLElement).style;
40
+ // menuRowFrame-derived horizontal padding, flat corners, full width
41
+ expect(style.padding).toBe("8px 12px");
42
+ expect(style.borderRadius).toBe("0px");
43
+ expect(style.width).toBe("100%");
44
+ });
45
+
46
+ it("marks the first row selected and navigates with arrows (wrapping)", () => {
47
+ const { ref, container } = renderList();
48
+ const selected = () =>
49
+ Array.from(container.querySelectorAll('[role="option"]')).findIndex(
50
+ (el) => el.getAttribute("aria-selected") === "true",
51
+ );
52
+ expect(selected()).toBe(0);
53
+ act(() => {
54
+ ref.current!.onKeyDown({ event: new KeyboardEvent("keydown", { key: "ArrowDown" }) });
55
+ });
56
+ expect(selected()).toBe(1);
57
+ act(() => {
58
+ ref.current!.onKeyDown({ event: new KeyboardEvent("keydown", { key: "ArrowUp" }) });
59
+ ref.current!.onKeyDown({ event: new KeyboardEvent("keydown", { key: "ArrowUp" }) });
60
+ });
61
+ expect(selected()).toBe(2);
62
+ });
63
+
64
+ it("selects with Enter and Tab", () => {
65
+ const { ref, onSelect } = renderList();
66
+ act(() => {
67
+ ref.current!.onKeyDown({ event: new KeyboardEvent("keydown", { key: "ArrowDown" }) });
68
+ });
69
+ let handled = false;
70
+ act(() => {
71
+ handled = ref.current!.onKeyDown({
72
+ event: new KeyboardEvent("keydown", { key: "Enter" }),
73
+ });
74
+ });
75
+ expect(handled).toBe(true);
76
+ expect(onSelect).toHaveBeenCalledWith(1);
77
+ });
78
+
79
+ it("selects on click", () => {
80
+ const { container, onSelect } = renderList();
81
+ const options = container.querySelectorAll('[role="option"]');
82
+ (options[2] as HTMLElement).click();
83
+ expect(onSelect).toHaveBeenCalledWith(2);
84
+ });
85
+
86
+ it("shows the empty label when there are no rows", () => {
87
+ const { container } = render(
88
+ <SuggestionList rows={[]} chrome={chrome} emptyLabel="No results" onSelect={vi.fn()} />,
89
+ );
90
+ expect(container.textContent).toContain("No results");
91
+ expect(container.querySelectorAll('[role="option"]').length).toBe(0);
92
+ });
93
+ });
94
+
95
+ describe("getSuggestionChrome", () => {
96
+ it("reads the chrome pushed by the editor host", () => {
97
+ const editor = { storage: { suggestionChrome: { value: chrome } } };
98
+ expect(getSuggestionChrome(editor)).toBe(chrome);
99
+ });
100
+
101
+ it("falls back to the neutral chrome before the host pushes values", () => {
102
+ expect(getSuggestionChrome(null)).toBe(fallbackSuggestionChrome);
103
+ expect(getSuggestionChrome({ storage: {} })).toBe(fallbackSuggestionChrome);
104
+ });
105
+ });
@@ -0,0 +1,414 @@
1
+ /**
2
+ * Shared suggestion popup for editor typeahead menus (slash commands and
3
+ * @ mentions).
4
+ *
5
+ * One implementation (LC-16): both menus render the same row anatomy with
6
+ * the shared menu-row geometry (SP-EDGE -- the container owns only its
7
+ * border, rows own all padding and span edge-to-edge, matching
8
+ * SelectRow / DropdownMenuItemFrame / MentionSuggestionItem: 12px
9
+ * horizontal x 8px vertical padding, 8px in-row gap, flat corners).
10
+ *
11
+ * The popup is portaled to document.body (it must escape the editor frame
12
+ * and the fullscreen z-index), which puts it OUTSIDE the Tamagui theme
13
+ * scope -- so no Tamagui components and no raw CSS fallbacks. Every color
14
+ * and structural role comes from `SuggestionChrome`, resolved from the
15
+ * live theme + knobs by the editor and pushed through editor storage.
16
+ * Enter/exit motion (LC-24) fades through `motionMs`, which is 0 when the
17
+ * animation knob is "none".
18
+ */
19
+
20
+ import {
21
+ forwardRef,
22
+ useCallback,
23
+ useEffect,
24
+ useImperativeHandle,
25
+ useRef,
26
+ useState,
27
+ type CSSProperties,
28
+ type ReactNode,
29
+ } from "react";
30
+ import { Extension } from "@tiptap/core";
31
+ import { ReactRenderer } from "@tiptap/react";
32
+
33
+ // ===========================================================================
34
+ // Chrome (resolved theme + knob values, no raw fallbacks)
35
+ // ===========================================================================
36
+
37
+ export interface SuggestionChrome {
38
+ /** Panel surface color (theme background) */
39
+ background: string;
40
+ /** Panel border color */
41
+ borderColor: string;
42
+ /** Row highlight surface (active/hover) */
43
+ activeBackground: string;
44
+ /** Leading icon tile surface */
45
+ iconTileBackground: string;
46
+ /** Primary row text color */
47
+ titleColor: string;
48
+ /** Secondary row text color */
49
+ descriptionColor: string;
50
+ /** Panel corner radius in px */
51
+ radius: number;
52
+ /** Shared floating-panel shadow (Axiom 14/15 light source) */
53
+ shadow: string;
54
+ /** Enter/exit fade duration in ms (0 = animation none) */
55
+ motionMs: number;
56
+ /**
57
+ * Row horizontal padding in px, resolved from the shared LC-16
58
+ * `menuRowFrame` recipe (theme) by the editor host — the DOM popup never
59
+ * invents its own geometry.
60
+ */
61
+ rowPaddingX: number;
62
+ }
63
+
64
+ /**
65
+ * Chrome used only when the editor has not pushed resolved values yet
66
+ * (first paint edge — a popup cannot open before the host's push effect
67
+ * runs). Colors reference the tamagui `:root` default-theme custom
68
+ * properties rather than literal values, so even this edge stays sourced
69
+ * from the theme system (Axiom 5).
70
+ */
71
+ export const fallbackSuggestionChrome: SuggestionChrome = {
72
+ background: "var(--background)",
73
+ borderColor: "var(--borderColor)",
74
+ activeBackground: "var(--color4)",
75
+ iconTileBackground: "var(--color3)",
76
+ titleColor: "var(--color12)",
77
+ descriptionColor: "var(--color11)",
78
+ radius: 8,
79
+ shadow: "0px 8px 28px var(--shadow2), 0px 2px 6px var(--shadow1)",
80
+ motionMs: 120,
81
+ rowPaddingX: 12,
82
+ };
83
+
84
+ declare module "@tiptap/core" {
85
+ interface Storage {
86
+ suggestionChrome: { value: SuggestionChrome };
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Storage-only extension carrying the resolved suggestion chrome. The
92
+ * editor host (TiptapEditor) resolves theme + knob values in React land and
93
+ * pushes them here so the DOM-portaled popups never invent their own colors.
94
+ */
95
+ export const SuggestionChromeStore = Extension.create({
96
+ name: "suggestionChrome",
97
+ addStorage(): { value: SuggestionChrome } {
98
+ return { value: fallbackSuggestionChrome };
99
+ },
100
+ });
101
+
102
+ /** Reads the resolved chrome pushed by the editor host */
103
+ export function getSuggestionChrome(editor: any): SuggestionChrome {
104
+ return editor?.storage?.suggestionChrome?.value ?? fallbackSuggestionChrome;
105
+ }
106
+
107
+ // ===========================================================================
108
+ // Rows
109
+ // ===========================================================================
110
+
111
+ export interface SuggestionRow {
112
+ key: string;
113
+ title: string;
114
+ description?: string;
115
+ /** Leading glyph rendered inside the icon tile */
116
+ icon?: ReactNode;
117
+ /** Avatar image URL (mentions); takes the icon tile slot */
118
+ avatarUrl?: string;
119
+ }
120
+
121
+ export interface SuggestionListProps {
122
+ rows: SuggestionRow[];
123
+ chrome: SuggestionChrome;
124
+ emptyLabel: string;
125
+ onSelect: (index: number) => void;
126
+ }
127
+
128
+ export interface SuggestionListRef {
129
+ onKeyDown: (props: { event: KeyboardEvent }) => boolean;
130
+ }
131
+
132
+ export const SuggestionList = forwardRef<SuggestionListRef, SuggestionListProps>(
133
+ ({ rows, chrome, emptyLabel, onSelect }, ref) => {
134
+ const [selectedIndex, setSelectedIndex] = useState(0);
135
+ const listRef = useRef<HTMLDivElement>(null);
136
+
137
+ useEffect(() => {
138
+ setSelectedIndex(0);
139
+ }, [rows]);
140
+
141
+ useEffect(() => {
142
+ const el = listRef.current?.children[selectedIndex] as HTMLElement | undefined;
143
+ el?.scrollIntoView({ block: "nearest" });
144
+ }, [selectedIndex]);
145
+
146
+ const selectItem = useCallback(
147
+ (index: number) => {
148
+ if (rows[index]) onSelect(index);
149
+ },
150
+ [rows, onSelect],
151
+ );
152
+
153
+ useImperativeHandle(ref, () => ({
154
+ onKeyDown: ({ event }: { event: KeyboardEvent }) => {
155
+ if (rows.length === 0) return false;
156
+ if (event.key === "ArrowUp") {
157
+ setSelectedIndex((i) => (i + rows.length - 1) % rows.length);
158
+ return true;
159
+ }
160
+ if (event.key === "ArrowDown") {
161
+ setSelectedIndex((i) => (i + 1) % rows.length);
162
+ return true;
163
+ }
164
+ if (event.key === "Enter" || event.key === "Tab") {
165
+ selectItem(selectedIndex);
166
+ return true;
167
+ }
168
+ return false;
169
+ },
170
+ }));
171
+
172
+ const containerStyle: CSSProperties = {
173
+ background: chrome.background,
174
+ border: `1px solid ${chrome.borderColor}`,
175
+ borderRadius: `${chrome.radius}px`,
176
+ boxShadow: chrome.shadow,
177
+ // SP-EDGE: container owns only its border -- rows own all padding
178
+ padding: 0,
179
+ maxHeight: "320px",
180
+ overflowY: "auto",
181
+ minWidth: "220px",
182
+ maxWidth: "320px",
183
+ };
184
+
185
+ if (rows.length === 0) {
186
+ return (
187
+ <div style={containerStyle} data-suggestion-popup="true">
188
+ <div
189
+ style={{
190
+ padding: `8px ${chrome.rowPaddingX}px`,
191
+ color: chrome.descriptionColor,
192
+ fontSize: "13px",
193
+ }}
194
+ >
195
+ {emptyLabel}
196
+ </div>
197
+ </div>
198
+ );
199
+ }
200
+
201
+ return (
202
+ <div style={containerStyle} ref={listRef} role="listbox" data-suggestion-popup="true">
203
+ {rows.map((row, index) => (
204
+ <button
205
+ key={row.key}
206
+ role="option"
207
+ aria-selected={index === selectedIndex}
208
+ type="button"
209
+ style={{
210
+ // LC-16 shared menu-row geometry (menuRowFrame): horizontal
211
+ // padding resolved from the theme recipe, 8px vertical, 8px
212
+ // in-row gap, full-width flat rows (SP-EDGE)
213
+ display: "flex",
214
+ alignItems: "center",
215
+ gap: "8px",
216
+ padding: `8px ${chrome.rowPaddingX}px`,
217
+ border: "none",
218
+ background: index === selectedIndex ? chrome.activeBackground : "none",
219
+ width: "100%",
220
+ textAlign: "start",
221
+ cursor: "pointer",
222
+ borderRadius: 0,
223
+ fontSize: "13px",
224
+ lineHeight: "1.3",
225
+ fontFamily: "inherit",
226
+ }}
227
+ onClick={() => selectItem(index)}
228
+ onMouseEnter={() => setSelectedIndex(index)}
229
+ >
230
+ {row.avatarUrl ? (
231
+ <img
232
+ src={row.avatarUrl}
233
+ alt=""
234
+ style={{
235
+ width: "24px",
236
+ height: "24px",
237
+ borderRadius: "50%",
238
+ flexShrink: 0,
239
+ objectFit: "cover",
240
+ }}
241
+ />
242
+ ) : row.icon !== undefined && row.icon !== null ? (
243
+ <span
244
+ aria-hidden="true"
245
+ style={{
246
+ width: "28px",
247
+ height: "28px",
248
+ display: "flex",
249
+ alignItems: "center",
250
+ justifyContent: "center",
251
+ borderRadius: "4px",
252
+ background: chrome.iconTileBackground,
253
+ color: chrome.titleColor,
254
+ fontWeight: 700,
255
+ fontSize: "12px",
256
+ flexShrink: 0,
257
+ }}
258
+ >
259
+ {row.icon}
260
+ </span>
261
+ ) : null}
262
+ <span style={{ display: "flex", flexDirection: "column", gap: "1px", minWidth: 0 }}>
263
+ <span
264
+ style={{
265
+ fontWeight: 600,
266
+ color: chrome.titleColor,
267
+ whiteSpace: "nowrap",
268
+ overflow: "hidden",
269
+ textOverflow: "ellipsis",
270
+ }}
271
+ >
272
+ {row.title}
273
+ </span>
274
+ {row.description ? (
275
+ <span style={{ fontSize: "11px", color: chrome.descriptionColor }}>
276
+ {row.description}
277
+ </span>
278
+ ) : null}
279
+ </span>
280
+ </button>
281
+ ))}
282
+ </div>
283
+ );
284
+ },
285
+ );
286
+
287
+ SuggestionList.displayName = "SuggestionList";
288
+
289
+ // ===========================================================================
290
+ // Popup lifecycle (shared tiptap suggestion render())
291
+ // ===========================================================================
292
+
293
+ interface PopupHandle {
294
+ element: HTMLDivElement;
295
+ destroy: (immediate?: boolean) => void;
296
+ position: (clientRect?: (() => DOMRect | null) | null) => void;
297
+ }
298
+
299
+ function createPopup(editorDom: HTMLElement, motionMs: number): PopupHandle {
300
+ const popup = document.createElement("div");
301
+ popup.style.position = "fixed";
302
+ // above the fullscreen editor frame (zIndex 100000), which the
303
+ // body-portaled popup would otherwise render underneath
304
+ popup.style.zIndex = "100001";
305
+ // Portal lives on document.body, outside the app font scope; inherit the
306
+ // editor's computed font so the menu matches the app
307
+ popup.style.fontFamily = getComputedStyle(editorDom).fontFamily;
308
+ if (motionMs > 0) {
309
+ popup.style.opacity = "0";
310
+ popup.style.transform = "translateY(4px)";
311
+ popup.style.transition = `opacity ${motionMs}ms ease, transform ${motionMs}ms ease`;
312
+ requestAnimationFrame(() => {
313
+ popup.style.opacity = "1";
314
+ popup.style.transform = "translateY(0)";
315
+ });
316
+ }
317
+ document.body.appendChild(popup);
318
+
319
+ return {
320
+ element: popup,
321
+ position: (clientRect) => {
322
+ const rect = clientRect?.();
323
+ if (!rect) return;
324
+ const menuHeight = Math.min(popup.offsetHeight || 320, 320);
325
+ const below = rect.bottom + 4;
326
+ const flip = below + menuHeight > window.innerHeight && rect.top - menuHeight - 4 > 0;
327
+ popup.style.left = `${Math.min(rect.left, Math.max(8, window.innerWidth - popup.offsetWidth - 8))}px`;
328
+ popup.style.top = flip ? `${rect.top - menuHeight - 4}px` : `${below}px`;
329
+ },
330
+ destroy: (immediate = false) => {
331
+ if (immediate || motionMs === 0) {
332
+ popup.remove();
333
+ return;
334
+ }
335
+ popup.style.opacity = "0";
336
+ popup.style.transform = "translateY(4px)";
337
+ popup.style.pointerEvents = "none";
338
+ window.setTimeout(() => popup.remove(), motionMs);
339
+ },
340
+ };
341
+ }
342
+
343
+ export interface SuggestionRendererOptions<ItemType> {
344
+ /** Maps suggestion items to shared rows */
345
+ toRow: (item: ItemType) => SuggestionRow;
346
+ /** Reads resolved chrome (editor storage) at open time */
347
+ getChrome: (editor: any) => SuggestionChrome;
348
+ /** Copy for the empty state */
349
+ getEmptyLabel: () => string;
350
+ }
351
+
352
+ /**
353
+ * Builds the `render()` lifecycle for a tiptap Suggestion configuration,
354
+ * portaling the shared SuggestionList and wiring keyboard navigation,
355
+ * Escape (consumed -- it must not reach outer handlers like fullscreen
356
+ * exit), repositioning, and enter/exit motion.
357
+ */
358
+ export function createSuggestionRenderer<ItemType>({
359
+ toRow,
360
+ getChrome,
361
+ getEmptyLabel,
362
+ }: SuggestionRendererOptions<ItemType>) {
363
+ return () => {
364
+ let component: ReactRenderer<SuggestionListRef> | null = null;
365
+ let popup: PopupHandle | null = null;
366
+
367
+ const makeProps = (props: any) => ({
368
+ rows: (props.items as ItemType[]).map(toRow),
369
+ chrome: getChrome(props.editor),
370
+ emptyLabel: getEmptyLabel(),
371
+ onSelect: (index: number) => {
372
+ const item = (props.items as ItemType[])[index];
373
+ if (item !== undefined) props.command(item);
374
+ },
375
+ });
376
+
377
+ return {
378
+ onStart: (props: any) => {
379
+ component = new ReactRenderer(SuggestionList, {
380
+ props: makeProps(props),
381
+ editor: props.editor,
382
+ });
383
+ popup = createPopup(props.editor.view.dom, getChrome(props.editor).motionMs);
384
+ popup.element.appendChild(component.element);
385
+ popup.position(props.clientRect);
386
+ // reposition once content has laid out (flip needs real height)
387
+ requestAnimationFrame(() => popup?.position(props.clientRect));
388
+ },
389
+ onUpdate: (props: any) => {
390
+ component?.updateProps(makeProps(props));
391
+ popup?.position(props.clientRect);
392
+ },
393
+ onKeyDown: (props: any) => {
394
+ if (props.event.key === "Escape") {
395
+ // consume the Escape entirely: closing the menu must not also
396
+ // trigger outer Escape handlers (e.g. fullscreen exit)
397
+ props.event.stopPropagation();
398
+ popup?.destroy();
399
+ component?.destroy();
400
+ popup = null;
401
+ component = null;
402
+ return true;
403
+ }
404
+ return component?.ref?.onKeyDown(props) ?? false;
405
+ },
406
+ onExit: () => {
407
+ popup?.destroy();
408
+ component?.destroy();
409
+ popup = null;
410
+ component = null;
411
+ },
412
+ };
413
+ };
414
+ }