@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,123 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import {
3
+ Pressable,
4
+ ScrollView,
5
+ StyleSheet,
6
+ Text,
7
+ type StyleProp,
8
+ type TextStyle,
9
+ type ViewStyle,
10
+ } from 'react-native';
11
+ import { useAIElementsTheme } from '../theme';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Types
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface SuggestionItem {
18
+ label: string;
19
+ value?: string;
20
+ }
21
+
22
+ export interface SuggestionProps {
23
+ suggestions: SuggestionItem[];
24
+ onSelect: (value: string) => void;
25
+ style?: StyleProp<ViewStyle>;
26
+ }
27
+
28
+ // ---------------------------------------------------------------------------
29
+ // Chip
30
+ // ---------------------------------------------------------------------------
31
+
32
+ interface ChipProps {
33
+ item: SuggestionItem;
34
+ onPress: (value: string) => void;
35
+ }
36
+
37
+ function Chip({ item, onPress }: ChipProps) {
38
+ const theme = useAIElementsTheme();
39
+
40
+ const handlePress = useCallback(() => {
41
+ onPress(item.value ?? item.label);
42
+ }, [item, onPress]);
43
+
44
+ const textStyle: TextStyle = {
45
+ color: theme.colors.foreground,
46
+ fontSize: theme.typography.fontSize.sm,
47
+ fontFamily: theme.typography.fontFamily,
48
+ fontWeight: theme.typography.fontWeight.medium as TextStyle['fontWeight'],
49
+ };
50
+
51
+ return (
52
+ <Pressable
53
+ onPress={handlePress}
54
+ style={({ pressed }) => [
55
+ styles.chip,
56
+ {
57
+ borderColor: theme.colors.border,
58
+ borderRadius: theme.radius.full,
59
+ paddingHorizontal: theme.spacing.lg,
60
+ paddingVertical: theme.spacing.sm,
61
+ backgroundColor: pressed ? theme.colors.muted : theme.colors.background,
62
+ },
63
+ ]}
64
+ >
65
+ <Text style={textStyle}>{item.label}</Text>
66
+ </Pressable>
67
+ );
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Component
72
+ // ---------------------------------------------------------------------------
73
+
74
+ function SuggestionComponent({
75
+ suggestions,
76
+ onSelect,
77
+ style,
78
+ }: SuggestionProps) {
79
+ const theme = useAIElementsTheme();
80
+
81
+ if (suggestions.length === 0) {
82
+ return null;
83
+ }
84
+
85
+ return (
86
+ <ScrollView
87
+ horizontal
88
+ showsHorizontalScrollIndicator={false}
89
+ contentContainerStyle={[
90
+ styles.container,
91
+ {
92
+ paddingHorizontal: theme.spacing.lg,
93
+ gap: theme.spacing.sm,
94
+ },
95
+ ]}
96
+ style={style}
97
+ >
98
+ {suggestions.map((item, index) => (
99
+ <Chip key={`${item.label}-${index}`} item={item} onPress={onSelect} />
100
+ ))}
101
+ </ScrollView>
102
+ );
103
+ }
104
+
105
+ // ---------------------------------------------------------------------------
106
+ // Styles
107
+ // ---------------------------------------------------------------------------
108
+
109
+ const styles = StyleSheet.create({
110
+ container: {
111
+ flexDirection: 'row',
112
+ alignItems: 'center',
113
+ },
114
+ chip: {
115
+ borderWidth: 1,
116
+ },
117
+ });
118
+
119
+ // ---------------------------------------------------------------------------
120
+ // Export
121
+ // ---------------------------------------------------------------------------
122
+
123
+ export const Suggestion = memo(SuggestionComponent);
@@ -0,0 +1,340 @@
1
+ import React, { createContext, memo, useContext, type ReactNode } from 'react';
2
+ import {
3
+ StyleSheet,
4
+ Text,
5
+ View,
6
+ type StyleProp,
7
+ type TextStyle,
8
+ type ViewStyle,
9
+ } from 'react-native';
10
+ import {
11
+ CheckCircle,
12
+ Loader,
13
+ AlertCircle,
14
+ Clock,
15
+ Wrench,
16
+ } from 'lucide-react-native';
17
+ import { useAIElementsTheme } from '../theme';
18
+ import type { AIElementsTheme } from '../theme';
19
+ import { Badge, type BadgeVariant } from '../primitives';
20
+ import {
21
+ Collapsible,
22
+ CollapsibleTrigger,
23
+ CollapsibleContent,
24
+ } from '../primitives';
25
+
26
+ // ---------------------------------------------------------------------------
27
+ // Types
28
+ // ---------------------------------------------------------------------------
29
+
30
+ export type ToolStatus = 'pending' | 'running' | 'completed' | 'failed';
31
+
32
+ export interface ToolProps {
33
+ name: string;
34
+ status: ToolStatus;
35
+ args?: Record<string, any>;
36
+ result?: string;
37
+ children?: ReactNode;
38
+ style?: StyleProp<ViewStyle>;
39
+ }
40
+
41
+ interface ToolContextValue {
42
+ name: string;
43
+ status: ToolStatus;
44
+ args?: Record<string, any>;
45
+ result?: string;
46
+ }
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // Context
50
+ // ---------------------------------------------------------------------------
51
+
52
+ const ToolContext = createContext<ToolContextValue | null>(null);
53
+
54
+ function useToolContext(): ToolContextValue {
55
+ const ctx = useContext(ToolContext);
56
+ if (!ctx) {
57
+ throw new Error(
58
+ 'Tool compound components must be used within a <Tool>.',
59
+ );
60
+ }
61
+ return ctx;
62
+ }
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Status helpers
66
+ // ---------------------------------------------------------------------------
67
+
68
+ function getStatusBadgeVariant(status: ToolStatus): BadgeVariant {
69
+ switch (status) {
70
+ case 'pending':
71
+ return 'secondary';
72
+ case 'running':
73
+ return 'warning';
74
+ case 'completed':
75
+ return 'success';
76
+ case 'failed':
77
+ return 'destructive';
78
+ }
79
+ }
80
+
81
+ function getStatusIcon(status: ToolStatus, theme: AIElementsTheme) {
82
+ const size = 14;
83
+
84
+ switch (status) {
85
+ case 'pending':
86
+ return <Clock size={size} color={theme.colors.mutedForeground} />;
87
+ case 'running':
88
+ return <Loader size={size} color={theme.colors.warning} />;
89
+ case 'completed':
90
+ return <CheckCircle size={size} color={theme.colors.success} />;
91
+ case 'failed':
92
+ return <AlertCircle size={size} color={theme.colors.destructive} />;
93
+ }
94
+ }
95
+
96
+ function getStatusLabel(status: ToolStatus): string {
97
+ switch (status) {
98
+ case 'pending':
99
+ return 'Pending';
100
+ case 'running':
101
+ return 'Running';
102
+ case 'completed':
103
+ return 'Completed';
104
+ case 'failed':
105
+ return 'Failed';
106
+ }
107
+ }
108
+
109
+ // ---------------------------------------------------------------------------
110
+ // Tool (root)
111
+ // ---------------------------------------------------------------------------
112
+
113
+ function ToolRoot({ name, status, args, result, children, style }: ToolProps) {
114
+ const theme = useAIElementsTheme();
115
+
116
+ return (
117
+ <ToolContext.Provider value={{ name, status, args, result }}>
118
+ <View
119
+ style={[
120
+ styles.container,
121
+ {
122
+ backgroundColor: theme.colors.card,
123
+ borderColor: theme.colors.border,
124
+ borderRadius: theme.radius.md,
125
+ padding: theme.spacing.md,
126
+ },
127
+ style,
128
+ ]}
129
+ >
130
+ {children ?? (
131
+ <>
132
+ <ToolHeader />
133
+ {args && Object.keys(args).length > 0 && <ToolArgs />}
134
+ {result && <ToolResult />}
135
+ </>
136
+ )}
137
+ </View>
138
+ </ToolContext.Provider>
139
+ );
140
+ }
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // ToolHeader
144
+ // ---------------------------------------------------------------------------
145
+
146
+ export interface ToolHeaderProps {
147
+ style?: StyleProp<ViewStyle>;
148
+ }
149
+
150
+ function ToolHeaderComponent({ style }: ToolHeaderProps) {
151
+ const theme = useAIElementsTheme();
152
+ const { name, status } = useToolContext();
153
+
154
+ const nameStyle: TextStyle = {
155
+ color: theme.colors.foreground,
156
+ fontSize: theme.typography.fontSize.sm,
157
+ fontWeight: theme.typography.fontWeight.semibold as TextStyle['fontWeight'],
158
+ fontFamily: theme.typography.fontFamily,
159
+ };
160
+
161
+ return (
162
+ <View style={[styles.header, { gap: theme.spacing.sm }, style]}>
163
+ <Wrench size={16} color={theme.colors.mutedForeground} />
164
+ <Text style={nameStyle} numberOfLines={1}>
165
+ {name}
166
+ </Text>
167
+ <Badge variant={getStatusBadgeVariant(status)}>
168
+ <View style={[styles.badgeContent, { gap: theme.spacing.xs }]}>
169
+ {getStatusIcon(status, theme)}
170
+ <Text
171
+ style={{
172
+ color:
173
+ status === 'completed'
174
+ ? theme.colors.successForeground
175
+ : status === 'failed'
176
+ ? theme.colors.destructiveForeground
177
+ : status === 'running'
178
+ ? theme.colors.warningForeground
179
+ : theme.colors.secondaryForeground,
180
+ fontSize: theme.typography.fontSize.xs,
181
+ fontWeight: theme.typography.fontWeight
182
+ .semibold as TextStyle['fontWeight'],
183
+ fontFamily: theme.typography.fontFamily,
184
+ // Pin the text's line box to the 14px icon height so
185
+ // `alignItems: center` in the row produces pixel-aligned
186
+ // cross-axis centering between glyph and icon.
187
+ lineHeight: 14,
188
+ includeFontPadding: false,
189
+ textAlignVertical: 'center',
190
+ }}
191
+ >
192
+ {getStatusLabel(status)}
193
+ </Text>
194
+ </View>
195
+ </Badge>
196
+ </View>
197
+ );
198
+ }
199
+
200
+ // ---------------------------------------------------------------------------
201
+ // ToolArgs
202
+ // ---------------------------------------------------------------------------
203
+
204
+ export interface ToolArgsProps {
205
+ style?: StyleProp<ViewStyle>;
206
+ }
207
+
208
+ function ToolArgsComponent({ style }: ToolArgsProps) {
209
+ const theme = useAIElementsTheme();
210
+ const { args } = useToolContext();
211
+
212
+ if (!args || Object.keys(args).length === 0) {
213
+ return null;
214
+ }
215
+
216
+ const labelStyle: TextStyle = {
217
+ color: theme.colors.mutedForeground,
218
+ fontSize: theme.typography.fontSize.xs,
219
+ fontWeight: theme.typography.fontWeight.medium as TextStyle['fontWeight'],
220
+ fontFamily: theme.typography.fontFamily,
221
+ };
222
+
223
+ const codeStyle: TextStyle = {
224
+ color: theme.colors.foreground,
225
+ fontSize: theme.typography.fontSize.xs,
226
+ fontFamily: theme.typography.monoFontFamily,
227
+ lineHeight:
228
+ theme.typography.fontSize.xs * theme.typography.lineHeight.relaxed,
229
+ };
230
+
231
+ return (
232
+ <Collapsible style={[{ marginTop: theme.spacing.sm }, style]}>
233
+ <CollapsibleTrigger>
234
+ <Text style={labelStyle}>Arguments</Text>
235
+ </CollapsibleTrigger>
236
+ <CollapsibleContent>
237
+ <View
238
+ style={[
239
+ styles.codeBlock,
240
+ {
241
+ backgroundColor: theme.colors.muted,
242
+ borderRadius: theme.radius.sm,
243
+ padding: theme.spacing.sm,
244
+ marginTop: theme.spacing.xs,
245
+ },
246
+ ]}
247
+ >
248
+ <Text style={codeStyle}>
249
+ {JSON.stringify(args, null, 2)}
250
+ </Text>
251
+ </View>
252
+ </CollapsibleContent>
253
+ </Collapsible>
254
+ );
255
+ }
256
+
257
+ // ---------------------------------------------------------------------------
258
+ // ToolResult
259
+ // ---------------------------------------------------------------------------
260
+
261
+ export interface ToolResultProps {
262
+ style?: StyleProp<ViewStyle>;
263
+ }
264
+
265
+ function ToolResultComponent({ style }: ToolResultProps) {
266
+ const theme = useAIElementsTheme();
267
+ const { result } = useToolContext();
268
+
269
+ if (!result) {
270
+ return null;
271
+ }
272
+
273
+ const labelStyle: TextStyle = {
274
+ color: theme.colors.mutedForeground,
275
+ fontSize: theme.typography.fontSize.xs,
276
+ fontWeight: theme.typography.fontWeight.medium as TextStyle['fontWeight'],
277
+ fontFamily: theme.typography.fontFamily,
278
+ };
279
+
280
+ const resultTextStyle: TextStyle = {
281
+ color: theme.colors.foreground,
282
+ fontSize: theme.typography.fontSize.xs,
283
+ fontFamily: theme.typography.monoFontFamily,
284
+ lineHeight:
285
+ theme.typography.fontSize.xs * theme.typography.lineHeight.relaxed,
286
+ };
287
+
288
+ return (
289
+ <Collapsible style={[{ marginTop: theme.spacing.sm }, style]}>
290
+ <CollapsibleTrigger>
291
+ <Text style={labelStyle}>Result</Text>
292
+ </CollapsibleTrigger>
293
+ <CollapsibleContent>
294
+ <View
295
+ style={[
296
+ styles.codeBlock,
297
+ {
298
+ backgroundColor: theme.colors.muted,
299
+ borderRadius: theme.radius.sm,
300
+ padding: theme.spacing.sm,
301
+ marginTop: theme.spacing.xs,
302
+ },
303
+ ]}
304
+ >
305
+ <Text style={resultTextStyle}>{result}</Text>
306
+ </View>
307
+ </CollapsibleContent>
308
+ </Collapsible>
309
+ );
310
+ }
311
+
312
+ // ---------------------------------------------------------------------------
313
+ // Styles
314
+ // ---------------------------------------------------------------------------
315
+
316
+ const styles = StyleSheet.create({
317
+ container: {
318
+ borderWidth: 1,
319
+ },
320
+ header: {
321
+ flexDirection: 'row',
322
+ alignItems: 'center',
323
+ },
324
+ badgeContent: {
325
+ flexDirection: 'row',
326
+ alignItems: 'center',
327
+ },
328
+ codeBlock: {
329
+ overflow: 'hidden',
330
+ },
331
+ });
332
+
333
+ // ---------------------------------------------------------------------------
334
+ // Exports
335
+ // ---------------------------------------------------------------------------
336
+
337
+ export const Tool = memo(ToolRoot);
338
+ export const ToolHeader = memo(ToolHeaderComponent);
339
+ export const ToolArgs = memo(ToolArgsComponent);
340
+ export const ToolResult = memo(ToolResultComponent);
@@ -0,0 +1,177 @@
1
+ import type {
2
+ UIMessage,
3
+ UIMessagePart,
4
+ TextUIPart,
5
+ ReasoningUIPart,
6
+ SourceUrlUIPart,
7
+ } from 'ai';
8
+ import type { ChatMessageData, ChatTool } from '../types';
9
+ import type { ToolStatus } from '../Tool';
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // UIMessage → ChatMessageData
13
+ // ---------------------------------------------------------------------------
14
+ //
15
+ // `@ai-sdk/react`'s `useChat()` returns messages in the canonical Vercel AI
16
+ // SDK shape: each message has a `parts` array, where each part is a tagged
17
+ // union (`text` / `reasoning` / `tool-*` / `source-url` / etc). Our
18
+ // `ChatMessageItem` consumes a flatter `ChatMessageData` shape, so this file
19
+ // provides the (small) adapter every consumer of `useChat` will need.
20
+ //
21
+ // The adapter is intentionally tolerant: missing parts are mapped to
22
+ // `undefined` and the renderer skips them.
23
+ //
24
+ // **Why `import type` only?** `ai` is an optional peer dependency of this
25
+ // package — consumers who don't use `@ai-sdk/react` shouldn't have to
26
+ // install it. All imports from `ai` are type-only here, so they're erased
27
+ // at runtime and the adapter function itself is plain JS that operates on
28
+ // structural-shaped inputs.
29
+ // ---------------------------------------------------------------------------
30
+
31
+ const isTextPart = (p: UIMessagePart<never, never>): p is TextUIPart =>
32
+ p.type === 'text';
33
+
34
+ const isReasoningPart = (
35
+ p: UIMessagePart<never, never>,
36
+ ): p is ReasoningUIPart => p.type === 'reasoning';
37
+
38
+ const isSourceUrlPart = (
39
+ p: UIMessagePart<never, never>,
40
+ ): p is SourceUrlUIPart => p.type === 'source-url';
41
+
42
+ /**
43
+ * Type guard for any tool part — covers both static `tool-${name}` parts
44
+ * and the `dynamic-tool` part. Both expose `state`, `toolCallId`, `input`,
45
+ * and (when complete) `output` / `errorText`.
46
+ */
47
+ function isAnyToolPart(p: UIMessagePart<never, never>): p is Extract<
48
+ UIMessagePart<never, never>,
49
+ { toolCallId: string }
50
+ > {
51
+ return p.type.startsWith('tool-') || p.type === 'dynamic-tool';
52
+ }
53
+
54
+ /** Extract the tool name from a `tool-${name}` part type, or fall back. */
55
+ function getToolName(part: { type: string; toolName?: string }): string {
56
+ if (part.type === 'dynamic-tool' && typeof part.toolName === 'string') {
57
+ return part.toolName;
58
+ }
59
+ if (part.type.startsWith('tool-')) {
60
+ return part.type.slice('tool-'.length);
61
+ }
62
+ return 'tool';
63
+ }
64
+
65
+ /**
66
+ * Map the AI SDK's tool-call lifecycle (`'input-streaming'` → `'output-error'`)
67
+ * onto our `ToolStatus` (`'pending' | 'running' | 'completed' | 'failed'`).
68
+ */
69
+ function mapToolState(state: string | undefined): ToolStatus {
70
+ switch (state) {
71
+ case 'input-streaming':
72
+ case 'input-available':
73
+ case 'approval-requested':
74
+ case 'approval-responded':
75
+ return 'running';
76
+ case 'output-available':
77
+ return 'completed';
78
+ case 'output-error':
79
+ case 'output-denied':
80
+ return 'failed';
81
+ default:
82
+ return 'pending';
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Convert an `@ai-sdk/react` `UIMessage` into the canonical
88
+ * {@link ChatMessageData} shape consumed by `<ChatMessageItem>`.
89
+ *
90
+ * Behavior:
91
+ * - All `text` parts are concatenated in document order.
92
+ * - The first **non-empty** `reasoning` part wins (most messages only
93
+ * have one); `isStreaming` follows the part's `state` field. Empty
94
+ * reasoning shells (no deltas ever emitted) are filtered out so the UI
95
+ * doesn't render a "Thinking..." ghost with nothing inside.
96
+ * - The first tool part wins (we only render one tool block per message
97
+ * today — multi-tool messages can be added later).
98
+ * - All `source-url` parts are collected into the sources array.
99
+ *
100
+ * @example
101
+ * ```tsx
102
+ * const data = uiMessageToChatMessageData(message);
103
+ * return <ChatMessageItem item={data} />;
104
+ * ```
105
+ */
106
+ export function uiMessageToChatMessageData(
107
+ message: UIMessage,
108
+ ): ChatMessageData {
109
+ // The `parts` array is generic over data + tool maps; we treat it as the
110
+ // base discriminated union here so the type guards stay simple.
111
+ const parts = message.parts as Array<UIMessagePart<never, never>>;
112
+
113
+ // Concatenate every text part.
114
+ const content = parts.filter(isTextPart).map((p) => p.text).join('');
115
+
116
+ // First non-empty reasoning part. A provider (or the AI SDK) may emit
117
+ // `reasoning-start` / `reasoning-end` markers without any deltas in
118
+ // between — for example when a reasoning model hasn't been opted into
119
+ // emitting summaries via `providerOptions.openai.reasoningSummary`.
120
+ // We filter those empty shells out so the UI doesn't render a
121
+ // "Thinking..." ghost with nothing inside.
122
+ const reasoningPart = parts.find(
123
+ (p): p is ReasoningUIPart => isReasoningPart(p) && p.text.length > 0,
124
+ );
125
+ const reasoning = reasoningPart
126
+ ? {
127
+ content: reasoningPart.text,
128
+ isStreaming: reasoningPart.state === 'streaming',
129
+ }
130
+ : undefined;
131
+
132
+ // First tool part.
133
+ const toolPart = parts.find(isAnyToolPart);
134
+ let tool: ChatTool | undefined;
135
+ if (toolPart) {
136
+ // The discriminated union splits across many state shapes; cast to a
137
+ // permissive view since we only read a small subset of fields.
138
+ const t = toolPart as unknown as {
139
+ state?: string;
140
+ input?: unknown;
141
+ output?: unknown;
142
+ errorText?: string;
143
+ toolName?: string;
144
+ type: string;
145
+ };
146
+ tool = {
147
+ name: getToolName(t),
148
+ status: mapToolState(t.state),
149
+ args:
150
+ t.input && typeof t.input === 'object'
151
+ ? (t.input as Record<string, unknown>)
152
+ : undefined,
153
+ result:
154
+ t.errorText ??
155
+ (t.output != null
156
+ ? typeof t.output === 'string'
157
+ ? t.output
158
+ : JSON.stringify(t.output)
159
+ : undefined),
160
+ };
161
+ }
162
+
163
+ // All source-url parts (we ignore source-document for now).
164
+ const sources = parts.filter(isSourceUrlPart).map((p) => ({
165
+ title: p.title ?? p.url,
166
+ url: p.url,
167
+ }));
168
+
169
+ return {
170
+ id: message.id,
171
+ role: message.role,
172
+ content,
173
+ reasoning,
174
+ tool,
175
+ sources: sources.length > 0 ? sources : undefined,
176
+ };
177
+ }