@chatsdk-dev/ui 0.0.1 → 0.1.3

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 (468) hide show
  1. package/README.md +7 -7
  2. package/dist/atoms/accordion.d.ts +7 -0
  3. package/dist/atoms/accordion.d.ts.map +1 -0
  4. package/dist/atoms/accordion.js +18 -0
  5. package/dist/atoms/alert-dialog.d.ts +19 -0
  6. package/dist/atoms/alert-dialog.d.ts.map +1 -0
  7. package/dist/atoms/alert-dialog.js +42 -0
  8. package/dist/atoms/alert.d.ts +11 -0
  9. package/dist/atoms/alert.d.ts.map +1 -0
  10. package/dist/atoms/alert.js +27 -0
  11. package/dist/atoms/avatar.d.ts +12 -0
  12. package/dist/atoms/avatar.d.ts.map +1 -0
  13. package/dist/atoms/avatar.js +23 -0
  14. package/dist/atoms/badge.d.ts +8 -0
  15. package/dist/atoms/badge.d.ts.map +1 -0
  16. package/dist/atoms/badge.js +44 -0
  17. package/dist/atoms/button-group.d.ts +11 -0
  18. package/dist/atoms/button-group.d.ts.map +1 -0
  19. package/dist/atoms/button-group.js +36 -0
  20. package/dist/atoms/button-loader.d.ts +9 -0
  21. package/dist/atoms/button-loader.d.ts.map +1 -0
  22. package/dist/atoms/button-loader.js +10 -0
  23. package/dist/atoms/button.d.ts +9 -0
  24. package/dist/atoms/button.d.ts.map +1 -0
  25. package/dist/atoms/button.js +32 -0
  26. package/dist/atoms/card.d.ts +12 -0
  27. package/dist/atoms/card.d.ts.map +1 -0
  28. package/dist/atoms/card.js +25 -0
  29. package/dist/atoms/carousel.d.ts +29 -0
  30. package/dist/atoms/carousel.d.ts.map +1 -0
  31. package/dist/atoms/carousel.js +91 -0
  32. package/dist/atoms/collapsible.d.ts +6 -0
  33. package/dist/atoms/collapsible.d.ts.map +1 -0
  34. package/dist/atoms/collapsible.js +13 -0
  35. package/dist/atoms/command.d.ts +20 -0
  36. package/dist/atoms/command.d.ts.map +1 -0
  37. package/dist/atoms/command.js +35 -0
  38. package/dist/atoms/container.d.ts +8 -0
  39. package/dist/atoms/container.d.ts.map +1 -0
  40. package/dist/atoms/container.js +5 -0
  41. package/dist/atoms/dialog.d.ts +19 -0
  42. package/dist/atoms/dialog.d.ts.map +1 -0
  43. package/dist/atoms/dialog.js +38 -0
  44. package/dist/atoms/dots-loader.d.ts +15 -0
  45. package/dist/atoms/dots-loader.d.ts.map +1 -0
  46. package/dist/atoms/dots-loader.js +21 -0
  47. package/dist/atoms/drawer.d.ts +14 -0
  48. package/dist/atoms/drawer.d.ts.map +1 -0
  49. package/dist/atoms/drawer.js +35 -0
  50. package/dist/atoms/dropdown-menu.d.ts +26 -0
  51. package/dist/atoms/dropdown-menu.d.ts.map +1 -0
  52. package/dist/atoms/dropdown-menu.js +51 -0
  53. package/dist/atoms/empty.d.ts +12 -0
  54. package/dist/atoms/empty.d.ts.map +1 -0
  55. package/dist/atoms/empty.js +33 -0
  56. package/dist/atoms/field.d.ts +25 -0
  57. package/dist/atoms/field.d.ts.map +1 -0
  58. package/dist/atoms/field.js +68 -0
  59. package/dist/atoms/form.d.ts +23 -0
  60. package/dist/atoms/form.d.ts.map +1 -0
  61. package/dist/atoms/form.js +68 -0
  62. package/dist/atoms/header.d.ts +6 -0
  63. package/dist/atoms/header.d.ts.map +1 -0
  64. package/dist/atoms/header.js +6 -0
  65. package/dist/atoms/hover-card.d.ts +6 -0
  66. package/dist/atoms/hover-card.d.ts.map +1 -0
  67. package/dist/atoms/hover-card.js +14 -0
  68. package/dist/atoms/index.d.ts +5 -0
  69. package/dist/atoms/index.d.ts.map +1 -0
  70. package/dist/atoms/index.js +5 -0
  71. package/dist/atoms/input-group.d.ts +19 -0
  72. package/dist/atoms/input-group.d.ts.map +1 -0
  73. package/dist/atoms/input-group.js +57 -0
  74. package/dist/atoms/input.d.ts +7 -0
  75. package/dist/atoms/input.d.ts.map +1 -0
  76. package/dist/atoms/input.js +6 -0
  77. package/dist/atoms/label.d.ts +3 -0
  78. package/dist/atoms/label.d.ts.map +1 -0
  79. package/dist/atoms/label.js +7 -0
  80. package/dist/atoms/logo.d.ts +7 -0
  81. package/dist/atoms/logo.d.ts.map +1 -0
  82. package/dist/atoms/logo.js +6 -0
  83. package/dist/atoms/number-flow.d.ts +3 -0
  84. package/dist/atoms/number-flow.d.ts.map +1 -0
  85. package/dist/atoms/number-flow.js +6 -0
  86. package/dist/atoms/popover.d.ts +10 -0
  87. package/dist/atoms/popover.d.ts.map +1 -0
  88. package/dist/atoms/popover.js +23 -0
  89. package/dist/atoms/progress.d.ts +8 -0
  90. package/dist/atoms/progress.d.ts.map +1 -0
  91. package/dist/atoms/progress.js +20 -0
  92. package/dist/atoms/radio-group.d.ts +6 -0
  93. package/dist/atoms/radio-group.d.ts.map +1 -0
  94. package/dist/atoms/radio-group.js +13 -0
  95. package/dist/atoms/scroll-area.d.ts +5 -0
  96. package/dist/atoms/scroll-area.d.ts.map +1 -0
  97. package/dist/atoms/scroll-area.js +11 -0
  98. package/dist/atoms/select.d.ts +17 -0
  99. package/dist/atoms/select.d.ts.map +1 -0
  100. package/dist/atoms/select.js +34 -0
  101. package/dist/atoms/separator.d.ts +3 -0
  102. package/dist/atoms/separator.d.ts.map +1 -0
  103. package/dist/atoms/separator.js +7 -0
  104. package/dist/atoms/sheet.d.ts +15 -0
  105. package/dist/atoms/sheet.d.ts.map +1 -0
  106. package/dist/atoms/sheet.js +37 -0
  107. package/dist/atoms/sidebar.d.ts +65 -0
  108. package/dist/atoms/sidebar.d.ts.map +1 -0
  109. package/dist/atoms/sidebar.js +258 -0
  110. package/dist/atoms/skeleton.d.ts +2 -0
  111. package/dist/atoms/skeleton.d.ts.map +1 -0
  112. package/dist/atoms/skeleton.js +5 -0
  113. package/dist/atoms/spinner.d.ts +3 -0
  114. package/dist/atoms/spinner.d.ts.map +1 -0
  115. package/dist/atoms/spinner.js +7 -0
  116. package/dist/atoms/switch.d.ts +5 -0
  117. package/dist/atoms/switch.d.ts.map +1 -0
  118. package/dist/atoms/switch.js +7 -0
  119. package/dist/atoms/table.d.ts +13 -0
  120. package/dist/atoms/table.d.ts.map +1 -0
  121. package/dist/atoms/table.js +28 -0
  122. package/dist/atoms/tabs.d.ts +12 -0
  123. package/dist/atoms/tabs.d.ts.map +1 -0
  124. package/dist/atoms/tabs.js +32 -0
  125. package/dist/atoms/textarea.d.ts +3 -0
  126. package/dist/atoms/textarea.d.ts.map +1 -0
  127. package/dist/atoms/textarea.js +5 -0
  128. package/dist/atoms/toggle.d.ts +9 -0
  129. package/dist/atoms/toggle.d.ts.map +1 -0
  130. package/dist/atoms/toggle.js +26 -0
  131. package/dist/atoms/tooltip.d.ts +7 -0
  132. package/dist/atoms/tooltip.d.ts.map +1 -0
  133. package/dist/atoms/tooltip.js +17 -0
  134. package/dist/atoms/typography/h1.d.ts +10 -0
  135. package/dist/atoms/typography/h1.d.ts.map +1 -0
  136. package/dist/atoms/typography/h1.js +6 -0
  137. package/dist/atoms/typography/paragraph.d.ts +6 -0
  138. package/dist/atoms/typography/paragraph.d.ts.map +1 -0
  139. package/dist/atoms/typography/paragraph.js +6 -0
  140. package/dist/atoms/typography/text.d.ts +14 -0
  141. package/dist/atoms/typography/text.d.ts.map +1 -0
  142. package/dist/atoms/typography/text.js +41 -0
  143. package/dist/components/responsive-alert-dialog.d.ts +16 -0
  144. package/dist/components/responsive-alert-dialog.d.ts.map +1 -0
  145. package/dist/components/responsive-alert-dialog.js +20 -0
  146. package/dist/components/responsive-dialog.d.ts +11 -0
  147. package/dist/components/responsive-dialog.d.ts.map +1 -0
  148. package/dist/components/responsive-dialog.js +21 -0
  149. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -0
  150. package/dist/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  151. package/dist/hooks/use-copy-to-clipboard.js +31 -0
  152. package/dist/index.css +1580 -39
  153. package/dist/molecules/actions.d.ts +10 -0
  154. package/dist/molecules/actions.d.ts.map +1 -0
  155. package/dist/molecules/actions.js +13 -0
  156. package/dist/molecules/agent.d.ts +27 -0
  157. package/dist/molecules/agent.d.ts.map +1 -0
  158. package/dist/molecules/agent.js +27 -0
  159. package/dist/molecules/ai/actions.d.ts +10 -0
  160. package/dist/molecules/ai/actions.d.ts.map +1 -0
  161. package/dist/molecules/ai/actions.js +13 -0
  162. package/dist/molecules/ai/agent.d.ts +27 -0
  163. package/dist/molecules/ai/agent.d.ts.map +1 -0
  164. package/dist/molecules/ai/agent.js +27 -0
  165. package/dist/molecules/ai/artifact.d.ts +24 -0
  166. package/dist/molecules/ai/artifact.d.ts.map +1 -0
  167. package/dist/molecules/ai/artifact.js +20 -0
  168. package/dist/molecules/ai/attachments.d.ts +55 -0
  169. package/dist/molecules/ai/attachments.d.ts.map +1 -0
  170. package/dist/molecules/ai/attachments.js +125 -0
  171. package/dist/molecules/ai/audio-player.d.ts +30 -0
  172. package/dist/molecules/ai/audio-player.d.ts.map +1 -0
  173. package/dist/molecules/ai/audio-player.js +43 -0
  174. package/dist/molecules/ai/canvas.d.ts +9 -0
  175. package/dist/molecules/ai/canvas.d.ts.map +1 -0
  176. package/dist/molecules/ai/canvas.js +5 -0
  177. package/dist/molecules/ai/chain-of-thought.d.ts +30 -0
  178. package/dist/molecules/ai/chain-of-thought.d.ts.map +1 -0
  179. package/dist/molecules/ai/chain-of-thought.js +49 -0
  180. package/dist/molecules/ai/checkpoint.d.ts +12 -0
  181. package/dist/molecules/ai/checkpoint.d.ts.map +1 -0
  182. package/dist/molecules/ai/checkpoint.js +10 -0
  183. package/dist/molecules/ai/code-block.d.ts +46 -0
  184. package/dist/molecules/ai/code-block.d.ts.map +1 -0
  185. package/dist/molecules/ai/code-block.js +216 -0
  186. package/dist/molecules/ai/commit.d.ts +65 -0
  187. package/dist/molecules/ai/commit.d.ts.map +1 -0
  188. package/dist/molecules/ai/commit.js +95 -0
  189. package/dist/molecules/ai/confirmation.d.ts +50 -0
  190. package/dist/molecules/ai/confirmation.d.ts.map +1 -0
  191. package/dist/molecules/ai/confirmation.js +61 -0
  192. package/dist/molecules/ai/connection.d.ts +3 -0
  193. package/dist/molecules/ai/connection.d.ts.map +1 -0
  194. package/dist/molecules/ai/connection.js +3 -0
  195. package/dist/molecules/ai/context.d.ts +33 -0
  196. package/dist/molecules/ai/context.d.ts.map +1 -0
  197. package/dist/molecules/ai/context.js +164 -0
  198. package/dist/molecules/ai/controls.d.ts +5 -0
  199. package/dist/molecules/ai/controls.d.ts.map +1 -0
  200. package/dist/molecules/ai/controls.js +5 -0
  201. package/dist/molecules/ai/conversation.d.ts +24 -0
  202. package/dist/molecules/ai/conversation.d.ts.map +1 -0
  203. package/dist/molecules/ai/conversation.js +41 -0
  204. package/dist/molecules/ai/edge.d.ts +6 -0
  205. package/dist/molecules/ai/edge.d.ts.map +1 -0
  206. package/dist/molecules/ai/edge.js +87 -0
  207. package/dist/molecules/ai/environment-variables.d.ts +39 -0
  208. package/dist/molecules/ai/environment-variables.d.ts.map +1 -0
  209. package/dist/molecules/ai/environment-variables.js +87 -0
  210. package/dist/molecules/ai/file-tree.d.ts +27 -0
  211. package/dist/molecules/ai/file-tree.d.ts.map +1 -0
  212. package/dist/molecules/ai/file-tree.js +71 -0
  213. package/dist/molecules/ai/image.d.ts +7 -0
  214. package/dist/molecules/ai/image.d.ts.map +1 -0
  215. package/dist/molecules/ai/image.js +3 -0
  216. package/dist/molecules/ai/inline-citation.d.ts +39 -0
  217. package/dist/molecules/ai/inline-citation.d.ts.map +1 -0
  218. package/dist/molecules/ai/inline-citation.js +68 -0
  219. package/dist/molecules/ai/jsx-preview.d.ts +30 -0
  220. package/dist/molecules/ai/jsx-preview.d.ts.map +1 -0
  221. package/dist/molecules/ai/jsx-preview.js +167 -0
  222. package/dist/molecules/ai/loader.d.ts +6 -0
  223. package/dist/molecules/ai/loader.d.ts.map +1 -0
  224. package/dist/molecules/ai/loader.js +4 -0
  225. package/dist/molecules/ai/message.d.ts +38 -0
  226. package/dist/molecules/ai/message.d.ts.map +1 -0
  227. package/dist/molecules/ai/message.js +92 -0
  228. package/dist/molecules/ai/mic-selector.d.ts +46 -0
  229. package/dist/molecules/ai/mic-selector.d.ts.map +1 -0
  230. package/dist/molecules/ai/mic-selector.js +184 -0
  231. package/dist/molecules/ai/model-selector.d.ts +36 -0
  232. package/dist/molecules/ai/model-selector.d.ts.map +1 -0
  233. package/dist/molecules/ai/model-selector.js +18 -0
  234. package/dist/molecules/ai/node.d.ts +22 -0
  235. package/dist/molecules/ai/node.d.ts.map +1 -0
  236. package/dist/molecules/ai/node.js +11 -0
  237. package/dist/molecules/ai/open-in-chat.d.ts +29 -0
  238. package/dist/molecules/ai/open-in-chat.d.ts.map +1 -0
  239. package/dist/molecules/ai/open-in-chat.js +100 -0
  240. package/dist/molecules/ai/package-info.d.ts +30 -0
  241. package/dist/molecules/ai/package-info.d.ts.map +1 -0
  242. package/dist/molecules/ai/package-info.js +50 -0
  243. package/dist/molecules/ai/panel.d.ts +6 -0
  244. package/dist/molecules/ai/panel.d.ts.map +1 -0
  245. package/dist/molecules/ai/panel.js +4 -0
  246. package/dist/molecules/ai/persona.d.ts +49 -0
  247. package/dist/molecules/ai/persona.d.ts.map +1 -0
  248. package/dist/molecules/ai/persona.js +189 -0
  249. package/dist/molecules/ai/plan.d.ts +26 -0
  250. package/dist/molecules/ai/plan.d.ts.map +1 -0
  251. package/dist/molecules/ai/plan.js +34 -0
  252. package/dist/molecules/ai/prompt-input.d.ts +149 -0
  253. package/dist/molecules/ai/prompt-input.d.ts.map +1 -0
  254. package/dist/molecules/ai/prompt-input.js +702 -0
  255. package/dist/molecules/ai/queue.d.ts +62 -0
  256. package/dist/molecules/ai/queue.d.ts.map +1 -0
  257. package/dist/molecules/ai/queue.js +28 -0
  258. package/dist/molecules/ai/reasoning.d.ts +27 -0
  259. package/dist/molecules/ai/reasoning.d.ts.map +1 -0
  260. package/dist/molecules/ai/reasoning.js +95 -0
  261. package/dist/molecules/ai/response.d.ts +6 -0
  262. package/dist/molecules/ai/response.d.ts.map +1 -0
  263. package/dist/molecules/ai/response.js +18 -0
  264. package/dist/molecules/ai/sandbox.d.ts +25 -0
  265. package/dist/molecules/ai/sandbox.d.ts.map +1 -0
  266. package/dist/molecules/ai/sandbox.js +15 -0
  267. package/dist/molecules/ai/schema-display.d.ts +56 -0
  268. package/dist/molecules/ai/schema-display.d.ts.map +1 -0
  269. package/dist/molecules/ai/schema-display.js +73 -0
  270. package/dist/molecules/ai/shimmer.d.ts +10 -0
  271. package/dist/molecules/ai/shimmer.d.ts.map +1 -0
  272. package/dist/molecules/ai/shimmer.js +28 -0
  273. package/dist/molecules/ai/snippet.d.ts +19 -0
  274. package/dist/molecules/ai/snippet.d.ts.map +1 -0
  275. package/dist/molecules/ai/snippet.js +46 -0
  276. package/dist/molecules/ai/sources.d.ts +13 -0
  277. package/dist/molecules/ai/sources.d.ts.map +1 -0
  278. package/dist/molecules/ai/sources.js +9 -0
  279. package/dist/molecules/ai/speech-input.d.ts +55 -0
  280. package/dist/molecules/ai/speech-input.d.ts.map +1 -0
  281. package/dist/molecules/ai/speech-input.js +187 -0
  282. package/dist/molecules/ai/stack-trace.d.ts +38 -0
  283. package/dist/molecules/ai/stack-trace.d.ts.map +1 -0
  284. package/dist/molecules/ai/stack-trace.js +194 -0
  285. package/dist/molecules/ai/suggestion.d.ts +11 -0
  286. package/dist/molecules/ai/suggestion.d.ts.map +1 -0
  287. package/dist/molecules/ai/suggestion.js +13 -0
  288. package/dist/molecules/ai/task.d.ts +15 -0
  289. package/dist/molecules/ai/task.d.ts.map +1 -0
  290. package/dist/molecules/ai/task.js +10 -0
  291. package/dist/molecules/ai/terminal.d.ts +28 -0
  292. package/dist/molecules/ai/terminal.d.ts.map +1 -0
  293. package/dist/molecules/ai/terminal.js +68 -0
  294. package/dist/molecules/ai/test-results.d.ts +59 -0
  295. package/dist/molecules/ai/test-results.d.ts.map +1 -0
  296. package/dist/molecules/ai/test-results.js +97 -0
  297. package/dist/molecules/ai/tool.d.ts +32 -0
  298. package/dist/molecules/ai/tool.d.ts.map +1 -0
  299. package/dist/molecules/ai/tool.js +49 -0
  300. package/dist/molecules/ai/toolbar.d.ts +6 -0
  301. package/dist/molecules/ai/toolbar.d.ts.map +1 -0
  302. package/dist/molecules/ai/toolbar.js +4 -0
  303. package/dist/molecules/ai/transcription.d.ts +17 -0
  304. package/dist/molecules/ai/transcription.d.ts.map +1 -0
  305. package/dist/molecules/ai/transcription.js +36 -0
  306. package/dist/molecules/ai/voice-selector.d.ts +64 -0
  307. package/dist/molecules/ai/voice-selector.d.ts.map +1 -0
  308. package/dist/molecules/ai/voice-selector.js +224 -0
  309. package/dist/molecules/ai/web-preview.d.ts +35 -0
  310. package/dist/molecules/ai/web-preview.d.ts.map +1 -0
  311. package/dist/molecules/ai/web-preview.js +65 -0
  312. package/dist/molecules/artifact.d.ts +24 -0
  313. package/dist/molecules/artifact.d.ts.map +1 -0
  314. package/dist/molecules/artifact.js +20 -0
  315. package/dist/molecules/attachments.d.ts +55 -0
  316. package/dist/molecules/attachments.d.ts.map +1 -0
  317. package/dist/molecules/attachments.js +125 -0
  318. package/dist/molecules/audio-player.d.ts +30 -0
  319. package/dist/molecules/audio-player.d.ts.map +1 -0
  320. package/dist/molecules/audio-player.js +43 -0
  321. package/dist/molecules/canvas.d.ts +9 -0
  322. package/dist/molecules/canvas.d.ts.map +1 -0
  323. package/dist/molecules/canvas.js +5 -0
  324. package/dist/molecules/chain-of-thought.d.ts +30 -0
  325. package/dist/molecules/chain-of-thought.d.ts.map +1 -0
  326. package/dist/molecules/chain-of-thought.js +49 -0
  327. package/dist/molecules/chat-message.d.ts +10 -0
  328. package/dist/molecules/chat-message.d.ts.map +1 -0
  329. package/dist/molecules/chat-message.js +53 -0
  330. package/dist/molecules/checkpoint.d.ts +12 -0
  331. package/dist/molecules/checkpoint.d.ts.map +1 -0
  332. package/dist/molecules/checkpoint.js +10 -0
  333. package/dist/molecules/code-block.d.ts +46 -0
  334. package/dist/molecules/code-block.d.ts.map +1 -0
  335. package/dist/molecules/code-block.js +216 -0
  336. package/dist/molecules/commit.d.ts +65 -0
  337. package/dist/molecules/commit.d.ts.map +1 -0
  338. package/dist/molecules/commit.js +95 -0
  339. package/dist/molecules/confirmation.d.ts +50 -0
  340. package/dist/molecules/confirmation.d.ts.map +1 -0
  341. package/dist/molecules/confirmation.js +61 -0
  342. package/dist/molecules/connection.d.ts +3 -0
  343. package/dist/molecules/connection.d.ts.map +1 -0
  344. package/dist/molecules/connection.js +3 -0
  345. package/dist/molecules/context.d.ts +33 -0
  346. package/dist/molecules/context.d.ts.map +1 -0
  347. package/dist/molecules/context.js +164 -0
  348. package/dist/molecules/controls.d.ts +5 -0
  349. package/dist/molecules/controls.d.ts.map +1 -0
  350. package/dist/molecules/controls.js +5 -0
  351. package/dist/molecules/conversation.d.ts +24 -0
  352. package/dist/molecules/conversation.d.ts.map +1 -0
  353. package/dist/molecules/conversation.js +41 -0
  354. package/dist/molecules/edge.d.ts +6 -0
  355. package/dist/molecules/edge.d.ts.map +1 -0
  356. package/dist/molecules/edge.js +87 -0
  357. package/dist/molecules/environment-variables.d.ts +39 -0
  358. package/dist/molecules/environment-variables.d.ts.map +1 -0
  359. package/dist/molecules/environment-variables.js +87 -0
  360. package/dist/molecules/file-tree.d.ts +27 -0
  361. package/dist/molecules/file-tree.d.ts.map +1 -0
  362. package/dist/molecules/file-tree.js +71 -0
  363. package/dist/molecules/image.d.ts +7 -0
  364. package/dist/molecules/image.d.ts.map +1 -0
  365. package/dist/molecules/image.js +3 -0
  366. package/dist/molecules/inline-citation.d.ts +39 -0
  367. package/dist/molecules/inline-citation.d.ts.map +1 -0
  368. package/dist/molecules/inline-citation.js +68 -0
  369. package/dist/molecules/jsx-preview.d.ts +30 -0
  370. package/dist/molecules/jsx-preview.d.ts.map +1 -0
  371. package/dist/molecules/jsx-preview.js +167 -0
  372. package/dist/molecules/loader.d.ts +6 -0
  373. package/dist/molecules/loader.d.ts.map +1 -0
  374. package/dist/molecules/loader.js +4 -0
  375. package/dist/molecules/message.d.ts +38 -0
  376. package/dist/molecules/message.d.ts.map +1 -0
  377. package/dist/molecules/message.js +92 -0
  378. package/dist/molecules/mic-selector.d.ts +46 -0
  379. package/dist/molecules/mic-selector.d.ts.map +1 -0
  380. package/dist/molecules/mic-selector.js +184 -0
  381. package/dist/molecules/model-selector.d.ts +36 -0
  382. package/dist/molecules/model-selector.d.ts.map +1 -0
  383. package/dist/molecules/model-selector.js +18 -0
  384. package/dist/molecules/node.d.ts +22 -0
  385. package/dist/molecules/node.d.ts.map +1 -0
  386. package/dist/molecules/node.js +11 -0
  387. package/dist/molecules/open-in-chat.d.ts +29 -0
  388. package/dist/molecules/open-in-chat.d.ts.map +1 -0
  389. package/dist/molecules/open-in-chat.js +100 -0
  390. package/dist/molecules/package-info.d.ts +30 -0
  391. package/dist/molecules/package-info.d.ts.map +1 -0
  392. package/dist/molecules/package-info.js +50 -0
  393. package/dist/molecules/panel.d.ts +6 -0
  394. package/dist/molecules/panel.d.ts.map +1 -0
  395. package/dist/molecules/panel.js +4 -0
  396. package/dist/molecules/persona.d.ts +49 -0
  397. package/dist/molecules/persona.d.ts.map +1 -0
  398. package/dist/molecules/persona.js +189 -0
  399. package/dist/molecules/plan.d.ts +26 -0
  400. package/dist/molecules/plan.d.ts.map +1 -0
  401. package/dist/molecules/plan.js +34 -0
  402. package/dist/molecules/prompt-input.d.ts +149 -0
  403. package/dist/molecules/prompt-input.d.ts.map +1 -0
  404. package/dist/molecules/prompt-input.js +702 -0
  405. package/dist/molecules/queue.d.ts +62 -0
  406. package/dist/molecules/queue.d.ts.map +1 -0
  407. package/dist/molecules/queue.js +28 -0
  408. package/dist/molecules/reasoning.d.ts +27 -0
  409. package/dist/molecules/reasoning.d.ts.map +1 -0
  410. package/dist/molecules/reasoning.js +95 -0
  411. package/dist/molecules/response.d.ts +6 -0
  412. package/dist/molecules/response.d.ts.map +1 -0
  413. package/dist/molecules/response.js +18 -0
  414. package/dist/molecules/responsive-alert-dialog.d.ts +16 -0
  415. package/dist/molecules/responsive-alert-dialog.d.ts.map +1 -0
  416. package/dist/molecules/responsive-alert-dialog.js +20 -0
  417. package/dist/molecules/responsive-dialog.d.ts +11 -0
  418. package/dist/molecules/responsive-dialog.d.ts.map +1 -0
  419. package/dist/molecules/responsive-dialog.js +21 -0
  420. package/dist/molecules/sandbox.d.ts +25 -0
  421. package/dist/molecules/sandbox.d.ts.map +1 -0
  422. package/dist/molecules/sandbox.js +15 -0
  423. package/dist/molecules/schema-display.d.ts +56 -0
  424. package/dist/molecules/schema-display.d.ts.map +1 -0
  425. package/dist/molecules/schema-display.js +73 -0
  426. package/dist/molecules/shimmer.d.ts +10 -0
  427. package/dist/molecules/shimmer.d.ts.map +1 -0
  428. package/dist/molecules/shimmer.js +28 -0
  429. package/dist/molecules/snippet.d.ts +19 -0
  430. package/dist/molecules/snippet.d.ts.map +1 -0
  431. package/dist/molecules/snippet.js +46 -0
  432. package/dist/molecules/sources.d.ts +13 -0
  433. package/dist/molecules/sources.d.ts.map +1 -0
  434. package/dist/molecules/sources.js +9 -0
  435. package/dist/molecules/speech-input.d.ts +55 -0
  436. package/dist/molecules/speech-input.d.ts.map +1 -0
  437. package/dist/molecules/speech-input.js +187 -0
  438. package/dist/molecules/stack-trace.d.ts +38 -0
  439. package/dist/molecules/stack-trace.d.ts.map +1 -0
  440. package/dist/molecules/stack-trace.js +194 -0
  441. package/dist/molecules/suggestion.d.ts +11 -0
  442. package/dist/molecules/suggestion.d.ts.map +1 -0
  443. package/dist/molecules/suggestion.js +13 -0
  444. package/dist/molecules/task.d.ts +15 -0
  445. package/dist/molecules/task.d.ts.map +1 -0
  446. package/dist/molecules/task.js +10 -0
  447. package/dist/molecules/terminal.d.ts +28 -0
  448. package/dist/molecules/terminal.d.ts.map +1 -0
  449. package/dist/molecules/terminal.js +68 -0
  450. package/dist/molecules/test-results.d.ts +59 -0
  451. package/dist/molecules/test-results.d.ts.map +1 -0
  452. package/dist/molecules/test-results.js +97 -0
  453. package/dist/molecules/tool.d.ts +32 -0
  454. package/dist/molecules/tool.d.ts.map +1 -0
  455. package/dist/molecules/tool.js +49 -0
  456. package/dist/molecules/toolbar.d.ts +6 -0
  457. package/dist/molecules/toolbar.d.ts.map +1 -0
  458. package/dist/molecules/toolbar.js +4 -0
  459. package/dist/molecules/transcription.d.ts +17 -0
  460. package/dist/molecules/transcription.d.ts.map +1 -0
  461. package/dist/molecules/transcription.js +36 -0
  462. package/dist/molecules/voice-selector.d.ts +64 -0
  463. package/dist/molecules/voice-selector.d.ts.map +1 -0
  464. package/dist/molecules/voice-selector.js +224 -0
  465. package/dist/molecules/web-preview.d.ts +35 -0
  466. package/dist/molecules/web-preview.d.ts.map +1 -0
  467. package/dist/molecules/web-preview.js +65 -0
  468. package/package.json +27 -8
