@crafter/rn-ai-elements 0.0.1

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 (344) hide show
  1. package/lib/commonjs/chatbot/AIImage.js +126 -0
  2. package/lib/commonjs/chatbot/AIImage.js.map +1 -0
  3. package/lib/commonjs/chatbot/Attachments.js +317 -0
  4. package/lib/commonjs/chatbot/Attachments.js.map +1 -0
  5. package/lib/commonjs/chatbot/ChatErrorBoundary.js +201 -0
  6. package/lib/commonjs/chatbot/ChatErrorBoundary.js.map +1 -0
  7. package/lib/commonjs/chatbot/ChatMessageItem.js +169 -0
  8. package/lib/commonjs/chatbot/ChatMessageItem.js.map +1 -0
  9. package/lib/commonjs/chatbot/Conversation.js +415 -0
  10. package/lib/commonjs/chatbot/Conversation.js.map +1 -0
  11. package/lib/commonjs/chatbot/ConversationScrollButton.js +131 -0
  12. package/lib/commonjs/chatbot/ConversationScrollButton.js.map +1 -0
  13. package/lib/commonjs/chatbot/Message.js +203 -0
  14. package/lib/commonjs/chatbot/Message.js.map +1 -0
  15. package/lib/commonjs/chatbot/PromptInput.js +352 -0
  16. package/lib/commonjs/chatbot/PromptInput.js.map +1 -0
  17. package/lib/commonjs/chatbot/Reasoning.js +184 -0
  18. package/lib/commonjs/chatbot/Reasoning.js.map +1 -0
  19. package/lib/commonjs/chatbot/Shimmer.js +116 -0
  20. package/lib/commonjs/chatbot/Shimmer.js.map +1 -0
  21. package/lib/commonjs/chatbot/Sources.js +212 -0
  22. package/lib/commonjs/chatbot/Sources.js.map +1 -0
  23. package/lib/commonjs/chatbot/Suggestion.js +99 -0
  24. package/lib/commonjs/chatbot/Suggestion.js.map +1 -0
  25. package/lib/commonjs/chatbot/Tool.js +307 -0
  26. package/lib/commonjs/chatbot/Tool.js.map +1 -0
  27. package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js +141 -0
  28. package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js.map +1 -0
  29. package/lib/commonjs/chatbot/index.js +140 -0
  30. package/lib/commonjs/chatbot/index.js.map +1 -0
  31. package/lib/commonjs/chatbot/types.js +6 -0
  32. package/lib/commonjs/chatbot/types.js.map +1 -0
  33. package/lib/commonjs/hooks/index.js +34 -0
  34. package/lib/commonjs/hooks/index.js.map +1 -0
  35. package/lib/commonjs/hooks/useAutoScroll.js +39 -0
  36. package/lib/commonjs/hooks/useAutoScroll.js.map +1 -0
  37. package/lib/commonjs/hooks/useClipboard.js +44 -0
  38. package/lib/commonjs/hooks/useClipboard.js.map +1 -0
  39. package/lib/commonjs/hooks/useCollapsible.js +35 -0
  40. package/lib/commonjs/hooks/useCollapsible.js.map +1 -0
  41. package/lib/commonjs/hooks/useStickToBottom.js +68 -0
  42. package/lib/commonjs/hooks/useStickToBottom.js.map +1 -0
  43. package/lib/commonjs/index.js +257 -0
  44. package/lib/commonjs/index.js.map +1 -0
  45. package/lib/commonjs/package.json +1 -0
  46. package/lib/commonjs/primitives/Badge.js +119 -0
  47. package/lib/commonjs/primitives/Badge.js.map +1 -0
  48. package/lib/commonjs/primitives/Button.js +185 -0
  49. package/lib/commonjs/primitives/Button.js.map +1 -0
  50. package/lib/commonjs/primitives/Card.js +166 -0
  51. package/lib/commonjs/primitives/Card.js.map +1 -0
  52. package/lib/commonjs/primitives/Collapsible.js +137 -0
  53. package/lib/commonjs/primitives/Collapsible.js.map +1 -0
  54. package/lib/commonjs/primitives/ScrollArea.js +40 -0
  55. package/lib/commonjs/primitives/ScrollArea.js.map +1 -0
  56. package/lib/commonjs/primitives/index.js +83 -0
  57. package/lib/commonjs/primitives/index.js.map +1 -0
  58. package/lib/commonjs/streaming/StreamingMarkdown.js +252 -0
  59. package/lib/commonjs/streaming/StreamingMarkdown.js.map +1 -0
  60. package/lib/commonjs/streaming/index.js +13 -0
  61. package/lib/commonjs/streaming/index.js.map +1 -0
  62. package/lib/commonjs/streaming/parser.js +482 -0
  63. package/lib/commonjs/streaming/parser.js.map +1 -0
  64. package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js +35 -0
  65. package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js.map +1 -0
  66. package/lib/commonjs/streaming/renderers/CodeRenderer.js +128 -0
  67. package/lib/commonjs/streaming/renderers/CodeRenderer.js.map +1 -0
  68. package/lib/commonjs/streaming/renderers/HeadingRenderer.js +61 -0
  69. package/lib/commonjs/streaming/renderers/HeadingRenderer.js.map +1 -0
  70. package/lib/commonjs/streaming/renderers/ImageRenderer.js +53 -0
  71. package/lib/commonjs/streaming/renderers/ImageRenderer.js.map +1 -0
  72. package/lib/commonjs/streaming/renderers/LinkRenderer.js +49 -0
  73. package/lib/commonjs/streaming/renderers/LinkRenderer.js.map +1 -0
  74. package/lib/commonjs/streaming/renderers/ListRenderer.js +63 -0
  75. package/lib/commonjs/streaming/renderers/ListRenderer.js.map +1 -0
  76. package/lib/commonjs/streaming/renderers/TableRenderer.js +77 -0
  77. package/lib/commonjs/streaming/renderers/TableRenderer.js.map +1 -0
  78. package/lib/commonjs/streaming/renderers/TextRenderer.js +41 -0
  79. package/lib/commonjs/streaming/renderers/TextRenderer.js.map +1 -0
  80. package/lib/commonjs/streaming/renderers/index.js +76 -0
  81. package/lib/commonjs/streaming/renderers/index.js.map +1 -0
  82. package/lib/commonjs/streaming/renderers/renderInlineChildren.js +112 -0
  83. package/lib/commonjs/streaming/renderers/renderInlineChildren.js.map +1 -0
  84. package/lib/commonjs/streaming/renderers/renderNode.js +81 -0
  85. package/lib/commonjs/streaming/renderers/renderNode.js.map +1 -0
  86. package/lib/commonjs/theme/ThemeProvider.js +68 -0
  87. package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
  88. package/lib/commonjs/theme/defaultTheme.js +96 -0
  89. package/lib/commonjs/theme/defaultTheme.js.map +1 -0
  90. package/lib/commonjs/theme/index.js +32 -0
  91. package/lib/commonjs/theme/index.js.map +1 -0
  92. package/lib/commonjs/theme/tokens.js +2 -0
  93. package/lib/commonjs/theme/tokens.js.map +1 -0
  94. package/lib/commonjs/types.d.js +2 -0
  95. package/lib/commonjs/types.d.js.map +1 -0
  96. package/lib/commonjs/voice/index.js +13 -0
  97. package/lib/commonjs/voice/index.js.map +1 -0
  98. package/lib/commonjs/voice/useSpeechRecognition.js +172 -0
  99. package/lib/commonjs/voice/useSpeechRecognition.js.map +1 -0
  100. package/lib/module/chatbot/AIImage.js +121 -0
  101. package/lib/module/chatbot/AIImage.js.map +1 -0
  102. package/lib/module/chatbot/Attachments.js +312 -0
  103. package/lib/module/chatbot/Attachments.js.map +1 -0
  104. package/lib/module/chatbot/ChatErrorBoundary.js +196 -0
  105. package/lib/module/chatbot/ChatErrorBoundary.js.map +1 -0
  106. package/lib/module/chatbot/ChatMessageItem.js +164 -0
  107. package/lib/module/chatbot/ChatMessageItem.js.map +1 -0
  108. package/lib/module/chatbot/Conversation.js +412 -0
  109. package/lib/module/chatbot/Conversation.js.map +1 -0
  110. package/lib/module/chatbot/ConversationScrollButton.js +126 -0
  111. package/lib/module/chatbot/ConversationScrollButton.js.map +1 -0
  112. package/lib/module/chatbot/Message.js +198 -0
  113. package/lib/module/chatbot/Message.js.map +1 -0
  114. package/lib/module/chatbot/PromptInput.js +347 -0
  115. package/lib/module/chatbot/PromptInput.js.map +1 -0
  116. package/lib/module/chatbot/Reasoning.js +179 -0
  117. package/lib/module/chatbot/Reasoning.js.map +1 -0
  118. package/lib/module/chatbot/Shimmer.js +111 -0
  119. package/lib/module/chatbot/Shimmer.js.map +1 -0
  120. package/lib/module/chatbot/Sources.js +207 -0
  121. package/lib/module/chatbot/Sources.js.map +1 -0
  122. package/lib/module/chatbot/Suggestion.js +94 -0
  123. package/lib/module/chatbot/Suggestion.js.map +1 -0
  124. package/lib/module/chatbot/Tool.js +303 -0
  125. package/lib/module/chatbot/Tool.js.map +1 -0
  126. package/lib/module/chatbot/adapters/uiMessageAdapter.js +137 -0
  127. package/lib/module/chatbot/adapters/uiMessageAdapter.js.map +1 -0
  128. package/lib/module/chatbot/index.js +39 -0
  129. package/lib/module/chatbot/index.js.map +1 -0
  130. package/lib/module/chatbot/types.js +4 -0
  131. package/lib/module/chatbot/types.js.map +1 -0
  132. package/lib/module/hooks/index.js +7 -0
  133. package/lib/module/hooks/index.js.map +1 -0
  134. package/lib/module/hooks/useAutoScroll.js +35 -0
  135. package/lib/module/hooks/useAutoScroll.js.map +1 -0
  136. package/lib/module/hooks/useClipboard.js +40 -0
  137. package/lib/module/hooks/useClipboard.js.map +1 -0
  138. package/lib/module/hooks/useCollapsible.js +31 -0
  139. package/lib/module/hooks/useCollapsible.js.map +1 -0
  140. package/lib/module/hooks/useStickToBottom.js +64 -0
  141. package/lib/module/hooks/useStickToBottom.js.map +1 -0
  142. package/lib/module/index.js +19 -0
  143. package/lib/module/index.js.map +1 -0
  144. package/lib/module/package.json +1 -0
  145. package/lib/module/primitives/Badge.js +114 -0
  146. package/lib/module/primitives/Badge.js.map +1 -0
  147. package/lib/module/primitives/Button.js +180 -0
  148. package/lib/module/primitives/Button.js.map +1 -0
  149. package/lib/module/primitives/Card.js +156 -0
  150. package/lib/module/primitives/Card.js.map +1 -0
  151. package/lib/module/primitives/Collapsible.js +130 -0
  152. package/lib/module/primitives/Collapsible.js.map +1 -0
  153. package/lib/module/primitives/ScrollArea.js +35 -0
  154. package/lib/module/primitives/ScrollArea.js.map +1 -0
  155. package/lib/module/primitives/index.js +8 -0
  156. package/lib/module/primitives/index.js.map +1 -0
  157. package/lib/module/streaming/StreamingMarkdown.js +246 -0
  158. package/lib/module/streaming/StreamingMarkdown.js.map +1 -0
  159. package/lib/module/streaming/index.js +4 -0
  160. package/lib/module/streaming/index.js.map +1 -0
  161. package/lib/module/streaming/parser.js +477 -0
  162. package/lib/module/streaming/parser.js.map +1 -0
  163. package/lib/module/streaming/renderers/BlockquoteRenderer.js +30 -0
  164. package/lib/module/streaming/renderers/BlockquoteRenderer.js.map +1 -0
  165. package/lib/module/streaming/renderers/CodeRenderer.js +123 -0
  166. package/lib/module/streaming/renderers/CodeRenderer.js.map +1 -0
  167. package/lib/module/streaming/renderers/HeadingRenderer.js +56 -0
  168. package/lib/module/streaming/renderers/HeadingRenderer.js.map +1 -0
  169. package/lib/module/streaming/renderers/ImageRenderer.js +48 -0
  170. package/lib/module/streaming/renderers/ImageRenderer.js.map +1 -0
  171. package/lib/module/streaming/renderers/LinkRenderer.js +44 -0
  172. package/lib/module/streaming/renderers/LinkRenderer.js.map +1 -0
  173. package/lib/module/streaming/renderers/ListRenderer.js +58 -0
  174. package/lib/module/streaming/renderers/ListRenderer.js.map +1 -0
  175. package/lib/module/streaming/renderers/TableRenderer.js +72 -0
  176. package/lib/module/streaming/renderers/TableRenderer.js.map +1 -0
  177. package/lib/module/streaming/renderers/TextRenderer.js +36 -0
  178. package/lib/module/streaming/renderers/TextRenderer.js.map +1 -0
  179. package/lib/module/streaming/renderers/index.js +13 -0
  180. package/lib/module/streaming/renderers/index.js.map +1 -0
  181. package/lib/module/streaming/renderers/renderInlineChildren.js +107 -0
  182. package/lib/module/streaming/renderers/renderInlineChildren.js.map +1 -0
  183. package/lib/module/streaming/renderers/renderNode.js +78 -0
  184. package/lib/module/streaming/renderers/renderNode.js.map +1 -0
  185. package/lib/module/theme/ThemeProvider.js +62 -0
  186. package/lib/module/theme/ThemeProvider.js.map +1 -0
  187. package/lib/module/theme/defaultTheme.js +92 -0
  188. package/lib/module/theme/defaultTheme.js.map +1 -0
  189. package/lib/module/theme/index.js +5 -0
  190. package/lib/module/theme/index.js.map +1 -0
  191. package/lib/module/theme/tokens.js +2 -0
  192. package/lib/module/theme/tokens.js.map +1 -0
  193. package/lib/module/types.d.js +2 -0
  194. package/lib/module/types.d.js.map +1 -0
  195. package/lib/module/voice/index.js +14 -0
  196. package/lib/module/voice/index.js.map +1 -0
  197. package/lib/module/voice/useSpeechRecognition.js +169 -0
  198. package/lib/module/voice/useSpeechRecognition.js.map +1 -0
  199. package/lib/typescript/src/chatbot/AIImage.d.ts +24 -0
  200. package/lib/typescript/src/chatbot/AIImage.d.ts.map +1 -0
  201. package/lib/typescript/src/chatbot/Attachments.d.ts +20 -0
  202. package/lib/typescript/src/chatbot/Attachments.d.ts.map +1 -0
  203. package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts +57 -0
  204. package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts.map +1 -0
  205. package/lib/typescript/src/chatbot/ChatMessageItem.d.ts +45 -0
  206. package/lib/typescript/src/chatbot/ChatMessageItem.d.ts.map +1 -0
  207. package/lib/typescript/src/chatbot/Conversation.d.ts +94 -0
  208. package/lib/typescript/src/chatbot/Conversation.d.ts.map +1 -0
  209. package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts +62 -0
  210. package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts.map +1 -0
  211. package/lib/typescript/src/chatbot/Message.d.ts +39 -0
  212. package/lib/typescript/src/chatbot/Message.d.ts.map +1 -0
  213. package/lib/typescript/src/chatbot/PromptInput.d.ts +93 -0
  214. package/lib/typescript/src/chatbot/PromptInput.d.ts.map +1 -0
  215. package/lib/typescript/src/chatbot/Reasoning.d.ts +14 -0
  216. package/lib/typescript/src/chatbot/Reasoning.d.ts.map +1 -0
  217. package/lib/typescript/src/chatbot/Shimmer.d.ts +13 -0
  218. package/lib/typescript/src/chatbot/Shimmer.d.ts.map +1 -0
  219. package/lib/typescript/src/chatbot/Sources.d.ts +17 -0
  220. package/lib/typescript/src/chatbot/Sources.d.ts.map +1 -0
  221. package/lib/typescript/src/chatbot/Suggestion.d.ts +15 -0
  222. package/lib/typescript/src/chatbot/Suggestion.d.ts.map +1 -0
  223. package/lib/typescript/src/chatbot/Tool.d.ts +30 -0
  224. package/lib/typescript/src/chatbot/Tool.d.ts.map +1 -0
  225. package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts +24 -0
  226. package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts.map +1 -0
  227. package/lib/typescript/src/chatbot/index.d.ts +29 -0
  228. package/lib/typescript/src/chatbot/index.d.ts.map +1 -0
  229. package/lib/typescript/src/chatbot/types.d.ts +49 -0
  230. package/lib/typescript/src/chatbot/types.d.ts.map +1 -0
  231. package/lib/typescript/src/hooks/index.d.ts +9 -0
  232. package/lib/typescript/src/hooks/index.d.ts.map +1 -0
  233. package/lib/typescript/src/hooks/useAutoScroll.d.ts +23 -0
  234. package/lib/typescript/src/hooks/useAutoScroll.d.ts.map +1 -0
  235. package/lib/typescript/src/hooks/useClipboard.d.ts +22 -0
  236. package/lib/typescript/src/hooks/useClipboard.d.ts.map +1 -0
  237. package/lib/typescript/src/hooks/useCollapsible.d.ts +28 -0
  238. package/lib/typescript/src/hooks/useCollapsible.d.ts.map +1 -0
  239. package/lib/typescript/src/hooks/useStickToBottom.d.ts +39 -0
  240. package/lib/typescript/src/hooks/useStickToBottom.d.ts.map +1 -0
  241. package/lib/typescript/src/index.d.ts +11 -0
  242. package/lib/typescript/src/index.d.ts.map +1 -0
  243. package/lib/typescript/src/primitives/Badge.d.ts +10 -0
  244. package/lib/typescript/src/primitives/Badge.d.ts.map +1 -0
  245. package/lib/typescript/src/primitives/Button.d.ts +16 -0
  246. package/lib/typescript/src/primitives/Button.d.ts.map +1 -0
  247. package/lib/typescript/src/primitives/Card.d.ts +33 -0
  248. package/lib/typescript/src/primitives/Card.d.ts.map +1 -0
  249. package/lib/typescript/src/primitives/Collapsible.d.ts +20 -0
  250. package/lib/typescript/src/primitives/Collapsible.d.ts.map +1 -0
  251. package/lib/typescript/src/primitives/ScrollArea.d.ts +10 -0
  252. package/lib/typescript/src/primitives/ScrollArea.d.ts.map +1 -0
  253. package/lib/typescript/src/primitives/index.d.ts +11 -0
  254. package/lib/typescript/src/primitives/index.d.ts.map +1 -0
  255. package/lib/typescript/src/streaming/StreamingMarkdown.d.ts +47 -0
  256. package/lib/typescript/src/streaming/StreamingMarkdown.d.ts.map +1 -0
  257. package/lib/typescript/src/streaming/index.d.ts +3 -0
  258. package/lib/typescript/src/streaming/index.d.ts.map +1 -0
  259. package/lib/typescript/src/streaming/parser.d.ts +41 -0
  260. package/lib/typescript/src/streaming/parser.d.ts.map +1 -0
  261. package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts +7 -0
  262. package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts.map +1 -0
  263. package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts +7 -0
  264. package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts.map +1 -0
  265. package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts +7 -0
  266. package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts.map +1 -0
  267. package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts +7 -0
  268. package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts.map +1 -0
  269. package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts +7 -0
  270. package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts.map +1 -0
  271. package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts +7 -0
  272. package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts.map +1 -0
  273. package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts +7 -0
  274. package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts.map +1 -0
  275. package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts +7 -0
  276. package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts.map +1 -0
  277. package/lib/typescript/src/streaming/renderers/index.d.ts +19 -0
  278. package/lib/typescript/src/streaming/renderers/index.d.ts.map +1 -0
  279. package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts +12 -0
  280. package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts.map +1 -0
  281. package/lib/typescript/src/streaming/renderers/renderNode.d.ts +8 -0
  282. package/lib/typescript/src/streaming/renderers/renderNode.d.ts.map +1 -0
  283. package/lib/typescript/src/theme/ThemeProvider.d.ts +14 -0
  284. package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -0
  285. package/lib/typescript/src/theme/defaultTheme.d.ts +4 -0
  286. package/lib/typescript/src/theme/defaultTheme.d.ts.map +1 -0
  287. package/lib/typescript/src/theme/index.d.ts +5 -0
  288. package/lib/typescript/src/theme/index.d.ts.map +1 -0
  289. package/lib/typescript/src/theme/tokens.d.ts +66 -0
  290. package/lib/typescript/src/theme/tokens.d.ts.map +1 -0
  291. package/lib/typescript/src/voice/index.d.ts +3 -0
  292. package/lib/typescript/src/voice/index.d.ts.map +1 -0
  293. package/lib/typescript/src/voice/useSpeechRecognition.d.ts +77 -0
  294. package/lib/typescript/src/voice/useSpeechRecognition.d.ts.map +1 -0
  295. package/package.json +132 -0
  296. package/src/chatbot/AIImage.tsx +166 -0
  297. package/src/chatbot/Attachments.tsx +382 -0
  298. package/src/chatbot/ChatErrorBoundary.tsx +230 -0
  299. package/src/chatbot/ChatMessageItem.tsx +195 -0
  300. package/src/chatbot/Conversation.tsx +537 -0
  301. package/src/chatbot/ConversationScrollButton.tsx +149 -0
  302. package/src/chatbot/Message.tsx +266 -0
  303. package/src/chatbot/PromptInput.tsx +532 -0
  304. package/src/chatbot/Reasoning.tsx +198 -0
  305. package/src/chatbot/Shimmer.tsx +146 -0
  306. package/src/chatbot/Sources.tsx +263 -0
  307. package/src/chatbot/Suggestion.tsx +123 -0
  308. package/src/chatbot/Tool.tsx +340 -0
  309. package/src/chatbot/adapters/uiMessageAdapter.ts +177 -0
  310. package/src/chatbot/index.ts +97 -0
  311. package/src/chatbot/types.ts +66 -0
  312. package/src/hooks/index.ts +17 -0
  313. package/src/hooks/useAutoScroll.ts +43 -0
  314. package/src/hooks/useClipboard.ts +46 -0
  315. package/src/hooks/useCollapsible.ts +42 -0
  316. package/src/hooks/useStickToBottom.ts +82 -0
  317. package/src/index.ts +139 -0
  318. package/src/primitives/Badge.tsx +119 -0
  319. package/src/primitives/Button.tsx +213 -0
  320. package/src/primitives/Card.tsx +221 -0
  321. package/src/primitives/Collapsible.tsx +168 -0
  322. package/src/primitives/ScrollArea.tsx +53 -0
  323. package/src/primitives/index.ts +36 -0
  324. package/src/streaming/StreamingMarkdown.tsx +282 -0
  325. package/src/streaming/index.ts +2 -0
  326. package/src/streaming/parser.ts +506 -0
  327. package/src/streaming/renderers/BlockquoteRenderer.tsx +42 -0
  328. package/src/streaming/renderers/CodeRenderer.tsx +158 -0
  329. package/src/streaming/renderers/HeadingRenderer.tsx +64 -0
  330. package/src/streaming/renderers/ImageRenderer.tsx +62 -0
  331. package/src/streaming/renderers/LinkRenderer.tsx +53 -0
  332. package/src/streaming/renderers/ListRenderer.tsx +65 -0
  333. package/src/streaming/renderers/TableRenderer.tsx +103 -0
  334. package/src/streaming/renderers/TextRenderer.tsx +39 -0
  335. package/src/streaming/renderers/index.ts +26 -0
  336. package/src/streaming/renderers/renderInlineChildren.tsx +115 -0
  337. package/src/streaming/renderers/renderNode.tsx +72 -0
  338. package/src/theme/ThemeProvider.tsx +77 -0
  339. package/src/theme/defaultTheme.ts +93 -0
  340. package/src/theme/index.ts +4 -0
  341. package/src/theme/tokens.ts +69 -0
  342. package/src/types.d.ts +71 -0
  343. package/src/voice/index.ts +15 -0
  344. package/src/voice/useSpeechRecognition.ts +230 -0
