@oxyhq/bloom 0.1.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 (456) hide show
  1. package/README.md +295 -0
  2. package/lib/commonjs/avatar/Avatar.js +215 -0
  3. package/lib/commonjs/avatar/Avatar.js.map +1 -0
  4. package/lib/commonjs/avatar/index.js +13 -0
  5. package/lib/commonjs/avatar/index.js.map +1 -0
  6. package/lib/commonjs/avatar/types.js +6 -0
  7. package/lib/commonjs/avatar/types.js.map +1 -0
  8. package/lib/commonjs/button/Button.js +169 -0
  9. package/lib/commonjs/button/Button.js.map +1 -0
  10. package/lib/commonjs/button/index.js +43 -0
  11. package/lib/commonjs/button/index.js.map +1 -0
  12. package/lib/commonjs/button/types.js +6 -0
  13. package/lib/commonjs/button/types.js.map +1 -0
  14. package/lib/commonjs/collapsible/Collapsible.js +58 -0
  15. package/lib/commonjs/collapsible/Collapsible.js.map +1 -0
  16. package/lib/commonjs/collapsible/index.js +13 -0
  17. package/lib/commonjs/collapsible/index.js.map +1 -0
  18. package/lib/commonjs/collapsible/types.js +6 -0
  19. package/lib/commonjs/collapsible/types.js.map +1 -0
  20. package/lib/commonjs/dialog/Dialog.js +186 -0
  21. package/lib/commonjs/dialog/Dialog.js.map +1 -0
  22. package/lib/commonjs/dialog/Dialog.web.js +244 -0
  23. package/lib/commonjs/dialog/Dialog.web.js.map +1 -0
  24. package/lib/commonjs/dialog/context.js +35 -0
  25. package/lib/commonjs/dialog/context.js.map +1 -0
  26. package/lib/commonjs/dialog/index.js +56 -0
  27. package/lib/commonjs/dialog/index.js.map +1 -0
  28. package/lib/commonjs/dialog/types.js +6 -0
  29. package/lib/commonjs/dialog/types.js.map +1 -0
  30. package/lib/commonjs/divider/Divider.js +39 -0
  31. package/lib/commonjs/divider/Divider.js.map +1 -0
  32. package/lib/commonjs/divider/index.js +13 -0
  33. package/lib/commonjs/divider/index.js.map +1 -0
  34. package/lib/commonjs/divider/types.js +6 -0
  35. package/lib/commonjs/divider/types.js.map +1 -0
  36. package/lib/commonjs/error-boundary/ErrorBoundary.js +116 -0
  37. package/lib/commonjs/error-boundary/ErrorBoundary.js.map +1 -0
  38. package/lib/commonjs/error-boundary/index.js +13 -0
  39. package/lib/commonjs/error-boundary/index.js.map +1 -0
  40. package/lib/commonjs/error-boundary/types.js +6 -0
  41. package/lib/commonjs/error-boundary/types.js.map +1 -0
  42. package/lib/commonjs/grouped-buttons/GroupedButtons.js +86 -0
  43. package/lib/commonjs/grouped-buttons/GroupedButtons.js.map +1 -0
  44. package/lib/commonjs/grouped-buttons/index.js +19 -0
  45. package/lib/commonjs/grouped-buttons/index.js.map +1 -0
  46. package/lib/commonjs/grouped-buttons/types.js +6 -0
  47. package/lib/commonjs/grouped-buttons/types.js.map +1 -0
  48. package/lib/commonjs/index.js +136 -0
  49. package/lib/commonjs/index.js.map +1 -0
  50. package/lib/commonjs/loading/Loading.js +274 -0
  51. package/lib/commonjs/loading/Loading.js.map +1 -0
  52. package/lib/commonjs/loading/index.js +13 -0
  53. package/lib/commonjs/loading/index.js.map +1 -0
  54. package/lib/commonjs/loading/types.js +6 -0
  55. package/lib/commonjs/loading/types.js.map +1 -0
  56. package/lib/commonjs/package.json +1 -0
  57. package/lib/commonjs/portal/index.js +90 -0
  58. package/lib/commonjs/portal/index.js.map +1 -0
  59. package/lib/commonjs/prompt/Prompt.js +267 -0
  60. package/lib/commonjs/prompt/Prompt.js.map +1 -0
  61. package/lib/commonjs/prompt/index.js +61 -0
  62. package/lib/commonjs/prompt/index.js.map +1 -0
  63. package/lib/commonjs/prompt-input/Actions.js +45 -0
  64. package/lib/commonjs/prompt-input/Actions.js.map +1 -0
  65. package/lib/commonjs/prompt-input/Attachments.js +277 -0
  66. package/lib/commonjs/prompt-input/Attachments.js.map +1 -0
  67. package/lib/commonjs/prompt-input/PromptInput.js +226 -0
  68. package/lib/commonjs/prompt-input/PromptInput.js.map +1 -0
  69. package/lib/commonjs/prompt-input/SubmitButton.js +81 -0
  70. package/lib/commonjs/prompt-input/SubmitButton.js.map +1 -0
  71. package/lib/commonjs/prompt-input/Textarea.js +101 -0
  72. package/lib/commonjs/prompt-input/Textarea.js.map +1 -0
  73. package/lib/commonjs/prompt-input/Textarea.web.js +148 -0
  74. package/lib/commonjs/prompt-input/Textarea.web.js.map +1 -0
  75. package/lib/commonjs/prompt-input/context.js +35 -0
  76. package/lib/commonjs/prompt-input/context.js.map +1 -0
  77. package/lib/commonjs/prompt-input/index.js +54 -0
  78. package/lib/commonjs/prompt-input/index.js.map +1 -0
  79. package/lib/commonjs/prompt-input/types.js +6 -0
  80. package/lib/commonjs/prompt-input/types.js.map +1 -0
  81. package/lib/commonjs/radio-indicator/RadioIndicator.js +48 -0
  82. package/lib/commonjs/radio-indicator/RadioIndicator.js.map +1 -0
  83. package/lib/commonjs/radio-indicator/index.js +13 -0
  84. package/lib/commonjs/radio-indicator/index.js.map +1 -0
  85. package/lib/commonjs/radio-indicator/types.js +6 -0
  86. package/lib/commonjs/radio-indicator/types.js.map +1 -0
  87. package/lib/commonjs/theme/BloomThemeProvider.js +122 -0
  88. package/lib/commonjs/theme/BloomThemeProvider.js.map +1 -0
  89. package/lib/commonjs/theme/adaptive-colors.js +96 -0
  90. package/lib/commonjs/theme/adaptive-colors.js.map +1 -0
  91. package/lib/commonjs/theme/apply-dark-class.js +13 -0
  92. package/lib/commonjs/theme/apply-dark-class.js.map +1 -0
  93. package/lib/commonjs/theme/color-presets.js +486 -0
  94. package/lib/commonjs/theme/color-presets.js.map +1 -0
  95. package/lib/commonjs/theme/index.js +57 -0
  96. package/lib/commonjs/theme/index.js.map +1 -0
  97. package/lib/commonjs/theme/set-color-scheme-safe.js +23 -0
  98. package/lib/commonjs/theme/set-color-scheme-safe.js.map +1 -0
  99. package/lib/commonjs/theme/types.js +2 -0
  100. package/lib/commonjs/theme/types.js.map +1 -0
  101. package/lib/commonjs/theme/use-theme.js +29 -0
  102. package/lib/commonjs/theme/use-theme.js.map +1 -0
  103. package/lib/module/avatar/Avatar.js +210 -0
  104. package/lib/module/avatar/Avatar.js.map +1 -0
  105. package/lib/module/avatar/index.js +4 -0
  106. package/lib/module/avatar/index.js.map +1 -0
  107. package/lib/module/avatar/types.js +4 -0
  108. package/lib/module/avatar/types.js.map +1 -0
  109. package/lib/module/button/Button.js +164 -0
  110. package/lib/module/button/Button.js.map +1 -0
  111. package/lib/module/button/index.js +4 -0
  112. package/lib/module/button/index.js.map +1 -0
  113. package/lib/module/button/types.js +4 -0
  114. package/lib/module/button/types.js.map +1 -0
  115. package/lib/module/collapsible/Collapsible.js +53 -0
  116. package/lib/module/collapsible/Collapsible.js.map +1 -0
  117. package/lib/module/collapsible/index.js +4 -0
  118. package/lib/module/collapsible/index.js.map +1 -0
  119. package/lib/module/collapsible/types.js +4 -0
  120. package/lib/module/collapsible/types.js.map +1 -0
  121. package/lib/module/dialog/Dialog.js +165 -0
  122. package/lib/module/dialog/Dialog.js.map +1 -0
  123. package/lib/module/dialog/Dialog.web.js +222 -0
  124. package/lib/module/dialog/Dialog.web.js.map +1 -0
  125. package/lib/module/dialog/context.js +29 -0
  126. package/lib/module/dialog/context.js.map +1 -0
  127. package/lib/module/dialog/index.js +5 -0
  128. package/lib/module/dialog/index.js.map +1 -0
  129. package/lib/module/dialog/types.js +4 -0
  130. package/lib/module/dialog/types.js.map +1 -0
  131. package/lib/module/divider/Divider.js +34 -0
  132. package/lib/module/divider/Divider.js.map +1 -0
  133. package/lib/module/divider/index.js +4 -0
  134. package/lib/module/divider/index.js.map +1 -0
  135. package/lib/module/divider/types.js +4 -0
  136. package/lib/module/divider/types.js.map +1 -0
  137. package/lib/module/error-boundary/ErrorBoundary.js +110 -0
  138. package/lib/module/error-boundary/ErrorBoundary.js.map +1 -0
  139. package/lib/module/error-boundary/index.js +4 -0
  140. package/lib/module/error-boundary/index.js.map +1 -0
  141. package/lib/module/error-boundary/types.js +4 -0
  142. package/lib/module/error-boundary/types.js.map +1 -0
  143. package/lib/module/grouped-buttons/GroupedButtons.js +80 -0
  144. package/lib/module/grouped-buttons/GroupedButtons.js.map +1 -0
  145. package/lib/module/grouped-buttons/index.js +4 -0
  146. package/lib/module/grouped-buttons/index.js.map +1 -0
  147. package/lib/module/grouped-buttons/types.js +4 -0
  148. package/lib/module/grouped-buttons/types.js.map +1 -0
  149. package/lib/module/index.js +16 -0
  150. package/lib/module/index.js.map +1 -0
  151. package/lib/module/loading/Loading.js +269 -0
  152. package/lib/module/loading/Loading.js.map +1 -0
  153. package/lib/module/loading/index.js +4 -0
  154. package/lib/module/loading/index.js.map +1 -0
  155. package/lib/module/loading/types.js +4 -0
  156. package/lib/module/loading/types.js.map +1 -0
  157. package/lib/module/package.json +1 -0
  158. package/lib/module/portal/index.js +85 -0
  159. package/lib/module/portal/index.js.map +1 -0
  160. package/lib/module/prompt/Prompt.js +250 -0
  161. package/lib/module/prompt/Prompt.js.map +1 -0
  162. package/lib/module/prompt/index.js +4 -0
  163. package/lib/module/prompt/index.js.map +1 -0
  164. package/lib/module/prompt-input/Actions.js +40 -0
  165. package/lib/module/prompt-input/Actions.js.map +1 -0
  166. package/lib/module/prompt-input/Attachments.js +272 -0
  167. package/lib/module/prompt-input/Attachments.js.map +1 -0
  168. package/lib/module/prompt-input/PromptInput.js +221 -0
  169. package/lib/module/prompt-input/PromptInput.js.map +1 -0
  170. package/lib/module/prompt-input/SubmitButton.js +76 -0
  171. package/lib/module/prompt-input/SubmitButton.js.map +1 -0
  172. package/lib/module/prompt-input/Textarea.js +96 -0
  173. package/lib/module/prompt-input/Textarea.js.map +1 -0
  174. package/lib/module/prompt-input/Textarea.web.js +143 -0
  175. package/lib/module/prompt-input/Textarea.web.js.map +1 -0
  176. package/lib/module/prompt-input/context.js +28 -0
  177. package/lib/module/prompt-input/context.js.map +1 -0
  178. package/lib/module/prompt-input/index.js +9 -0
  179. package/lib/module/prompt-input/index.js.map +1 -0
  180. package/lib/module/prompt-input/types.js +4 -0
  181. package/lib/module/prompt-input/types.js.map +1 -0
  182. package/lib/module/radio-indicator/RadioIndicator.js +43 -0
  183. package/lib/module/radio-indicator/RadioIndicator.js.map +1 -0
  184. package/lib/module/radio-indicator/index.js +4 -0
  185. package/lib/module/radio-indicator/index.js.map +1 -0
  186. package/lib/module/radio-indicator/types.js +4 -0
  187. package/lib/module/radio-indicator/types.js.map +1 -0
  188. package/lib/module/theme/BloomThemeProvider.js +116 -0
  189. package/lib/module/theme/BloomThemeProvider.js.map +1 -0
  190. package/lib/module/theme/adaptive-colors.js +92 -0
  191. package/lib/module/theme/adaptive-colors.js.map +1 -0
  192. package/lib/module/theme/apply-dark-class.js +9 -0
  193. package/lib/module/theme/apply-dark-class.js.map +1 -0
  194. package/lib/module/theme/color-presets.js +481 -0
  195. package/lib/module/theme/color-presets.js.map +1 -0
  196. package/lib/module/theme/index.js +6 -0
  197. package/lib/module/theme/index.js.map +1 -0
  198. package/lib/module/theme/set-color-scheme-safe.js +19 -0
  199. package/lib/module/theme/set-color-scheme-safe.js.map +1 -0
  200. package/lib/module/theme/types.js +2 -0
  201. package/lib/module/theme/types.js.map +1 -0
  202. package/lib/module/theme/use-theme.js +23 -0
  203. package/lib/module/theme/use-theme.js.map +1 -0
  204. package/lib/typescript/commonjs/avatar/Avatar.d.ts +4 -0
  205. package/lib/typescript/commonjs/avatar/Avatar.d.ts.map +1 -0
  206. package/lib/typescript/commonjs/avatar/index.d.ts +3 -0
  207. package/lib/typescript/commonjs/avatar/index.d.ts.map +1 -0
  208. package/lib/typescript/commonjs/avatar/types.d.ts +31 -0
  209. package/lib/typescript/commonjs/avatar/types.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/button/Button.d.ts +10 -0
  211. package/lib/typescript/commonjs/button/Button.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/button/index.d.ts +3 -0
  213. package/lib/typescript/commonjs/button/index.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/button/types.d.ts +25 -0
  215. package/lib/typescript/commonjs/button/types.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/collapsible/Collapsible.d.ts +4 -0
  217. package/lib/typescript/commonjs/collapsible/Collapsible.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/collapsible/index.d.ts +3 -0
  219. package/lib/typescript/commonjs/collapsible/index.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/collapsible/types.d.ts +18 -0
  221. package/lib/typescript/commonjs/collapsible/types.d.ts.map +1 -0
  222. package/lib/typescript/commonjs/dialog/Dialog.d.ts +11 -0
  223. package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -0
  224. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts +23 -0
  225. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -0
  226. package/lib/typescript/commonjs/dialog/context.d.ts +5 -0
  227. package/lib/typescript/commonjs/dialog/context.d.ts.map +1 -0
  228. package/lib/typescript/commonjs/dialog/index.d.ts +4 -0
  229. package/lib/typescript/commonjs/dialog/index.d.ts.map +1 -0
  230. package/lib/typescript/commonjs/dialog/types.d.ts +30 -0
  231. package/lib/typescript/commonjs/dialog/types.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/divider/Divider.d.ts +4 -0
  233. package/lib/typescript/commonjs/divider/Divider.d.ts.map +1 -0
  234. package/lib/typescript/commonjs/divider/index.d.ts +3 -0
  235. package/lib/typescript/commonjs/divider/index.d.ts.map +1 -0
  236. package/lib/typescript/commonjs/divider/types.d.ts +15 -0
  237. package/lib/typescript/commonjs/divider/types.d.ts.map +1 -0
  238. package/lib/typescript/commonjs/error-boundary/ErrorBoundary.d.ts +16 -0
  239. package/lib/typescript/commonjs/error-boundary/ErrorBoundary.d.ts.map +1 -0
  240. package/lib/typescript/commonjs/error-boundary/index.d.ts +3 -0
  241. package/lib/typescript/commonjs/error-boundary/index.d.ts.map +1 -0
  242. package/lib/typescript/commonjs/error-boundary/types.d.ts +16 -0
  243. package/lib/typescript/commonjs/error-boundary/types.d.ts.map +1 -0
  244. package/lib/typescript/commonjs/grouped-buttons/GroupedButtons.d.ts +8 -0
  245. package/lib/typescript/commonjs/grouped-buttons/GroupedButtons.d.ts.map +1 -0
  246. package/lib/typescript/commonjs/grouped-buttons/index.d.ts +3 -0
  247. package/lib/typescript/commonjs/grouped-buttons/index.d.ts.map +1 -0
  248. package/lib/typescript/commonjs/grouped-buttons/types.d.ts +15 -0
  249. package/lib/typescript/commonjs/grouped-buttons/types.d.ts.map +1 -0
  250. package/lib/typescript/commonjs/index.d.ts +15 -0
  251. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  252. package/lib/typescript/commonjs/loading/Loading.d.ts +4 -0
  253. package/lib/typescript/commonjs/loading/Loading.d.ts.map +1 -0
  254. package/lib/typescript/commonjs/loading/index.d.ts +3 -0
  255. package/lib/typescript/commonjs/loading/index.d.ts.map +1 -0
  256. package/lib/typescript/commonjs/loading/types.d.ts +60 -0
  257. package/lib/typescript/commonjs/loading/types.d.ts.map +1 -0
  258. package/lib/typescript/commonjs/package.json +1 -0
  259. package/lib/typescript/commonjs/portal/index.d.ts +5 -0
  260. package/lib/typescript/commonjs/portal/index.d.ts.map +1 -0
  261. package/lib/typescript/commonjs/prompt/Prompt.d.ts +42 -0
  262. package/lib/typescript/commonjs/prompt/Prompt.d.ts.map +1 -0
  263. package/lib/typescript/commonjs/prompt/index.d.ts +3 -0
  264. package/lib/typescript/commonjs/prompt/index.d.ts.map +1 -0
  265. package/lib/typescript/commonjs/prompt-input/Actions.d.ts +3 -0
  266. package/lib/typescript/commonjs/prompt-input/Actions.d.ts.map +1 -0
  267. package/lib/typescript/commonjs/prompt-input/Attachments.d.ts +3 -0
  268. package/lib/typescript/commonjs/prompt-input/Attachments.d.ts.map +1 -0
  269. package/lib/typescript/commonjs/prompt-input/PromptInput.d.ts +3 -0
  270. package/lib/typescript/commonjs/prompt-input/PromptInput.d.ts.map +1 -0
  271. package/lib/typescript/commonjs/prompt-input/SubmitButton.d.ts +3 -0
  272. package/lib/typescript/commonjs/prompt-input/SubmitButton.d.ts.map +1 -0
  273. package/lib/typescript/commonjs/prompt-input/Textarea.d.ts +3 -0
  274. package/lib/typescript/commonjs/prompt-input/Textarea.d.ts.map +1 -0
  275. package/lib/typescript/commonjs/prompt-input/Textarea.web.d.ts +3 -0
  276. package/lib/typescript/commonjs/prompt-input/Textarea.web.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/prompt-input/context.d.ts +34 -0
  278. package/lib/typescript/commonjs/prompt-input/context.d.ts.map +1 -0
  279. package/lib/typescript/commonjs/prompt-input/index.d.ts +8 -0
  280. package/lib/typescript/commonjs/prompt-input/index.d.ts.map +1 -0
  281. package/lib/typescript/commonjs/prompt-input/types.d.ts +88 -0
  282. package/lib/typescript/commonjs/prompt-input/types.d.ts.map +1 -0
  283. package/lib/typescript/commonjs/radio-indicator/RadioIndicator.d.ts +4 -0
  284. package/lib/typescript/commonjs/radio-indicator/RadioIndicator.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/radio-indicator/index.d.ts +3 -0
  286. package/lib/typescript/commonjs/radio-indicator/index.d.ts.map +1 -0
  287. package/lib/typescript/commonjs/radio-indicator/types.d.ts +15 -0
  288. package/lib/typescript/commonjs/radio-indicator/types.d.ts.map +1 -0
  289. package/lib/typescript/commonjs/theme/BloomThemeProvider.d.ts +20 -0
  290. package/lib/typescript/commonjs/theme/BloomThemeProvider.d.ts.map +1 -0
  291. package/lib/typescript/commonjs/theme/adaptive-colors.d.ts +3 -0
  292. package/lib/typescript/commonjs/theme/adaptive-colors.d.ts.map +1 -0
  293. package/lib/typescript/commonjs/theme/apply-dark-class.d.ts +2 -0
  294. package/lib/typescript/commonjs/theme/apply-dark-class.d.ts.map +1 -0
  295. package/lib/typescript/commonjs/theme/color-presets.d.ts +12 -0
  296. package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -0
  297. package/lib/typescript/commonjs/theme/index.d.ts +7 -0
  298. package/lib/typescript/commonjs/theme/index.d.ts.map +1 -0
  299. package/lib/typescript/commonjs/theme/set-color-scheme-safe.d.ts +9 -0
  300. package/lib/typescript/commonjs/theme/set-color-scheme-safe.d.ts.map +1 -0
  301. package/lib/typescript/commonjs/theme/types.d.ts +39 -0
  302. package/lib/typescript/commonjs/theme/types.d.ts.map +1 -0
  303. package/lib/typescript/commonjs/theme/use-theme.d.ts +5 -0
  304. package/lib/typescript/commonjs/theme/use-theme.d.ts.map +1 -0
  305. package/lib/typescript/module/avatar/Avatar.d.ts +4 -0
  306. package/lib/typescript/module/avatar/Avatar.d.ts.map +1 -0
  307. package/lib/typescript/module/avatar/index.d.ts +3 -0
  308. package/lib/typescript/module/avatar/index.d.ts.map +1 -0
  309. package/lib/typescript/module/avatar/types.d.ts +31 -0
  310. package/lib/typescript/module/avatar/types.d.ts.map +1 -0
  311. package/lib/typescript/module/button/Button.d.ts +10 -0
  312. package/lib/typescript/module/button/Button.d.ts.map +1 -0
  313. package/lib/typescript/module/button/index.d.ts +3 -0
  314. package/lib/typescript/module/button/index.d.ts.map +1 -0
  315. package/lib/typescript/module/button/types.d.ts +25 -0
  316. package/lib/typescript/module/button/types.d.ts.map +1 -0
  317. package/lib/typescript/module/collapsible/Collapsible.d.ts +4 -0
  318. package/lib/typescript/module/collapsible/Collapsible.d.ts.map +1 -0
  319. package/lib/typescript/module/collapsible/index.d.ts +3 -0
  320. package/lib/typescript/module/collapsible/index.d.ts.map +1 -0
  321. package/lib/typescript/module/collapsible/types.d.ts +18 -0
  322. package/lib/typescript/module/collapsible/types.d.ts.map +1 -0
  323. package/lib/typescript/module/dialog/Dialog.d.ts +11 -0
  324. package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -0
  325. package/lib/typescript/module/dialog/Dialog.web.d.ts +23 -0
  326. package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -0
  327. package/lib/typescript/module/dialog/context.d.ts +5 -0
  328. package/lib/typescript/module/dialog/context.d.ts.map +1 -0
  329. package/lib/typescript/module/dialog/index.d.ts +4 -0
  330. package/lib/typescript/module/dialog/index.d.ts.map +1 -0
  331. package/lib/typescript/module/dialog/types.d.ts +30 -0
  332. package/lib/typescript/module/dialog/types.d.ts.map +1 -0
  333. package/lib/typescript/module/divider/Divider.d.ts +4 -0
  334. package/lib/typescript/module/divider/Divider.d.ts.map +1 -0
  335. package/lib/typescript/module/divider/index.d.ts +3 -0
  336. package/lib/typescript/module/divider/index.d.ts.map +1 -0
  337. package/lib/typescript/module/divider/types.d.ts +15 -0
  338. package/lib/typescript/module/divider/types.d.ts.map +1 -0
  339. package/lib/typescript/module/error-boundary/ErrorBoundary.d.ts +16 -0
  340. package/lib/typescript/module/error-boundary/ErrorBoundary.d.ts.map +1 -0
  341. package/lib/typescript/module/error-boundary/index.d.ts +3 -0
  342. package/lib/typescript/module/error-boundary/index.d.ts.map +1 -0
  343. package/lib/typescript/module/error-boundary/types.d.ts +16 -0
  344. package/lib/typescript/module/error-boundary/types.d.ts.map +1 -0
  345. package/lib/typescript/module/grouped-buttons/GroupedButtons.d.ts +8 -0
  346. package/lib/typescript/module/grouped-buttons/GroupedButtons.d.ts.map +1 -0
  347. package/lib/typescript/module/grouped-buttons/index.d.ts +3 -0
  348. package/lib/typescript/module/grouped-buttons/index.d.ts.map +1 -0
  349. package/lib/typescript/module/grouped-buttons/types.d.ts +15 -0
  350. package/lib/typescript/module/grouped-buttons/types.d.ts.map +1 -0
  351. package/lib/typescript/module/index.d.ts +15 -0
  352. package/lib/typescript/module/index.d.ts.map +1 -0
  353. package/lib/typescript/module/loading/Loading.d.ts +4 -0
  354. package/lib/typescript/module/loading/Loading.d.ts.map +1 -0
  355. package/lib/typescript/module/loading/index.d.ts +3 -0
  356. package/lib/typescript/module/loading/index.d.ts.map +1 -0
  357. package/lib/typescript/module/loading/types.d.ts +60 -0
  358. package/lib/typescript/module/loading/types.d.ts.map +1 -0
  359. package/lib/typescript/module/package.json +1 -0
  360. package/lib/typescript/module/portal/index.d.ts +5 -0
  361. package/lib/typescript/module/portal/index.d.ts.map +1 -0
  362. package/lib/typescript/module/prompt/Prompt.d.ts +42 -0
  363. package/lib/typescript/module/prompt/Prompt.d.ts.map +1 -0
  364. package/lib/typescript/module/prompt/index.d.ts +3 -0
  365. package/lib/typescript/module/prompt/index.d.ts.map +1 -0
  366. package/lib/typescript/module/prompt-input/Actions.d.ts +3 -0
  367. package/lib/typescript/module/prompt-input/Actions.d.ts.map +1 -0
  368. package/lib/typescript/module/prompt-input/Attachments.d.ts +3 -0
  369. package/lib/typescript/module/prompt-input/Attachments.d.ts.map +1 -0
  370. package/lib/typescript/module/prompt-input/PromptInput.d.ts +3 -0
  371. package/lib/typescript/module/prompt-input/PromptInput.d.ts.map +1 -0
  372. package/lib/typescript/module/prompt-input/SubmitButton.d.ts +3 -0
  373. package/lib/typescript/module/prompt-input/SubmitButton.d.ts.map +1 -0
  374. package/lib/typescript/module/prompt-input/Textarea.d.ts +3 -0
  375. package/lib/typescript/module/prompt-input/Textarea.d.ts.map +1 -0
  376. package/lib/typescript/module/prompt-input/Textarea.web.d.ts +3 -0
  377. package/lib/typescript/module/prompt-input/Textarea.web.d.ts.map +1 -0
  378. package/lib/typescript/module/prompt-input/context.d.ts +34 -0
  379. package/lib/typescript/module/prompt-input/context.d.ts.map +1 -0
  380. package/lib/typescript/module/prompt-input/index.d.ts +8 -0
  381. package/lib/typescript/module/prompt-input/index.d.ts.map +1 -0
  382. package/lib/typescript/module/prompt-input/types.d.ts +88 -0
  383. package/lib/typescript/module/prompt-input/types.d.ts.map +1 -0
  384. package/lib/typescript/module/radio-indicator/RadioIndicator.d.ts +4 -0
  385. package/lib/typescript/module/radio-indicator/RadioIndicator.d.ts.map +1 -0
  386. package/lib/typescript/module/radio-indicator/index.d.ts +3 -0
  387. package/lib/typescript/module/radio-indicator/index.d.ts.map +1 -0
  388. package/lib/typescript/module/radio-indicator/types.d.ts +15 -0
  389. package/lib/typescript/module/radio-indicator/types.d.ts.map +1 -0
  390. package/lib/typescript/module/theme/BloomThemeProvider.d.ts +20 -0
  391. package/lib/typescript/module/theme/BloomThemeProvider.d.ts.map +1 -0
  392. package/lib/typescript/module/theme/adaptive-colors.d.ts +3 -0
  393. package/lib/typescript/module/theme/adaptive-colors.d.ts.map +1 -0
  394. package/lib/typescript/module/theme/apply-dark-class.d.ts +2 -0
  395. package/lib/typescript/module/theme/apply-dark-class.d.ts.map +1 -0
  396. package/lib/typescript/module/theme/color-presets.d.ts +12 -0
  397. package/lib/typescript/module/theme/color-presets.d.ts.map +1 -0
  398. package/lib/typescript/module/theme/index.d.ts +7 -0
  399. package/lib/typescript/module/theme/index.d.ts.map +1 -0
  400. package/lib/typescript/module/theme/set-color-scheme-safe.d.ts +9 -0
  401. package/lib/typescript/module/theme/set-color-scheme-safe.d.ts.map +1 -0
  402. package/lib/typescript/module/theme/types.d.ts +39 -0
  403. package/lib/typescript/module/theme/types.d.ts.map +1 -0
  404. package/lib/typescript/module/theme/use-theme.d.ts +5 -0
  405. package/lib/typescript/module/theme/use-theme.d.ts.map +1 -0
  406. package/package.json +260 -0
  407. package/src/avatar/Avatar.tsx +217 -0
  408. package/src/avatar/index.ts +2 -0
  409. package/src/avatar/types.ts +32 -0
  410. package/src/button/Button.tsx +172 -0
  411. package/src/button/index.ts +10 -0
  412. package/src/button/types.ts +25 -0
  413. package/src/collapsible/Collapsible.tsx +62 -0
  414. package/src/collapsible/index.ts +2 -0
  415. package/src/collapsible/types.ts +18 -0
  416. package/src/dialog/Dialog.tsx +160 -0
  417. package/src/dialog/Dialog.web.tsx +238 -0
  418. package/src/dialog/context.ts +34 -0
  419. package/src/dialog/index.ts +3 -0
  420. package/src/dialog/types.ts +34 -0
  421. package/src/divider/Divider.tsx +42 -0
  422. package/src/divider/index.ts +2 -0
  423. package/src/divider/types.ts +15 -0
  424. package/src/error-boundary/ErrorBoundary.tsx +112 -0
  425. package/src/error-boundary/index.ts +2 -0
  426. package/src/error-boundary/types.ts +16 -0
  427. package/src/grouped-buttons/GroupedButtons.tsx +94 -0
  428. package/src/grouped-buttons/index.ts +2 -0
  429. package/src/grouped-buttons/types.ts +16 -0
  430. package/src/index.ts +14 -0
  431. package/src/loading/Loading.tsx +258 -0
  432. package/src/loading/index.ts +10 -0
  433. package/src/loading/types.ts +69 -0
  434. package/src/portal/index.tsx +100 -0
  435. package/src/prompt/Prompt.tsx +248 -0
  436. package/src/prompt/index.ts +13 -0
  437. package/src/prompt-input/Actions.tsx +45 -0
  438. package/src/prompt-input/Attachments.tsx +264 -0
  439. package/src/prompt-input/PromptInput.tsx +263 -0
  440. package/src/prompt-input/SubmitButton.tsx +74 -0
  441. package/src/prompt-input/Textarea.tsx +102 -0
  442. package/src/prompt-input/Textarea.web.tsx +154 -0
  443. package/src/prompt-input/context.ts +59 -0
  444. package/src/prompt-input/index.ts +18 -0
  445. package/src/prompt-input/types.ts +92 -0
  446. package/src/radio-indicator/RadioIndicator.tsx +52 -0
  447. package/src/radio-indicator/index.ts +2 -0
  448. package/src/radio-indicator/types.ts +15 -0
  449. package/src/theme/BloomThemeProvider.tsx +160 -0
  450. package/src/theme/adaptive-colors.ts +90 -0
  451. package/src/theme/apply-dark-class.ts +7 -0
  452. package/src/theme/color-presets.ts +499 -0
  453. package/src/theme/index.ts +6 -0
  454. package/src/theme/set-color-scheme-safe.ts +19 -0
  455. package/src/theme/types.ts +48 -0
  456. package/src/theme/use-theme.ts +24 -0
