@multiplatform.one/rich-text 6.0.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 (450) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cjs/RichEditor.cjs +132 -0
  3. package/dist/cjs/RichEditor.native.js +120 -0
  4. package/dist/cjs/RichEditor.native.js.map +1 -0
  5. package/dist/cjs/RichEditor.stories.cjs +327 -0
  6. package/dist/cjs/RichEditor.stories.native.js +342 -0
  7. package/dist/cjs/RichEditor.stories.native.js.map +1 -0
  8. package/dist/cjs/RichTextEditor/index.cjs +148 -0
  9. package/dist/cjs/RichTextEditor/index.native.js +160 -0
  10. package/dist/cjs/RichTextEditor/index.native.js.map +1 -0
  11. package/dist/cjs/constants.cjs +135 -0
  12. package/dist/cjs/constants.native.js +138 -0
  13. package/dist/cjs/constants.native.js.map +1 -0
  14. package/dist/cjs/context.cjs +33 -0
  15. package/dist/cjs/context.native.js +36 -0
  16. package/dist/cjs/context.native.js.map +1 -0
  17. package/dist/cjs/editor/BlockDragHandle.cjs +137 -0
  18. package/dist/cjs/editor/BlockDragHandle.native.js +142 -0
  19. package/dist/cjs/editor/BlockDragHandle.native.js.map +1 -0
  20. package/dist/cjs/editor/MarkdownPaste.cjs +65 -0
  21. package/dist/cjs/editor/MarkdownPaste.native.js +68 -0
  22. package/dist/cjs/editor/MarkdownPaste.native.js.map +1 -0
  23. package/dist/cjs/editor/SlashCommands.cjs +369 -0
  24. package/dist/cjs/editor/SlashCommands.native.js +424 -0
  25. package/dist/cjs/editor/SlashCommands.native.js.map +1 -0
  26. package/dist/cjs/editor/TentapEditor.native.js +242 -0
  27. package/dist/cjs/editor/TentapEditor.native.js.map +1 -0
  28. package/dist/cjs/editor/TiptapEditor.cjs +578 -0
  29. package/dist/cjs/editor/TiptapEditor.native.js +661 -0
  30. package/dist/cjs/editor/TiptapEditor.native.js.map +1 -0
  31. package/dist/cjs/editor/editorStyles.cjs +272 -0
  32. package/dist/cjs/editor/editorStyles.native.js +276 -0
  33. package/dist/cjs/editor/editorStyles.native.js.map +1 -0
  34. package/dist/cjs/editor/index.cjs +33 -0
  35. package/dist/cjs/editor/index.native.js +36 -0
  36. package/dist/cjs/editor/index.native.js.map +1 -0
  37. package/dist/cjs/editor/types.cjs +54 -0
  38. package/dist/cjs/editor/types.native.js +57 -0
  39. package/dist/cjs/editor/types.native.js.map +1 -0
  40. package/dist/cjs/editor/useEditorState.cjs +129 -0
  41. package/dist/cjs/editor/useEditorState.native.js +135 -0
  42. package/dist/cjs/editor/useEditorState.native.js.map +1 -0
  43. package/dist/cjs/index.cjs +30 -0
  44. package/dist/cjs/index.native.js +33 -0
  45. package/dist/cjs/index.native.js.map +1 -0
  46. package/dist/cjs/styled.cjs +173 -0
  47. package/dist/cjs/styled.native.js +185 -0
  48. package/dist/cjs/styled.native.js.map +1 -0
  49. package/dist/cjs/toolbar/BubbleToolbar.cjs +130 -0
  50. package/dist/cjs/toolbar/BubbleToolbar.native.js +159 -0
  51. package/dist/cjs/toolbar/BubbleToolbar.native.js.map +1 -0
  52. package/dist/cjs/toolbar/CodeBlockBubble.cjs +211 -0
  53. package/dist/cjs/toolbar/CodeBlockBubble.native.js +228 -0
  54. package/dist/cjs/toolbar/CodeBlockBubble.native.js.map +1 -0
  55. package/dist/cjs/toolbar/ColorPicker.cjs +217 -0
  56. package/dist/cjs/toolbar/ColorPicker.native.js +234 -0
  57. package/dist/cjs/toolbar/ColorPicker.native.js.map +1 -0
  58. package/dist/cjs/toolbar/FixedToolbar.cjs +221 -0
  59. package/dist/cjs/toolbar/FixedToolbar.native.js +322 -0
  60. package/dist/cjs/toolbar/FixedToolbar.native.js.map +1 -0
  61. package/dist/cjs/toolbar/HeadingPicker.cjs +158 -0
  62. package/dist/cjs/toolbar/HeadingPicker.native.js +167 -0
  63. package/dist/cjs/toolbar/HeadingPicker.native.js.map +1 -0
  64. package/dist/cjs/toolbar/ImageBubble.cjs +156 -0
  65. package/dist/cjs/toolbar/ImageBubble.native.js +165 -0
  66. package/dist/cjs/toolbar/ImageBubble.native.js.map +1 -0
  67. package/dist/cjs/toolbar/ImageDialog.cjs +115 -0
  68. package/dist/cjs/toolbar/ImageDialog.native.js +122 -0
  69. package/dist/cjs/toolbar/ImageDialog.native.js.map +1 -0
  70. package/dist/cjs/toolbar/LinkBubble.cjs +195 -0
  71. package/dist/cjs/toolbar/LinkBubble.native.js +204 -0
  72. package/dist/cjs/toolbar/LinkBubble.native.js.map +1 -0
  73. package/dist/cjs/toolbar/LinkDialog.cjs +138 -0
  74. package/dist/cjs/toolbar/LinkDialog.native.js +146 -0
  75. package/dist/cjs/toolbar/LinkDialog.native.js.map +1 -0
  76. package/dist/cjs/toolbar/ListPicker.cjs +117 -0
  77. package/dist/cjs/toolbar/ListPicker.native.js +124 -0
  78. package/dist/cjs/toolbar/ListPicker.native.js.map +1 -0
  79. package/dist/cjs/toolbar/MoreDropdown.cjs +201 -0
  80. package/dist/cjs/toolbar/MoreDropdown.native.js +224 -0
  81. package/dist/cjs/toolbar/MoreDropdown.native.js.map +1 -0
  82. package/dist/cjs/toolbar/ResizeHandle.cjs +105 -0
  83. package/dist/cjs/toolbar/ResizeHandle.native.js +109 -0
  84. package/dist/cjs/toolbar/ResizeHandle.native.js.map +1 -0
  85. package/dist/cjs/toolbar/StatusBar.cjs +91 -0
  86. package/dist/cjs/toolbar/StatusBar.native.js +100 -0
  87. package/dist/cjs/toolbar/StatusBar.native.js.map +1 -0
  88. package/dist/cjs/toolbar/TableBubble.cjs +232 -0
  89. package/dist/cjs/toolbar/TableBubble.native.js +273 -0
  90. package/dist/cjs/toolbar/TableBubble.native.js.map +1 -0
  91. package/dist/cjs/toolbar/ToolbarButton.cjs +105 -0
  92. package/dist/cjs/toolbar/ToolbarButton.native.js +97 -0
  93. package/dist/cjs/toolbar/ToolbarButton.native.js.map +1 -0
  94. package/dist/cjs/toolbar/ToolbarGroup.cjs +41 -0
  95. package/dist/cjs/toolbar/ToolbarGroup.native.js +45 -0
  96. package/dist/cjs/toolbar/ToolbarGroup.native.js.map +1 -0
  97. package/dist/cjs/toolbar/icons.cjs +601 -0
  98. package/dist/cjs/toolbar/icons.native.js +165 -0
  99. package/dist/cjs/toolbar/icons.native.js.map +1 -0
  100. package/dist/cjs/toolbar/shortcuts.cjs +62 -0
  101. package/dist/cjs/toolbar/shortcuts.native.js +66 -0
  102. package/dist/cjs/toolbar/shortcuts.native.js.map +1 -0
  103. package/dist/cjs/toolbar/useHorizontalScroll.cjs +250 -0
  104. package/dist/cjs/toolbar/useHorizontalScroll.native.js +260 -0
  105. package/dist/cjs/toolbar/useHorizontalScroll.native.js.map +1 -0
  106. package/dist/cjs/types.cjs +56 -0
  107. package/dist/cjs/types.native.js +59 -0
  108. package/dist/cjs/types.native.js.map +1 -0
  109. package/dist/esm/RichEditor.mjs +107 -0
  110. package/dist/esm/RichEditor.mjs.map +1 -0
  111. package/dist/esm/RichEditor.native.js +92 -0
  112. package/dist/esm/RichEditor.native.js.map +1 -0
  113. package/dist/esm/RichEditor.stories.mjs +291 -0
  114. package/dist/esm/RichEditor.stories.mjs.map +1 -0
  115. package/dist/esm/RichEditor.stories.native.js +303 -0
  116. package/dist/esm/RichEditor.stories.native.js.map +1 -0
  117. package/dist/esm/RichTextEditor/index.mjs +123 -0
  118. package/dist/esm/RichTextEditor/index.mjs.map +1 -0
  119. package/dist/esm/RichTextEditor/index.native.js +132 -0
  120. package/dist/esm/RichTextEditor/index.native.js.map +1 -0
  121. package/dist/esm/constants.mjs +108 -0
  122. package/dist/esm/constants.mjs.map +1 -0
  123. package/dist/esm/constants.native.js +108 -0
  124. package/dist/esm/constants.native.js.map +1 -0
  125. package/dist/esm/context.mjs +8 -0
  126. package/dist/esm/context.mjs.map +1 -0
  127. package/dist/esm/context.native.js +8 -0
  128. package/dist/esm/context.native.js.map +1 -0
  129. package/dist/esm/editor/BlockDragHandle.mjs +112 -0
  130. package/dist/esm/editor/BlockDragHandle.mjs.map +1 -0
  131. package/dist/esm/editor/BlockDragHandle.native.js +114 -0
  132. package/dist/esm/editor/BlockDragHandle.native.js.map +1 -0
  133. package/dist/esm/editor/MarkdownPaste.mjs +40 -0
  134. package/dist/esm/editor/MarkdownPaste.mjs.map +1 -0
  135. package/dist/esm/editor/MarkdownPaste.native.js +40 -0
  136. package/dist/esm/editor/MarkdownPaste.native.js.map +1 -0
  137. package/dist/esm/editor/SlashCommands.mjs +333 -0
  138. package/dist/esm/editor/SlashCommands.mjs.map +1 -0
  139. package/dist/esm/editor/SlashCommands.native.js +385 -0
  140. package/dist/esm/editor/SlashCommands.native.js.map +1 -0
  141. package/dist/esm/editor/TentapEditor.native.js +214 -0
  142. package/dist/esm/editor/TentapEditor.native.js.map +1 -0
  143. package/dist/esm/editor/TiptapEditor.mjs +542 -0
  144. package/dist/esm/editor/TiptapEditor.mjs.map +1 -0
  145. package/dist/esm/editor/TiptapEditor.native.js +622 -0
  146. package/dist/esm/editor/TiptapEditor.native.js.map +1 -0
  147. package/dist/esm/editor/editorStyles.mjs +247 -0
  148. package/dist/esm/editor/editorStyles.mjs.map +1 -0
  149. package/dist/esm/editor/editorStyles.native.js +248 -0
  150. package/dist/esm/editor/editorStyles.native.js.map +1 -0
  151. package/dist/esm/editor/index.mjs +5 -0
  152. package/dist/esm/editor/index.mjs.map +1 -0
  153. package/dist/esm/editor/index.native.js +5 -0
  154. package/dist/esm/editor/index.native.js.map +1 -0
  155. package/dist/esm/editor/types.mjs +29 -0
  156. package/dist/esm/editor/types.mjs.map +1 -0
  157. package/dist/esm/editor/types.native.js +29 -0
  158. package/dist/esm/editor/types.native.js.map +1 -0
  159. package/dist/esm/editor/useEditorState.mjs +102 -0
  160. package/dist/esm/editor/useEditorState.mjs.map +1 -0
  161. package/dist/esm/editor/useEditorState.native.js +105 -0
  162. package/dist/esm/editor/useEditorState.native.js.map +1 -0
  163. package/dist/esm/index.mjs +4 -0
  164. package/dist/esm/index.mjs.map +1 -0
  165. package/dist/esm/index.native.js +4 -0
  166. package/dist/esm/index.native.js.map +1 -0
  167. package/dist/esm/styled.mjs +144 -0
  168. package/dist/esm/styled.mjs.map +1 -0
  169. package/dist/esm/styled.native.js +153 -0
  170. package/dist/esm/styled.native.js.map +1 -0
  171. package/dist/esm/toolbar/BubbleToolbar.mjs +105 -0
  172. package/dist/esm/toolbar/BubbleToolbar.mjs.map +1 -0
  173. package/dist/esm/toolbar/BubbleToolbar.native.js +131 -0
  174. package/dist/esm/toolbar/BubbleToolbar.native.js.map +1 -0
  175. package/dist/esm/toolbar/CodeBlockBubble.mjs +186 -0
  176. package/dist/esm/toolbar/CodeBlockBubble.mjs.map +1 -0
  177. package/dist/esm/toolbar/CodeBlockBubble.native.js +200 -0
  178. package/dist/esm/toolbar/CodeBlockBubble.native.js.map +1 -0
  179. package/dist/esm/toolbar/ColorPicker.mjs +191 -0
  180. package/dist/esm/toolbar/ColorPicker.mjs.map +1 -0
  181. package/dist/esm/toolbar/ColorPicker.native.js +205 -0
  182. package/dist/esm/toolbar/ColorPicker.native.js.map +1 -0
  183. package/dist/esm/toolbar/FixedToolbar.mjs +196 -0
  184. package/dist/esm/toolbar/FixedToolbar.mjs.map +1 -0
  185. package/dist/esm/toolbar/FixedToolbar.native.js +294 -0
  186. package/dist/esm/toolbar/FixedToolbar.native.js.map +1 -0
  187. package/dist/esm/toolbar/HeadingPicker.mjs +133 -0
  188. package/dist/esm/toolbar/HeadingPicker.mjs.map +1 -0
  189. package/dist/esm/toolbar/HeadingPicker.native.js +139 -0
  190. package/dist/esm/toolbar/HeadingPicker.native.js.map +1 -0
  191. package/dist/esm/toolbar/ImageBubble.mjs +131 -0
  192. package/dist/esm/toolbar/ImageBubble.mjs.map +1 -0
  193. package/dist/esm/toolbar/ImageBubble.native.js +137 -0
  194. package/dist/esm/toolbar/ImageBubble.native.js.map +1 -0
  195. package/dist/esm/toolbar/ImageDialog.mjs +90 -0
  196. package/dist/esm/toolbar/ImageDialog.mjs.map +1 -0
  197. package/dist/esm/toolbar/ImageDialog.native.js +94 -0
  198. package/dist/esm/toolbar/ImageDialog.native.js.map +1 -0
  199. package/dist/esm/toolbar/LinkBubble.mjs +170 -0
  200. package/dist/esm/toolbar/LinkBubble.mjs.map +1 -0
  201. package/dist/esm/toolbar/LinkBubble.native.js +176 -0
  202. package/dist/esm/toolbar/LinkBubble.native.js.map +1 -0
  203. package/dist/esm/toolbar/LinkDialog.mjs +112 -0
  204. package/dist/esm/toolbar/LinkDialog.mjs.map +1 -0
  205. package/dist/esm/toolbar/LinkDialog.native.js +117 -0
  206. package/dist/esm/toolbar/LinkDialog.native.js.map +1 -0
  207. package/dist/esm/toolbar/ListPicker.mjs +92 -0
  208. package/dist/esm/toolbar/ListPicker.mjs.map +1 -0
  209. package/dist/esm/toolbar/ListPicker.native.js +96 -0
  210. package/dist/esm/toolbar/ListPicker.native.js.map +1 -0
  211. package/dist/esm/toolbar/MoreDropdown.mjs +176 -0
  212. package/dist/esm/toolbar/MoreDropdown.mjs.map +1 -0
  213. package/dist/esm/toolbar/MoreDropdown.native.js +196 -0
  214. package/dist/esm/toolbar/MoreDropdown.native.js.map +1 -0
  215. package/dist/esm/toolbar/ResizeHandle.mjs +80 -0
  216. package/dist/esm/toolbar/ResizeHandle.mjs.map +1 -0
  217. package/dist/esm/toolbar/ResizeHandle.native.js +81 -0
  218. package/dist/esm/toolbar/ResizeHandle.native.js.map +1 -0
  219. package/dist/esm/toolbar/StatusBar.mjs +66 -0
  220. package/dist/esm/toolbar/StatusBar.mjs.map +1 -0
  221. package/dist/esm/toolbar/StatusBar.native.js +72 -0
  222. package/dist/esm/toolbar/StatusBar.native.js.map +1 -0
  223. package/dist/esm/toolbar/TableBubble.mjs +207 -0
  224. package/dist/esm/toolbar/TableBubble.mjs.map +1 -0
  225. package/dist/esm/toolbar/TableBubble.native.js +245 -0
  226. package/dist/esm/toolbar/TableBubble.native.js.map +1 -0
  227. package/dist/esm/toolbar/ToolbarButton.mjs +79 -0
  228. package/dist/esm/toolbar/ToolbarButton.mjs.map +1 -0
  229. package/dist/esm/toolbar/ToolbarButton.native.js +68 -0
  230. package/dist/esm/toolbar/ToolbarButton.native.js.map +1 -0
  231. package/dist/esm/toolbar/ToolbarGroup.mjs +16 -0
  232. package/dist/esm/toolbar/ToolbarGroup.mjs.map +1 -0
  233. package/dist/esm/toolbar/ToolbarGroup.native.js +17 -0
  234. package/dist/esm/toolbar/ToolbarGroup.native.js.map +1 -0
  235. package/dist/esm/toolbar/icons.mjs +554 -0
  236. package/dist/esm/toolbar/icons.mjs.map +1 -0
  237. package/dist/esm/toolbar/icons.native.js +115 -0
  238. package/dist/esm/toolbar/icons.native.js.map +1 -0
  239. package/dist/esm/toolbar/shortcuts.mjs +36 -0
  240. package/dist/esm/toolbar/shortcuts.mjs.map +1 -0
  241. package/dist/esm/toolbar/shortcuts.native.js +37 -0
  242. package/dist/esm/toolbar/shortcuts.native.js.map +1 -0
  243. package/dist/esm/toolbar/useHorizontalScroll.mjs +223 -0
  244. package/dist/esm/toolbar/useHorizontalScroll.mjs.map +1 -0
  245. package/dist/esm/toolbar/useHorizontalScroll.native.js +230 -0
  246. package/dist/esm/toolbar/useHorizontalScroll.native.js.map +1 -0
  247. package/dist/esm/types.mjs +31 -0
  248. package/dist/esm/types.mjs.map +1 -0
  249. package/dist/esm/types.native.js +31 -0
  250. package/dist/esm/types.native.js.map +1 -0
  251. package/dist/jsx/RichEditor.mjs +107 -0
  252. package/dist/jsx/RichEditor.mjs.map +1 -0
  253. package/dist/jsx/RichEditor.native.js +120 -0
  254. package/dist/jsx/RichEditor.native.js.map +1 -0
  255. package/dist/jsx/RichEditor.stories.mjs +291 -0
  256. package/dist/jsx/RichEditor.stories.mjs.map +1 -0
  257. package/dist/jsx/RichEditor.stories.native.js +342 -0
  258. package/dist/jsx/RichEditor.stories.native.js.map +1 -0
  259. package/dist/jsx/RichTextEditor/index.mjs +123 -0
  260. package/dist/jsx/RichTextEditor/index.mjs.map +1 -0
  261. package/dist/jsx/RichTextEditor/index.native.js +160 -0
  262. package/dist/jsx/RichTextEditor/index.native.js.map +1 -0
  263. package/dist/jsx/constants.mjs +108 -0
  264. package/dist/jsx/constants.mjs.map +1 -0
  265. package/dist/jsx/constants.native.js +138 -0
  266. package/dist/jsx/constants.native.js.map +1 -0
  267. package/dist/jsx/context.mjs +8 -0
  268. package/dist/jsx/context.mjs.map +1 -0
  269. package/dist/jsx/context.native.js +36 -0
  270. package/dist/jsx/context.native.js.map +1 -0
  271. package/dist/jsx/editor/BlockDragHandle.mjs +112 -0
  272. package/dist/jsx/editor/BlockDragHandle.mjs.map +1 -0
  273. package/dist/jsx/editor/BlockDragHandle.native.js +142 -0
  274. package/dist/jsx/editor/BlockDragHandle.native.js.map +1 -0
  275. package/dist/jsx/editor/MarkdownPaste.mjs +40 -0
  276. package/dist/jsx/editor/MarkdownPaste.mjs.map +1 -0
  277. package/dist/jsx/editor/MarkdownPaste.native.js +68 -0
  278. package/dist/jsx/editor/MarkdownPaste.native.js.map +1 -0
  279. package/dist/jsx/editor/SlashCommands.mjs +333 -0
  280. package/dist/jsx/editor/SlashCommands.mjs.map +1 -0
  281. package/dist/jsx/editor/SlashCommands.native.js +424 -0
  282. package/dist/jsx/editor/SlashCommands.native.js.map +1 -0
  283. package/dist/jsx/editor/TentapEditor.native.js +242 -0
  284. package/dist/jsx/editor/TentapEditor.native.js.map +1 -0
  285. package/dist/jsx/editor/TiptapEditor.mjs +542 -0
  286. package/dist/jsx/editor/TiptapEditor.mjs.map +1 -0
  287. package/dist/jsx/editor/TiptapEditor.native.js +661 -0
  288. package/dist/jsx/editor/TiptapEditor.native.js.map +1 -0
  289. package/dist/jsx/editor/editorStyles.mjs +247 -0
  290. package/dist/jsx/editor/editorStyles.mjs.map +1 -0
  291. package/dist/jsx/editor/editorStyles.native.js +276 -0
  292. package/dist/jsx/editor/editorStyles.native.js.map +1 -0
  293. package/dist/jsx/editor/index.mjs +5 -0
  294. package/dist/jsx/editor/index.mjs.map +1 -0
  295. package/dist/jsx/editor/index.native.js +36 -0
  296. package/dist/jsx/editor/index.native.js.map +1 -0
  297. package/dist/jsx/editor/types.mjs +29 -0
  298. package/dist/jsx/editor/types.mjs.map +1 -0
  299. package/dist/jsx/editor/types.native.js +57 -0
  300. package/dist/jsx/editor/types.native.js.map +1 -0
  301. package/dist/jsx/editor/useEditorState.mjs +102 -0
  302. package/dist/jsx/editor/useEditorState.mjs.map +1 -0
  303. package/dist/jsx/editor/useEditorState.native.js +135 -0
  304. package/dist/jsx/editor/useEditorState.native.js.map +1 -0
  305. package/dist/jsx/index.js +4 -0
  306. package/dist/jsx/index.js.map +1 -0
  307. package/dist/jsx/index.mjs +4 -0
  308. package/dist/jsx/index.mjs.map +1 -0
  309. package/dist/jsx/index.native.js +33 -0
  310. package/dist/jsx/index.native.js.map +1 -0
  311. package/dist/jsx/styled.mjs +144 -0
  312. package/dist/jsx/styled.mjs.map +1 -0
  313. package/dist/jsx/styled.native.js +185 -0
  314. package/dist/jsx/styled.native.js.map +1 -0
  315. package/dist/jsx/toolbar/BubbleToolbar.mjs +105 -0
  316. package/dist/jsx/toolbar/BubbleToolbar.mjs.map +1 -0
  317. package/dist/jsx/toolbar/BubbleToolbar.native.js +159 -0
  318. package/dist/jsx/toolbar/BubbleToolbar.native.js.map +1 -0
  319. package/dist/jsx/toolbar/CodeBlockBubble.mjs +186 -0
  320. package/dist/jsx/toolbar/CodeBlockBubble.mjs.map +1 -0
  321. package/dist/jsx/toolbar/CodeBlockBubble.native.js +228 -0
  322. package/dist/jsx/toolbar/CodeBlockBubble.native.js.map +1 -0
  323. package/dist/jsx/toolbar/ColorPicker.mjs +191 -0
  324. package/dist/jsx/toolbar/ColorPicker.mjs.map +1 -0
  325. package/dist/jsx/toolbar/ColorPicker.native.js +234 -0
  326. package/dist/jsx/toolbar/ColorPicker.native.js.map +1 -0
  327. package/dist/jsx/toolbar/FixedToolbar.mjs +196 -0
  328. package/dist/jsx/toolbar/FixedToolbar.mjs.map +1 -0
  329. package/dist/jsx/toolbar/FixedToolbar.native.js +322 -0
  330. package/dist/jsx/toolbar/FixedToolbar.native.js.map +1 -0
  331. package/dist/jsx/toolbar/HeadingPicker.mjs +133 -0
  332. package/dist/jsx/toolbar/HeadingPicker.mjs.map +1 -0
  333. package/dist/jsx/toolbar/HeadingPicker.native.js +167 -0
  334. package/dist/jsx/toolbar/HeadingPicker.native.js.map +1 -0
  335. package/dist/jsx/toolbar/ImageBubble.mjs +131 -0
  336. package/dist/jsx/toolbar/ImageBubble.mjs.map +1 -0
  337. package/dist/jsx/toolbar/ImageBubble.native.js +165 -0
  338. package/dist/jsx/toolbar/ImageBubble.native.js.map +1 -0
  339. package/dist/jsx/toolbar/ImageDialog.mjs +90 -0
  340. package/dist/jsx/toolbar/ImageDialog.mjs.map +1 -0
  341. package/dist/jsx/toolbar/ImageDialog.native.js +122 -0
  342. package/dist/jsx/toolbar/ImageDialog.native.js.map +1 -0
  343. package/dist/jsx/toolbar/LinkBubble.mjs +170 -0
  344. package/dist/jsx/toolbar/LinkBubble.mjs.map +1 -0
  345. package/dist/jsx/toolbar/LinkBubble.native.js +204 -0
  346. package/dist/jsx/toolbar/LinkBubble.native.js.map +1 -0
  347. package/dist/jsx/toolbar/LinkDialog.mjs +112 -0
  348. package/dist/jsx/toolbar/LinkDialog.mjs.map +1 -0
  349. package/dist/jsx/toolbar/LinkDialog.native.js +146 -0
  350. package/dist/jsx/toolbar/LinkDialog.native.js.map +1 -0
  351. package/dist/jsx/toolbar/ListPicker.mjs +92 -0
  352. package/dist/jsx/toolbar/ListPicker.mjs.map +1 -0
  353. package/dist/jsx/toolbar/ListPicker.native.js +124 -0
  354. package/dist/jsx/toolbar/ListPicker.native.js.map +1 -0
  355. package/dist/jsx/toolbar/MoreDropdown.mjs +176 -0
  356. package/dist/jsx/toolbar/MoreDropdown.mjs.map +1 -0
  357. package/dist/jsx/toolbar/MoreDropdown.native.js +224 -0
  358. package/dist/jsx/toolbar/MoreDropdown.native.js.map +1 -0
  359. package/dist/jsx/toolbar/ResizeHandle.mjs +80 -0
  360. package/dist/jsx/toolbar/ResizeHandle.mjs.map +1 -0
  361. package/dist/jsx/toolbar/ResizeHandle.native.js +109 -0
  362. package/dist/jsx/toolbar/ResizeHandle.native.js.map +1 -0
  363. package/dist/jsx/toolbar/StatusBar.mjs +66 -0
  364. package/dist/jsx/toolbar/StatusBar.mjs.map +1 -0
  365. package/dist/jsx/toolbar/StatusBar.native.js +100 -0
  366. package/dist/jsx/toolbar/StatusBar.native.js.map +1 -0
  367. package/dist/jsx/toolbar/TableBubble.mjs +207 -0
  368. package/dist/jsx/toolbar/TableBubble.mjs.map +1 -0
  369. package/dist/jsx/toolbar/TableBubble.native.js +273 -0
  370. package/dist/jsx/toolbar/TableBubble.native.js.map +1 -0
  371. package/dist/jsx/toolbar/ToolbarButton.mjs +79 -0
  372. package/dist/jsx/toolbar/ToolbarButton.mjs.map +1 -0
  373. package/dist/jsx/toolbar/ToolbarButton.native.js +97 -0
  374. package/dist/jsx/toolbar/ToolbarButton.native.js.map +1 -0
  375. package/dist/jsx/toolbar/ToolbarGroup.mjs +16 -0
  376. package/dist/jsx/toolbar/ToolbarGroup.mjs.map +1 -0
  377. package/dist/jsx/toolbar/ToolbarGroup.native.js +45 -0
  378. package/dist/jsx/toolbar/ToolbarGroup.native.js.map +1 -0
  379. package/dist/jsx/toolbar/icons.mjs +554 -0
  380. package/dist/jsx/toolbar/icons.mjs.map +1 -0
  381. package/dist/jsx/toolbar/icons.native.js +165 -0
  382. package/dist/jsx/toolbar/icons.native.js.map +1 -0
  383. package/dist/jsx/toolbar/shortcuts.mjs +36 -0
  384. package/dist/jsx/toolbar/shortcuts.mjs.map +1 -0
  385. package/dist/jsx/toolbar/shortcuts.native.js +66 -0
  386. package/dist/jsx/toolbar/shortcuts.native.js.map +1 -0
  387. package/dist/jsx/toolbar/useHorizontalScroll.mjs +223 -0
  388. package/dist/jsx/toolbar/useHorizontalScroll.mjs.map +1 -0
  389. package/dist/jsx/toolbar/useHorizontalScroll.native.js +260 -0
  390. package/dist/jsx/toolbar/useHorizontalScroll.native.js.map +1 -0
  391. package/dist/jsx/types.mjs +31 -0
  392. package/dist/jsx/types.mjs.map +1 -0
  393. package/dist/jsx/types.native.js +59 -0
  394. package/dist/jsx/types.native.js.map +1 -0
  395. package/package.json +117 -0
  396. package/src/RichEditor.native.tsx +161 -0
  397. package/src/RichEditor.stories.tsx +324 -0
  398. package/src/RichEditor.tsx +185 -0
  399. package/src/RichTextEditor/index.tsx +245 -0
  400. package/src/RichTextEditor/richTextEditor.spec.tsx +239 -0
  401. package/src/constants.ts +100 -0
  402. package/src/context.spec.ts +9 -0
  403. package/src/context.ts +16 -0
  404. package/src/editor/BlockDragHandle.ts +141 -0
  405. package/src/editor/MarkdownPaste.ts +50 -0
  406. package/src/editor/SlashCommands.tsx +357 -0
  407. package/src/editor/TentapEditor.native.tsx +269 -0
  408. package/src/editor/TiptapEditor.tsx +616 -0
  409. package/src/editor/editorStyles.spec.ts +24 -0
  410. package/src/editor/editorStyles.ts +260 -0
  411. package/src/editor/index.ts +10 -0
  412. package/src/editor/tentapEditor.spec.ts +125 -0
  413. package/src/editor/tiptapEditor.spec.tsx +169 -0
  414. package/src/editor/types.ts +142 -0
  415. package/src/editor/useEditorState.spec.ts +93 -0
  416. package/src/editor/useEditorState.ts +125 -0
  417. package/src/exports.spec.ts +128 -0
  418. package/src/index.ts +13 -0
  419. package/src/integration.spec.tsx +430 -0
  420. package/src/richEditor.spec.tsx +169 -0
  421. package/src/styled.spec.tsx +42 -0
  422. package/src/styled.ts +177 -0
  423. package/src/toolbar/BubbleToolbar.tsx +151 -0
  424. package/src/toolbar/CodeBlockBubble.tsx +141 -0
  425. package/src/toolbar/ColorPicker.tsx +211 -0
  426. package/src/toolbar/FixedToolbar.native.tsx +381 -0
  427. package/src/toolbar/FixedToolbar.tsx +252 -0
  428. package/src/toolbar/HeadingPicker.tsx +169 -0
  429. package/src/toolbar/ImageBubble.tsx +126 -0
  430. package/src/toolbar/ImageDialog.tsx +93 -0
  431. package/src/toolbar/LinkBubble.tsx +166 -0
  432. package/src/toolbar/LinkDialog.tsx +124 -0
  433. package/src/toolbar/ListPicker.tsx +121 -0
  434. package/src/toolbar/MoreDropdown.tsx +185 -0
  435. package/src/toolbar/ResizeHandle.tsx +80 -0
  436. package/src/toolbar/StatusBar.tsx +76 -0
  437. package/src/toolbar/TableBubble.tsx +197 -0
  438. package/src/toolbar/ToolbarButton.native.tsx +105 -0
  439. package/src/toolbar/ToolbarButton.tsx +114 -0
  440. package/src/toolbar/ToolbarGroup.tsx +38 -0
  441. package/src/toolbar/bubbleToolbar.spec.tsx +93 -0
  442. package/src/toolbar/fixedToolbar.spec.tsx +127 -0
  443. package/src/toolbar/icons.native.tsx +112 -0
  444. package/src/toolbar/icons.tsx +417 -0
  445. package/src/toolbar/shortcuts.ts +42 -0
  446. package/src/toolbar/toolbarPrimitives.spec.tsx +118 -0
  447. package/src/toolbar/toolbarSubComponents.spec.tsx +115 -0
  448. package/src/toolbar/useHorizontalScroll.tsx +270 -0
  449. package/src/types.spec.ts +102 -0
  450. package/src/types.ts +217 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * RichTextEditor with form integration