@@ -0,0 +1,532 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useImperativeHandle,
5
+ useRef,
6
+ useState,
7
+ type ReactNode,
8
+ } from 'react';
9
+ import {
10
+ ActivityIndicator,
11
+ Platform,
12
+ Pressable,
13
+ StyleSheet,
14
+ TextInput,
15
+ View,
16
+ type NativeSyntheticEvent,
17
+ type TextInputContentSizeChangeEventData,
18
+ type TextInputProps,
19
+ type ViewProps,
20
+ } from 'react-native';
21
+ import { Plus, Mic, ArrowUp, Square, AlertCircle } from 'lucide-react-native';
22
+ import { KeyboardStickyView } from 'react-native-keyboard-controller';
23
+ import { GlassView } from 'expo-glass-effect';
24
+ import { useAIElementsTheme } from '../theme';
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Types
28
+ // ---------------------------------------------------------------------------
29
+
30
+ /**
31
+ * Lifecycle status of the chat the PromptInput is attached to. Drives the
32
+ * shape of the right-side action button.
33
+ *
34
+ * - `'ready'` — idle. Right action shows mic (empty) or send (has text).
35
+ * - `'submitted'` — request just sent, awaiting first token. Right action
36
+ * shows a spinner.
37
+ * - `'streaming'` — assistant is generating. Right action shows a Stop
38
+ * button (calls `onStop` when pressed).
39
+ * - `'error'` — request failed. Right action shows an error icon; tap
40
+ * re-submits.
41
+ *
42
+ * Inspired by Vercel ai-elements `PromptInputSubmit.status`.
43
+ */
44
+ export type PromptInputStatus = 'ready' | 'submitted' | 'streaming' | 'error';
45
+
46
+ /** Imperative handle exposed via ref. */
47
+ export interface PromptInputRef {
48
+ /** Focus the underlying TextInput. */
49
+ focus: () => void;
50
+ /** Blur the underlying TextInput. */
51
+ blur: () => void;
52
+ /** Clear the input value and reset the expanding-textarea height. */
53
+ clear: () => void;
54
+ /** Whether the underlying TextInput currently has focus. */
55
+ isFocused: () => boolean;
56
+ }
57
+
58
+ export interface PromptInputProps extends Omit<ViewProps, 'children'> {
59
+ /** Current input text value (controlled). */
60
+ value: string;
61
+ /** Called when the input text changes. */
62
+ onChangeText: (text: string) => void;
63
+ /**
64
+ * Called when the user submits — either by tapping the send button or
65
+ * pressing enter/return on the keyboard.
66
+ */
67
+ onSubmit: () => void;
68
+ /**
69
+ * Called when the user taps the Stop button while `status === 'streaming'`.
70
+ * If omitted, the Stop button still appears but does nothing on press.
71
+ */
72
+ onStop?: () => void;
73
+ /**
74
+ * Lifecycle status. When omitted (or `'ready'`), the right-side action
75
+ * uses the legacy mic-or-send behavior driven by `disabled`.
76
+ */
77
+ status?: PromptInputStatus;
78
+ /**
79
+ * Disables editing. Independent of `status` so callers can keep the bar
80
+ * editable while showing a loader, or vice-versa.
81
+ */
82
+ disabled?: boolean;
83
+ /** Placeholder text. Default: `"Ask me anything..."` */
84
+ placeholder?: string;
85
+ /** Minimum pill height. Default `36`. */
86
+ minHeight?: number;
87
+ /** Maximum pill height before the textarea scrolls. Default `100`. */
88
+ maxHeight?: number;
89
+ /** Safe-area bottom inset — applied to the row and the keyboard offset. */
90
+ bottomInset?: number;
91
+ /** Slot above the input row (e.g. starter suggestions). */
92
+ suggestions?: ReactNode;
93
+ /** Optional override for the default left action (Plus circle). */
94
+ leftAction?: ReactNode;
95
+ /** Pressed when the default Plus button is tapped. */
96
+ onLeftActionPress?: () => void;
97
+ /** Optional override for the default right action (Mic / Send / Stop). */
98
+ rightAction?: ReactNode;
99
+ /**
100
+ * True while a speech-recognition session is active. When set, the
101
+ * default mic button flips to an "active" look (destructive tint +
102
+ * subtle pulsing) so the recording state is obvious. Pair with
103
+ * `onMicPress` to actually start/stop recognition.
104
+ */
105
+ isListening?: boolean;
106
+ /**
107
+ * Handler for the default mic button. When omitted (or when a custom
108
+ * `rightAction` is provided) the built-in mic is a no-op placeholder.
109
+ * Typically wired to a `useSpeechRecognition` hook's `toggle()`.
110
+ */
111
+ onMicPress?: () => void;
112
+ /**
113
+ * iOS software keyboard appearance. Defaults to the current theme's mode
114
+ * (`'dark'` when the theme is dark, `'light'` otherwise). Pass `'default'`
115
+ * to fall back to the system setting, or force a specific value.
116
+ *
117
+ * Note: iOS only — Android ignores this.
118
+ */
119
+ keyboardAppearance?: TextInputProps['keyboardAppearance'];
120
+ }
121
+
122
+ // ---------------------------------------------------------------------------
123
+ // Constants
124
+ // ---------------------------------------------------------------------------
125
+
126
+ const DEFAULT_MIN_HEIGHT = 36;
127
+ const DEFAULT_MAX_HEIGHT = 100;
128
+ const CIRCLE_BUTTON_SIZE = 36;
129
+ const ICON_SIZE = 18;
130
+ const isIOS = Platform.OS === 'ios';
131
+
132
+ // ---------------------------------------------------------------------------
133
+ // CircleButton — lucide icon inside a native iOS glass circle.
134
+ // Uses `expo-glass-effect`'s GlassView, which renders a real
135
+ // UIVisualEffectView on iOS (liquid glass on iOS 26+) and degrades to a
136
+ // plain View on Android/web.
137
+ // ---------------------------------------------------------------------------
138
+
139
+ interface CircleButtonProps {
140
+ /** Icon node (any RN component — lucide, image, custom). */
141
+ icon: React.ReactNode;
142
+ /** Press handler. Skipped when undefined / disabled. */
143
+ onPress?: () => void;
144
+ /** Disables the button visually and prevents press events. */
145
+ isDisabled?: boolean;
146
+ /**
147
+ * Optional tint color for the glass — used to make the active send
148
+ * button visually prominent. Hex string.
149
+ */
150
+ tintColor?: string;
151
+ /** Drives the GlassView color scheme so the glass picks the right tone. */
152
+ dark: boolean;
153
+ /** Background color used on non-iOS where GlassView is a plain View. */
154
+ fallbackBackground: string;
155
+ /** Accessibility label for screen readers. */
156
+ accessibilityLabel?: string;
157
+ }
158
+
159
+ function CircleButton({
160
+ icon,
161
+ onPress,
162
+ isDisabled = false,
163
+ tintColor,
164
+ dark,
165
+ fallbackBackground,
166
+ accessibilityLabel,
167
+ }: CircleButtonProps) {
168
+ return (
169
+ <GlassView
170
+ glassEffectStyle={isIOS ? 'regular' : 'none'}
171
+ tintColor={tintColor}
172
+ isInteractive
173
+ colorScheme={dark ? 'dark' : 'light'}
174
+ style={[
175
+ styles.circleButton,
176
+ // On non-iOS GlassView is just a plain View, so paint the bg
177
+ // ourselves to keep the visible circle.
178
+ !isIOS && { backgroundColor: fallbackBackground },
179
+ ]}
180
+ >
181
+ <Pressable
182
+ onPress={onPress}
183
+ disabled={isDisabled}
184
+ accessibilityLabel={accessibilityLabel}
185
+ accessibilityRole="button"
186
+ accessibilityState={{ disabled: isDisabled }}
187
+ style={({ pressed }) => [
188
+ styles.circleButtonInner,
189
+ { opacity: pressed ? 0.6 : isDisabled ? 0.5 : 1 },
190
+ ]}
191
+ >
192
+ {icon}
193
+ </Pressable>
194
+ </GlassView>
195
+ );
196
+ }
197
+
198
+ CircleButton.displayName = 'PromptInput.CircleButton';
199
+
200
+ // ---------------------------------------------------------------------------
201
+ // Component
202
+ // ---------------------------------------------------------------------------
203
+
204
+ /**
205
+ * The sticky bottom input bar for a chat. Owns its own expanding-textarea
206
+ * height state so keystrokes don't re-render the parent screen. Moves with
207
+ * the keyboard via `KeyboardStickyView` from `react-native-keyboard-controller`.
208
+ *
209
+ * The right-side action is computed from `status`:
210
+ * - `'submitted'` → spinner
211
+ * - `'streaming'` → Stop button (calls `onStop`)
212
+ * - `'error'` → error icon (tap re-submits)
213
+ * - otherwise → Mic (empty input) or Send (has input)
214
+ *
215
+ * @example
216
+ * ```tsx
217
+ * <PromptInput
218
+ * value={input}
219
+ * onChangeText={setInput}
220
+ * onSubmit={sendMessage}
221
+ * onStop={stop}
222
+ * status={isStreaming ? 'streaming' : 'ready'}
223
+ * bottomInset={insets.bottom}
224
+ * suggestions={messages.length === 0 ? <Suggestions /> : null}
225
+ * />
226
+ * ```
227
+ */
228
+ const PromptInputImpl = forwardRef<PromptInputRef, PromptInputProps>(
229
+ function PromptInput(
230
+ {
231
+ value,
232
+ onChangeText,
233
+ onSubmit,
234
+ onStop,
235
+ status = 'ready',
236
+ disabled = false,
237
+ placeholder = 'Ask me anything...',
238
+ minHeight = DEFAULT_MIN_HEIGHT,
239
+ maxHeight = DEFAULT_MAX_HEIGHT,
240
+ bottomInset = 0,
241
+ suggestions,
242
+ leftAction,
243
+ onLeftActionPress,
244
+ rightAction,
245
+ isListening = false,
246
+ onMicPress,
247
+ keyboardAppearance,
248
+ style,
249
+ ...viewProps
250
+ },
251
+ ref,
252
+ ) {
253
+ const theme = useAIElementsTheme();
254
+ const textInputRef = useRef<TextInput>(null);
255
+ const [inputHeight, setInputHeight] = useState(minHeight);
256
+
257
+ // Default the iOS keyboard to match the current theme. An explicit prop
258
+ // from the caller still wins.
259
+ const effectiveKeyboardAppearance =
260
+ keyboardAppearance ?? (theme.dark ? 'dark' : 'light');
261
+
262
+ const hasText = value.trim().length > 0;
263
+ const canSubmit = hasText && !disabled && status === 'ready';
264
+
265
+ useImperativeHandle(
266
+ ref,
267
+ () => ({
268
+ focus: () => textInputRef.current?.focus(),
269
+ blur: () => textInputRef.current?.blur(),
270
+ clear: () => {
271
+ onChangeText('');
272
+ setInputHeight(minHeight);
273
+ },
274
+ isFocused: () => textInputRef.current?.isFocused() ?? false,
275
+ }),
276
+ [onChangeText, minHeight],
277
+ );
278
+
279
+ const handleContentSizeChange = useCallback(
280
+ (e: NativeSyntheticEvent<TextInputContentSizeChangeEventData>) => {
281
+ const next = Math.min(
282
+ Math.max(e.nativeEvent.contentSize.height, minHeight),
283
+ maxHeight,
284
+ );
285
+ setInputHeight(next);
286
+ },
287
+ [minHeight, maxHeight],
288
+ );
289
+
290
+ const handleSubmit = useCallback(() => {
291
+ if (!canSubmit) return;
292
+ onSubmit();
293
+ setInputHeight(minHeight);
294
+ }, [canSubmit, onSubmit, minHeight]);
295
+
296
+ // --- Defaults -----------------------------------------------------------
297
+ // CircleButton wraps a lucide icon inside a real native iOS glass effect
298
+ // (UIVisualEffectView / liquid glass on iOS 26+). On Android/web it
299
+ // degrades to a flat themed circle so behavior is preserved.
300
+
301
+ const defaultLeftAction = (
302
+ <CircleButton
303
+ icon={<Plus size={ICON_SIZE} color={theme.colors.foreground} />}
304
+ onPress={onLeftActionPress}
305
+ dark={theme.dark}
306
+ fallbackBackground={theme.colors.secondary}
307
+ accessibilityLabel="More options"
308
+ />
309
+ );
310
+
311
+ // The right-side action is a function of `status` first, then text content.
312
+ const defaultRightAction = (() => {
313
+ if (status === 'streaming') {
314
+ return (
315
+ <CircleButton
316
+ icon={
317
+ <Square
318
+ size={14}
319
+ color={theme.colors.background}
320
+ fill={theme.colors.background}
321
+ />
322
+ }
323
+ onPress={onStop}
324
+ tintColor={theme.colors.foreground}
325
+ dark={theme.dark}
326
+ fallbackBackground={theme.colors.foreground}
327
+ accessibilityLabel="Stop generating"
328
+ />
329
+ );
330
+ }
331
+
332
+ if (status === 'submitted') {
333
+ return (
334
+ <CircleButton
335
+ icon={
336
+ <ActivityIndicator
337
+ size="small"
338
+ color={theme.colors.foreground}
339
+ />
340
+ }
341
+ isDisabled
342
+ dark={theme.dark}
343
+ fallbackBackground={theme.colors.secondary}
344
+ accessibilityLabel="Sending"
345
+ />
346
+ );
347
+ }
348
+
349
+ if (status === 'error') {
350
+ return (
351
+ <CircleButton
352
+ icon={
353
+ <AlertCircle size={ICON_SIZE} color={theme.colors.destructive} />
354
+ }
355
+ onPress={hasText && !disabled ? handleSubmit : undefined}
356
+ dark={theme.dark}
357
+ fallbackBackground={theme.colors.secondary}
358
+ accessibilityLabel="Send failed — tap to retry"
359
+ />
360
+ );
361
+ }
362
+
363
+ // status === 'ready' — original mic/send behavior.
364
+ if (hasText) {
365
+ return (
366
+ <CircleButton
367
+ icon={
368
+ <ArrowUp
369
+ size={ICON_SIZE}
370
+ color={
371
+ canSubmit
372
+ ? theme.colors.background
373
+ : theme.colors.mutedForeground
374
+ }
375
+ />
376
+ }
377
+ onPress={canSubmit ? handleSubmit : undefined}
378
+ isDisabled={!canSubmit}
379
+ // Tint the glass with the foreground color so the active send
380
+ // button reads as prominent against the muted plus/mic siblings.
381
+ tintColor={canSubmit ? theme.colors.foreground : undefined}
382
+ dark={theme.dark}
383
+ fallbackBackground={
384
+ canSubmit ? theme.colors.foreground : theme.colors.secondary
385
+ }
386
+ accessibilityLabel="Send message"
387
+ />
388
+ );
389
+ }
390
+
391
+ // Empty input + not streaming → Mic (voice input).
392
+ // While listening, tint the glass with `destructive` and flip the
393
+ // icon color so the recording state is unmissable.
394
+ return (
395
+ <CircleButton
396
+ icon={
397
+ <Mic
398
+ size={ICON_SIZE}
399
+ color={
400
+ isListening
401
+ ? theme.colors.destructiveForeground
402
+ : theme.colors.foreground
403
+ }
404
+ />
405
+ }
406
+ onPress={onMicPress}
407
+ tintColor={isListening ? theme.colors.destructive : undefined}
408
+ dark={theme.dark}
409
+ fallbackBackground={
410
+ isListening ? theme.colors.destructive : theme.colors.secondary
411
+ }
412
+ accessibilityLabel={
413
+ isListening ? 'Stop voice input' : 'Start voice input'
414
+ }
415
+ />
416
+ );
417
+ })();
418
+
419
+ return (
420
+ <KeyboardStickyView offset={{ opened: bottomInset, closed: 0 }}>
421
+ {suggestions}
422
+
423
+ <View
424
+ {...viewProps}
425
+ style={[
426
+ styles.row,
427
+ {
428
+ paddingHorizontal: theme.spacing.md,
429
+ paddingBottom: bottomInset + theme.spacing.sm,
430
+ },
431
+ style,
432
+ ]}
433
+ >
434
+ {leftAction ?? defaultLeftAction}
435
+
436
+ <GlassView
437
+ glassEffectStyle={isIOS ? 'regular' : 'none'}
438
+ isInteractive
439
+ colorScheme={theme.dark ? 'dark' : 'light'}
440
+ style={[
441
+ styles.inputPill,
442
+ // On iOS, the glass provides its own subtle edge — no border.
443
+ // On Android/web fall back to the original tinted pill.
444
+ isIOS
445
+ ? null
446
+ : {
447
+ backgroundColor: theme.colors.secondary,
448
+ borderWidth: 1,
449
+ borderColor: theme.dark
450
+ ? 'transparent'
451
+ : theme.colors.border,
452
+ },
453
+ ]}
454
+ >
455
+ <TextInput
456
+ ref={textInputRef}
457
+ value={value}
458
+ onChangeText={onChangeText}
459
+ placeholder={placeholder}
460
+ placeholderTextColor={theme.colors.mutedForeground}
461
+ multiline
462
+ editable={!disabled}
463
+ keyboardAppearance={effectiveKeyboardAppearance}
464
+ onContentSizeChange={handleContentSizeChange}
465
+ onSubmitEditing={handleSubmit}
466
+ blurOnSubmit={false}
467
+ accessibilityLabel="Message input"
468
+ style={[
469
+ styles.textInput,
470
+ {
471
+ height: inputHeight,
472
+ maxHeight,
473
+ color: theme.colors.foreground,
474
+ fontSize: theme.typography.fontSize.md,
475
+ fontFamily: theme.typography.fontFamily,
476
+ },
477
+ ]}
478
+ />
479
+ </GlassView>
480
+
481
+ {rightAction ?? defaultRightAction}
482
+ </View>
483
+ </KeyboardStickyView>
484
+ );
485
+ },
486
+ );
487
+
488
+ PromptInputImpl.displayName = 'PromptInput';
489
+
490
+ export const PromptInput = PromptInputImpl;
491
+
492
+ // ---------------------------------------------------------------------------
493
+ // Styles — static so they're not reallocated per render
494
+ // ---------------------------------------------------------------------------
495
+
496
+ const styles = StyleSheet.create({
497
+ row: {
498
+ flexDirection: 'row',
499
+ alignItems: 'flex-end',
500
+ gap: 8,
501
+ },
502
+ circleButton: {
503
+ width: CIRCLE_BUTTON_SIZE,
504
+ height: CIRCLE_BUTTON_SIZE,
505
+ borderRadius: CIRCLE_BUTTON_SIZE / 2,
506
+ // Clip the GlassView blur to the rounded shape on iOS, and the
507
+ // background fill on other platforms.
508
+ overflow: 'hidden',
509
+ alignItems: 'center',
510
+ justifyContent: 'center',
511
+ },
512
+ circleButtonInner: {
513
+ width: '100%',
514
+ height: '100%',
515
+ alignItems: 'center',
516
+ justifyContent: 'center',
517
+ },
518
+ inputPill: {
519
+ flex: 1,
520
+ borderRadius: 20,
521
+ paddingHorizontal: 14,
522
+ // Clip the GlassView blur (and the non-iOS background) to the rounded
523
+ // pill shape.
524
+ overflow: 'hidden',
525
+ },
526
+ textInput: {
527
+ textAlignVertical: 'top',
528
+ paddingTop: Platform.OS === 'ios' ? 8 : 6,
529
+ paddingBottom: Platform.OS === 'ios' ? 8 : 6,
530
+ paddingHorizontal: 0,
531
+ },
532
+ });