@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,64 @@
1
+ import React from 'react';
2
+ import { Text, StyleSheet, type TextStyle } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { AIElementsTheme } from '../../theme';
5
+ import type { MarkdownNode } from '../parser';
6
+ import { renderInlineChildren } from './renderInlineChildren';
7
+
8
+ export interface HeadingRendererProps {
9
+ node: MarkdownNode;
10
+ }
11
+
12
+ function headingStyle(level: number, theme: AIElementsTheme): TextStyle {
13
+ const { typography, colors } = theme;
14
+ const weight = typography.fontWeight.bold as TextStyle['fontWeight'];
15
+
16
+ const sizeMap: Record<number, number> = {
17
+ 1: typography.fontSize['2xl'],
18
+ 2: typography.fontSize.xl,
19
+ 3: typography.fontSize.lg,
20
+ 4: typography.fontSize.md,
21
+ 5: typography.fontSize.sm,
22
+ 6: typography.fontSize.xs,
23
+ };
24
+
25
+ const marginMap: Record<number, number> = {
26
+ 1: 20,
27
+ 2: 16,
28
+ 3: 14,
29
+ 4: 12,
30
+ 5: 10,
31
+ 6: 8,
32
+ };
33
+
34
+ const fontSize = sizeMap[level] ?? typography.fontSize.md;
35
+
36
+ return {
37
+ fontSize,
38
+ fontWeight: weight,
39
+ fontFamily: typography.fontFamily,
40
+ color: colors.foreground,
41
+ lineHeight: fontSize * typography.lineHeight.tight,
42
+ marginTop: marginMap[level] ?? 12,
43
+ marginBottom: 8,
44
+ };
45
+ }
46
+
47
+ export const HeadingRenderer = React.memo(function HeadingRenderer({
48
+ node,
49
+ }: HeadingRendererProps) {
50
+ const theme = useAIElementsTheme();
51
+ const level = node.level ?? 1;
52
+
53
+ return (
54
+ <Text style={[styles.base, headingStyle(level, theme)]}>
55
+ {renderInlineChildren(node.children, theme)}
56
+ </Text>
57
+ );
58
+ });
59
+
60
+ const styles = StyleSheet.create({
61
+ base: {
62
+ flexShrink: 1,
63
+ },
64
+ });
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import { Image, View, Text, StyleSheet } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+
6
+ export interface ImageRendererProps {
7
+ node: MarkdownNode;
8
+ }
9
+
10
+ export const ImageRenderer = React.memo(function ImageRenderer({
11
+ node,
12
+ }: ImageRendererProps) {
13
+ const theme = useAIElementsTheme();
14
+
15
+ if (!node.url) return null;
16
+
17
+ return (
18
+ <View style={styles.container}>
19
+ <Image
20
+ source={{ uri: node.url }}
21
+ style={[
22
+ styles.image,
23
+ {
24
+ borderRadius: theme.radius.md,
25
+ backgroundColor: theme.colors.muted,
26
+ },
27
+ ]}
28
+ resizeMode="contain"
29
+ accessibilityLabel={node.alt ?? undefined}
30
+ />
31
+ {node.alt ? (
32
+ <Text
33
+ style={[
34
+ styles.caption,
35
+ {
36
+ color: theme.colors.mutedForeground,
37
+ fontSize: theme.typography.fontSize.sm,
38
+ fontFamily: theme.typography.fontFamily,
39
+ },
40
+ ]}
41
+ >
42
+ {node.alt}
43
+ </Text>
44
+ ) : null}
45
+ </View>
46
+ );
47
+ });
48
+
49
+ const styles = StyleSheet.create({
50
+ container: {
51
+ marginVertical: 8,
52
+ alignItems: 'center',
53
+ },
54
+ image: {
55
+ width: '100%',
56
+ height: 200,
57
+ },
58
+ caption: {
59
+ marginTop: 4,
60
+ textAlign: 'center',
61
+ },
62
+ });
@@ -0,0 +1,53 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Text, Pressable, Linking, StyleSheet, type TextStyle } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+ import { renderInlineChildren } from './renderInlineChildren';
6
+
7
+ export interface LinkRendererProps {
8
+ node: MarkdownNode;
9
+ }
10
+
11
+ export const LinkRenderer = React.memo(function LinkRenderer({
12
+ node,
13
+ }: LinkRendererProps) {
14
+ const theme = useAIElementsTheme();
15
+
16
+ const handlePress = useCallback(() => {
17
+ if (node.url) {
18
+ Linking.openURL(node.url).catch(() => {
19
+ // Silently ignore -- the URL may not be openable.
20
+ });
21
+ }
22
+ }, [node.url]);
23
+
24
+ const textStyle: TextStyle = {
25
+ color: theme.colors.primary,
26
+ fontSize: theme.typography.fontSize.md,
27
+ fontFamily: theme.typography.fontFamily,
28
+ textDecorationLine: 'underline',
29
+ };
30
+
31
+ return (
32
+ <Pressable
33
+ onPress={handlePress}
34
+ style={({ pressed }) => [
35
+ styles.pressable,
36
+ pressed && styles.pressed,
37
+ ]}
38
+ >
39
+ <Text style={textStyle}>
40
+ {renderInlineChildren(node.children, theme)}
41
+ </Text>
42
+ </Pressable>
43
+ );
44
+ });
45
+
46
+ const styles = StyleSheet.create({
47
+ pressable: {
48
+ alignSelf: 'flex-start',
49
+ },
50
+ pressed: {
51
+ opacity: 0.7,
52
+ },
53
+ });
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet, type TextStyle } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+ import { renderInlineChildren } from './renderInlineChildren';
6
+
7
+ export interface ListRendererProps {
8
+ node: MarkdownNode;
9
+ }
10
+
11
+ export const ListRenderer = React.memo(function ListRenderer({
12
+ node,
13
+ }: ListRendererProps) {
14
+ const theme = useAIElementsTheme();
15
+ const ordered = node.ordered ?? false;
16
+
17
+ const bulletStyle: TextStyle = {
18
+ color: theme.colors.mutedForeground,
19
+ fontSize: theme.typography.fontSize.md,
20
+ fontFamily: theme.typography.fontFamily,
21
+ lineHeight: theme.typography.fontSize.md * theme.typography.lineHeight.normal,
22
+ };
23
+
24
+ const textStyle: TextStyle = {
25
+ color: theme.colors.foreground,
26
+ fontSize: theme.typography.fontSize.md,
27
+ fontFamily: theme.typography.fontFamily,
28
+ lineHeight: theme.typography.fontSize.md * theme.typography.lineHeight.normal,
29
+ flexShrink: 1,
30
+ };
31
+
32
+ return (
33
+ <View style={styles.list}>
34
+ {(node.children ?? []).map((item, index) => (
35
+ <View key={`list-item-${index}`} style={styles.item}>
36
+ <Text style={[styles.bullet, bulletStyle]}>
37
+ {ordered ? `${index + 1}.` : '\u2022'}
38
+ </Text>
39
+ <Text style={[styles.content, textStyle]}>
40
+ {renderInlineChildren(item.children, theme)}
41
+ </Text>
42
+ </View>
43
+ ))}
44
+ </View>
45
+ );
46
+ });
47
+
48
+ const styles = StyleSheet.create({
49
+ list: {
50
+ marginVertical: 4,
51
+ },
52
+ item: {
53
+ flexDirection: 'row',
54
+ alignItems: 'flex-start',
55
+ marginBottom: 4,
56
+ },
57
+ bullet: {
58
+ width: 24,
59
+ textAlign: 'right',
60
+ marginRight: 8,
61
+ },
62
+ content: {
63
+ flex: 1,
64
+ },
65
+ });
@@ -0,0 +1,103 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet, type TextStyle } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+ import { renderInlineChildren } from './renderInlineChildren';
6
+
7
+ export interface TableRendererProps {
8
+ node: MarkdownNode;
9
+ }
10
+
11
+ export const TableRenderer = React.memo(function TableRenderer({
12
+ node,
13
+ }: TableRendererProps) {
14
+ const theme = useAIElementsTheme();
15
+
16
+ const rows = node.children ?? [];
17
+
18
+ const headerTextStyle: TextStyle = {
19
+ fontWeight: theme.typography.fontWeight.semibold as TextStyle['fontWeight'],
20
+ color: theme.colors.foreground,
21
+ fontSize: theme.typography.fontSize.sm,
22
+ fontFamily: theme.typography.fontFamily,
23
+ };
24
+
25
+ const cellTextStyle: TextStyle = {
26
+ color: theme.colors.foreground,
27
+ fontSize: theme.typography.fontSize.sm,
28
+ fontFamily: theme.typography.fontFamily,
29
+ };
30
+
31
+ return (
32
+ <View
33
+ style={[
34
+ styles.table,
35
+ {
36
+ borderColor: theme.colors.border,
37
+ borderRadius: theme.radius.sm,
38
+ },
39
+ ]}
40
+ >
41
+ {rows.map((row, rowIndex) => {
42
+ const cells = row.children ?? [];
43
+ const isHeaderRow = cells.some((c) => c.header);
44
+
45
+ return (
46
+ <View
47
+ key={`row-${rowIndex}`}
48
+ style={[
49
+ styles.row,
50
+ {
51
+ borderBottomColor: theme.colors.border,
52
+ backgroundColor: isHeaderRow
53
+ ? theme.colors.muted
54
+ : 'transparent',
55
+ },
56
+ rowIndex === rows.length - 1 && styles.lastRow,
57
+ ]}
58
+ >
59
+ {cells.map((cell, cellIndex) => (
60
+ <View
61
+ key={`cell-${rowIndex}-${cellIndex}`}
62
+ style={[
63
+ styles.cell,
64
+ {
65
+ borderRightColor: theme.colors.border,
66
+ },
67
+ cellIndex === cells.length - 1 && styles.lastCell,
68
+ ]}
69
+ >
70
+ <Text style={cell.header ? headerTextStyle : cellTextStyle}>
71
+ {renderInlineChildren(cell.children, theme)}
72
+ </Text>
73
+ </View>
74
+ ))}
75
+ </View>
76
+ );
77
+ })}
78
+ </View>
79
+ );
80
+ });
81
+
82
+ const styles = StyleSheet.create({
83
+ table: {
84
+ borderWidth: 1,
85
+ marginVertical: 8,
86
+ overflow: 'hidden',
87
+ },
88
+ row: {
89
+ flexDirection: 'row',
90
+ borderBottomWidth: 1,
91
+ },
92
+ lastRow: {
93
+ borderBottomWidth: 0,
94
+ },
95
+ cell: {
96
+ flex: 1,
97
+ padding: 8,
98
+ borderRightWidth: 1,
99
+ },
100
+ lastCell: {
101
+ borderRightWidth: 0,
102
+ },
103
+ });
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { Text, StyleSheet, type TextStyle } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+ import { renderInlineChildren } from './renderInlineChildren';
6
+
7
+ export interface TextRendererProps {
8
+ node: MarkdownNode;
9
+ }
10
+
11
+ export const TextRenderer = React.memo(function TextRenderer({
12
+ node,
13
+ }: TextRendererProps) {
14
+ const theme = useAIElementsTheme();
15
+
16
+ const baseStyle: TextStyle = {
17
+ color: theme.colors.foreground,
18
+ fontSize: theme.typography.fontSize.md,
19
+ lineHeight: theme.typography.fontSize.md * theme.typography.lineHeight.normal,
20
+ fontFamily: theme.typography.fontFamily,
21
+ };
22
+
23
+ if (node.type === 'text') {
24
+ return <Text style={baseStyle}>{node.content}</Text>;
25
+ }
26
+
27
+ // paragraph
28
+ return (
29
+ <Text style={[baseStyle, styles.paragraph]}>
30
+ {renderInlineChildren(node.children, theme)}
31
+ </Text>
32
+ );
33
+ });
34
+
35
+ const styles = StyleSheet.create({
36
+ paragraph: {
37
+ marginBottom: 8,
38
+ },
39
+ });
@@ -0,0 +1,26 @@
1
+ export { TextRenderer } from './TextRenderer';
2
+ export type { TextRendererProps } from './TextRenderer';
3
+
4
+ export { HeadingRenderer } from './HeadingRenderer';
5
+ export type { HeadingRendererProps } from './HeadingRenderer';
6
+
7
+ export { CodeRenderer } from './CodeRenderer';
8
+ export type { CodeRendererProps } from './CodeRenderer';
9
+
10
+ export { ListRenderer } from './ListRenderer';
11
+ export type { ListRendererProps } from './ListRenderer';
12
+
13
+ export { LinkRenderer } from './LinkRenderer';
14
+ export type { LinkRendererProps } from './LinkRenderer';
15
+
16
+ export { ImageRenderer } from './ImageRenderer';
17
+ export type { ImageRendererProps } from './ImageRenderer';
18
+
19
+ export { BlockquoteRenderer } from './BlockquoteRenderer';
20
+ export type { BlockquoteRendererProps } from './BlockquoteRenderer';
21
+
22
+ export { TableRenderer } from './TableRenderer';
23
+ export type { TableRendererProps } from './TableRenderer';
24
+
25
+ export { renderNode } from './renderNode';
26
+ export { renderInlineChildren } from './renderInlineChildren';
@@ -0,0 +1,115 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import { Text, type TextStyle } from 'react-native';
3
+ import type { AIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+
6
+ /**
7
+ * Recursively render inline markdown nodes (text, bold, italic, bold_italic,
8
+ * code_inline, link, image) as nested React Native <Text> elements.
9
+ *
10
+ * This is extracted as a shared helper so every block-level renderer can
11
+ * render its inline children consistently.
12
+ */
13
+ export function renderInlineChildren(
14
+ children: MarkdownNode[] | undefined,
15
+ theme: AIElementsTheme,
16
+ ): ReactNode {
17
+ if (!children || children.length === 0) return null;
18
+
19
+ return children.map((child, index) => {
20
+ const key = `${child.type}-${index}`;
21
+
22
+ switch (child.type) {
23
+ case 'text':
24
+ return (
25
+ <Text key={key} style={{ color: theme.colors.foreground }}>
26
+ {child.content}
27
+ </Text>
28
+ );
29
+
30
+ case 'bold': {
31
+ const style: TextStyle = {
32
+ fontWeight: theme.typography.fontWeight.bold as TextStyle['fontWeight'],
33
+ color: theme.colors.foreground,
34
+ };
35
+ return (
36
+ <Text key={key} style={style}>
37
+ {renderInlineChildren(child.children, theme)}
38
+ </Text>
39
+ );
40
+ }
41
+
42
+ case 'italic': {
43
+ const style: TextStyle = {
44
+ fontStyle: 'italic',
45
+ color: theme.colors.foreground,
46
+ };
47
+ return (
48
+ <Text key={key} style={style}>
49
+ {renderInlineChildren(child.children, theme)}
50
+ </Text>
51
+ );
52
+ }
53
+
54
+ case 'bold_italic': {
55
+ const style: TextStyle = {
56
+ fontWeight: theme.typography.fontWeight.bold as TextStyle['fontWeight'],
57
+ fontStyle: 'italic',
58
+ color: theme.colors.foreground,
59
+ };
60
+ return (
61
+ <Text key={key} style={style}>
62
+ {renderInlineChildren(child.children, theme)}
63
+ </Text>
64
+ );
65
+ }
66
+
67
+ case 'code_inline': {
68
+ const style: TextStyle = {
69
+ fontFamily: theme.typography.monoFontFamily,
70
+ fontSize: theme.typography.fontSize.sm,
71
+ backgroundColor: theme.colors.muted,
72
+ color: theme.colors.foreground,
73
+ borderRadius: theme.radius.sm,
74
+ paddingHorizontal: 4,
75
+ paddingVertical: 1,
76
+ };
77
+ return (
78
+ <Text key={key} style={style}>
79
+ {child.content}
80
+ </Text>
81
+ );
82
+ }
83
+
84
+ case 'link': {
85
+ const style: TextStyle = {
86
+ color: theme.colors.primary,
87
+ textDecorationLine: 'underline',
88
+ };
89
+ // Links inline are rendered as styled text.
90
+ // The LinkRenderer handles the Pressable wrapper at block level.
91
+ // Inside inline contexts we just show styled text.
92
+ return (
93
+ <Text key={key} style={style}>
94
+ {renderInlineChildren(child.children, theme)}
95
+ </Text>
96
+ );
97
+ }
98
+
99
+ case 'image':
100
+ // Images inline are rendered as their alt text within a Text tree.
101
+ return (
102
+ <Text key={key} style={{ color: theme.colors.mutedForeground }}>
103
+ {child.alt ?? '[image]'}
104
+ </Text>
105
+ );
106
+
107
+ default:
108
+ return (
109
+ <Text key={key} style={{ color: theme.colors.foreground }}>
110
+ {child.content}
111
+ </Text>
112
+ );
113
+ }
114
+ });
115
+ }
@@ -0,0 +1,72 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import { View, StyleSheet } from 'react-native';
3
+ import { useAIElementsTheme } from '../../theme';
4
+ import type { MarkdownNode } from '../parser';
5
+ import { TextRenderer } from './TextRenderer';
6
+ import { HeadingRenderer } from './HeadingRenderer';
7
+ import { CodeRenderer } from './CodeRenderer';
8
+ import { ListRenderer } from './ListRenderer';
9
+ import { LinkRenderer } from './LinkRenderer';
10
+ import { ImageRenderer } from './ImageRenderer';
11
+ import { BlockquoteRenderer } from './BlockquoteRenderer';
12
+ import { TableRenderer } from './TableRenderer';
13
+
14
+ /** Themed horizontal rule. */
15
+ const HorizontalRule = React.memo(function HorizontalRule() {
16
+ const theme = useAIElementsTheme();
17
+ return (
18
+ <View
19
+ style={[
20
+ hrStyles.rule,
21
+ { backgroundColor: theme.colors.border },
22
+ ]}
23
+ />
24
+ );
25
+ });
26
+
27
+ const hrStyles = StyleSheet.create({
28
+ rule: {
29
+ height: 1,
30
+ marginVertical: 16,
31
+ },
32
+ });
33
+
34
+ /**
35
+ * Map a single MarkdownNode to its corresponding React Native renderer.
36
+ * Used by both StreamingMarkdown and BlockquoteRenderer (for nested blocks).
37
+ */
38
+ export function renderNode(node: MarkdownNode, key: string): ReactNode {
39
+ switch (node.type) {
40
+ case 'paragraph':
41
+ case 'text':
42
+ return <TextRenderer key={key} node={node} />;
43
+
44
+ case 'heading':
45
+ return <HeadingRenderer key={key} node={node} />;
46
+
47
+ case 'code_inline':
48
+ case 'code_block':
49
+ return <CodeRenderer key={key} node={node} />;
50
+
51
+ case 'list':
52
+ return <ListRenderer key={key} node={node} />;
53
+
54
+ case 'link':
55
+ return <LinkRenderer key={key} node={node} />;
56
+
57
+ case 'image':
58
+ return <ImageRenderer key={key} node={node} />;
59
+
60
+ case 'blockquote':
61
+ return <BlockquoteRenderer key={key} node={node} />;
62
+
63
+ case 'horizontal_rule':
64
+ return <HorizontalRule key={key} />;
65
+
66
+ case 'table':
67
+ return <TableRenderer key={key} node={node} />;
68
+
69
+ default:
70
+ return null;
71
+ }
72
+ }
@@ -0,0 +1,77 @@
1
+ import React, {
2
+ createContext,
3
+ useContext,
4
+ useMemo,
5
+ type PropsWithChildren,
6
+ } from 'react';
7
+ import { useColorScheme } from 'react-native';
8
+ import type { AIElementsTheme } from './tokens';
9
+ import { lightTheme, darkTheme } from './defaultTheme';
10
+
11
+ const ThemeContext = createContext<AIElementsTheme>(lightTheme);
12
+
13
+ export type ColorSchemeMode = 'light' | 'dark' | 'system';
14
+
15
+ type DeepPartial<T> = {
16
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
17
+ };
18
+
19
+ export interface AIElementsProviderProps {
20
+ theme?: DeepPartial<AIElementsTheme>;
21
+ mode?: ColorSchemeMode;
22
+ }
23
+
24
+ function mergeTheme(
25
+ base: AIElementsTheme,
26
+ overrides?: DeepPartial<AIElementsTheme>
27
+ ): AIElementsTheme {
28
+ if (!overrides) return base;
29
+ return {
30
+ ...base,
31
+ ...overrides,
32
+ colors: { ...base.colors, ...overrides.colors },
33
+ spacing: { ...base.spacing, ...overrides.spacing },
34
+ radius: { ...base.radius, ...overrides.radius },
35
+ typography: {
36
+ ...base.typography,
37
+ ...overrides.typography,
38
+ fontSize: {
39
+ ...base.typography.fontSize,
40
+ ...overrides.typography?.fontSize,
41
+ },
42
+ lineHeight: {
43
+ ...base.typography.lineHeight,
44
+ ...overrides.typography?.lineHeight,
45
+ },
46
+ fontWeight: {
47
+ ...base.typography.fontWeight,
48
+ ...overrides.typography?.fontWeight,
49
+ },
50
+ },
51
+ };
52
+ }
53
+
54
+ export function AIElementsProvider({
55
+ theme: themeOverrides,
56
+ mode = 'system',
57
+ children,
58
+ }: PropsWithChildren<AIElementsProviderProps>) {
59
+ const systemScheme = useColorScheme();
60
+
61
+ const resolvedTheme = useMemo(() => {
62
+ const isDark =
63
+ mode === 'system' ? systemScheme === 'dark' : mode === 'dark';
64
+ const base = isDark ? darkTheme : lightTheme;
65
+ return mergeTheme(base, themeOverrides);
66
+ }, [mode, systemScheme, themeOverrides]);
67
+
68
+ return (
69
+ <ThemeContext.Provider value={resolvedTheme}>
70
+ {children}
71
+ </ThemeContext.Provider>
72
+ );
73
+ }
74
+
75
+ export function useAIElementsTheme(): AIElementsTheme {
76
+ return useContext(ThemeContext);
77
+ }