3
+ *
4
+ * Three-branch architecture following field architecture standard:
5
+ * - Branch 1: Skeleton loading state
6
+ * - Branch 2: Standalone (no form context)
7
+ * - Branch 3: Form-integrated (with TanStack Form)
8
+ *
9
+ * Wraps RichEditor compound component with FieldLayout and validation.
10
+ * Uses custom empty check for '<p></p>' which is Tiptap's empty state.
11
+ */
12
+ import type { DeepKeys, DeepValue } from "@tanstack/form-core";
13
+ import type React from "react";
14
+ import { useCallback, useRef, useState } from "react";
15
+ import type { LabelProps, SizeTokens } from "tamagui";
16
+ import { YStack } from "tamagui";
17
+
18
+ import {
19
+ Field,
20
+ FieldLayout,
21
+ Skeleton,
22
+ getFieldError,
23
+ mergeFieldHandler,
24
+ useFormField,
25
+ useResolvedValidators,
26
+ type FormFieldProps,
27
+ type FieldComponentProps,
28
+ type Validator,
29
+ } from "@multiplatform.one/forms";
30
+ import type { ToolbarSection } from "../types";
31
+ import type { RichEditorRef } from "../types";
32
+ import { RichEditor } from "../RichEditor";
33
+
34
+ // ---------------------------------------------------------------------------
35
+ // Custom empty check for rich text
36
+ // ---------------------------------------------------------------------------
37
+
38
+ /**
39
+ * Rich text empty check: treats null, undefined, empty string, and
40
+ * Tiptap's default empty paragraph as empty values.
41
+ */
42
+ const richTextIsEmpty = (v: unknown): boolean => !v || v === "<p></p>" || v === "";
43
+
44
+ // ---------------------------------------------------------------------------
45
+ // Types
46
+ // ---------------------------------------------------------------------------
47
+
48
+ export type RichTextEditorProps<
49
+ TParentData = any,
50
+ TName extends DeepKeys<TParentData> = any,
51
+ TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined,
52
+ TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
53
+ TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
54
+ > = Omit<
55
+ FormFieldProps<TParentData, TName, TFieldValidator, TFormValidator, TData>,
56
+ "children" | "field"
57
+ > &
58
+ Partial<
59
+ Omit<
60
+ FieldComponentProps<TParentData, TName, TFieldValidator, TFormValidator, TData>,
61
+ "children"
62
+ >
63
+ > & {
64
+ value?: string;
65
+ defaultValue?: string;
66
+ onChange?: (value: string) => void;
67
+ onBlur?: (...args: any[]) => void;
68
+ placeholder?: string;
69
+ disabled?: boolean;
70
+ readOnly?: boolean;
71
+ minHeight?: number;
72
+ maxHeight?: number;
73
+ label?: React.ReactNode;
74
+ labelProps?: Omit<LabelProps, "htmlFor" | "ref">;
75
+ helperText?: string;
76
+ error?: string | boolean;
77
+ required?: boolean;
78
+ size?: SizeTokens;
79
+ /** Show the formatting toolbar (default: true) */
80
+ showToolbar?: boolean;
81
+ /** Use compact sizing for toolbar (default: false) */
82
+ compact?: boolean;
83
+ /** Show the bubble toolbar on text selection (default: false, web only) */
84
+ showBubbleToolbar?: boolean;
85
+ /** Toolbar sections to display (shows all when omitted) */
86
+ sections?: ToolbarSection[];
87
+ /** When true, renders a skeleton placeholder instead of the editor */
88
+ skeleton?: boolean;
89
+ };
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // RichTextEditor Component
93
+ // ---------------------------------------------------------------------------
94
+
95
+ export function RichTextEditor<
96
+ TParentData,
97
+ TName extends DeepKeys<TParentData>,
98
+ TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined,
99
+ TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
100
+ TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>,
101
+ >(props: RichTextEditorProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) {
102
+ const {
103
+ defaultValue = "",
104
+ form,
105
+ placeholder = "Write something...",
106
+ disabled,
107
+ readOnly,
108
+ minHeight = 150,
109
+ maxHeight,
110
+ mode,
111
+ name,
112
+ preserveValue,
113
+ validators,
114
+ label,
115
+ labelProps,
116
+ error: errorProp,
117
+ helperText,
118
+ required,
119
+ size,
120
+ value: controlledValue,
121
+ onChange,
122
+ onBlur,
123
+ showToolbar = true,
124
+ compact = false,
125
+ showBubbleToolbar = false,
126
+ sections,
127
+ skeleton,
128
+ ..._restProps
129
+ } = props;
130
+
131
+ const { resolvedForm, knobProps, id } = useFormField({ form });
132
+ const resolvedValidators = useResolvedValidators(
133
+ required,
134
+ validators,
135
+ label,
136
+ name,
137
+ richTextIsEmpty,
138
+ );
139
+ const editorRef = useRef<RichEditorRef>(null);
140
+ const [internalValue, setInternalValue] = useState(controlledValue ?? defaultValue);
141
+
142
+ const value = controlledValue ?? internalValue;
143
+
144
+ const handleChange = useCallback(
145
+ (html: string) => {
146
+ setInternalValue(html);
147
+ onChange?.(html);
148
+ },
149
+ [onChange],
150
+ );
151
+
152
+ // ── Branch 1: Skeleton ──────────────────────────────────────────
153
+ if (skeleton) {
154
+ return (
155
+ <YStack gap="$2">
156
+ {label && <Skeleton variant="text" width="30%" height={14} />}
157
+ <Skeleton variant="rounded" width="100%" height={minHeight} />
158
+ </YStack>
159
+ );
160
+ }
161
+
162
+ // ── Shared editor renderer ──────────────────────────────────────
163
+ const renderEditor = (
164
+ currentValue: string,
165
+ onValueChange: (v: string) => void,
166
+ handleBlur?: () => void,
167
+ hasError?: boolean,
168
+ ) => {
169
+ return (
170
+ <RichEditor
171
+ ref={editorRef}
172
+ initialContent={currentValue}
173
+ onChange={(html) => onValueChange(html)}
174
+ onBlur={handleBlur}
175
+ placeholder={placeholder}
176
+ editable={!disabled && !readOnly}
177
+ minHeight={minHeight}
178
+ maxHeight={maxHeight}
179
+ showToolbar={showToolbar}
180
+ showBubbleToolbar={showBubbleToolbar}
181
+ sections={sections}
182
+ hasError={hasError}
183
+ size={size}
184
+ compact={compact}
185
+ />
186
+ );
187
+ };
188
+
189
+ // ── Branch 2: Standalone (no form context) ──────────────────────
190
+ if (!resolvedForm || !name) {
191
+ return (
192
+ <FieldLayout
193
+ id={id}
194
+ label={label}
195
+ labelProps={labelProps}
196
+ error={errorProp}
197
+ helperText={helperText}
198
+ required={required}
199
+ size={size}
200
+ knobProps={knobProps}
201
+ onBlur={onBlur}
202
+ >
203
+ {renderEditor(value, handleChange, onBlur as any, !!errorProp)}
204
+ </FieldLayout>
205
+ );
206
+ }
207
+
208
+ // ── Branch 3: Form-integrated ───────────────────────────────────
209
+ return (
210
+ <Field
211
+ defaultValue={defaultValue}
212
+ form={resolvedForm}
213
+ mode={mode}
214
+ name={name}
215
+ preserveValue={preserveValue}
216
+ validators={resolvedValidators}
217
+ >
218
+ {(field) => {
219
+ const resolvedError = getFieldError(field, errorProp);
220
+ const fieldValue = (field.state.value as string) ?? "";
221
+
222
+ return (
223
+ <FieldLayout
224
+ id={id}
225
+ label={label}
226
+ labelProps={labelProps}
227
+ error={resolvedError}
228
+ helperText={helperText}
229
+ required={required}
230
+ size={size}
231
+ knobProps={knobProps}
232
+ onBlur={mergeFieldHandler(field, "handleBlur", onBlur)}
233
+ >
234
+ {renderEditor(
235
+ fieldValue,
236
+ (v) => field.handleChange(v as any),
237
+ () => field.handleBlur(),
238
+ !!resolvedError,
239
+ )}
240
+ </FieldLayout>
241
+ );
242
+ }}
243
+ </Field>
244
+ );
245
+ }
@@ -0,0 +1,239 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Mocks -- must come before imports
5
+ // ---------------------------------------------------------------------------
6
+
7
+ vi.mock("@multiplatform.one/forms", () => {
8
+ return {
9
+ Field: ({ children, ...props }: any) => {
10
+ const field = {
11
+ state: { value: props.defaultValue ?? "", meta: { errors: [] } },
12
+ handleChange: vi.fn(),
13
+ handleBlur: vi.fn(),
14
+ };
15
+ return <div data-testid="tanstack-field">{children(field)}</div>;
16
+ },
17
+ FieldLayout: ({ children, label, error, ...props }: any) => (
18
+ <div
19
+ data-testid="field-layout"
20
+ data-label={label}
21
+ data-error={error || undefined}
22
+ data-skeleton={props.skeleton || undefined}
23
+ >
24
+ {children}
25
+ </div>
26
+ ),
27
+ Skeleton: ({ variant, width, height, ..._props }: any) => (
28
+ <div data-testid="skeleton" data-variant={variant} style={{ width, height }} />
29
+ ),
30
+ getFieldError: (field: any, propError: any) => {
31
+ const fieldError = field.state.meta.errors.length
32
+ ? String(field.state.meta.errors[0])
33
+ : undefined;
34
+ return propError ?? fieldError;
35
+ },
36
+ useFormField: ({ form }: any) => ({
37
+ resolvedForm: form || undefined,
38
+ knobProps: {
39
+ body: {},
40
+ borderRadius: { borderRadius: "$3", borderWidth: 1 },
41
+ elevation: undefined,
42
+ sizeToken: "$4",
43
+ outlined: false,
44
+ inputBackground: "$color2",
45
+ textAccentColor: "$color",
46
+ transition: undefined,
47
+ heading: {},
48
+ gap: { gap: "$2" },
49
+ },
50
+ id: "test-id",
51
+ }),
52
+ useResolvedValidators: (
53
+ required: boolean | undefined,
54
+ validators: any,
55
+ label: any,
56
+ name: any,
57
+ isEmpty?: (v: unknown) => boolean,
58
+ ) => {
59
+ if (!required) return validators;
60
+ const check = isEmpty || ((v: unknown) => v == null || v === "");
61
+ const requiredValidator = ({ value }: { value: unknown }) =>
62
+ check(value)
63
+ ? `${typeof label === "string" ? label : name || "Field"} is required`
64
+ : undefined;
65
+ if (!validators) return { onSubmit: requiredValidator };
66
+ return { ...validators, onSubmit: requiredValidator };
67
+ },
68
+ mergeFieldHandler: (field: any, name: string, handler: any) => {
69
+ return (...args: any[]) => {
70
+ (field[name] as Function)(...args);
71
+ handler?.(...args);
72
+ };
73
+ },
74
+ clampRadiusForLargeComponent: (radiusToken: string | undefined, maxTokenNum = 4) => {
75
+ if (!radiusToken) return "$3";
76
+ if (radiusToken === "$0") return 0;
77
+ if (typeof radiusToken === "string" && radiusToken.startsWith("$")) {
78
+ const num = Number.parseInt(radiusToken.slice(1), 10);
79
+ return num > maxTokenNum ? `$${maxTokenNum}` : radiusToken;
80
+ }
81
+ return radiusToken;
82
+ },
83
+ Button: (props: any) => <button>{props.children}</button>,
84
+ };
85
+ });
86
+
87
+ vi.mock("@multiplatform.one/components", () => ({
88
+ Tooltip: ({ children }: any) => children,
89
+ }));
90
+
91
+ vi.mock("@multiplatform.one/theme", () => ({
92
+ useResolvedKnobs: () => ({
93
+ knobProps: {
94
+ body: {},
95
+ borderRadius: { borderRadius: "$3", borderWidth: 1 },
96
+ elevation: undefined,
97
+ sizeToken: "$4",
98
+ outlined: false,
99
+ inputBackground: "$color2",
100
+ textAccentColor: "$color",
101
+ transition: undefined,
102
+ heading: {},
103
+ gap: { gap: "$2" },
104
+ },
105
+ control: {
106
+ hoverKnobProps: undefined,
107
+ pressKnobProps: undefined,
108
+ focusKnobProps: undefined,
109
+ focusVisibleKnobProps: undefined,
110
+ },
111
+ }),
112
+ }));
113
+
114
+ vi.mock("@tiptap/react/menus", () => ({
115
+ BubbleMenu: ({ children }: any) => <div data-testid="bubble-menu">{children}</div>,
116
+ }));
117
+
118
+ const mockEditor = {
119
+ isActive: vi.fn().mockReturnValue(false),
120
+ getAttributes: vi.fn().mockReturnValue({}),
121
+ can: vi.fn().mockReturnValue({ undo: () => false, redo: () => false }),
122
+ getHTML: vi.fn().mockReturnValue("<p></p>"),
123
+ getJSON: vi.fn().mockReturnValue({ type: "doc", content: [] }),
124
+ chain: vi.fn().mockReturnValue({
125
+ focus: vi.fn().mockReturnValue({
126
+ toggleBold: vi.fn().mockReturnValue({ run: vi.fn() }),
127
+ }),
128
+ }),
129
+ commands: {
130
+ setContent: vi.fn(),
131
+ focus: vi.fn(),
132
+ blur: vi.fn(),
133
+ },
134
+ setEditable: vi.fn(),
135
+ };
136
+
137
+ vi.mock("@tiptap/react", () => ({
138
+ useEditor: vi.fn().mockReturnValue(mockEditor),
139
+ EditorContent: ({ editor: _editor }: any) => <div data-testid="editor-content">Editor</div>,
140
+ }));
141
+
142
+ vi.mock("@tiptap/starter-kit", () => ({
143
+ default: { configure: vi.fn().mockReturnValue({}) },
144
+ }));
145
+ vi.mock("@tiptap/extension-underline", () => ({ default: {} }));
146
+ vi.mock("@tiptap/extension-link", () => ({
147
+ default: { configure: vi.fn().mockReturnValue({}) },
148
+ }));
149
+ vi.mock("@tiptap/extension-placeholder", () => ({
150
+ default: { configure: vi.fn().mockReturnValue({}) },
151
+ }));
152
+ vi.mock("@tiptap/extension-text-align", () => ({
153
+ default: { configure: vi.fn().mockReturnValue({}) },
154
+ }));
155
+ vi.mock("@tiptap/extension-color", () => ({ Color: {} }));
156
+ vi.mock("@tiptap/extension-text-style", () => ({ TextStyle: {} }));
157
+ vi.mock("@tiptap/extension-highlight", () => ({
158
+ Highlight: { configure: vi.fn().mockReturnValue({}) },
159
+ }));
160
+ vi.mock("@tiptap/extension-subscript", () => ({ Subscript: {} }));
161
+ vi.mock("@tiptap/extension-superscript", () => ({ Superscript: {} }));
162
+ vi.mock("@tiptap/extension-task-list", () => ({ default: {} }));
163
+ vi.mock("@tiptap/extension-task-item", () => ({
164
+ default: { configure: vi.fn().mockReturnValue({}) },
165
+ }));
166
+ vi.mock("@tiptap/extension-image", () => ({
167
+ default: { configure: vi.fn().mockReturnValue({}) },
168
+ }));
169
+
170
+ // ---------------------------------------------------------------------------
171
+ // Imports (after mocks)
172
+ // ---------------------------------------------------------------------------
173
+
174
+ import { renderWithProviders } from "@multiplatform.one/test-utils";
175
+
176
+ const { RichTextEditor } = await import("./index");
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // Tests
180
+ // ---------------------------------------------------------------------------
181
+
182
+ describe("RichTextEditor form-integrated field", () => {
183
+ it("renders skeleton loading state when skeleton={true}", () => {
184
+ const { getAllByTestId, queryByTestId } = renderWithProviders(
185
+ <RichTextEditor skeleton label="Content" />,
186
+ );
187
+ const skeletons = getAllByTestId("skeleton");
188
+ // Should render label skeleton + editor skeleton
189
+ expect(skeletons.length).toBe(2);
190
+ // Should NOT render the editor content
191
+ expect(queryByTestId("editor-content")).toBeNull();
192
+ });
193
+
194
+ it("renders standalone (Branch 2) without form context and manages internal state", () => {
195
+ const handleChange = vi.fn();
196
+ const { container } = renderWithProviders(
197
+ <RichTextEditor label="Content" onChange={handleChange} placeholder="Write something..." />,
198
+ );
199
+ // Should render FieldLayout wrapper
200
+ const fieldLayout = container.querySelector("[data-testid='field-layout']");
201
+ expect(fieldLayout).toBeTruthy();
202
+ // Should render the RichEditor inside
203
+ const editorContent = container.querySelector("[data-testid='editor-content']");
204
+ expect(editorContent).toBeTruthy();
205
+ });
206
+
207
+ it("renders form-integrated (Branch 3) when form and name are provided", () => {
208
+ const mockForm = { store: {} } as any;
209
+ const { getByTestId } = renderWithProviders(
210
+ <RichTextEditor form={mockForm} name="content" label="Content" required />,
211
+ );
212
+ // Should render the TanStack Field wrapper
213
+ const field = getByTestId("tanstack-field");
214
+ expect(field).toBeTruthy();
215
+ // Should render FieldLayout inside the field
216
+ const fieldLayout = getByTestId("field-layout");
217
+ expect(fieldLayout).toBeTruthy();
218
+ });
219
+
220
+ it("custom empty check recognizes '<p></p>' and '' as empty for required validation", () => {
221
+ // The custom isEmpty function should treat '<p></p>' and '' as empty
222
+ const isEmpty = (v: unknown) => !v || v === "<p></p>" || v === "";
223
+
224
+ expect(isEmpty("")).toBe(true);
225
+ expect(isEmpty("<p></p>")).toBe(true);
226
+ expect(isEmpty(null)).toBe(true);
227
+ expect(isEmpty(undefined)).toBe(true);
228
+ expect(isEmpty("<p>Hello</p>")).toBe(false);
229
+ expect(isEmpty("<h1>Title</h1>")).toBe(false);
230
+ });
231
+
232
+ it("passes showBubbleToolbar and sections props through to RichEditor", () => {
233
+ const { container } = renderWithProviders(
234
+ <RichTextEditor label="Content" showBubbleToolbar sections={["formatting", "list"]} />,
235
+ );
236
+ // Should render without error (props are passed through)
237
+ expect(container.firstChild).toBeTruthy();
238
+ });
239
+ });
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Shared constants for the rich text editor
3
+ */
4
+
5
+ import type { NativeCapability } from "./types";
6
+
7
+ // ===========================================================================
8
+ // Color Palettes
9
+ // ===========================================================================
10
+
11
+ export interface ColorEntry {
12
+ /** Display name for the color */
13
+ name: string;
14
+ /** Hex color value, or null for default/none */
15
+ value: string | null;
16
+ }
17
+
18
+ export const TEXT_COLORS: ColorEntry[] = [
19
+ { name: "Default", value: null },
20
+ { name: "Black", value: "#000000" },
21
+ { name: "Dark Gray", value: "#4a4a4a" },
22
+ { name: "Gray", value: "#9b9b9b" },
23
+ { name: "Red", value: "#e53935" },
24
+ { name: "Orange", value: "#fb8c00" },
25
+ { name: "Yellow", value: "#fdd835" },
26
+ { name: "Green", value: "#43a047" },
27
+ { name: "Blue", value: "#1e88e5" },
28
+ { name: "Purple", value: "#8e24aa" },
29
+ { name: "Pink", value: "#d81b60" },
30
+ ];
31
+
32
+ export const HIGHLIGHT_COLORS: ColorEntry[] = [
33
+ { name: "None", value: null },
34
+ { name: "Yellow", value: "#fff59d" },
35
+ { name: "Green", value: "#c8e6c9" },
36
+ { name: "Blue", value: "#bbdefb" },
37
+ { name: "Pink", value: "#f8bbd9" },
38
+ { name: "Purple", value: "#e1bee7" },
39
+ { name: "Orange", value: "#ffe0b2" },
40
+ { name: "Red", value: "#ffcdd2" },
41
+ { name: "Cyan", value: "#b2ebf2" },
42
+ ];
43
+
44
+ // ===========================================================================
45
+ // Native (10Tap) Supported Commands
46
+ // ===========================================================================
47
+
48
+ /**
49
+ * Maps each EditorCommand to whether 10Tap supports it via bridge extensions.
50
+ *
51
+ * Supported commands use actual bridge methods (ColorBridge, HighlightBridge,
52
+ * ImageBridge, TaskListBridge, etc.).
53
+ *
54
+ * Unsupported commands (subscript, superscript, textAlign, codeBlock,
55
+ * horizontalRule, clearFormatting) have no 10Tap bridge equivalent.
56
+ */
57
+ export const NATIVE_SUPPORTED_COMMANDS: NativeCapability = {
58
+ bold: true,
59
+ italic: true,
60
+ underline: true,
61
+ strike: true,
62
+ code: true,
63
+ subscript: false,
64
+ superscript: false,
65
+ heading1: true,
66
+ heading2: true,
67
+ heading3: true,
68
+ heading4: true,
69
+ heading5: true,
70
+ heading6: true,
71
+ paragraph: true,
72
+ bulletList: true,
73
+ orderedList: true,
74
+ taskList: true,
75
+ blockquote: true,
76
+ codeBlock: false,
77
+ link: true,
78
+ image: true,
79
+ undo: true,
80
+ redo: true,
81
+ alignLeft: false,
82
+ alignCenter: false,
83
+ alignRight: false,
84
+ alignJustify: false,
85
+ textColor: true,
86
+ highlight: true,
87
+ horizontalRule: false,
88
+ clearFormatting: false,
89
+ insertTable: false,
90
+ addColumnBefore: false,
91
+ addColumnAfter: false,
92
+ deleteColumn: false,
93
+ addRowBefore: false,
94
+ addRowAfter: false,
95
+ deleteRow: false,
96
+ deleteTable: false,
97
+ mergeCells: false,
98
+ splitCell: false,
99
+ toggleHeaderRow: false,
100
+ };
@@ -0,0 +1,9 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { RichEditorContext } from "./context";
3
+
4
+ describe("RichEditorContext", () => {
5
+ it("is a valid styled context with expected default values", () => {
6
+ expect(RichEditorContext).toBeDefined();
7
+ expect(RichEditorContext.Provider).toBeDefined();
8
+ });
9
+ });
package/src/context.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared context for the rich text editor compound component
3
+ */
4
+
5
+ import type { FontSizeTokens } from "tamagui";
6
+ import { createStyledContext } from "tamagui";
7
+
8
+ export const RichEditorContext = createStyledContext<{
9
+ size: FontSizeTokens;
10
+ compact: boolean;
11
+ disabled: boolean;
12
+ }>({
13
+ size: "$true" as FontSizeTokens,
14
+ compact: false,
15
+ disabled: false,
16
+ });