@@ -0,0 +1,264 @@
1
+ import React from 'react';
2
+ import { View, Text, Image, Pressable, ScrollView, ActivityIndicator } from 'react-native';
3
+
4
+ import { useTheme } from '../theme/use-theme';
5
+ import { usePromptInput, type Attachment } from './context';
6
+ import type { PromptInputAttachmentsProps } from './types';
7
+
8
+ function formatFileSize(bytes: number): string {
9
+ if (bytes < 1024) return `${bytes} B`;
10
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
11
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
12
+ }
13
+
14
+ function truncateFilename(name: string, maxLength = 20): string {
15
+ if (name.length <= maxLength) return name;
16
+ const lastDot = name.lastIndexOf('.');
17
+ if (lastDot < 0) return name.slice(0, maxLength - 3) + '...';
18
+ const ext = name.slice(lastDot);
19
+ const base = name.slice(0, lastDot);
20
+ const available = maxLength - ext.length - 3;
21
+ if (available <= 0) return name.slice(0, maxLength - 3) + '...';
22
+ return base.slice(0, available) + '...' + ext;
23
+ }
24
+
25
+ interface DocIconInfo {
26
+ label: string;
27
+ color: string;
28
+ bgColor: string;
29
+ }
30
+
31
+ function getDocumentIconInfo(mimeType: string, name: string): DocIconInfo {
32
+ const ext = name.split('.').pop()?.toLowerCase() ?? '';
33
+
34
+ if (mimeType === 'application/pdf' || ext === 'pdf')
35
+ return { label: 'PDF', color: '#EF4444', bgColor: '#EF444418' };
36
+ if (mimeType.includes('word') || ['doc', 'docx'].includes(ext))
37
+ return { label: 'DOC', color: '#3B82F6', bgColor: '#3B82F618' };
38
+ if (mimeType.includes('spreadsheet') || mimeType.includes('excel') || ['xls', 'xlsx', 'csv'].includes(ext))
39
+ return { label: 'XLS', color: '#22C55E', bgColor: '#22C55E18' };
40
+ if (['js', 'ts', 'tsx', 'jsx', 'py', 'rb', 'go', 'rs', 'java', 'c', 'cpp', 'h', 'json', 'xml', 'yaml', 'yml', 'html', 'css', 'scss', 'sh', 'sql'].includes(ext))
41
+ return { label: '</>', color: '#8B5CF6', bgColor: '#8B5CF618' };
42
+ if (mimeType.includes('zip') || mimeType.includes('archive') || ['zip', 'rar', 'tar', 'gz', '7z'].includes(ext))
43
+ return { label: 'ZIP', color: '#EAB308', bgColor: '#EAB30818' };
44
+ if (mimeType.startsWith('audio/') || ['mp3', 'wav', 'ogg', 'flac', 'aac'].includes(ext))
45
+ return { label: '♫', color: '#EC4899', bgColor: '#EC489918' };
46
+ if (mimeType === 'text/plain' || ['txt', 'md', 'rtf'].includes(ext))
47
+ return { label: 'TXT', color: '#6B7280', bgColor: '#6B728018' };
48
+ return { label: 'FILE', color: '#9CA3AF', bgColor: '#9CA3AF18' };
49
+ }
50
+
51
+ function RemoveButton({
52
+ onPress,
53
+ size,
54
+ backgroundColor,
55
+ removeIcon,
56
+ label,
57
+ }: {
58
+ onPress: () => void;
59
+ size: number;
60
+ backgroundColor: string;
61
+ removeIcon?: React.ReactNode;
62
+ label: string;
63
+ }) {
64
+ return (
65
+ <Pressable
66
+ onPress={onPress}
67
+ accessibilityRole="button"
68
+ accessibilityLabel={`Remove ${label}`}
69
+ style={{
70
+ position: 'absolute',
71
+ top: 6,
72
+ right: 6,
73
+ width: size,
74
+ height: size,
75
+ borderRadius: size / 2,
76
+ backgroundColor,
77
+ alignItems: 'center',
78
+ justifyContent: 'center',
79
+ }}
80
+ >
81
+ {removeIcon ?? <Text style={{ color: '#FFFFFF', fontSize: size * 0.6, fontWeight: '700', lineHeight: size * 0.7 }}>×</Text>}
82
+ </Pressable>
83
+ );
84
+ }
85
+
86
+ function ImageAttachmentItem({
87
+ attachment,
88
+ onRemove,
89
+ removeIcon,
90
+ }: {
91
+ attachment: Attachment;
92
+ onRemove: () => void;
93
+ removeIcon?: React.ReactNode;
94
+ }) {
95
+ const theme = useTheme();
96
+
97
+ return (
98
+ <View
99
+ style={{
100
+ width: 120,
101
+ height: 120,
102
+ borderRadius: 16,
103
+ overflow: 'hidden',
104
+ backgroundColor: theme.colors.backgroundSecondary,
105
+ borderWidth: 1,
106
+ borderColor: theme.colors.border,
107
+ }}
108
+ >
109
+ {!attachment.isLoading && attachment.uri ? (
110
+ <Image
111
+ source={{ uri: attachment.uri }}
112
+ style={{ width: '100%', height: '100%' }}
113
+ resizeMode="cover"
114
+ />
115
+ ) : (
116
+ <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
117
+ <ActivityIndicator size="small" />
118
+ </View>
119
+ )}
120
+ {attachment.name && !attachment.isLoading && (
121
+ <View
122
+ style={{
123
+ position: 'absolute',
124
+ bottom: 0,
125
+ left: 0,
126
+ right: 0,
127
+ paddingHorizontal: 8,
128
+ paddingVertical: 4,
129
+ backgroundColor: 'rgba(0,0,0,0.5)',
130
+ }}
131
+ >
132
+ <Text style={{ fontSize: 11, color: '#FFFFFF' }} numberOfLines={1}>
133
+ {truncateFilename(attachment.name)}
134
+ </Text>
135
+ </View>
136
+ )}
137
+ <RemoveButton
138
+ onPress={onRemove}
139
+ size={24}
140
+ backgroundColor="rgba(0,0,0,0.6)"
141
+ removeIcon={removeIcon}
142
+ label={attachment.name || 'image'}
143
+ />
144
+ </View>
145
+ );
146
+ }
147
+
148
+ function DocumentAttachmentItem({
149
+ attachment,
150
+ onRemove,
151
+ removeIcon,
152
+ renderDocumentIcon,
153
+ }: {
154
+ attachment: Attachment;
155
+ onRemove: () => void;
156
+ removeIcon?: React.ReactNode;
157
+ renderDocumentIcon?: (mimeType: string, name: string) => React.ReactNode;
158
+ }) {
159
+ const theme = useTheme();
160
+ const iconInfo = getDocumentIconInfo(attachment.mimeType, attachment.name);
161
+
162
+ return (
163
+ <View
164
+ style={{
165
+ width: 180,
166
+ height: 80,
167
+ borderRadius: 16,
168
+ borderWidth: 1,
169
+ borderColor: theme.colors.border,
170
+ overflow: 'hidden',
171
+ backgroundColor: theme.colors.backgroundSecondary,
172
+ }}
173
+ >
174
+ <View
175
+ style={{
176
+ flex: 1,
177
+ flexDirection: 'row',
178
+ alignItems: 'center',
179
+ paddingHorizontal: 12,
180
+ gap: 12,
181
+ }}
182
+ >
183
+ {renderDocumentIcon ? (
184
+ renderDocumentIcon(attachment.mimeType, attachment.name)
185
+ ) : (
186
+ <View
187
+ style={{
188
+ width: 40,
189
+ height: 40,
190
+ borderRadius: 12,
191
+ alignItems: 'center',
192
+ justifyContent: 'center',
193
+ backgroundColor: iconInfo.bgColor,
194
+ }}
195
+ >
196
+ <Text style={{ fontSize: 12, fontWeight: '700', color: iconInfo.color }}>
197
+ {iconInfo.label}
198
+ </Text>
199
+ </View>
200
+ )}
201
+ <View style={{ flex: 1, paddingRight: 16 }}>
202
+ <Text
203
+ style={{ fontSize: 12, fontWeight: '500', color: theme.colors.text }}
204
+ numberOfLines={1}
205
+ >
206
+ {truncateFilename(attachment.name)}
207
+ </Text>
208
+ {attachment.size > 0 && (
209
+ <Text style={{ fontSize: 11, color: theme.colors.textSecondary, marginTop: 2 }}>
210
+ {formatFileSize(attachment.size)}
211
+ </Text>
212
+ )}
213
+ </View>
214
+ </View>
215
+ <RemoveButton
216
+ onPress={onRemove}
217
+ size={20}
218
+ backgroundColor={theme.colors.backgroundTertiary}
219
+ removeIcon={removeIcon}
220
+ label={attachment.name || 'document'}
221
+ />
222
+ </View>
223
+ );
224
+ }
225
+
226
+ export function PromptInputAttachments({
227
+ removeIcon,
228
+ renderDocumentIcon,
229
+ style,
230
+ testID,
231
+ }: PromptInputAttachmentsProps) {
232
+ const { attachments, removeAttachment } = usePromptInput();
233
+
234
+ if (attachments.length === 0) return null;
235
+
236
+ return (
237
+ <ScrollView
238
+ horizontal
239
+ showsHorizontalScrollIndicator={false}
240
+ style={[{ flexGrow: 0, marginBottom: 8, paddingTop: 8 }, style]}
241
+ contentContainerStyle={{ gap: 10, paddingHorizontal: 12 }}
242
+ testID={testID}
243
+ >
244
+ {attachments.map((attachment) => (
245
+ <View key={attachment.id}>
246
+ {attachment.type === 'image' ? (
247
+ <ImageAttachmentItem
248
+ attachment={attachment}
249
+ onRemove={() => removeAttachment(attachment.id)}
250
+ removeIcon={removeIcon}
251
+ />
252
+ ) : (
253
+ <DocumentAttachmentItem
254
+ attachment={attachment}
255
+ onRemove={() => removeAttachment(attachment.id)}
256
+ removeIcon={removeIcon}
257
+ renderDocumentIcon={renderDocumentIcon}
258
+ />
259
+ )}
260
+ </View>
261
+ ))}
262
+ </ScrollView>
263
+ );
264
+ }
@@ -0,0 +1,263 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import {
3
+ View,
4
+ Pressable,
5
+ Text,
6
+ KeyboardAvoidingView,
7
+ Platform,
8
+ StyleSheet,
9
+ type TextInput as RNTextInput,
10
+ } from 'react-native';
11
+
12
+ import { useTheme } from '../theme/use-theme';
13
+ import { Portal } from '../portal';
14
+ import { PromptInputContext, type Attachment } from './context';
15
+ import { PromptInputTextarea } from './Textarea';
16
+ import { PromptInputActions } from './Actions';
17
+ import { PromptInputAttachments } from './Attachments';
18
+ import { PromptInputSubmitButton } from './SubmitButton';
19
+ import type { PromptInputProps } from './types';
20
+
21
+ export function PromptInput({
22
+ isLoading = false,
23
+ maxHeight = 240,
24
+ value,
25
+ onValueChange,
26
+ onSubmit,
27
+ children,
28
+ style,
29
+ disabled = false,
30
+ onImagePaste,
31
+ placeholder,
32
+ actionsLeft,
33
+ onStop,
34
+ emptyAction,
35
+ attachments: controlledAttachments,
36
+ onAddAttachment,
37
+ onRemoveAttachment,
38
+ onUpdateAttachment,
39
+ disableKeyboardAvoidance = false,
40
+ expandIcon,
41
+ collapseIcon,
42
+ testID,
43
+ }: PromptInputProps) {
44
+ const [internalValue, setInternalValue] = useState(value ?? '');
45
+ const [currentHeight, setCurrentHeight] = useState(44);
46
+ const [showFullscreen, setShowFullscreen] = useState(false);
47
+ const [handleCompletionKey, setHandleCompletionKey] = useState<((key: string) => boolean) | null>(null);
48
+ const textareaRef = useRef<RNTextInput>(null);
49
+ const theme = useTheme();
50
+
51
+ // Internal attachment state (used when no controlled props)
52
+ const [internalAttachments, setInternalAttachments] = useState<Attachment[]>([]);
53
+ const attachments = controlledAttachments ?? internalAttachments;
54
+
55
+ const addAttachment = useCallback(
56
+ (a: Attachment) => {
57
+ if (onAddAttachment) {
58
+ onAddAttachment(a);
59
+ } else {
60
+ setInternalAttachments((prev) => [...prev, a]);
61
+ }
62
+ },
63
+ [onAddAttachment],
64
+ );
65
+
66
+ const removeAttachment = useCallback(
67
+ (id: string) => {
68
+ if (onRemoveAttachment) {
69
+ onRemoveAttachment(id);
70
+ } else {
71
+ setInternalAttachments((prev) => prev.filter((a) => a.id !== id));
72
+ }
73
+ },
74
+ [onRemoveAttachment],
75
+ );
76
+
77
+ const updateAttachment = useCallback(
78
+ (id: string, updates: Partial<Attachment>) => {
79
+ if (onUpdateAttachment) {
80
+ onUpdateAttachment(id, updates);
81
+ } else {
82
+ setInternalAttachments((prev) =>
83
+ prev.map((a) => (a.id === id ? { ...a, ...updates } : a)),
84
+ );
85
+ }
86
+ },
87
+ [onUpdateAttachment],
88
+ );
89
+
90
+ const handleChange = useCallback(
91
+ (newValue: string) => {
92
+ setInternalValue(newValue);
93
+ onValueChange?.(newValue);
94
+ },
95
+ [onValueChange],
96
+ );
97
+
98
+ const handleSubmit = useCallback(() => {
99
+ onSubmit?.();
100
+ if (showFullscreen) setShowFullscreen(false);
101
+ }, [onSubmit, showFullscreen]);
102
+
103
+ useEffect(() => {
104
+ if (!showFullscreen) setCurrentHeight(44);
105
+ }, [showFullscreen]);
106
+
107
+ const showExpandIcon = currentHeight > 100;
108
+ const isSimpleMode = !children;
109
+
110
+ const currentValue = value ?? internalValue;
111
+ const currentSetValue = onValueChange ?? handleChange;
112
+
113
+ const contextValue = useMemo(
114
+ () => ({
115
+ isLoading,
116
+ value: currentValue,
117
+ setValue: currentSetValue,
118
+ maxHeight,
119
+ onSubmit: handleSubmit,
120
+ disabled,
121
+ textareaRef,
122
+ currentHeight,
123
+ setCurrentHeight,
124
+ isFullscreen: showFullscreen,
125
+ onImagePaste,
126
+ attachments,
127
+ addAttachment,
128
+ removeAttachment,
129
+ updateAttachment,
130
+ handleCompletionKey,
131
+ setHandleCompletionKey,
132
+ }),
133
+ [
134
+ isLoading, currentValue, currentSetValue, maxHeight, handleSubmit,
135
+ disabled, currentHeight, showFullscreen, onImagePaste,
136
+ attachments, addAttachment, removeAttachment, updateAttachment,
137
+ handleCompletionKey,
138
+ ],
139
+ );
140
+
141
+ const content = isSimpleMode ? (
142
+ <>
143
+ <PromptInputAttachments />
144
+ <PromptInputTextarea placeholder={placeholder} />
145
+ <PromptInputActions
146
+ style={{
147
+ flexDirection: 'row',
148
+ alignItems: 'center',
149
+ justifyContent: 'space-between',
150
+ gap: 8,
151
+ marginTop: 6,
152
+ marginBottom: 12,
153
+ paddingHorizontal: 12,
154
+ }}
155
+ >
156
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
157
+ {actionsLeft}
158
+ </View>
159
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
160
+ <PromptInputSubmitButton
161
+ isLoading={isLoading}
162
+ onStop={onStop}
163
+ emptyAction={emptyAction}
164
+ />
165
+ </View>
166
+ </PromptInputActions>
167
+ </>
168
+ ) : (
169
+ children
170
+ );
171
+
172
+ const inputBox = (
173
+ <Pressable
174
+ onPress={() => {
175
+ if (!disabled) textareaRef.current?.focus();
176
+ }}
177
+ disabled={disabled}
178
+ >
179
+ <View
180
+ style={[
181
+ {
182
+ borderRadius: 24,
183
+ borderWidth: 1,
184
+ borderColor: theme.colors.border,
185
+ backgroundColor: theme.colors.background,
186
+ overflow: 'hidden',
187
+ position: 'relative',
188
+ },
189
+ disabled && { opacity: 0.6 },
190
+ style,
191
+ ]}
192
+ testID={testID}
193
+ >
194
+ {showExpandIcon && !disabled && (
195
+ <Pressable
196
+ onPress={() => setShowFullscreen(true)}
197
+ style={{
198
+ position: 'absolute',
199
+ top: 8,
200
+ right: 8,
201
+ zIndex: 10,
202
+ backgroundColor: theme.colors.background,
203
+ borderRadius: 9999,
204
+ padding: 6,
205
+ borderWidth: 1,
206
+ borderColor: theme.colors.border,
207
+ }}
208
+ >
209
+ {expandIcon ?? (
210
+ <Text style={{ fontSize: 14, color: theme.colors.textSecondary }}>⤢</Text>
211
+ )}
212
+ </Pressable>
213
+ )}
214
+ {content}
215
+ </View>
216
+ </Pressable>
217
+ );
218
+
219
+ const Wrapper = disableKeyboardAvoidance ? View : KeyboardAvoidingView;
220
+ const wrapperProps = disableKeyboardAvoidance
221
+ ? {}
222
+ : { behavior: Platform.OS === 'ios' ? 'padding' as const : undefined };
223
+
224
+ return (
225
+ <PromptInputContext.Provider value={contextValue}>
226
+ <Wrapper {...wrapperProps}>
227
+ {inputBox}
228
+ </Wrapper>
229
+
230
+ {showFullscreen && (
231
+ <Portal>
232
+ <View
233
+ style={[
234
+ StyleSheet.absoluteFillObject,
235
+ {
236
+ zIndex: 9998,
237
+ backgroundColor: theme.colors.background,
238
+ },
239
+ ]}
240
+ >
241
+ <Pressable
242
+ onPress={() => setShowFullscreen(false)}
243
+ style={{
244
+ position: 'absolute',
245
+ top: 16,
246
+ right: 16,
247
+ zIndex: 50,
248
+ padding: 8,
249
+ backgroundColor: theme.colors.background,
250
+ borderRadius: 9999,
251
+ }}
252
+ >
253
+ {collapseIcon ?? (
254
+ <Text style={{ fontSize: 18, color: theme.colors.text }}>⤡</Text>
255
+ )}
256
+ </Pressable>
257
+ <View style={{ flex: 1 }}>{content}</View>
258
+ </View>
259
+ </Portal>
260
+ )}
261
+ </PromptInputContext.Provider>
262
+ );
263
+ }
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { Text, TouchableOpacity } from 'react-native';
3
+
4
+ import { useTheme } from '../theme/use-theme';
5
+ import { usePromptInput } from './context';
6
+ import type { PromptInputSubmitButtonProps } from './types';
7
+
8
+ export function PromptInputSubmitButton({
9
+ isLoading,
10
+ onStop,
11
+ emptyAction,
12
+ submitIcon,
13
+ stopIcon,
14
+ style,
15
+ testID,
16
+ }: PromptInputSubmitButtonProps) {
17
+ const { onSubmit, value, attachments } = usePromptInput();
18
+ const theme = useTheme();
19
+ const hasContent = value.trim().length > 0 || attachments.length > 0;
20
+
21
+ if (isLoading && onStop) {
22
+ return (
23
+ <TouchableOpacity
24
+ onPress={onStop}
25
+ activeOpacity={0.7}
26
+ style={[
27
+ {
28
+ width: 32,
29
+ height: 32,
30
+ borderRadius: 16,
31
+ backgroundColor: theme.colors.primary,
32
+ alignItems: 'center',
33
+ justifyContent: 'center',
34
+ },
35
+ style,
36
+ ]}
37
+ testID={testID}
38
+ >
39
+ {stopIcon ?? (
40
+ <Text style={{ fontSize: 12, color: '#FFFFFF', fontWeight: '700' }}>■</Text>
41
+ )}
42
+ </TouchableOpacity>
43
+ );
44
+ }
45
+
46
+ if (!hasContent && emptyAction) {
47
+ return <>{emptyAction}</>;
48
+ }
49
+
50
+ return (
51
+ <TouchableOpacity
52
+ onPress={onSubmit}
53
+ disabled={!hasContent}
54
+ activeOpacity={0.7}
55
+ style={[
56
+ {
57
+ width: 32,
58
+ height: 32,
59
+ borderRadius: 16,
60
+ backgroundColor: theme.colors.primary,
61
+ alignItems: 'center',
62
+ justifyContent: 'center',
63
+ opacity: hasContent ? 1 : 0.4,
64
+ },
65
+ style,
66
+ ]}
67
+ testID={testID}
68
+ >
69
+ {submitIcon ?? (
70
+ <Text style={{ fontSize: 16, color: '#FFFFFF', fontWeight: '700' }}>↑</Text>
71
+ )}
72
+ </TouchableOpacity>
73
+ );
74
+ }
@@ -0,0 +1,102 @@
1
+ import React, { useCallback, useImperativeHandle, useRef } from 'react';
2
+ import {
3
+ TextInput,
4
+ View,
5
+ type NativeSyntheticEvent,
6
+ type TextInputContentSizeChangeEventData,
7
+ type TextInputKeyPressEventData,
8
+ } from 'react-native';
9
+
10
+ import { useTheme } from '../theme/use-theme';
11
+ import { usePromptInput } from './context';
12
+ import type { PromptInputTextareaProps } from './types';
13
+
14
+ export function PromptInputTextarea({
15
+ placeholder,
16
+ style,
17
+ inputStyle,
18
+ textInputProps,
19
+ testID,
20
+ }: PromptInputTextareaProps) {
21
+ const {
22
+ value,
23
+ setValue,
24
+ onSubmit,
25
+ disabled,
26
+ textareaRef,
27
+ setCurrentHeight,
28
+ isFullscreen,
29
+ maxHeight,
30
+ handleCompletionKey,
31
+ } = usePromptInput();
32
+ const theme = useTheme();
33
+ const inputRef = useRef<TextInput>(null);
34
+
35
+ useImperativeHandle(textareaRef, () => inputRef.current as TextInput);
36
+
37
+ const handleKeyPress = useCallback(
38
+ (e: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
39
+ textInputProps?.onKeyPress?.(e);
40
+ const key = e.nativeEvent.key;
41
+
42
+ if (handleCompletionKey && ['ArrowUp', 'ArrowDown', 'Enter', 'Escape'].includes(key)) {
43
+ if (handleCompletionKey(key)) {
44
+ e.preventDefault();
45
+ return;
46
+ }
47
+ }
48
+ },
49
+ [handleCompletionKey, textInputProps],
50
+ );
51
+
52
+ const handleContentSizeChange = useCallback(
53
+ (e: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
54
+ textInputProps?.onContentSizeChange?.(e);
55
+ },
56
+ [textInputProps],
57
+ );
58
+
59
+ const textInput = (
60
+ <View
61
+ style={[{ width: '100%' }, isFullscreen && { flex: 1 }]}
62
+ onLayout={(e) => setCurrentHeight(e.nativeEvent.layout.height)}
63
+ >
64
+ <TextInput
65
+ ref={inputRef}
66
+ accessibilityLabel="Message input"
67
+ value={value}
68
+ onChangeText={setValue}
69
+ onSubmitEditing={onSubmit}
70
+ onKeyPress={handleKeyPress}
71
+ onContentSizeChange={handleContentSizeChange}
72
+ multiline
73
+ editable={!disabled}
74
+ scrollEnabled={isFullscreen}
75
+ placeholder={placeholder}
76
+ placeholderTextColor={theme.colors.textTertiary}
77
+ style={[
78
+ {
79
+ width: '100%',
80
+ fontSize: 16,
81
+ color: theme.colors.text,
82
+ paddingHorizontal: 14,
83
+ backgroundColor: 'transparent',
84
+ borderWidth: 0,
85
+ },
86
+ isFullscreen
87
+ ? { flex: 1, paddingTop: 16, paddingBottom: 100 }
88
+ : { minHeight: 44, paddingVertical: 12, maxHeight, overflow: 'scroll' },
89
+ inputStyle,
90
+ ]}
91
+ testID={testID}
92
+ {...textInputProps}
93
+ />
94
+ </View>
95
+ );
96
+
97
+ if (isFullscreen) {
98
+ return <View style={[{ flex: 1 }, style]}>{textInput}</View>;
99
+ }
100
+
101
+ return <View style={style}>{textInput}</View>;
102
+ }