@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
package/src/styled.ts ADDED
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Shared styled components for the rich text editor
3
+ */
4
+
5
+ import { Separator, View, XStack, styled } from "tamagui";
6
+ import { RichEditorContext } from "./context";
7
+
8
+ // ===========================================================================
9
+ // EditorFrame
10
+ // ===========================================================================
11
+
12
+ export const EditorFrame = styled(View, {
13
+ name: "EditorFrame",
14
+ context: RichEditorContext,
15
+ borderWidth: 1,
16
+ borderColor: "$color7",
17
+ backgroundColor: "$color2",
18
+ overflow: "hidden",
19
+
20
+ variants: {
21
+ hasError: {
22
+ true: {
23
+ borderColor: "$red10",
24
+ },
25
+ },
26
+ size: {
27
+ "...size": (_val, { tokens: _tokens }) => {
28
+ return {};
29
+ },
30
+ },
31
+ compact: {
32
+ true: {},
33
+ false: {},
34
+ },
35
+ disabled: {
36
+ true: {
37
+ opacity: 0.5,
38
+ pointerEvents: "none",
39
+ },
40
+ },
41
+ } as const,
42
+ });
43
+
44
+ // ===========================================================================
45
+ // ToolbarFrame
46
+ // ===========================================================================
47
+
48
+ export const ToolbarFrame = styled(XStack, {
49
+ name: "ToolbarFrame",
50
+ context: RichEditorContext,
51
+ backgroundColor: "$color3",
52
+ borderBottomWidth: 1,
53
+ borderBottomColor: "$color6",
54
+ paddingVertical: "$1",
55
+ position: "relative",
56
+
57
+ variants: {
58
+ hasError: {
59
+ true: {
60
+ borderBottomColor: "$red10",
61
+ },
62
+ },
63
+ size: {
64
+ "...size": () => ({}),
65
+ },
66
+ compact: {
67
+ true: {},
68
+ false: {},
69
+ },
70
+ disabled: {
71
+ true: {},
72
+ false: {},
73
+ },
74
+ } as const,
75
+ });
76
+
77
+ // ===========================================================================
78
+ // ToolbarGroupFrame
79
+ // ===========================================================================
80
+
81
+ export const ToolbarGroupFrame = styled(XStack, {
82
+ name: "ToolbarGroupFrame",
83
+ context: RichEditorContext,
84
+ alignItems: "center",
85
+ gap: 2,
86
+
87
+ variants: {
88
+ size: {
89
+ "...size": () => ({}),
90
+ },
91
+ compact: {
92
+ true: {},
93
+ false: {},
94
+ },
95
+ disabled: {
96
+ true: {},
97
+ false: {},
98
+ },
99
+ } as const,
100
+ });
101
+
102
+ // ===========================================================================
103
+ // ToolbarSeparatorFrame
104
+ // ===========================================================================
105
+
106
+ export const ToolbarSeparatorFrame = styled(Separator, {
107
+ name: "ToolbarSeparatorFrame",
108
+ context: RichEditorContext,
109
+ vertical: true,
110
+ backgroundColor: "$color6",
111
+ width: 1,
112
+ height: 16,
113
+ marginHorizontal: "$2",
114
+
115
+ variants: {
116
+ size: {
117
+ "...size": () => ({}),
118
+ },
119
+ compact: {
120
+ true: {},
121
+ false: {},
122
+ },
123
+ disabled: {
124
+ true: {},
125
+ false: {},
126
+ },
127
+ } as const,
128
+ });
129
+
130
+ // ===========================================================================
131
+ // DropdownMenuItemFrame
132
+ // ===========================================================================
133
+
134
+ export const DropdownMenuItemFrame = styled(XStack, {
135
+ name: "DropdownMenuItemFrame",
136
+ context: RichEditorContext,
137
+ paddingHorizontal: "$3",
138
+ paddingVertical: "$2",
139
+ gap: "$2",
140
+ alignItems: "center",
141
+ cursor: "pointer",
142
+ borderRadius: "$2",
143
+
144
+ hoverStyle: {
145
+ backgroundColor: "$color4",
146
+ },
147
+
148
+ pressStyle: {
149
+ backgroundColor: "$color5",
150
+ },
151
+
152
+ focusVisibleStyle: {
153
+ backgroundColor: "$color4",
154
+ outlineColor: "$color8",
155
+ outlineStyle: "solid",
156
+ outlineWidth: 2,
157
+ },
158
+
159
+ variants: {
160
+ active: {
161
+ true: {
162
+ backgroundColor: "$color4",
163
+ },
164
+ },
165
+ size: {
166
+ "...size": () => ({}),
167
+ },
168
+ compact: {
169
+ true: {},
170
+ false: {},
171
+ },
172
+ disabled: {
173
+ true: {},
174
+ false: {},
175
+ },
176
+ } as const,
177
+ });
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Bubble toolbar for the rich text editor (web only)
3
+ *
4
+ * Uses Tiptap 3's BubbleMenu to show inline formatting controls
5
+ * when text is selected. Contains only inline formatting:
6
+ * Bold, Italic, Underline, Strike, Code, Subscript, Superscript,
7
+ * Text Color, Highlight, Link.
8
+ *
9
+ * No headings, lists, alignment -- those stay in the fixed toolbar.
10
+ * No native equivalent (10Tap does not support floating menus).
11
+ */
12
+
13
+ import type { Editor } from "@tiptap/react";
14
+ import { BubbleMenu } from "@tiptap/react/menus";
15
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
16
+ import { XStack } from "tamagui";
17
+ import type { EditorState, RichEditorRef } from "../types";
18
+ import { defaultEditorState } from "../types";
19
+ import { ToolbarButton } from "./ToolbarButton";
20
+ import {
21
+ BoldIcon,
22
+ ItalicIcon,
23
+ UnderlineIcon,
24
+ StrikeIcon,
25
+ SubscriptIcon,
26
+ SuperscriptIcon,
27
+ } from "./icons";
28
+ import { TextColorPicker, HighlightColorPicker } from "./ColorPicker";
29
+ import { LinkDialog } from "./LinkDialog";
30
+ import { SHORTCUTS } from "./shortcuts";
31
+
32
+ // ===========================================================================
33
+ // Types
34
+ // ===========================================================================
35
+
36
+ export interface BubbleToolbarProps {
37
+ /** Direct Tiptap editor instance (not through ref) */
38
+ editor: Editor | null;
39
+ /** Reference to the editor for executeCommand */
40
+ editorRef: React.RefObject<RichEditorRef | null>;
41
+ /** Current editor state */
42
+ state?: EditorState;
43
+ }
44
+
45
+ // ===========================================================================
46
+ // BubbleToolbar
47
+ // ===========================================================================
48
+
49
+ export function BubbleToolbar({
50
+ editor,
51
+ editorRef,
52
+ state = defaultEditorState,
53
+ }: BubbleToolbarProps) {
54
+ const { knobProps } = useResolvedKnobs();
55
+
56
+ if (!editor) return null;
57
+
58
+ return (
59
+ <BubbleMenu
60
+ editor={editor}
61
+ shouldShow={({ editor: e, from, to }) => {
62
+ if (from === to) return false;
63
+ if (e.isActive("codeBlock")) return false;
64
+ if (e.isActive("image")) return false;
65
+ return true;
66
+ }}
67
+ >
68
+ <XStack
69
+ backgroundColor="$background"
70
+ borderWidth={1}
71
+ borderColor="$borderColor"
72
+ borderRadius={knobProps.borderRadius.borderRadius}
73
+ padding="$1"
74
+ gap={2}
75
+ alignItems="center"
76
+ elevation={knobProps.elevation}
77
+ >
78
+ {/* Inline formatting only */}
79
+ <ToolbarButton
80
+ active={state.isBold}
81
+ onPress={() => editorRef.current?.executeCommand("bold")}
82
+ aria-label="Bold"
83
+ tooltip={SHORTCUTS.bold}
84
+ >
85
+ <BoldIcon>B</BoldIcon>
86
+ </ToolbarButton>
87
+
88
+ <ToolbarButton
89
+ active={state.isItalic}
90
+ onPress={() => editorRef.current?.executeCommand("italic")}
91
+ aria-label="Italic"
92
+ tooltip={SHORTCUTS.italic}
93
+ >
94
+ <ItalicIcon>I</ItalicIcon>
95
+ </ToolbarButton>
96
+
97
+ <ToolbarButton
98
+ active={state.isUnderline}
99
+ onPress={() => editorRef.current?.executeCommand("underline")}
100
+ aria-label="Underline"
101
+ tooltip={SHORTCUTS.underline}
102
+ >
103
+ <UnderlineIcon>U</UnderlineIcon>
104
+ </ToolbarButton>
105
+
106
+ <ToolbarButton
107
+ active={state.isStrike}
108
+ onPress={() => editorRef.current?.executeCommand("strike")}
109
+ aria-label="Strikethrough"
110
+ tooltip={SHORTCUTS.strike}
111
+ >
112
+ <StrikeIcon>S</StrikeIcon>
113
+ </ToolbarButton>
114
+
115
+ <ToolbarButton
116
+ active={state.isCode}
117
+ onPress={() => editorRef.current?.executeCommand("code")}
118
+ aria-label="Code"
119
+ tooltip={SHORTCUTS.code}
120
+ >
121
+ {"</>"}
122
+ </ToolbarButton>
123
+
124
+ <ToolbarButton
125
+ active={state.isSubscript}
126
+ onPress={() => editorRef.current?.executeCommand("subscript")}
127
+ aria-label="Subscript"
128
+ tooltip={SHORTCUTS.subscript}
129
+ >
130
+ <SubscriptIcon />
131
+ </ToolbarButton>
132
+
133
+ <ToolbarButton
134
+ active={state.isSuperscript}
135
+ onPress={() => editorRef.current?.executeCommand("superscript")}
136
+ aria-label="Superscript"
137
+ tooltip={SHORTCUTS.superscript}
138
+ >
139
+ <SuperscriptIcon />
140
+ </ToolbarButton>
141
+
142
+ {/* Color pickers */}
143
+ <TextColorPicker editorRef={editorRef} state={state} />
144
+ <HighlightColorPicker editorRef={editorRef} state={state} />
145
+
146
+ {/* Link */}
147
+ <LinkDialog editorRef={editorRef} state={state} />
148
+ </XStack>
149
+ </BubbleMenu>
150
+ );
151
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Bubble menu shown when cursor is inside a code block.
3
+ * Provides language selection and remove/convert actions.
4
+ */
5
+
6
+ import { useCallback, useState } from "react";
7
+ import type { Editor } from "@tiptap/react";
8
+ import { BubbleMenu } from "@tiptap/react/menus";
9
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
10
+ import { Popover, Text, XStack, YStack } from "tamagui";
11
+ import { DropdownMenuItemFrame } from "../styled";
12
+ import { ToolbarButton, ToolbarDropdownButton } from "./ToolbarButton";
13
+
14
+ const LANGUAGES = [
15
+ { value: null, label: "Plain text" },
16
+ { value: "bash", label: "Bash" },
17
+ { value: "c", label: "C" },
18
+ { value: "cpp", label: "C++" },
19
+ { value: "csharp", label: "C#" },
20
+ { value: "css", label: "CSS" },
21
+ { value: "go", label: "Go" },
22
+ { value: "graphql", label: "GraphQL" },
23
+ { value: "java", label: "Java" },
24
+ { value: "javascript", label: "JavaScript" },
25
+ { value: "json", label: "JSON" },
26
+ { value: "kotlin", label: "Kotlin" },
27
+ { value: "markdown", label: "Markdown" },
28
+ { value: "php", label: "PHP" },
29
+ { value: "python", label: "Python" },
30
+ { value: "ruby", label: "Ruby" },
31
+ { value: "rust", label: "Rust" },
32
+ { value: "scss", label: "SCSS" },
33
+ { value: "sql", label: "SQL" },
34
+ { value: "swift", label: "Swift" },
35
+ { value: "typescript", label: "TypeScript" },
36
+ { value: "xml", label: "XML / HTML" },
37
+ { value: "yaml", label: "YAML" },
38
+ ] as const;
39
+
40
+ function TrashIcon() {
41
+ return (
42
+ <svg
43
+ width="14"
44
+ height="14"
45
+ viewBox="0 0 24 24"
46
+ fill="none"
47
+ stroke="currentColor"
48
+ strokeWidth="2"
49
+ >
50
+ <polyline points="3 6 5 6 21 6" />
51
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
52
+ </svg>
53
+ );
54
+ }
55
+
56
+ export interface CodeBlockBubbleProps {
57
+ editor: Editor | null;
58
+ }
59
+
60
+ export function CodeBlockBubble({ editor }: CodeBlockBubbleProps) {
61
+ const { knobProps } = useResolvedKnobs();
62
+ const [langOpen, setLangOpen] = useState(false);
63
+
64
+ const currentLang = editor?.getAttributes("codeBlock")?.language ?? null;
65
+ const currentLabel =
66
+ LANGUAGES.find((l) => l.value === currentLang)?.label ?? currentLang ?? "Plain text";
67
+
68
+ const setLanguage = useCallback(
69
+ (lang: string | null) => {
70
+ if (!editor) return;
71
+ editor.chain().focus().updateAttributes("codeBlock", { language: lang }).run();
72
+ setLangOpen(false);
73
+ },
74
+ [editor],
75
+ );
76
+
77
+ const removeCodeBlock = useCallback(() => {
78
+ if (!editor) return;
79
+ editor.chain().focus().toggleCodeBlock().run();
80
+ }, [editor]);
81
+
82
+ if (!editor) return null;
83
+
84
+ return (
85
+ <BubbleMenu
86
+ editor={editor}
87
+ shouldShow={({ editor: e }) => e.isActive("codeBlock")}
88
+ options={{ placement: "top-start" }}
89
+ >
90
+ <XStack
91
+ backgroundColor="$background"
92
+ borderWidth={1}
93
+ borderColor="$borderColor"
94
+ borderRadius={knobProps.borderRadius.borderRadius}
95
+ padding="$1"
96
+ gap="$1"
97
+ alignItems="center"
98
+ elevation={knobProps.elevation}
99
+ >
100
+ <Popover open={langOpen} onOpenChange={setLangOpen} placement="bottom-start">
101
+ <Popover.Trigger asChild>
102
+ <ToolbarDropdownButton onPress={() => setLangOpen(true)} aria-label="Select language">
103
+ <Text fontSize={12}>{currentLabel}</Text>
104
+ </ToolbarDropdownButton>
105
+ </Popover.Trigger>
106
+ <Popover.Content
107
+ {...knobProps.panelPadding}
108
+ backgroundColor="$background"
109
+ borderWidth={1}
110
+ borderColor="$borderColor"
111
+ borderRadius={knobProps.borderRadius.borderRadius}
112
+ elevation={knobProps.elevation}
113
+ enterStyle={{ opacity: 0, y: -5 }}
114
+ exitStyle={{ opacity: 0, y: -5 }}
115
+ >
116
+ <YStack gap="$0.5" minWidth={160} maxHeight={280} overflow="scroll">
117
+ {LANGUAGES.map((lang) => (
118
+ <DropdownMenuItemFrame
119
+ key={lang.label}
120
+ active={currentLang === lang.value}
121
+ onPress={() => setLanguage(lang.value)}
122
+ aria-label={lang.label}
123
+ >
124
+ <Text fontSize={13}>{lang.label}</Text>
125
+ </DropdownMenuItemFrame>
126
+ ))}
127
+ </YStack>
128
+ </Popover.Content>
129
+ </Popover>
130
+
131
+ <ToolbarButton
132
+ onPress={removeCodeBlock}
133
+ aria-label="Remove code block"
134
+ tooltip="Remove code block"
135
+ >
136
+ <TrashIcon />
137
+ </ToolbarButton>
138
+ </XStack>
139
+ </BubbleMenu>
140
+ );
141
+ }
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Color picker popover for text color and highlight color
3
+ */
4
+
5
+ import { useCallback, useState } from "react";
6
+ import { useResolvedKnobs } from "@multiplatform.one/theme";
7
+ import { Popover, Text, View, XStack, YStack } from "tamagui";
8
+ import type { EditorState, RichEditorRef } from "../types";
9
+ import { TEXT_COLORS, HIGHLIGHT_COLORS } from "../constants";
10
+ import type { ColorEntry } from "../constants";
11
+ import { ToolbarButton } from "./ToolbarButton";
12
+ import { TextColorIcon, HighlightIcon } from "./icons";
13
+
14
+ // ===========================================================================
15
+ // Types
16
+ // ===========================================================================
17
+
18
+ export interface ColorPickerProps {
19
+ /** Reference to the editor */
20
+ editorRef: React.RefObject<RichEditorRef | null>;
21
+ /** Current editor state */
22
+ state: EditorState;
23
+ /** Whether the picker is disabled */
24
+ disabled?: boolean;
25
+ }
26
+
27
+ // ===========================================================================
28
+ // ColorSwatch
29
+ // ===========================================================================
30
+
31
+ function ColorSwatch({
32
+ color,
33
+ isSelected,
34
+ onPress,
35
+ isNone,
36
+ }: {
37
+ color: string | null;
38
+ isSelected: boolean;
39
+ onPress: () => void;
40
+ isNone?: boolean;
41
+ }) {
42
+ return (
43
+ <View
44
+ width={24}
45
+ height={24}
46
+ borderRadius={4}
47
+ backgroundColor={color || "$background"}
48
+ borderWidth={isSelected ? 2 : 1}
49
+ borderColor={isSelected ? "$blue10" : "$color6"}
50
+ cursor="pointer"
51
+ hoverStyle={{ opacity: 0.8 }}
52
+ pressStyle={{ scale: 0.95 }}
53
+ onPress={onPress}
54
+ alignItems="center"
55
+ justifyContent="center"
56
+ aria-label={isNone ? "Remove color" : `Color ${color}`}
57
+ >
58
+ {isNone && (
59
+ <View
60
+ position="absolute"
61
+ width={20}
62
+ height={2}
63
+ backgroundColor="$red10"
64
+ transform={[{ rotate: "45deg" }]}
65
+ />
66
+ )}
67
+ </View>
68
+ );
69
+ }
70
+
71
+ // ===========================================================================
72
+ // ColorGrid
73
+ // ===========================================================================
74
+
75
+ function ColorGrid({
76
+ title,
77
+ colors,
78
+ selectedColor,
79
+ onSelect,
80
+ maxWidth,
81
+ }: {
82
+ title: string;
83
+ colors: ColorEntry[];
84
+ selectedColor: string | null;
85
+ onSelect: (color: string | null) => void;
86
+ maxWidth: number;
87
+ }) {
88
+ const { knobProps } = useResolvedKnobs();
89
+ return (
90
+ <YStack {...knobProps.gap}>
91
+ <Text fontSize={knobProps.sizeToken} fontWeight="600">
92
+ {title}
93
+ </Text>
94
+ <XStack flexWrap="wrap" gap="$1" maxWidth={maxWidth}>
95
+ {colors.map((c) => (
96
+ <ColorSwatch
97
+ key={c.name}
98
+ color={c.value}
99
+ isSelected={selectedColor === c.value}
100
+ isNone={c.value === null}
101
+ onPress={() => onSelect(c.value)}
102
+ />
103
+ ))}
104
+ </XStack>
105
+ </YStack>
106
+ );
107
+ }
108
+
109
+ // ===========================================================================
110
+ // TextColorPicker
111
+ // ===========================================================================
112
+
113
+ export function TextColorPicker({ editorRef, state, disabled }: ColorPickerProps) {
114
+ const { knobProps } = useResolvedKnobs();
115
+ const [open, setOpen] = useState(false);
116
+
117
+ const handleSelect = useCallback(
118
+ (color: string | null) => {
119
+ editorRef.current?.executeCommand("textColor", { color });
120
+ setOpen(false);
121
+ },
122
+ [editorRef],
123
+ );
124
+
125
+ return (
126
+ <Popover open={open} onOpenChange={setOpen} placement="bottom">
127
+ <Popover.Trigger asChild>
128
+ <ToolbarButton
129
+ active={!!state.textColor}
130
+ disabled={disabled}
131
+ onPress={() => setOpen(true)}
132
+ aria-label="Text Color"
133
+ tooltip="Text Color"
134
+ >
135
+ <TextColorIcon color={state.textColor} />
136
+ </ToolbarButton>
137
+ </Popover.Trigger>
138
+ <Popover.Content
139
+ {...knobProps.panelPadding}
140
+ backgroundColor="$background"
141
+ borderWidth={1}
142
+ borderColor="$borderColor"
143
+ borderRadius={knobProps.borderRadius.borderRadius}
144
+ elevation={knobProps.elevation}
145
+ enterStyle={{ opacity: 0, y: -5 }}
146
+ exitStyle={{ opacity: 0, y: -5 }}
147
+ >
148
+ <Popover.Arrow borderColor="$borderColor" backgroundColor="$background" />
149
+ <ColorGrid
150
+ title="Text Color"
151
+ colors={TEXT_COLORS}
152
+ selectedColor={state.textColor}
153
+ onSelect={handleSelect}
154
+ maxWidth={160}
155
+ />
156
+ </Popover.Content>
157
+ </Popover>
158
+ );
159
+ }
160
+
161
+ // ===========================================================================
162
+ // HighlightColorPicker
163
+ // ===========================================================================
164
+
165
+ export function HighlightColorPicker({ editorRef, state, disabled }: ColorPickerProps) {
166
+ const { knobProps } = useResolvedKnobs();
167
+ const [open, setOpen] = useState(false);
168
+
169
+ const handleSelect = useCallback(
170
+ (color: string | null) => {
171
+ editorRef.current?.executeCommand("highlight", { color });
172
+ setOpen(false);
173
+ },
174
+ [editorRef],
175
+ );
176
+
177
+ return (
178
+ <Popover open={open} onOpenChange={setOpen} placement="bottom">
179
+ <Popover.Trigger asChild>
180
+ <ToolbarButton
181
+ active={!!state.highlightColor}
182
+ disabled={disabled}
183
+ onPress={() => setOpen(true)}
184
+ aria-label="Highlight Color"
185
+ tooltip="Highlight"
186
+ >
187
+ <HighlightIcon color={state.highlightColor} />
188
+ </ToolbarButton>
189
+ </Popover.Trigger>
190
+ <Popover.Content
191
+ {...knobProps.panelPadding}
192
+ backgroundColor="$background"
193
+ borderWidth={1}
194
+ borderColor="$borderColor"
195
+ borderRadius={knobProps.borderRadius.borderRadius}
196
+ elevation={knobProps.elevation}
197
+ enterStyle={{ opacity: 0, y: -5 }}
198
+ exitStyle={{ opacity: 0, y: -5 }}
199
+ >
200
+ <Popover.Arrow borderColor="$borderColor" backgroundColor="$background" />
201
+ <ColorGrid
202
+ title="Highlight"
203
+ colors={HIGHLIGHT_COLORS}
204
+ selectedColor={state.highlightColor}
205
+ onSelect={handleSelect}
206
+ maxWidth={130}
207
+ />
208
+ </Popover.Content>
209
+ </Popover>
210
+ );
211
+ }