@@ -0,0 +1,702 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from "@chatsdk-dev/ui/atoms/command";
4
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@chatsdk-dev/ui/atoms/dropdown-menu";
5
+ import { HoverCard, HoverCardContent, HoverCardTrigger, } from "@chatsdk-dev/ui/atoms/hover-card";
6
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupTextarea, } from "@chatsdk-dev/ui/atoms/input-group";
7
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@chatsdk-dev/ui/atoms/select";
8
+ import { Spinner } from "@chatsdk-dev/ui/atoms/spinner";
9
+ import { Tooltip, TooltipContent, TooltipTrigger, } from "@chatsdk-dev/ui/atoms/tooltip";
10
+ import { cn } from "@chatsdk-dev/ui/lib/utils";
11
+ import { CornerDownLeftIcon, ImageIcon, Monitor, PlusIcon, SquareIcon, XIcon, } from "lucide-react";
12
+ import { nanoid } from "nanoid";
13
+ import { Children, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
14
+ // ============================================================================
15
+ // Helpers
16
+ // ============================================================================
17
+ const convertBlobUrlToDataUrl = async (url) => {
18
+ try {
19
+ const response = await fetch(url);
20
+ const blob = await response.blob();
21
+ // FileReader uses callback-based API, wrapping in Promise is necessary
22
+ // oxlint-disable-next-line eslint-plugin-promise(avoid-new)
23
+ return new Promise((resolve) => {
24
+ const reader = new FileReader();
25
+ // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)
26
+ reader.onloadend = () => resolve(reader.result);
27
+ // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)
28
+ reader.onerror = () => resolve(null);
29
+ reader.readAsDataURL(blob);
30
+ });
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ };
36
+ const captureScreenshot = async () => {
37
+ if (typeof navigator === "undefined" ||
38
+ !navigator.mediaDevices?.getDisplayMedia) {
39
+ return null;
40
+ }
41
+ let stream = null;
42
+ const video = document.createElement("video");
43
+ video.muted = true;
44
+ video.playsInline = true;
45
+ try {
46
+ stream = await navigator.mediaDevices.getDisplayMedia({
47
+ audio: false,
48
+ video: true,
49
+ });
50
+ video.srcObject = stream;
51
+ // Video element uses callback-based API, wrapping in Promise is necessary
52
+ // oxlint-disable-next-line eslint-plugin-promise(avoid-new)
53
+ await new Promise((resolve, reject) => {
54
+ // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)
55
+ video.onloadedmetadata = () => resolve();
56
+ // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)
57
+ video.onerror = () => reject(new Error("Failed to load screen stream"));
58
+ });
59
+ await video.play();
60
+ const width = video.videoWidth;
61
+ const height = video.videoHeight;
62
+ if (!width || !height) {
63
+ return null;
64
+ }
65
+ const canvas = document.createElement("canvas");
66
+ canvas.width = width;
67
+ canvas.height = height;
68
+ const context = canvas.getContext("2d");
69
+ if (!context) {
70
+ return null;
71
+ }
72
+ context.drawImage(video, 0, 0, width, height);
73
+ // canvas.toBlob uses callback-based API, wrapping in Promise is necessary
74
+ // oxlint-disable-next-line eslint-plugin-promise(avoid-new)
75
+ const blob = await new Promise((resolve) => {
76
+ canvas.toBlob(resolve, "image/png");
77
+ });
78
+ if (!blob) {
79
+ return null;
80
+ }
81
+ const timestamp = new Date()
82
+ .toISOString()
83
+ .replaceAll(/[:.]/g, "-")
84
+ .replace("T", "_")
85
+ .replace("Z", "");
86
+ return new File([blob], `screenshot-${timestamp}.png`, {
87
+ lastModified: Date.now(),
88
+ type: "image/png",
89
+ });
90
+ }
91
+ finally {
92
+ if (stream) {
93
+ for (const track of stream.getTracks()) {
94
+ track.stop();
95
+ }
96
+ }
97
+ video.pause();
98
+ video.srcObject = null;
99
+ }
100
+ };
101
+ const PromptInputController = createContext(null);
102
+ const ProviderAttachmentsContext = createContext(null);
103
+ export const usePromptInputController = () => {
104
+ const ctx = useContext(PromptInputController);
105
+ if (!ctx) {
106
+ throw new Error("Wrap your component inside <PromptInputProvider> to use usePromptInputController().");
107
+ }
108
+ return ctx;
109
+ };
110
+ // Optional variants (do NOT throw). Useful for dual-mode components.
111
+ const useOptionalPromptInputController = () => useContext(PromptInputController);
112
+ export const useProviderAttachments = () => {
113
+ const ctx = useContext(ProviderAttachmentsContext);
114
+ if (!ctx) {
115
+ throw new Error("Wrap your component inside <PromptInputProvider> to use useProviderAttachments().");
116
+ }
117
+ return ctx;
118
+ };
119
+ const useOptionalProviderAttachments = () => useContext(ProviderAttachmentsContext);
120
+ /**
121
+ * Optional global provider that lifts PromptInput state outside of PromptInput.
122
+ * If you don't use it, PromptInput stays fully self-managed.
123
+ */
124
+ export const PromptInputProvider = ({ initialInput: initialTextInput = "", children, }) => {
125
+ // ----- textInput state
126
+ const [textInput, setTextInput] = useState(initialTextInput);
127
+ const clearInput = useCallback(() => setTextInput(""), []);
128
+ // ----- attachments state (global when wrapped)
129
+ const [attachmentFiles, setAttachmentFiles] = useState([]);
130
+ const fileInputRef = useRef(null);
131
+ // oxlint-disable-next-line eslint(no-empty-function)
132
+ const openRef = useRef(() => { });
133
+ const add = useCallback((files) => {
134
+ const incoming = [...files];
135
+ if (incoming.length === 0) {
136
+ return;
137
+ }
138
+ setAttachmentFiles((prev) => [
139
+ ...prev,
140
+ ...incoming.map((file) => ({
141
+ filename: file.name,
142
+ id: nanoid(),
143
+ mediaType: file.type,
144
+ type: "file",
145
+ url: URL.createObjectURL(file),
146
+ })),
147
+ ]);
148
+ }, []);
149
+ const remove = useCallback((id) => {
150
+ setAttachmentFiles((prev) => {
151
+ const found = prev.find((f) => f.id === id);
152
+ if (found?.url) {
153
+ URL.revokeObjectURL(found.url);
154
+ }
155
+ return prev.filter((f) => f.id !== id);
156
+ });
157
+ }, []);
158
+ const clear = useCallback(() => {
159
+ setAttachmentFiles((prev) => {
160
+ for (const f of prev) {
161
+ if (f.url) {
162
+ URL.revokeObjectURL(f.url);
163
+ }
164
+ }
165
+ return [];
166
+ });
167
+ }, []);
168
+ // Keep a ref to attachments for cleanup on unmount (avoids stale closure)
169
+ const attachmentsRef = useRef(attachmentFiles);
170
+ useEffect(() => {
171
+ attachmentsRef.current = attachmentFiles;
172
+ }, [attachmentFiles]);
173
+ // Cleanup blob URLs on unmount to prevent memory leaks
174
+ useEffect(() => () => {
175
+ for (const f of attachmentsRef.current) {
176
+ if (f.url) {
177
+ URL.revokeObjectURL(f.url);
178
+ }
179
+ }
180
+ }, []);
181
+ const openFileDialog = useCallback(() => {
182
+ openRef.current?.();
183
+ }, []);
184
+ const attachments = useMemo(() => ({
185
+ add,
186
+ clear,
187
+ fileInputRef,
188
+ files: attachmentFiles,
189
+ openFileDialog,
190
+ remove,
191
+ }), [attachmentFiles, add, remove, clear, openFileDialog]);
192
+ const __registerFileInput = useCallback((ref, open) => {
193
+ fileInputRef.current = ref.current;
194
+ openRef.current = open;
195
+ }, []);
196
+ const controller = useMemo(() => ({
197
+ __registerFileInput,
198
+ attachments,
199
+ textInput: {
200
+ clear: clearInput,
201
+ setInput: setTextInput,
202
+ value: textInput,
203
+ },
204
+ }), [textInput, clearInput, attachments, __registerFileInput]);
205
+ return (_jsx(PromptInputController.Provider, { value: controller, children: _jsx(ProviderAttachmentsContext.Provider, { value: attachments, children: children }) }));
206
+ };
207
+ // ============================================================================
208
+ // Component Context & Hooks
209
+ // ============================================================================
210
+ const LocalAttachmentsContext = createContext(null);
211
+ export const usePromptInputAttachments = () => {
212
+ // Prefer local context (inside PromptInput) as it has validation, fall back to provider
213
+ const provider = useOptionalProviderAttachments();
214
+ const local = useContext(LocalAttachmentsContext);
215
+ const context = local ?? provider;
216
+ if (!context) {
217
+ throw new Error("usePromptInputAttachments must be used within a PromptInput or PromptInputProvider");
218
+ }
219
+ return context;
220
+ };
221
+ export const LocalReferencedSourcesContext = createContext(null);
222
+ export const usePromptInputReferencedSources = () => {
223
+ const ctx = useContext(LocalReferencedSourcesContext);
224
+ if (!ctx) {
225
+ throw new Error("usePromptInputReferencedSources must be used within a LocalReferencedSourcesContext.Provider");
226
+ }
227
+ return ctx;
228
+ };
229
+ export const PromptInputActionAddAttachments = ({ label = "Add photos or files", ...props }) => {
230
+ const attachments = usePromptInputAttachments();
231
+ const handleSelect = useCallback((e) => {
232
+ e.preventDefault();
233
+ attachments.openFileDialog();
234
+ }, [attachments]);
235
+ return (_jsxs(DropdownMenuItem, { ...props, onSelect: handleSelect, children: [_jsx(ImageIcon, { className: "mr-2 size-4" }), " ", label] }));
236
+ };
237
+ export const PromptInputActionAddScreenshot = ({ label = "Take screenshot", onSelect, ...props }) => {
238
+ const attachments = usePromptInputAttachments();
239
+ const handleSelect = useCallback(async (event) => {
240
+ onSelect?.(event);
241
+ if (event.defaultPrevented) {
242
+ return;
243
+ }
244
+ try {
245
+ const screenshot = await captureScreenshot();
246
+ if (screenshot) {
247
+ attachments.add([screenshot]);
248
+ }
249
+ }
250
+ catch (error) {
251
+ if (error instanceof DOMException &&
252
+ (error.name === "NotAllowedError" || error.name === "AbortError")) {
253
+ return;
254
+ }
255
+ throw error;
256
+ }
257
+ }, [onSelect, attachments]);
258
+ return (_jsxs(DropdownMenuItem, { ...props, onSelect: handleSelect, children: [_jsx(Monitor, { className: "mr-2 size-4" }), label] }));
259
+ };
260
+ export const PromptInput = ({ className, accept, multiple, globalDrop, syncHiddenInput, maxFiles, maxFileSize, onError, onSubmit, children, ...props }) => {
261
+ // Try to use a provider controller if present
262
+ const controller = useOptionalPromptInputController();
263
+ const usingProvider = !!controller;
264
+ // Refs
265
+ const inputRef = useRef(null);
266
+ const formRef = useRef(null);
267
+ // ----- Local attachments (only used when no provider)
268
+ const [items, setItems] = useState([]);
269
+ const files = usingProvider ? controller.attachments.files : items;
270
+ // ----- Local referenced sources (always local to PromptInput)
271
+ const [referencedSources, setReferencedSources] = useState([]);
272
+ // Keep a ref to files for cleanup on unmount (avoids stale closure)
273
+ const filesRef = useRef(files);
274
+ useEffect(() => {
275
+ filesRef.current = files;
276
+ }, [files]);
277
+ const openFileDialogLocal = useCallback(() => {
278
+ inputRef.current?.click();
279
+ }, []);
280
+ const matchesAccept = useCallback((f) => {
281
+ if (!accept || accept.trim() === "") {
282
+ return true;
283
+ }
284
+ const patterns = accept
285
+ .split(",")
286
+ .map((s) => s.trim())
287
+ .filter(Boolean);
288
+ return patterns.some((pattern) => {
289
+ if (pattern.endsWith("/*")) {
290
+ // e.g: image/* -> image/
291
+ const prefix = pattern.slice(0, -1);
292
+ return f.type.startsWith(prefix);
293
+ }
294
+ return f.type === pattern;
295
+ });
296
+ }, [accept]);
297
+ const addLocal = useCallback((fileList) => {
298
+ const incoming = [...fileList];
299
+ const accepted = incoming.filter((f) => matchesAccept(f));
300
+ if (incoming.length && accepted.length === 0) {
301
+ onError?.({
302
+ code: "accept",
303
+ message: "No files match the accepted types.",
304
+ });
305
+ return;
306
+ }
307
+ const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
308
+ const sized = accepted.filter(withinSize);
309
+ if (accepted.length > 0 && sized.length === 0) {
310
+ onError?.({
311
+ code: "max_file_size",
312
+ message: "All files exceed the maximum size.",
313
+ });
314
+ return;
315
+ }
316
+ setItems((prev) => {
317
+ const capacity = typeof maxFiles === "number"
318
+ ? Math.max(0, maxFiles - prev.length)
319
+ : undefined;
320
+ const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
321
+ if (typeof capacity === "number" && sized.length > capacity) {
322
+ onError?.({
323
+ code: "max_files",
324
+ message: "Too many files. Some were not added.",
325
+ });
326
+ }
327
+ const next = [];
328
+ for (const file of capped) {
329
+ next.push({
330
+ filename: file.name,
331
+ id: nanoid(),
332
+ mediaType: file.type,
333
+ type: "file",
334
+ url: URL.createObjectURL(file),
335
+ });
336
+ }
337
+ return [...prev, ...next];
338
+ });
339
+ }, [matchesAccept, maxFiles, maxFileSize, onError]);
340
+ const removeLocal = useCallback((id) => setItems((prev) => {
341
+ const found = prev.find((file) => file.id === id);
342
+ if (found?.url) {
343
+ URL.revokeObjectURL(found.url);
344
+ }
345
+ return prev.filter((file) => file.id !== id);
346
+ }), []);
347
+ // Wrapper that validates files before calling provider's add
348
+ const addWithProviderValidation = useCallback((fileList) => {
349
+ const incoming = [...fileList];
350
+ const accepted = incoming.filter((f) => matchesAccept(f));
351
+ if (incoming.length && accepted.length === 0) {
352
+ onError?.({
353
+ code: "accept",
354
+ message: "No files match the accepted types.",
355
+ });
356
+ return;
357
+ }
358
+ const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
359
+ const sized = accepted.filter(withinSize);
360
+ if (accepted.length > 0 && sized.length === 0) {
361
+ onError?.({
362
+ code: "max_file_size",
363
+ message: "All files exceed the maximum size.",
364
+ });
365
+ return;
366
+ }
367
+ const currentCount = files.length;
368
+ const capacity = typeof maxFiles === "number"
369
+ ? Math.max(0, maxFiles - currentCount)
370
+ : undefined;
371
+ const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
372
+ if (typeof capacity === "number" && sized.length > capacity) {
373
+ onError?.({
374
+ code: "max_files",
375
+ message: "Too many files. Some were not added.",
376
+ });
377
+ }
378
+ if (capped.length > 0) {
379
+ controller?.attachments.add(capped);
380
+ }
381
+ }, [matchesAccept, maxFileSize, maxFiles, onError, files.length, controller]);
382
+ const clearAttachments = useCallback(() => usingProvider
383
+ ? controller?.attachments.clear()
384
+ : setItems((prev) => {
385
+ for (const file of prev) {
386
+ if (file.url) {
387
+ URL.revokeObjectURL(file.url);
388
+ }
389
+ }
390
+ return [];
391
+ }), [usingProvider, controller]);
392
+ const clearReferencedSources = useCallback(() => setReferencedSources([]), []);
393
+ const add = usingProvider ? addWithProviderValidation : addLocal;
394
+ const remove = usingProvider ? controller.attachments.remove : removeLocal;
395
+ const openFileDialog = usingProvider
396
+ ? controller.attachments.openFileDialog
397
+ : openFileDialogLocal;
398
+ const clear = useCallback(() => {
399
+ clearAttachments();
400
+ clearReferencedSources();
401
+ }, [clearAttachments, clearReferencedSources]);
402
+ // Let provider know about our hidden file input so external menus can call openFileDialog()
403
+ useEffect(() => {
404
+ if (!usingProvider) {
405
+ return;
406
+ }
407
+ controller.__registerFileInput(inputRef, () => inputRef.current?.click());
408
+ }, [usingProvider, controller]);
409
+ // Note: File input cannot be programmatically set for security reasons
410
+ // The syncHiddenInput prop is no longer functional
411
+ useEffect(() => {
412
+ if (syncHiddenInput && inputRef.current && files.length === 0) {
413
+ inputRef.current.value = "";
414
+ }
415
+ }, [files, syncHiddenInput]);
416
+ // Attach drop handlers on nearest form and document (opt-in)
417
+ useEffect(() => {
418
+ const form = formRef.current;
419
+ if (!form) {
420
+ return;
421
+ }
422
+ if (globalDrop) {
423
+ // when global drop is on, let the document-level handler own drops
424
+ return;
425
+ }
426
+ const onDragOver = (e) => {
427
+ if (e.dataTransfer?.types?.includes("Files")) {
428
+ e.preventDefault();
429
+ }
430
+ };
431
+ const onDrop = (e) => {
432
+ if (e.dataTransfer?.types?.includes("Files")) {
433
+ e.preventDefault();
434
+ }
435
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
436
+ add(e.dataTransfer.files);
437
+ }
438
+ };
439
+ form.addEventListener("dragover", onDragOver);
440
+ form.addEventListener("drop", onDrop);
441
+ return () => {
442
+ form.removeEventListener("dragover", onDragOver);
443
+ form.removeEventListener("drop", onDrop);
444
+ };
445
+ }, [add, globalDrop]);
446
+ useEffect(() => {
447
+ if (!globalDrop) {
448
+ return;
449
+ }
450
+ const onDragOver = (e) => {
451
+ if (e.dataTransfer?.types?.includes("Files")) {
452
+ e.preventDefault();
453
+ }
454
+ };
455
+ const onDrop = (e) => {
456
+ if (e.dataTransfer?.types?.includes("Files")) {
457
+ e.preventDefault();
458
+ }
459
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {
460
+ add(e.dataTransfer.files);
461
+ }
462
+ };
463
+ document.addEventListener("dragover", onDragOver);
464
+ document.addEventListener("drop", onDrop);
465
+ return () => {
466
+ document.removeEventListener("dragover", onDragOver);
467
+ document.removeEventListener("drop", onDrop);
468
+ };
469
+ }, [add, globalDrop]);
470
+ useEffect(() => () => {
471
+ if (!usingProvider) {
472
+ for (const f of filesRef.current) {
473
+ if (f.url) {
474
+ URL.revokeObjectURL(f.url);
475
+ }
476
+ }
477
+ }
478
+ }, [usingProvider]);
479
+ const handleChange = useCallback((event) => {
480
+ if (event.currentTarget.files) {
481
+ add(event.currentTarget.files);
482
+ }
483
+ // Reset input value to allow selecting files that were previously removed
484
+ event.currentTarget.value = "";
485
+ }, [add]);
486
+ const attachmentsCtx = useMemo(() => ({
487
+ add,
488
+ clear: clearAttachments,
489
+ fileInputRef: inputRef,
490
+ files: files.map((item) => ({ ...item, id: item.id })),
491
+ openFileDialog,
492
+ remove,
493
+ }), [files, add, remove, clearAttachments, openFileDialog]);
494
+ const refsCtx = useMemo(() => ({
495
+ add: (incoming) => {
496
+ const array = Array.isArray(incoming) ? incoming : [incoming];
497
+ setReferencedSources((prev) => [
498
+ ...prev,
499
+ ...array.map((s) => ({ ...s, id: nanoid() })),
500
+ ]);
501
+ },
502
+ clear: clearReferencedSources,
503
+ remove: (id) => {
504
+ setReferencedSources((prev) => prev.filter((s) => s.id !== id));
505
+ },
506
+ sources: referencedSources,
507
+ }), [referencedSources, clearReferencedSources]);
508
+ const handleSubmit = useCallback(async (event) => {
509
+ event.preventDefault();
510
+ const form = event.currentTarget;
511
+ const text = usingProvider
512
+ ? controller.textInput.value
513
+ : (() => {
514
+ const formData = new FormData(form);
515
+ return formData.get("message") || "";
516
+ })();
517
+ // Reset form immediately after capturing text to avoid race condition
518
+ // where user input during async blob conversion would be lost
519
+ if (!usingProvider) {
520
+ form.reset();
521
+ }
522
+ try {
523
+ // Convert blob URLs to data URLs asynchronously
524
+ const convertedFiles = await Promise.all(files.map(async ({ id: _id, ...item }) => {
525
+ if (item.url?.startsWith("blob:")) {
526
+ const dataUrl = await convertBlobUrlToDataUrl(item.url);
527
+ // If conversion failed, keep the original blob URL
528
+ return {
529
+ ...item,
530
+ url: dataUrl ?? item.url,
531
+ };
532
+ }
533
+ return item;
534
+ }));
535
+ const result = onSubmit({ files: convertedFiles, text }, event);
536
+ // Handle both sync and async onSubmit
537
+ if (result instanceof Promise) {
538
+ try {
539
+ await result;
540
+ clear();
541
+ if (usingProvider) {
542
+ controller.textInput.clear();
543
+ }
544
+ }
545
+ catch {
546
+ // Don't clear on error - user may want to retry
547
+ }
548
+ }
549
+ else {
550
+ // Sync function completed without throwing, clear inputs
551
+ clear();
552
+ if (usingProvider) {
553
+ controller.textInput.clear();
554
+ }
555
+ }
556
+ }
557
+ catch {
558
+ // Don't clear on error - user may want to retry
559
+ }
560
+ }, [usingProvider, controller, files, onSubmit, clear]);
561
+ // Render with or without local provider
562
+ const inner = (_jsxs(_Fragment, { children: [_jsx("input", { accept: accept, "aria-label": "Upload files", className: "hidden", multiple: multiple, onChange: handleChange, ref: inputRef, title: "Upload files", type: "file" }), _jsx("form", { className: cn("w-full", className), onSubmit: handleSubmit, ref: formRef, ...props, children: _jsx(InputGroup, { className: "overflow-hidden", children: children }) })] }));
563
+ const withReferencedSources = (_jsx(LocalReferencedSourcesContext.Provider, { value: refsCtx, children: inner }));
564
+ // Always provide LocalAttachmentsContext so children get validated add function
565
+ return (_jsx(LocalAttachmentsContext.Provider, { value: attachmentsCtx, children: withReferencedSources }));
566
+ };
567
+ export const PromptInputBody = ({ className, ...props }) => (_jsx("div", { className: cn("contents", className), ...props }));
568
+ export const PromptInputTextarea = ({ onChange, onKeyDown, className, placeholder = "What would you like to know?", ...props }) => {
569
+ const controller = useOptionalPromptInputController();
570
+ const attachments = usePromptInputAttachments();
571
+ const [isComposing, setIsComposing] = useState(false);
572
+ const handleKeyDown = useCallback((e) => {
573
+ // Call the external onKeyDown handler first
574
+ onKeyDown?.(e);
575
+ // If the external handler prevented default, don't run internal logic
576
+ if (e.defaultPrevented) {
577
+ return;
578
+ }
579
+ if (e.key === "Enter") {
580
+ if (isComposing || e.nativeEvent.isComposing) {
581
+ return;
582
+ }
583
+ if (e.shiftKey) {
584
+ return;
585
+ }
586
+ e.preventDefault();
587
+ // Check if the submit button is disabled before submitting
588
+ const { form } = e.currentTarget;
589
+ const submitButton = form?.querySelector('button[type="submit"]');
590
+ if (submitButton?.disabled) {
591
+ return;
592
+ }
593
+ form?.requestSubmit();
594
+ }
595
+ // Remove last attachment when Backspace is pressed and textarea is empty
596
+ if (e.key === "Backspace" &&
597
+ e.currentTarget.value === "" &&
598
+ attachments.files.length > 0) {
599
+ e.preventDefault();
600
+ const lastAttachment = attachments.files.at(-1);
601
+ if (lastAttachment) {
602
+ attachments.remove(lastAttachment.id);
603
+ }
604
+ }
605
+ }, [onKeyDown, isComposing, attachments]);
606
+ const handlePaste = useCallback((event) => {
607
+ const items = event.clipboardData?.items;
608
+ if (!items) {
609
+ return;
610
+ }
611
+ const files = [];
612
+ for (const item of items) {
613
+ if (item.kind === "file") {
614
+ const file = item.getAsFile();
615
+ if (file) {
616
+ files.push(file);
617
+ }
618
+ }
619
+ }
620
+ if (files.length > 0) {
621
+ event.preventDefault();
622
+ attachments.add(files);
623
+ }
624
+ }, [attachments]);
625
+ const handleCompositionEnd = useCallback(() => setIsComposing(false), []);
626
+ const handleCompositionStart = useCallback(() => setIsComposing(true), []);
627
+ const controlledProps = controller
628
+ ? {
629
+ onChange: (e) => {
630
+ controller.textInput.setInput(e.currentTarget.value);
631
+ onChange?.(e);
632
+ },
633
+ value: controller.textInput.value,
634
+ }
635
+ : {
636
+ onChange,
637
+ };
638
+ return (_jsx(InputGroupTextarea, { className: cn("field-sizing-content max-h-48 min-h-16", className), name: "message", onCompositionEnd: handleCompositionEnd, onCompositionStart: handleCompositionStart, onKeyDown: handleKeyDown, onPaste: handlePaste, placeholder: placeholder, ...props, ...controlledProps }));
639
+ };
640
+ export const PromptInputHeader = ({ className, ...props }) => (_jsx(InputGroupAddon, { align: "block-end", className: cn("order-first flex-wrap gap-1", className), ...props }));
641
+ export const PromptInputFooter = ({ className, ...props }) => (_jsx(InputGroupAddon, { align: "block-end", className: cn("justify-between gap-1", className), ...props }));
642
+ export const PromptInputTools = ({ className, ...props }) => (_jsx("div", { className: cn("flex min-w-0 items-center gap-1", className), ...props }));
643
+ export const PromptInputButton = ({ variant = "ghost", className, size, tooltip, ...props }) => {
644
+ const newSize = size ?? (Children.count(props.children) > 1 ? "sm" : "icon-sm");
645
+ const button = (_jsx(InputGroupButton, { className: cn(className), size: newSize, type: "button", variant: variant, ...props }));
646
+ if (!tooltip) {
647
+ return button;
648
+ }
649
+ const tooltipContent = typeof tooltip === "string" ? tooltip : tooltip.content;
650
+ const shortcut = typeof tooltip === "string" ? undefined : tooltip.shortcut;
651
+ const side = typeof tooltip === "string" ? "top" : (tooltip.side ?? "top");
652
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: () => button }), _jsxs(TooltipContent, { side: side, children: [tooltipContent, shortcut && (_jsx("span", { className: "ml-2 text-muted-foreground", children: shortcut }))] })] }));
653
+ };
654
+ export const PromptInputActionMenu = (props) => (_jsx(DropdownMenu, { ...props }));
655
+ export const PromptInputActionMenuTrigger = ({ className, children, ...props }) => (_jsx(DropdownMenuTrigger, { render: () => (_jsx(PromptInputButton, { className: className, ...props, children: children ?? _jsx(PlusIcon, { className: "size-4" }) })) }));
656
+ export const PromptInputActionMenuContent = ({ className, ...props }) => (_jsx(DropdownMenuContent, { align: "start", className: cn(className), ...props }));
657
+ export const PromptInputActionMenuItem = ({ className, ...props }) => (_jsx(DropdownMenuItem, { className: cn(className), ...props }));
658
+ export const PromptInputSubmit = ({ className, variant = "primary", size = "icon-sm", status, onStop, onClick, children, ...props }) => {
659
+ const isGenerating = status === "submitted" || status === "streaming";
660
+ let Icon = _jsx(CornerDownLeftIcon, { className: "size-4" });
661
+ if (status === "submitted") {
662
+ Icon = _jsx(Spinner, {});
663
+ }
664
+ else if (status === "streaming") {
665
+ Icon = _jsx(SquareIcon, { className: "size-4" });
666
+ }
667
+ else if (status === "error") {
668
+ Icon = _jsx(XIcon, { className: "size-4" });
669
+ }
670
+ const handleClick = useCallback((e) => {
671
+ if (isGenerating && onStop) {
672
+ e.preventDefault();
673
+ onStop();
674
+ return;
675
+ }
676
+ onClick?.(e);
677
+ }, [isGenerating, onStop, onClick]);
678
+ return (_jsx(InputGroupButton, { "aria-label": isGenerating ? "Stop" : "Submit", className: cn(className), onClick: handleClick, size: size, type: isGenerating && onStop ? "button" : "submit", variant: variant, ...props, children: children ?? Icon }));
679
+ };
680
+ export const PromptInputSelect = (props) => (_jsx(Select, { ...props }));
681
+ export const PromptInputSelectTrigger = ({ className, ...props }) => (_jsx(SelectTrigger, { className: cn("border-none bg-transparent font-medium text-muted-foreground shadow-none transition-colors", "hover:bg-accent hover:text-foreground aria-expanded:bg-accent aria-expanded:text-foreground", className), ...props }));
682
+ export const PromptInputSelectContent = ({ className, ...props }) => (_jsx(SelectContent, { className: cn(className), ...props }));
683
+ export const PromptInputSelectItem = ({ className, ...props }) => (_jsx(SelectItem, { className: cn(className), ...props }));
684
+ export const PromptInputSelectValue = ({ className, ...props }) => (_jsx(SelectValue, { className: cn(className), ...props }));
685
+ export const PromptInputHoverCard = ({ ...props }) => _jsx(HoverCard, { ...props });
686
+ export const PromptInputHoverCardTrigger = (props) => _jsx(HoverCardTrigger, { ...props });
687
+ export const PromptInputHoverCardContent = ({ align = "start", ...props }) => (_jsx(HoverCardContent, { align: align, ...props }));
688
+ export const PromptInputTabsList = ({ className, ...props }) => _jsx("div", { className: cn(className), ...props });
689
+ export const PromptInputTab = ({ className, ...props }) => _jsx("div", { className: cn(className), ...props });
690
+ export const PromptInputTabLabel = ({ className, ...props }) => (
691
+ // Content provided via children in props
692
+ // oxlint-disable-next-line eslint-plugin-jsx-a11y(heading-has-content)
693
+ _jsx("h3", { className: cn("mb-2 px-3 font-medium text-muted-foreground text-xs", className), ...props }));
694
+ export const PromptInputTabBody = ({ className, ...props }) => (_jsx("div", { className: cn("space-y-1", className), ...props }));
695
+ export const PromptInputTabItem = ({ className, ...props }) => (_jsx("div", { className: cn("flex items-center gap-2 px-3 py-2 text-xs hover:bg-accent", className), ...props }));
696
+ export const PromptInputCommand = ({ className, ...props }) => _jsx(Command, { className: cn(className), ...props });
697
+ export const PromptInputCommandInput = ({ className, ...props }) => (_jsx(CommandInput, { className: cn(className), ...props }));
698
+ export const PromptInputCommandList = ({ className, ...props }) => (_jsx(CommandList, { className: cn(className), ...props }));
699
+ export const PromptInputCommandEmpty = ({ className, ...props }) => (_jsx(CommandEmpty, { className: cn(className), ...props }));
700
+ export const PromptInputCommandGroup = ({ className, ...props }) => (_jsx(CommandGroup, { className: cn(className), ...props }));
701
+ export const PromptInputCommandItem = ({ className, ...props }) => (_jsx(CommandItem, { className: cn(className), ...props }));
702
+ export const PromptInputCommandSeparator = ({ className, ...props }) => (_jsx(CommandSeparator, { className: cn(className), ...props }));