@multiplatform.one/rich-text 6.0.4 → 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
@@ -15,18 +15,53 @@ export interface EditorCSSOptions {
15
15
  bodyFontFamily?: string;
16
16
  /** CSS font-family string for headings */
17
17
  headingFontFamily?: string;
18
+ /** Fullscreen mode: fill the container instead of min/max pixel heights */
19
+ fullscreen?: boolean;
20
+ /** Bubble/popup fade duration in ms; 0 = animation none (motion silenced) */
21
+ motionMs?: number;
22
+ /** Per-instance scope class so bubble motion rules do not cross editors */
23
+ scopeClass?: string;
18
24
  }
19
25
 
20
26
  export function getEditorCSS(options: EditorCSSOptions = {}): string {
21
- const { minHeight = 150, maxHeight, bodyFontFamily, headingFontFamily } = options;
27
+ const {
28
+ minHeight = 150,
29
+ maxHeight,
30
+ bodyFontFamily,
31
+ headingFontFamily,
32
+ fullscreen,
33
+ motionMs = 120,
34
+ scopeClass,
35
+ } = options;
22
36
  const bodyFont = bodyFontFamily || "inherit";
23
37
  const headingFont = headingFontFamily || bodyFont;
38
+ const bubbleScope = scopeClass ? `.${scopeClass} .rt-bubble-menu` : ".rt-bubble-menu";
24
39
 
25
40
  return `
41
+ /*
42
+ LC-24 A-ENTEREXIT: the bubble-menu plugin persists its element and
43
+ flips inline visibility/opacity on show/hide. A transition on the same
44
+ element pairs enter AND exit: the destination-state selector (inline
45
+ style attribute) picks instant visibility on show and delayed
46
+ visibility on hide so the exit fade stays visible. motionMs 0
47
+ (animation none) silences both.
48
+ */
49
+ ${bubbleScope} {
50
+ transition: opacity ${motionMs}ms ease, transform ${motionMs}ms ease,
51
+ visibility 0s linear ${motionMs}ms;
52
+ }
53
+ ${bubbleScope}[style*="visibility: visible"] {
54
+ transition: opacity ${motionMs}ms ease, transform ${motionMs}ms ease, visibility 0s;
55
+ }
56
+
26
57
  .ProseMirror {
27
58
  padding: 12px 12px 12px 16px;
28
- min-height: ${minHeight}px;
29
- ${maxHeight ? `max-height: ${maxHeight}px; overflow-y: auto;` : ""}
59
+ ${
60
+ fullscreen
61
+ ? "min-height: 100%;"
62
+ : `min-height: ${minHeight}px;
63
+ ${maxHeight ? `max-height: ${maxHeight}px; overflow-y: auto;` : ""}`
64
+ }
30
65
  outline: none;
31
66
  font-family: ${bodyFont};
32
67
  color: var(--color12);
@@ -34,7 +69,35 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
34
69
  .ProseMirror:focus {
35
70
  outline: none;
36
71
  }
72
+ /* Axiom 12 LEGIBLE FLOOR: non-removable >=2px focus ring on the
73
+ keyboard-focused editing surface */
74
+ .ProseMirror:focus-visible {
75
+ outline: 2px solid var(--color8);
76
+ outline-offset: -2px;
77
+ }
78
+ /* Mention chips (@ mention nodes) */
79
+ .ProseMirror .rt-mention {
80
+ background-color: var(--color4);
81
+ border-radius: 4px;
82
+ padding: 0.1em 0.3em;
83
+ color: var(--color12);
84
+ font-weight: 500;
85
+ white-space: nowrap;
86
+ }
87
+ /* Attachment chips (non-image file uploads) */
88
+ .ProseMirror a.rt-attachment {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ background-color: var(--color3);
92
+ border: 1px solid var(--color6);
93
+ border-radius: 999px;
94
+ padding: 0.05em 0.6em;
95
+ text-decoration: none;
96
+ color: var(--color12);
97
+ }
37
98
  .ProseMirror p {
99
+ /* @tamagui/core reset.css does p { all: unset } (display -> inline); restore block flow */
100
+ display: block;
38
101
  margin: 0 0 0.5em 0;
39
102
  }
40
103
  .ProseMirror p:last-child {
@@ -80,7 +143,10 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
80
143
  }
81
144
  .ProseMirror ul,
82
145
  .ProseMirror ol {
83
- padding-left: 1em;
146
+ /* reset.css also unsets ul/ol display; restore block flow.
147
+ Logical padding so list indent mirrors in RTL content. */
148
+ display: block;
149
+ padding-inline-start: 1em;
84
150
  margin: 0.5em 0;
85
151
  }
86
152
  .ProseMirror ul {
@@ -104,8 +170,8 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
104
170
  }
105
171
  .ProseMirror ul[data-type="taskList"] {
106
172
  list-style: none;
107
- padding-left: 0;
108
- margin-left: 0;
173
+ padding-inline-start: 0;
174
+ margin-inline-start: 0;
109
175
  }
110
176
  .ProseMirror ul[data-type="taskList"] li {
111
177
  display: flex;
@@ -130,16 +196,17 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
130
196
  border-radius: 4px;
131
197
  }
132
198
  .ProseMirror img.ProseMirror-selectednode {
133
- outline: 2px solid var(--blue10, #0066cc);
199
+ outline: 2px solid var(--blue10);
134
200
  }
135
201
  .ProseMirror blockquote {
136
- border-left: 3px solid var(--color6, #ccc);
137
- padding-left: 1em;
202
+ /* Logical start rail so the quote accent mirrors in RTL. */
203
+ border-inline-start: 3px solid var(--color6);
204
+ padding-inline-start: 1em;
138
205
  margin: 0.5em 0;
139
- color: var(--color10, #666);
206
+ color: var(--color10);
140
207
  }
141
208
  .ProseMirror code {
142
- background-color: var(--color4, rgba(0,0,0,0.05));
209
+ background-color: var(--color4);
143
210
  padding: 0.15em 0.35em;
144
211
  border-radius: 4px;
145
212
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
@@ -147,8 +214,8 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
147
214
  word-break: break-word;
148
215
  }
149
216
  .ProseMirror pre {
150
- background-color: var(--color3, rgba(0,0,0,0.04));
151
- border: 1px solid var(--color5, rgba(0,0,0,0.08));
217
+ background-color: var(--color3);
218
+ border: 1px solid var(--color5);
152
219
  padding: 0.75em 1em;
153
220
  border-radius: 4px;
154
221
  overflow-x: auto;
@@ -168,25 +235,34 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
168
235
  white-space: pre;
169
236
  }
170
237
  .ProseMirror a {
171
- color: var(--blue10, #0066cc);
238
+ color: var(--blue10);
172
239
  text-decoration: underline;
173
240
  }
241
+ /* Highlight marks: the swatch palette rides scheme-aware theme ramps
242
+ (radix step-5 washes — pastel in light, deep-dim in dark), so the
243
+ inherited scheme ink stays legible on them; no forced ink needed. */
174
244
  .ProseMirror hr {
175
245
  border: none;
176
- border-top: 2px solid var(--color6, #ccc);
246
+ border-top: 2px solid var(--color6);
177
247
  margin: 1em 0;
178
248
  }
179
249
  .ProseMirror p.is-editor-empty:first-child::before {
180
250
  content: attr(data-placeholder);
181
- color: var(--color8, #aaa);
251
+ /* Axiom 12: placeholder is an owned text role — color11 is the muted
252
+ step that still clears 4.5:1 on the color2 editor surface in both
253
+ schemes (color10 measured 3.76:1 light / 3.87:1 dark) */
254
+ color: var(--color11);
182
255
  pointer-events: none;
183
- float: left;
256
+ float: inline-start;
184
257
  height: 0;
185
258
  }
186
259
 
187
- /* Block drag handle */
260
+ /* Block drag handle (decorative fade stops at animation none) */
261
+ .block-drag-handle {
262
+ transition: opacity ${motionMs}ms ease;
263
+ }
188
264
  .block-drag-handle:hover {
189
- background-color: var(--color4, rgba(0,0,0,0.05));
265
+ background-color: var(--color4);
190
266
  opacity: 1 !important;
191
267
  }
192
268
  .block-drag-handle:active {
@@ -202,18 +278,18 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
202
278
  }
203
279
  .ProseMirror td,
204
280
  .ProseMirror th {
205
- border: 1px solid var(--color6, #ddd);
281
+ border: 1px solid var(--color6);
206
282
  padding: 0.4em 0.6em;
207
283
  vertical-align: top;
208
284
  position: relative;
209
285
  min-width: 80px;
210
286
  }
211
287
  .ProseMirror th {
212
- background-color: var(--color3, #f5f5f5);
288
+ background-color: var(--color3);
213
289
  font-weight: 600;
214
290
  }
215
291
  .ProseMirror .selectedCell {
216
- background-color: var(--blue3, rgba(0, 102, 204, 0.08));
292
+ background-color: var(--blue3);
217
293
  }
218
294
  .ProseMirror .column-resize-handle {
219
295
  position: absolute;
@@ -221,39 +297,147 @@ export function getEditorCSS(options: EditorCSSOptions = {}): string {
221
297
  top: 0;
222
298
  bottom: 0;
223
299
  width: 4px;
224
- background-color: var(--blue10, #0066cc);
300
+ background-color: var(--blue10);
225
301
  pointer-events: none;
226
302
  }
227
303
  .ProseMirror.resize-cursor {
228
304
  cursor: col-resize;
229
305
  }
230
306
 
307
+ /* Inline math (KaTeX-rendered atom; raw TeX while loading) */
308
+ .ProseMirror .rt-math-inline {
309
+ display: inline-block;
310
+ padding: 0 0.15em;
311
+ border-radius: 4px;
312
+ cursor: pointer;
313
+ max-width: 100%;
314
+ }
315
+ .ProseMirror .rt-math-inline.ProseMirror-selectednode {
316
+ outline: 2px solid var(--blue10);
317
+ }
318
+ .ProseMirror .rt-math-inline.rt-math-error {
319
+ color: var(--red10);
320
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
321
+ font-size: 0.875em;
322
+ text-decoration: underline dashed var(--red10);
323
+ text-underline-offset: 3px;
324
+ }
325
+ .ProseMirror .rt-math-inline.rt-math-empty {
326
+ color: var(--color10);
327
+ font-style: italic;
328
+ border: 1px dashed var(--color8);
329
+ padding: 0 0.4em;
330
+ }
331
+ .ProseMirror .katex { font-size: 1.06em; }
332
+
333
+ /* Code block wrapper with live preview pane (mermaid / math) */
334
+ .ProseMirror .rt-codeblock { margin: 0.5em 0; }
335
+ .ProseMirror .rt-codeblock pre { margin: 0; }
336
+ .ProseMirror .rt-block-preview[data-state="hidden"] { display: none; }
337
+ .ProseMirror .rt-codeblock:has(.rt-block-preview:not([data-state="hidden"])) pre {
338
+ border-bottom-left-radius: 0;
339
+ border-bottom-right-radius: 0;
340
+ }
341
+ .ProseMirror .rt-block-preview {
342
+ border: 1px solid var(--color5);
343
+ border-top: 1px dashed var(--color6);
344
+ border-radius: 0 0 4px 4px;
345
+ padding: 0.75em 1em;
346
+ background-color: var(--color2);
347
+ overflow-x: auto;
348
+ }
349
+ .ProseMirror .rt-preview-diagram { display: flex; justify-content: center; }
350
+ .ProseMirror .rt-preview-diagram svg { max-width: 100%; height: auto; }
351
+ .ProseMirror .rt-preview-math .katex-display { margin: 0.25em 0; }
352
+ .ProseMirror .rt-preview-error {
353
+ color: var(--red10);
354
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
355
+ font-size: 0.8125em;
356
+ white-space: pre-wrap;
357
+ }
358
+ .ProseMirror .rt-preview-hint {
359
+ color: var(--color10);
360
+ font-size: 0.8125em;
361
+ font-style: italic;
362
+ }
363
+
364
+ /* Collapsible details sections (GitLab <details> parity) */
365
+ .ProseMirror [data-type="details"] {
366
+ display: flex;
367
+ gap: 0.4em;
368
+ border: 1px solid var(--color5);
369
+ border-radius: 4px;
370
+ padding: 0.5em 0.75em;
371
+ margin: 0.5em 0;
372
+ }
373
+ .ProseMirror [data-type="details"] > button {
374
+ flex: 0 0 auto;
375
+ width: 1.5em;
376
+ height: 1.5em;
377
+ margin-top: 0.1em;
378
+ display: flex;
379
+ align-items: center;
380
+ justify-content: center;
381
+ background: none;
382
+ border: none;
383
+ border-radius: 4px;
384
+ cursor: pointer;
385
+ color: var(--color11);
386
+ font-size: 1em;
387
+ padding: 0;
388
+ }
389
+ .ProseMirror [data-type="details"] > button:hover {
390
+ background-color: var(--color4);
391
+ }
392
+ .ProseMirror [data-type="details"] > button::before {
393
+ content: "\\25B8";
394
+ display: block;
395
+ transition: transform ${motionMs}ms ease;
396
+ }
397
+ .ProseMirror [data-type="details"].is-open > button::before {
398
+ transform: rotate(90deg);
399
+ }
400
+ .ProseMirror [data-type="details"] > div {
401
+ flex: 1 1 auto;
402
+ min-width: 0;
403
+ }
404
+ .ProseMirror [data-type="details"] summary {
405
+ display: block;
406
+ font-weight: 600;
407
+ list-style: none;
408
+ }
409
+ .ProseMirror [data-type="details"] summary::-webkit-details-marker { display: none; }
410
+ .ProseMirror [data-type="detailsContent"] { margin-top: 0.25em; }
411
+ /* The tamagui reset defeats the UA's [hidden] display:none — restore
412
+ it so the details toggle actually collapses the content */
413
+ .ProseMirror [data-type="detailsContent"][hidden] { display: none; }
414
+
231
415
  /* Syntax highlighting (lowlight / highlight.js compatible) */
232
416
  .ProseMirror pre .hljs-comment,
233
- .ProseMirror pre .hljs-quote { color: var(--color9, #6a737d); font-style: italic; }
417
+ .ProseMirror pre .hljs-quote { color: var(--color9); font-style: italic; }
234
418
  .ProseMirror pre .hljs-keyword,
235
419
  .ProseMirror pre .hljs-selector-tag,
236
- .ProseMirror pre .hljs-meta { color: var(--purple10, #d73a49); }
420
+ .ProseMirror pre .hljs-meta { color: var(--purple10); }
237
421
  .ProseMirror pre .hljs-string,
238
422
  .ProseMirror pre .hljs-attr,
239
423
  .ProseMirror pre .hljs-template-tag,
240
- .ProseMirror pre .hljs-template-variable { color: var(--green10, #22863a); }
424
+ .ProseMirror pre .hljs-template-variable { color: var(--green10); }
241
425
  .ProseMirror pre .hljs-number,
242
426
  .ProseMirror pre .hljs-literal,
243
427
  .ProseMirror pre .hljs-type,
244
- .ProseMirror pre .hljs-params { color: var(--blue10, #005cc5); }
428
+ .ProseMirror pre .hljs-params { color: var(--blue10); }
245
429
  .ProseMirror pre .hljs-built_in,
246
- .ProseMirror pre .hljs-builtin-name { color: var(--orange10, #e36209); }
430
+ .ProseMirror pre .hljs-builtin-name { color: var(--orange10); }
247
431
  .ProseMirror pre .hljs-title,
248
- .ProseMirror pre .hljs-section { color: var(--blue10, #005cc5); font-weight: 600; }
432
+ .ProseMirror pre .hljs-section { color: var(--blue10); font-weight: 600; }
249
433
  .ProseMirror pre .hljs-name,
250
- .ProseMirror pre .hljs-tag { color: var(--green10, #22863a); }
251
- .ProseMirror pre .hljs-attribute { color: var(--purple10, #6f42c1); }
434
+ .ProseMirror pre .hljs-tag { color: var(--green10); }
435
+ .ProseMirror pre .hljs-attribute { color: var(--purple10); }
252
436
  .ProseMirror pre .hljs-variable,
253
437
  .ProseMirror pre .hljs-symbol,
254
- .ProseMirror pre .hljs-bullet { color: var(--orange10, #e36209); }
255
- .ProseMirror pre .hljs-addition { color: var(--green10, #22863a); background-color: rgba(34,134,58,0.1); }
256
- .ProseMirror pre .hljs-deletion { color: var(--red10, #b31d28); background-color: rgba(179,29,40,0.1); }
438
+ .ProseMirror pre .hljs-bullet { color: var(--orange10); }
439
+ .ProseMirror pre .hljs-addition { color: var(--green10); background-color: color-mix(in srgb, var(--green10) 12%, transparent); }
440
+ .ProseMirror pre .hljs-deletion { color: var(--red10); background-color: color-mix(in srgb, var(--red10) 12%, transparent); }
257
441
  .ProseMirror pre .hljs-emphasis { font-style: italic; }
258
442
  .ProseMirror pre .hljs-strong { font-weight: bold; }
259
443
  `;
@@ -0,0 +1,88 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { Editor } from "@tiptap/core";
3
+ import StarterKit from "@tiptap/starter-kit";
4
+ import {
5
+ EmojiSuggestion,
6
+ insertEmoji,
7
+ loadEmojiIndex,
8
+ searchEmoji,
9
+ type EmojiEntry,
10
+ } from "./emoji";
11
+
12
+ const ENTRIES: EmojiEntry[] = [
13
+ { name: "smile", char: "😄", keywords: ["face", "happy"] },
14
+ { name: "smiley", char: "😃", keywords: ["face", "happy"] },
15
+ { name: "sweat_smile", char: "😅", keywords: ["face", "hot"] },
16
+ { name: "cat", char: "🐱", keywords: ["animal", "meow"] },
17
+ { name: "tada", char: "🎉", keywords: ["party", "celebration", "smashing"] },
18
+ ];
19
+
20
+ describe("searchEmoji", () => {
21
+ it("returns the head of the dataset for an empty query", () => {
22
+ expect(searchEmoji(ENTRIES, "", 3).map((e) => e.name)).toEqual([
23
+ "smile",
24
+ "smiley",
25
+ "sweat_smile",
26
+ ]);
27
+ });
28
+
29
+ it("ranks exact name over prefix over substring over keyword", () => {
30
+ const names = searchEmoji(ENTRIES, "smile").map((e) => e.name);
31
+ // exact: smile; prefix: smiley; substring: sweat_smile; keyword: none
32
+ expect(names).toEqual(["smile", "smiley", "sweat_smile"]);
33
+ });
34
+
35
+ it("falls back to keyword matches", () => {
36
+ const names = searchEmoji(ENTRIES, "party").map((e) => e.name);
37
+ expect(names).toEqual(["tada"]);
38
+ });
39
+
40
+ it("is case-insensitive and respects the limit", () => {
41
+ expect(searchEmoji(ENTRIES, "SMI", 2).map((e) => e.name)).toEqual(["smile", "smiley"]);
42
+ });
43
+
44
+ it("returns empty for a no-match query", () => {
45
+ expect(searchEmoji(ENTRIES, "zzzz")).toEqual([]);
46
+ });
47
+ });
48
+
49
+ describe("loadEmojiIndex", () => {
50
+ it("lazy-loads the real dataset with usable shortnames", async () => {
51
+ const entries = await loadEmojiIndex();
52
+ expect(entries.length).toBeGreaterThan(1000);
53
+ const thumbsup = entries.find((e) => e.name === "+1");
54
+ expect(thumbsup?.char).toBe("👍");
55
+ // every entry is insertable
56
+ expect(entries.every((e) => e.name.length > 0 && e.char!.length > 0)).toBe(true);
57
+ });
58
+
59
+ it("caches the dataset promise (single fetch per session)", () => {
60
+ expect(loadEmojiIndex()).toBe(loadEmojiIndex());
61
+ });
62
+ });
63
+
64
+ describe("EmojiSuggestion extension", () => {
65
+ it("configures the : trigger on its own plugin key", () => {
66
+ expect(EmojiSuggestion.name).toBe("emojiSuggestion");
67
+ expect(EmojiSuggestion.options.suggestion.char).toBe(":");
68
+ // must not collide with the slash menu's default Suggestion key
69
+ expect(EmojiSuggestion.options.suggestion.pluginKey).toBeDefined();
70
+ });
71
+
72
+ it("resolves items through the lazy dataset", async () => {
73
+ const items = await EmojiSuggestion.options.suggestion.items({ query: "tada" });
74
+ expect(items[0]?.char).toBe("🎉");
75
+ });
76
+
77
+ it("insertEmoji replaces the trigger range with the unicode character", () => {
78
+ const editor = new Editor({
79
+ element: document.createElement("div"),
80
+ extensions: [StarterKit],
81
+ content: "<p>hello :sm</p>",
82
+ });
83
+ // ":sm" occupies positions 7-10 in <p>hello :sm</p>
84
+ insertEmoji(editor, { from: 7, to: 10 }, "😄");
85
+ expect(editor.getText()).toBe("hello 😄");
86
+ editor.destroy();
87
+ });
88
+ });
@@ -0,0 +1,147 @@
1
+ /**
2
+ * `:emoji:` autocomplete for the rich text editor (web) — GitLab parity.
3
+ *
4
+ * Third suggestion source on the shared LC-16 popup (same rows, chrome,
5
+ * keyboard handling, and ARIA roles as slash commands and @ mentions).
6
+ * Typing `:` opens a searchable shortname list; selecting inserts the plain
7
+ * unicode character (like GitLab's editor), so the markdown round-trip is
8
+ * lossless by construction — an emoji is just text.
9
+ *
10
+ * Bundle discipline: the emoji dataset (emojilib, ~32 KB gz) is NOT in the
11
+ * editor chunk. It is dynamically imported on the first `:` trigger and
12
+ * cached for the session.
13
+ */
14
+
15
+ import { Extension } from "@tiptap/core";
16
+ import type { Editor, Range } from "@tiptap/core";
17
+ import { PluginKey } from "@tiptap/pm/state";
18
+ import Suggestion from "@tiptap/suggestion";
19
+ import { t } from "../shared/t";
20
+ import { createSuggestionRenderer, getSuggestionChrome } from "./suggestionPopup";
21
+
22
+ // ===========================================================================
23
+ // Dataset (lazy)
24
+ // ===========================================================================
25
+
26
+ export interface EmojiEntry {
27
+ /** Shortname, e.g. "thumbsup" (typed between colons) */
28
+ name: string;
29
+ /** The unicode character inserted into the document */
30
+ char: string;
31
+ /** Search keywords from the dataset */
32
+ keywords: string[];
33
+ }
34
+
35
+ interface EmojilibRecord {
36
+ char?: string;
37
+ keywords?: string[];
38
+ }
39
+
40
+ let emojiIndexPromise: Promise<EmojiEntry[]> | null = null;
41
+
42
+ /**
43
+ * Loads and flattens the emojilib dataset on first use. The dynamic import
44
+ * keeps the JSON out of the editor chunk (zero eager bytes); the promise is
45
+ * cached so the fetch happens at most once per session.
46
+ */
47
+ export function loadEmojiIndex(): Promise<EmojiEntry[]> {
48
+ if (!emojiIndexPromise) {
49
+ emojiIndexPromise = import("emojilib/emojis.json").then((mod: any) => {
50
+ const lib = (mod?.default ?? mod) as Record<string, EmojilibRecord>;
51
+ const entries: EmojiEntry[] = [];
52
+ for (const [name, value] of Object.entries(lib)) {
53
+ if (!value?.char) continue;
54
+ entries.push({ name, char: value.char, keywords: value.keywords ?? [] });
55
+ }
56
+ return entries;
57
+ });
58
+ }
59
+ return emojiIndexPromise;
60
+ }
61
+
62
+ /** Test seam: reset the cached dataset promise */
63
+ export function resetEmojiIndexForTesting(): void {
64
+ emojiIndexPromise = null;
65
+ }
66
+
67
+ // ===========================================================================
68
+ // Search
69
+ // ===========================================================================
70
+
71
+ /**
72
+ * Ranked shortname search: exact name, name prefix, name substring, then
73
+ * keyword prefix/substring. Ties keep dataset order (faces first), matching
74
+ * the GitLab popup's feel. An empty query lists the head of the dataset.
75
+ */
76
+ export function searchEmoji(entries: EmojiEntry[], query: string, limit = 20): EmojiEntry[] {
77
+ const q = query.trim().toLowerCase();
78
+ if (!q) return entries.slice(0, limit);
79
+
80
+ const tiers: EmojiEntry[][] = [[], [], [], []];
81
+ for (const entry of entries) {
82
+ const name = entry.name.toLowerCase();
83
+ if (name === q) {
84
+ tiers[0]!.push(entry);
85
+ } else if (name.startsWith(q)) {
86
+ tiers[1]!.push(entry);
87
+ } else if (name.includes(q)) {
88
+ tiers[2]!.push(entry);
89
+ } else if (entry.keywords.some((keyword) => keyword.toLowerCase().startsWith(q))) {
90
+ tiers[3]!.push(entry);
91
+ }
92
+ if (tiers[0]!.length + tiers[1]!.length >= limit) break;
93
+ }
94
+ return tiers.flat().slice(0, limit);
95
+ }
96
+
97
+ // ===========================================================================
98
+ // Extension
99
+ // ===========================================================================
100
+
101
+ /** Inserts the unicode character, replacing the `:query` trigger text */
102
+ export function insertEmoji(editor: Editor, range: Range, char: string): void {
103
+ editor.chain().focus().insertContentAt(range, char).run();
104
+ }
105
+
106
+ const EmojiSuggestionPluginKey = new PluginKey("emojiSuggestion");
107
+
108
+ /**
109
+ * `:` trigger suggestion menu. Own plugin key — the slash menu owns the
110
+ * default Suggestion key and the two must coexist.
111
+ */
112
+ export const EmojiSuggestion = Extension.create({
113
+ name: "emojiSuggestion",
114
+
115
+ addOptions() {
116
+ return {
117
+ suggestion: {
118
+ char: ":",
119
+ pluginKey: EmojiSuggestionPluginKey,
120
+ startOfLine: false,
121
+ items: async ({ query }: { query: string }): Promise<EmojiEntry[]> =>
122
+ searchEmoji(await loadEmojiIndex(), query),
123
+ render: createSuggestionRenderer<EmojiEntry>({
124
+ toRow: (item) => ({
125
+ key: item.name,
126
+ title: `:${item.name}:`,
127
+ description: item.keywords.slice(0, 3).join(", ") || undefined,
128
+ icon: item.char,
129
+ }),
130
+ getChrome: getSuggestionChrome,
131
+ getEmptyLabel: () => t("No results"),
132
+ }),
133
+ command: ({ editor, range, props }: { editor: Editor; range: Range; props: EmojiEntry }) =>
134
+ insertEmoji(editor, range, props.char),
135
+ },
136
+ };
137
+ },
138
+
139
+ addProseMirrorPlugins() {
140
+ return [
141
+ Suggestion({
142
+ editor: this.editor,
143
+ ...this.options.suggestion,
144
+ }),
145
+ ];
146
+ },
147
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Ambient declaration for the emojilib v2 dataset JSON, imported directly
3
+ * (subpath) so the lazy emoji chunk skips index.js and ordered.json.
4
+ */
5
+ declare module "emojilib/emojis.json" {
6
+ const lib: Record<
7
+ string,
8
+ {
9
+ keywords?: string[];
10
+ char?: string;
11
+ fitzpatrick_scale?: boolean;
12
+ category?: string;
13
+ }
14
+ >;
15
+ export default lib;
16
+ }
@@ -0,0 +1,38 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { mountKatexHtml, renderKatexHtml } from "./lazyKatex";
3
+
4
+ describe("renderKatexHtml", () => {
5
+ it("renders valid TeX to KaTeX markup", async () => {
6
+ const result = await renderKatexHtml("x^2");
7
+ expect(result.ok).toBe(true);
8
+ if (result.ok) expect(result.html).toContain("katex");
9
+ });
10
+
11
+ it("renders display mode for block math", async () => {
12
+ const result = await renderKatexHtml("\\sum_{i=0}^n i", { displayMode: true });
13
+ expect(result.ok).toBe(true);
14
+ if (result.ok) expect(result.html).toContain("katex-display");
15
+ });
16
+
17
+ it("returns the parse error for invalid TeX (Axiom 6: never blank)", async () => {
18
+ const result = await renderKatexHtml("\\undefinedmacro{");
19
+ expect(result.ok).toBe(false);
20
+ if (!result.ok) expect(result.error).toMatch(/parse error/i);
21
+ });
22
+ });
23
+
24
+ describe("mountKatexHtml", () => {
25
+ it("mounts markup as real nodes", async () => {
26
+ const result = await renderKatexHtml("x^2");
27
+ const container = document.createElement("span");
28
+ if (result.ok) mountKatexHtml(container, result.html);
29
+ expect(container.querySelector(".katex")).not.toBeNull();
30
+ });
31
+
32
+ it("strips executable elements (defense in depth)", () => {
33
+ const container = document.createElement("span");
34
+ mountKatexHtml(container, '<span class="katex">ok</span><script>alert(1)</script>');
35
+ expect(container.querySelector("script")).toBeNull();
36
+ expect(container.querySelector(".katex")?.textContent).toBe("ok");
37
+ });
38
+ });