@elabs-ai/components-ai 4.2.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (462) hide show
  1. package/README.md +1 -1
  2. package/dist/{_audio-player-media-chrome-T3XVXWRZ.js → _audio-player-media-chrome.js} +1 -1
  3. package/dist/_code-block-theme.js +12 -0
  4. package/dist/_code-block-theme.js.map +1 -0
  5. package/dist/{_flow-boundary-SHNWLQG5.js → _flow-boundary.js} +1 -1
  6. package/dist/_flow-boundary.js.map +1 -0
  7. package/dist/_flow-lazy.js +8 -0
  8. package/dist/_flow-lazy.js.map +1 -0
  9. package/dist/_lazy-boundary-conformance.js +2 -0
  10. package/dist/_lazy-boundary-conformance.js.map +1 -0
  11. package/dist/_lazy-cjk.js +13 -0
  12. package/dist/_lazy-cjk.js.map +1 -0
  13. package/dist/_lazy-engine-boundary.js +9 -0
  14. package/dist/_lazy-engine-boundary.js.map +1 -0
  15. package/dist/_lazy-math.js +13 -0
  16. package/dist/_lazy-math.js.map +1 -0
  17. package/dist/_lazy-mermaid.js +12 -0
  18. package/dist/_lazy-mermaid.js.map +1 -0
  19. package/dist/_mermaid-error-panel.js +9 -0
  20. package/dist/_mermaid-error-panel.js.map +1 -0
  21. package/dist/{_persona-rive-JEG44YHX.js → _persona-rive.js} +19 -24
  22. package/dist/_persona-rive.js.map +1 -0
  23. package/dist/_streamdown-i18n.js +21 -0
  24. package/dist/_streamdown-i18n.js.map +1 -0
  25. package/dist/_streamdown-safety.js +10 -0
  26. package/dist/_streamdown-safety.js.map +1 -0
  27. package/dist/_theme-scope-store.js +13 -0
  28. package/dist/_theme-scope-store.js.map +1 -0
  29. package/dist/a2ui/a2ui-surface.js +17 -0
  30. package/dist/a2ui/a2ui-surface.js.map +1 -0
  31. package/dist/a2ui/core/catalog.generated.js +10 -0
  32. package/dist/a2ui/core/catalog.generated.js.map +1 -0
  33. package/dist/a2ui/core/complete-json.js +10 -0
  34. package/dist/a2ui/core/complete-json.js.map +1 -0
  35. package/dist/a2ui/core/index.js +37 -0
  36. package/dist/a2ui/core/index.js.map +1 -0
  37. package/dist/a2ui/core/schema.js +11 -0
  38. package/dist/a2ui/core/schema.js.map +1 -0
  39. package/dist/a2ui/core/spec.js +10 -0
  40. package/dist/a2ui/core/spec.js.map +1 -0
  41. package/dist/a2ui/core/validate.js +16 -0
  42. package/dist/a2ui/core/validate.js.map +1 -0
  43. package/dist/a2ui/index.js +54 -0
  44. package/dist/a2ui/index.js.map +1 -0
  45. package/dist/a2ui/ui-catalog.js +18 -0
  46. package/dist/a2ui/ui-catalog.js.map +1 -0
  47. package/dist/agent-event.js +10 -0
  48. package/dist/agent-event.js.map +1 -0
  49. package/dist/agent-timeline.js +11 -0
  50. package/dist/agent-timeline.js.map +1 -0
  51. package/dist/agent.js +25 -0
  52. package/dist/agent.js.map +1 -0
  53. package/dist/artifact.js +23 -0
  54. package/dist/artifact.js.map +1 -0
  55. package/dist/asset-preview.js +22 -0
  56. package/dist/asset-preview.js.map +1 -0
  57. package/dist/attachments.js +33 -0
  58. package/dist/attachments.js.map +1 -0
  59. package/dist/audio-player.js +30 -0
  60. package/dist/audio-player.js.map +1 -0
  61. package/dist/audio-visualizer.js +9 -0
  62. package/dist/audio-visualizer.js.map +1 -0
  63. package/dist/canvas.js +10 -0
  64. package/dist/canvas.js.map +1 -0
  65. package/dist/chain-of-thought.js +22 -0
  66. package/dist/chain-of-thought.js.map +1 -0
  67. package/dist/chat-greeting.js +8 -0
  68. package/dist/chat-greeting.js.map +1 -0
  69. package/dist/chat-shell.js +9 -0
  70. package/dist/chat-shell.js.map +1 -0
  71. package/dist/checkpoint.js +13 -0
  72. package/dist/checkpoint.js.map +1 -0
  73. package/dist/chunk-2XOIG5TG.js +72 -0
  74. package/dist/chunk-2XOIG5TG.js.map +1 -0
  75. package/dist/chunk-34CQ2VHM.js +172 -0
  76. package/dist/chunk-34CQ2VHM.js.map +1 -0
  77. package/dist/chunk-3TDHPXZZ.js +60 -0
  78. package/dist/chunk-3TDHPXZZ.js.map +1 -0
  79. package/dist/chunk-3XNPMDZY.js +478 -0
  80. package/dist/chunk-3XNPMDZY.js.map +1 -0
  81. package/dist/chunk-3YPT3V7L.js +56 -0
  82. package/dist/chunk-3YPT3V7L.js.map +1 -0
  83. package/dist/chunk-475UEU2Q.js +87 -0
  84. package/dist/chunk-475UEU2Q.js.map +1 -0
  85. package/dist/chunk-4CBTII2I.js +95 -0
  86. package/dist/chunk-4CBTII2I.js.map +1 -0
  87. package/dist/chunk-4XRNIZMG.js +22 -0
  88. package/dist/chunk-4XRNIZMG.js.map +1 -0
  89. package/dist/chunk-5NNWUKK5.js +2 -0
  90. package/dist/chunk-5NNWUKK5.js.map +1 -0
  91. package/dist/chunk-5UOMU27Z.js +164 -0
  92. package/dist/chunk-5UOMU27Z.js.map +1 -0
  93. package/dist/chunk-5VGYZ62I.js +264 -0
  94. package/dist/chunk-5VGYZ62I.js.map +1 -0
  95. package/dist/chunk-6IQPH2OS.js +21 -0
  96. package/dist/chunk-6IQPH2OS.js.map +1 -0
  97. package/dist/chunk-6PB2MXCI.js +482 -0
  98. package/dist/chunk-6PB2MXCI.js.map +1 -0
  99. package/dist/chunk-7FD5CZEU.js +215 -0
  100. package/dist/chunk-7FD5CZEU.js.map +1 -0
  101. package/dist/chunk-7RL6KZDF.js +266 -0
  102. package/dist/chunk-7RL6KZDF.js.map +1 -0
  103. package/dist/chunk-ADOYAGGK.js +482 -0
  104. package/dist/chunk-ADOYAGGK.js.map +1 -0
  105. package/dist/chunk-BA3AEMOU.js +21 -0
  106. package/dist/chunk-BA3AEMOU.js.map +1 -0
  107. package/dist/chunk-BBHFOYML.js +336 -0
  108. package/dist/chunk-BBHFOYML.js.map +1 -0
  109. package/dist/chunk-BHUVISIY.js +221 -0
  110. package/dist/chunk-BHUVISIY.js.map +1 -0
  111. package/dist/chunk-BM2LWERA.js +100 -0
  112. package/dist/chunk-BM2LWERA.js.map +1 -0
  113. package/dist/chunk-CMOYXNPJ.js +211 -0
  114. package/dist/chunk-CMOYXNPJ.js.map +1 -0
  115. package/dist/chunk-CZP3RHC4.js +74 -0
  116. package/dist/chunk-CZP3RHC4.js.map +1 -0
  117. package/dist/chunk-DDG5JHQT.js +112 -0
  118. package/dist/chunk-DDG5JHQT.js.map +1 -0
  119. package/dist/chunk-DJODXO7I.js +38 -0
  120. package/dist/chunk-DJODXO7I.js.map +1 -0
  121. package/dist/chunk-DWJDJLPU.js +192 -0
  122. package/dist/chunk-DWJDJLPU.js.map +1 -0
  123. package/dist/chunk-DZW6LM22.js +45 -0
  124. package/dist/chunk-DZW6LM22.js.map +1 -0
  125. package/dist/chunk-ELGCZLZF.js +305 -0
  126. package/dist/chunk-ELGCZLZF.js.map +1 -0
  127. package/dist/chunk-EV3U6ZZB.js +209 -0
  128. package/dist/chunk-EV3U6ZZB.js.map +1 -0
  129. package/dist/chunk-EY7LVUKQ.js +87 -0
  130. package/dist/chunk-EY7LVUKQ.js.map +1 -0
  131. package/dist/chunk-F4C74F7M.js +230 -0
  132. package/dist/chunk-F4C74F7M.js.map +1 -0
  133. package/dist/chunk-FERYDFZA.js +108 -0
  134. package/dist/chunk-FERYDFZA.js.map +1 -0
  135. package/dist/chunk-FUIYG2DS.js +166 -0
  136. package/dist/chunk-FUIYG2DS.js.map +1 -0
  137. package/dist/chunk-GA7M34KU.js +236 -0
  138. package/dist/chunk-GA7M34KU.js.map +1 -0
  139. package/dist/chunk-GKYZT3LA.js +136 -0
  140. package/dist/chunk-GKYZT3LA.js.map +1 -0
  141. package/dist/chunk-H42LRUQ4.js +102 -0
  142. package/dist/chunk-H42LRUQ4.js.map +1 -0
  143. package/dist/chunk-HVXM2G5F.js +222 -0
  144. package/dist/chunk-HVXM2G5F.js.map +1 -0
  145. package/dist/chunk-I4RDAGVY.js +53 -0
  146. package/dist/chunk-I4RDAGVY.js.map +1 -0
  147. package/dist/chunk-IQJG4IDX.js +208 -0
  148. package/dist/chunk-IQJG4IDX.js.map +1 -0
  149. package/dist/chunk-IX2PXG4Y.js +144 -0
  150. package/dist/chunk-IX2PXG4Y.js.map +1 -0
  151. package/dist/chunk-IXICSOOP.js +287 -0
  152. package/dist/chunk-IXICSOOP.js.map +1 -0
  153. package/dist/chunk-JY5HSN4D.js +84 -0
  154. package/dist/chunk-JY5HSN4D.js.map +1 -0
  155. package/dist/chunk-L4SU3QJV.js +174 -0
  156. package/dist/chunk-L4SU3QJV.js.map +1 -0
  157. package/dist/chunk-LMNSBOBG.js +19 -0
  158. package/dist/chunk-LMNSBOBG.js.map +1 -0
  159. package/dist/chunk-MBI7D6IL.js +42 -0
  160. package/dist/chunk-MBI7D6IL.js.map +1 -0
  161. package/dist/chunk-MLFMYCPH.js +192 -0
  162. package/dist/chunk-MLFMYCPH.js.map +1 -0
  163. package/dist/chunk-MOK66734.js +33 -0
  164. package/dist/chunk-MOK66734.js.map +1 -0
  165. package/dist/chunk-MXTAWPYM.js +196 -0
  166. package/dist/chunk-MXTAWPYM.js.map +1 -0
  167. package/dist/chunk-NCL2UZKI.js +96 -0
  168. package/dist/chunk-NCL2UZKI.js.map +1 -0
  169. package/dist/chunk-NET4YLRY.js +107 -0
  170. package/dist/chunk-NET4YLRY.js.map +1 -0
  171. package/dist/chunk-NIG67CFM.js +329 -0
  172. package/dist/chunk-NIG67CFM.js.map +1 -0
  173. package/dist/chunk-NMVNNO3L.js +10 -0
  174. package/dist/chunk-NMVNNO3L.js.map +1 -0
  175. package/dist/chunk-NP7VID4K.js +2 -0
  176. package/dist/chunk-NP7VID4K.js.map +1 -0
  177. package/dist/chunk-NPUCMAG2.js +382 -0
  178. package/dist/chunk-NPUCMAG2.js.map +1 -0
  179. package/dist/chunk-NSCLRHES.js +102 -0
  180. package/dist/chunk-NSCLRHES.js.map +1 -0
  181. package/dist/chunk-OEUXHVFW.js +86 -0
  182. package/dist/chunk-OEUXHVFW.js.map +1 -0
  183. package/dist/chunk-ONBHFIMZ.js +137 -0
  184. package/dist/chunk-ONBHFIMZ.js.map +1 -0
  185. package/dist/chunk-OPH2HHL2.js +228 -0
  186. package/dist/chunk-OPH2HHL2.js.map +1 -0
  187. package/dist/chunk-OQERHIQP.js +287 -0
  188. package/dist/chunk-OQERHIQP.js.map +1 -0
  189. package/dist/chunk-P6YJAZFG.js +103 -0
  190. package/dist/chunk-P6YJAZFG.js.map +1 -0
  191. package/dist/chunk-PG7ERDOD.js +65 -0
  192. package/dist/chunk-PG7ERDOD.js.map +1 -0
  193. package/dist/chunk-PIB5JBMA.js +90 -0
  194. package/dist/chunk-PIB5JBMA.js.map +1 -0
  195. package/dist/chunk-PQ5BPIWQ.js +22 -0
  196. package/dist/chunk-PQ5BPIWQ.js.map +1 -0
  197. package/dist/chunk-PQBF6ZIQ.js +55 -0
  198. package/dist/chunk-PQBF6ZIQ.js.map +1 -0
  199. package/dist/chunk-PTWCTSZL.js +173 -0
  200. package/dist/chunk-PTWCTSZL.js.map +1 -0
  201. package/dist/chunk-QJUNPVOS.js +101 -0
  202. package/dist/chunk-QJUNPVOS.js.map +1 -0
  203. package/dist/chunk-QOBSEGCG.js +996 -0
  204. package/dist/chunk-QOBSEGCG.js.map +1 -0
  205. package/dist/chunk-QUDZOTRV.js +43 -0
  206. package/dist/chunk-QUDZOTRV.js.map +1 -0
  207. package/dist/chunk-RB7G65JC.js +213 -0
  208. package/dist/chunk-RB7G65JC.js.map +1 -0
  209. package/dist/chunk-RPHAOR7P.js +45 -0
  210. package/dist/chunk-RPHAOR7P.js.map +1 -0
  211. package/dist/chunk-RTCSH2AN.js +331 -0
  212. package/dist/chunk-RTCSH2AN.js.map +1 -0
  213. package/dist/chunk-S3ISPW3A.js +28 -0
  214. package/dist/chunk-S3ISPW3A.js.map +1 -0
  215. package/dist/chunk-SEVN656N.js +36 -0
  216. package/dist/chunk-SEVN656N.js.map +1 -0
  217. package/dist/chunk-SKVG672B.js +64 -0
  218. package/dist/chunk-SKVG672B.js.map +1 -0
  219. package/dist/chunk-SSGJ6MEM.js +1076 -0
  220. package/dist/chunk-SSGJ6MEM.js.map +1 -0
  221. package/dist/chunk-SSKZ2AED.js +118 -0
  222. package/dist/chunk-SSKZ2AED.js.map +1 -0
  223. package/dist/chunk-T56JFGXI.js +561 -0
  224. package/dist/chunk-T56JFGXI.js.map +1 -0
  225. package/dist/chunk-TCB6O74A.js +137 -0
  226. package/dist/chunk-TCB6O74A.js.map +1 -0
  227. package/dist/chunk-TTEYPO6X.js +57 -0
  228. package/dist/chunk-TTEYPO6X.js.map +1 -0
  229. package/dist/chunk-TWPHAJNM.js +462 -0
  230. package/dist/chunk-TWPHAJNM.js.map +1 -0
  231. package/dist/chunk-TXJJLP4O.js +336 -0
  232. package/dist/chunk-TXJJLP4O.js.map +1 -0
  233. package/dist/chunk-TZ6TB7VM.js +245 -0
  234. package/dist/chunk-TZ6TB7VM.js.map +1 -0
  235. package/dist/chunk-UBLKJJ7K.js +278 -0
  236. package/dist/chunk-UBLKJJ7K.js.map +1 -0
  237. package/dist/chunk-UCJ6IUFS.js +52 -0
  238. package/dist/chunk-UCJ6IUFS.js.map +1 -0
  239. package/dist/chunk-UCKFJ3QF.js +197 -0
  240. package/dist/chunk-UCKFJ3QF.js.map +1 -0
  241. package/dist/chunk-UPXSLILN.js +20 -0
  242. package/dist/chunk-UPXSLILN.js.map +1 -0
  243. package/dist/chunk-V4DORGWJ.js +92 -0
  244. package/dist/chunk-V4DORGWJ.js.map +1 -0
  245. package/dist/chunk-V6E5DYZD.js +80 -0
  246. package/dist/chunk-V6E5DYZD.js.map +1 -0
  247. package/dist/chunk-VLLYKF3P.js +96 -0
  248. package/dist/chunk-VLLYKF3P.js.map +1 -0
  249. package/dist/chunk-VLNBTOH6.js +43 -0
  250. package/dist/chunk-VLNBTOH6.js.map +1 -0
  251. package/dist/chunk-WMDSMSPL.js +303 -0
  252. package/dist/chunk-WMDSMSPL.js.map +1 -0
  253. package/dist/chunk-WU5BLGTF.js +149 -0
  254. package/dist/chunk-WU5BLGTF.js.map +1 -0
  255. package/dist/chunk-WYTZVSGK.js +245 -0
  256. package/dist/chunk-WYTZVSGK.js.map +1 -0
  257. package/dist/chunk-X47QMM6K.js +187 -0
  258. package/dist/chunk-X47QMM6K.js.map +1 -0
  259. package/dist/chunk-YHUSW7D2.js +40 -0
  260. package/dist/chunk-YHUSW7D2.js.map +1 -0
  261. package/dist/chunk-YSKD7UXX.js +126 -0
  262. package/dist/chunk-YSKD7UXX.js.map +1 -0
  263. package/dist/chunk-YYRDGWOU.js +72 -0
  264. package/dist/chunk-YYRDGWOU.js.map +1 -0
  265. package/dist/chunk-ZIGZMWM7.js +19 -0
  266. package/dist/chunk-ZIGZMWM7.js.map +1 -0
  267. package/dist/chunk-ZKRTUKNP.js +40 -0
  268. package/dist/chunk-ZKRTUKNP.js.map +1 -0
  269. package/dist/code-block.js +38 -0
  270. package/dist/code-block.js.map +1 -0
  271. package/dist/commit.js +51 -0
  272. package/dist/commit.js.map +1 -0
  273. package/dist/composer.js +15 -0
  274. package/dist/composer.js.map +1 -0
  275. package/dist/confirmation.js +53 -0
  276. package/dist/confirmation.js.map +1 -0
  277. package/dist/connection.js +8 -0
  278. package/dist/connection.js.map +1 -0
  279. package/dist/context-panel.js +25 -0
  280. package/dist/context-panel.js.map +1 -0
  281. package/dist/controls.js +10 -0
  282. package/dist/controls.js.map +1 -0
  283. package/dist/conversation.js +19 -0
  284. package/dist/conversation.js.map +1 -0
  285. package/dist/diff-view.js +15 -0
  286. package/dist/diff-view.js.map +1 -0
  287. package/dist/edge.js +10 -0
  288. package/dist/edge.js.map +1 -0
  289. package/dist/environment-variables.js +29 -0
  290. package/dist/environment-variables.js.map +1 -0
  291. package/dist/file-tree.js +23 -0
  292. package/dist/file-tree.js.map +1 -0
  293. package/dist/gallery.js +9 -0
  294. package/dist/gallery.js.map +1 -0
  295. package/dist/grouped-parts.js +21 -0
  296. package/dist/grouped-parts.js.map +1 -0
  297. package/dist/image.js +9 -0
  298. package/dist/image.js.map +1 -0
  299. package/dist/index.d.ts +366 -98
  300. package/dist/index.js +672 -13577
  301. package/dist/index.js.map +1 -1
  302. package/dist/inline-citation.js +39 -0
  303. package/dist/inline-citation.js.map +1 -0
  304. package/dist/jsx-preview.js +17 -0
  305. package/dist/jsx-preview.js.map +1 -0
  306. package/dist/markdown-view.js +17 -0
  307. package/dist/markdown-view.js.map +1 -0
  308. package/dist/message-compare.js +12 -0
  309. package/dist/message-compare.js.map +1 -0
  310. package/dist/message-edit.js +19 -0
  311. package/dist/message-edit.js.map +1 -0
  312. package/dist/message-feedback.js +11 -0
  313. package/dist/message-feedback.js.map +1 -0
  314. package/dist/message-form-spec.js +38 -0
  315. package/dist/message-form-spec.js.map +1 -0
  316. package/dist/message-form.js +26 -0
  317. package/dist/message-form.js.map +1 -0
  318. package/dist/message-table-spec.js +26 -0
  319. package/dist/message-table-spec.js.map +1 -0
  320. package/dist/message-table.js +12 -0
  321. package/dist/message-table.js.map +1 -0
  322. package/dist/message.js +51 -0
  323. package/dist/message.js.map +1 -0
  324. package/dist/mic-selector.js +27 -0
  325. package/dist/mic-selector.js.map +1 -0
  326. package/dist/model-provider-logo.js +13 -0
  327. package/dist/model-provider-logo.js.map +1 -0
  328. package/dist/motion-config.js +9 -0
  329. package/dist/motion-config.js.map +1 -0
  330. package/dist/node.js +22 -0
  331. package/dist/node.js.map +1 -0
  332. package/dist/open-in-chat.js +31 -0
  333. package/dist/open-in-chat.js.map +1 -0
  334. package/dist/package-info.js +25 -0
  335. package/dist/package-info.js.map +1 -0
  336. package/dist/panel.js +10 -0
  337. package/dist/panel.js.map +1 -0
  338. package/dist/part-groups.js +18 -0
  339. package/dist/part-groups.js.map +1 -0
  340. package/dist/permission-mode-select.js +9 -0
  341. package/dist/permission-mode-select.js.map +1 -0
  342. package/dist/persona-sources.js +8 -0
  343. package/dist/persona-sources.js.map +1 -0
  344. package/dist/persona.js +14 -0
  345. package/dist/persona.js.map +1 -0
  346. package/dist/plan.js +32 -0
  347. package/dist/plan.js.map +1 -0
  348. package/dist/prompt-input-effort.js +9 -0
  349. package/dist/prompt-input-effort.js.map +1 -0
  350. package/dist/prompt-input-mode.js +10 -0
  351. package/dist/prompt-input-mode.js.map +1 -0
  352. package/dist/prompt-input-slash.js +12 -0
  353. package/dist/prompt-input-slash.js.map +1 -0
  354. package/dist/prompt-input.js +89 -0
  355. package/dist/prompt-input.js.map +1 -0
  356. package/dist/queue.js +37 -0
  357. package/dist/queue.js.map +1 -0
  358. package/dist/reasoning.js +23 -0
  359. package/dist/reasoning.js.map +1 -0
  360. package/dist/sandbox.js +28 -0
  361. package/dist/sandbox.js.map +1 -0
  362. package/dist/schema-display.js +33 -0
  363. package/dist/schema-display.js.map +1 -0
  364. package/dist/selection-toolbar.js +11 -0
  365. package/dist/selection-toolbar.js.map +1 -0
  366. package/dist/session-header.js +9 -0
  367. package/dist/session-header.js.map +1 -0
  368. package/dist/session-status-bar.js +9 -0
  369. package/dist/session-status-bar.js.map +1 -0
  370. package/dist/shimmer.js +9 -0
  371. package/dist/shimmer.js.map +1 -0
  372. package/dist/snippet.js +17 -0
  373. package/dist/snippet.js.map +1 -0
  374. package/dist/sources.js +17 -0
  375. package/dist/sources.js.map +1 -0
  376. package/dist/speech-input.js +9 -0
  377. package/dist/speech-input.js.map +1 -0
  378. package/dist/stack-trace.js +27 -0
  379. package/dist/stack-trace.js.map +1 -0
  380. package/dist/suggestion.js +16 -0
  381. package/dist/suggestion.js.map +1 -0
  382. package/dist/task.js +18 -0
  383. package/dist/task.js.map +1 -0
  384. package/dist/test-results.js +43 -0
  385. package/dist/test-results.js.map +1 -0
  386. package/dist/token-usage.js +27 -0
  387. package/dist/token-usage.js.map +1 -0
  388. package/dist/tool-result-card.js +9 -0
  389. package/dist/tool-result-card.js.map +1 -0
  390. package/dist/tool.js +27 -0
  391. package/dist/tool.js.map +1 -0
  392. package/dist/toolbar.js +10 -0
  393. package/dist/toolbar.js.map +1 -0
  394. package/dist/transcription.js +11 -0
  395. package/dist/transcription.js.map +1 -0
  396. package/dist/turn-status.js +9 -0
  397. package/dist/turn-status.js.map +1 -0
  398. package/dist/use-audio-level.js +9 -0
  399. package/dist/use-audio-level.js.map +1 -0
  400. package/dist/voice-selector.js +47 -0
  401. package/dist/voice-selector.js.map +1 -0
  402. package/dist/web-preview.js +19 -0
  403. package/dist/web-preview.js.map +1 -0
  404. package/package.json +11 -9
  405. package/schemas/a2ui-surface.v1.schema.json +5434 -0
  406. package/src/_chat-shell-rail.tsx +3 -1
  407. package/src/_flow-boundary.tsx +2 -2
  408. package/src/_persona-rive.tsx +27 -41
  409. package/src/a2ui/a2ui-surface.stories.tsx +662 -0
  410. package/src/a2ui/a2ui-surface.test.tsx +201 -0
  411. package/src/a2ui/a2ui-surface.tsx +354 -0
  412. package/src/a2ui/catalog.source.json +772 -0
  413. package/src/a2ui/core/a2ui-core.test.ts +178 -0
  414. package/src/a2ui/core/catalog.generated.ts +1019 -0
  415. package/src/a2ui/core/complete-json.ts +81 -0
  416. package/src/a2ui/core/index.ts +10 -0
  417. package/src/a2ui/core/schema.ts +111 -0
  418. package/src/a2ui/core/spec.ts +148 -0
  419. package/src/a2ui/core/validate.ts +266 -0
  420. package/src/a2ui/index.ts +7 -0
  421. package/src/a2ui/ui-catalog.tsx +225 -0
  422. package/src/a2ui/wave1-chart-spec.test.ts +87 -0
  423. package/src/a2ui/wave2-chart-spec.test.ts +108 -0
  424. package/src/agentic-workspace.stories.tsx +6 -45
  425. package/src/chat-shell.test.tsx +40 -10
  426. package/src/chat-shell.tsx +90 -44
  427. package/src/chat.stories.tsx +47 -42
  428. package/src/composer.stories.tsx +4 -5
  429. package/src/composer.test.tsx +45 -0
  430. package/src/composer.tsx +104 -21
  431. package/src/context-panel.stories.tsx +1 -1
  432. package/src/context-panel.tsx +1 -1
  433. package/src/conversation.stories.tsx +1 -0
  434. package/src/conversation.test.tsx +16 -0
  435. package/src/conversation.tsx +16 -2
  436. package/src/diff-view.stories.tsx +79 -0
  437. package/src/diff-view.tsx +3 -2
  438. package/src/file-tree.tsx +24 -17
  439. package/src/gallery.stories.tsx +42 -0
  440. package/src/gallery.tsx +2 -2
  441. package/src/grouped-parts.stories.tsx +23 -0
  442. package/src/grouped-parts.tsx +1 -1
  443. package/src/index.ts +1 -0
  444. package/src/message-compare.stories.tsx +40 -0
  445. package/src/message-compare.tsx +2 -1
  446. package/src/message-form.tsx +1 -1
  447. package/src/message-table.stories.tsx +24 -0
  448. package/src/message-table.tsx +1 -1
  449. package/src/package-info.tsx +12 -9
  450. package/src/reasoning.stories.tsx +27 -0
  451. package/src/reasoning.tsx +1 -1
  452. package/src/session-header.stories.tsx +35 -1
  453. package/src/session-header.tsx +1 -1
  454. package/src/sources.stories.tsx +30 -0
  455. package/src/sources.tsx +4 -1
  456. package/src/templates-ai-assistant.stories.tsx +151 -87
  457. package/src/tool.stories.tsx +39 -0
  458. package/src/tool.tsx +3 -3
  459. package/src/toolbar.tsx +0 -10
  460. package/dist/_flow-boundary-SHNWLQG5.js.map +0 -1
  461. package/dist/_persona-rive-JEG44YHX.js.map +0 -1
  462. /package/dist/{_audio-player-media-chrome-T3XVXWRZ.js.map → _audio-player-media-chrome.js.map} +0 -0
@@ -0,0 +1,215 @@
1
+ "use client";
2
+ import {
3
+ A2UI_COMMON_PROPS,
4
+ A2UI_VERSION
5
+ } from "./chunk-4XRNIZMG.js";
6
+
7
+ // src/a2ui/core/validate.ts
8
+ var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
9
+ var isA2uiElement = (v) => isRecord(v) && typeof v.type === "string";
10
+ var ELEMENT_KEYS = /* @__PURE__ */ new Set(["type", "id", "props", "children", "on"]);
11
+ function checkValue(value, schema, path, report, errors, catalog) {
12
+ if (schema.enum) {
13
+ if (!schema.enum.includes(value)) {
14
+ report({
15
+ path,
16
+ code: "invalid-value",
17
+ message: `must be one of ${schema.enum.map((e) => JSON.stringify(e)).join(", ")}; got ${JSON.stringify(value)}`
18
+ });
19
+ }
20
+ return;
21
+ }
22
+ const t = schema.type;
23
+ const bad = (expected) => report({
24
+ path,
25
+ code: "invalid-value",
26
+ message: `expected ${expected}; got ${Array.isArray(value) ? "array" : typeof value}`
27
+ });
28
+ switch (t) {
29
+ case "string":
30
+ if (typeof value !== "string") bad("a string");
31
+ break;
32
+ case "number":
33
+ if (typeof value !== "number" || !Number.isFinite(value)) bad("a number");
34
+ break;
35
+ case "boolean":
36
+ if (typeof value !== "boolean") bad("a boolean");
37
+ break;
38
+ case "array":
39
+ if (!Array.isArray(value)) bad("an array");
40
+ break;
41
+ case "object":
42
+ if (!isRecord(value)) bad("an object");
43
+ break;
44
+ case "node": {
45
+ const items = Array.isArray(value) ? value : [value];
46
+ items.forEach((item, i) => {
47
+ const p = Array.isArray(value) ? `${path}[${i}]` : path;
48
+ if (typeof item === "string" || typeof item === "number") return;
49
+ if (isA2uiElement(item)) return checkNode(item, p, errors, catalog);
50
+ report({
51
+ path: p,
52
+ code: "invalid-value",
53
+ message: "expected text or a node ({ type, \u2026 })"
54
+ });
55
+ });
56
+ break;
57
+ }
58
+ case "any":
59
+ break;
60
+ }
61
+ }
62
+ function checkAction(value, path, report) {
63
+ if (!isRecord(value) || typeof value.name !== "string" || !value.name.trim()) {
64
+ report({
65
+ path,
66
+ code: "invalid-action",
67
+ message: 'an action is { "name": "<host verb>", "payload"?: <json> }'
68
+ });
69
+ return false;
70
+ }
71
+ return true;
72
+ }
73
+ function checkNode(node, path, errors, catalog) {
74
+ const report = (e) => errors.push({ ...e, node: path });
75
+ if (typeof node === "string") return;
76
+ if (!isA2uiElement(node)) {
77
+ report({
78
+ path,
79
+ code: "invalid-node",
80
+ message: 'a node is a string or { "type": "<catalog type>", \u2026 }'
81
+ });
82
+ return;
83
+ }
84
+ const entry = catalog[node.type];
85
+ if (!entry) {
86
+ report({
87
+ path: `${path}.type`,
88
+ code: "unknown-type",
89
+ message: `"${node.type}" is not in the catalog (run \`brand-ui a2ui catalog\`)`
90
+ });
91
+ return;
92
+ }
93
+ for (const key of Object.keys(node)) {
94
+ if (!ELEMENT_KEYS.has(key)) {
95
+ report({
96
+ path: `${path}.${key}`,
97
+ code: "invalid-node",
98
+ message: `unknown key "${key}" \u2014 a node has type, id, props, children, on`
99
+ });
100
+ }
101
+ }
102
+ if (node.id !== void 0 && typeof node.id !== "string") {
103
+ report({ path: `${path}.id`, code: "invalid-value", message: "id must be a string" });
104
+ }
105
+ const props = node.props;
106
+ if (props !== void 0 && !isRecord(props)) {
107
+ report({ path: `${path}.props`, code: "invalid-value", message: "props must be an object" });
108
+ } else {
109
+ const allowed = entry.builtin ? entry.props : { ...A2UI_COMMON_PROPS, ...entry.props };
110
+ for (const [name, schema] of Object.entries(entry.props)) {
111
+ if (schema.required && (props === void 0 || props[name] === void 0)) {
112
+ report({
113
+ path: `${path}.props.${name}`,
114
+ code: "missing-prop",
115
+ message: `"${node.type}" requires "${name}"`
116
+ });
117
+ }
118
+ }
119
+ if (props) {
120
+ for (const [name, value] of Object.entries(props)) {
121
+ const schema = allowed[name];
122
+ if (!schema) {
123
+ report({
124
+ path: `${path}.props.${name}`,
125
+ code: "unknown-prop",
126
+ message: `"${name}" is not a prop of "${node.type}" (allowed: ${Object.keys(allowed).join(", ") || "none"})`
127
+ });
128
+ continue;
129
+ }
130
+ checkValue(value, schema, `${path}.props.${name}`, report, errors, catalog);
131
+ }
132
+ }
133
+ }
134
+ if (node.children !== void 0) {
135
+ if (!entry.children) {
136
+ report({
137
+ path: `${path}.children`,
138
+ code: "children-not-allowed",
139
+ message: `"${node.type}" does not take children`
140
+ });
141
+ } else if (!Array.isArray(node.children)) {
142
+ report({
143
+ path: `${path}.children`,
144
+ code: "invalid-value",
145
+ message: "children must be an array of nodes"
146
+ });
147
+ } else {
148
+ node.children.forEach(
149
+ (child, i) => checkNode(child, `${path}.children[${i}]`, errors, catalog)
150
+ );
151
+ }
152
+ }
153
+ if (node.on !== void 0) {
154
+ if (!isRecord(node.on)) {
155
+ report({ path: `${path}.on`, code: "invalid-value", message: "on must be an object" });
156
+ } else {
157
+ for (const [event, action] of Object.entries(node.on)) {
158
+ if (!entry.events[event]) {
159
+ report({
160
+ path: `${path}.on.${event}`,
161
+ code: "unknown-event",
162
+ message: `"${node.type}" has no "${event}" event (${Object.keys(entry.events).join(", ") || "none"})`
163
+ });
164
+ continue;
165
+ }
166
+ checkAction(action, `${path}.on.${event}`, report);
167
+ }
168
+ }
169
+ }
170
+ }
171
+ function validateA2uiSurface(input, catalog) {
172
+ const errors = [];
173
+ const report = (e) => errors.push({ ...e, node: "root" });
174
+ if (!isRecord(input)) {
175
+ return {
176
+ ok: false,
177
+ spec: null,
178
+ errors: [
179
+ {
180
+ path: "",
181
+ node: "root",
182
+ code: "invalid-root",
183
+ message: 'expected { "a2ui": "1", "root": \u2026 }'
184
+ }
185
+ ]
186
+ };
187
+ }
188
+ if (input.a2ui !== A2UI_VERSION) {
189
+ report({
190
+ path: "a2ui",
191
+ code: "unsupported-version",
192
+ message: `expected "a2ui": "${A2UI_VERSION}"; got ${JSON.stringify(input.a2ui)}`
193
+ });
194
+ }
195
+ if (input.title !== void 0 && typeof input.title !== "string") {
196
+ report({ path: "title", code: "invalid-value", message: "title must be a string" });
197
+ }
198
+ if (input.root === void 0) {
199
+ report({ path: "root", code: "invalid-root", message: "root is required" });
200
+ } else {
201
+ checkNode(input.root, "root", errors, catalog);
202
+ }
203
+ const spec = input;
204
+ return errors.length ? { ok: false, spec, errors } : { ok: true, spec, errors: [] };
205
+ }
206
+ function invalidNodePaths(errors) {
207
+ return new Set(errors.map((e) => e.node));
208
+ }
209
+
210
+ export {
211
+ isA2uiElement,
212
+ validateA2uiSurface,
213
+ invalidNodePaths
214
+ };
215
+ //# sourceMappingURL=chunk-7FD5CZEU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/a2ui/core/validate.ts"],"sourcesContent":["/**\n * validate.ts — `validateA2uiSurface`: is this JSON a surface the catalog can\n * render? Never throws, never repairs; every problem is a typed `A2uiError` with\n * a path, so an agent can fix its own output from the message and a host can\n * prune the failing subtree while streaming (`invalidNodePaths`).\n */\nimport {\n A2UI_COMMON_PROPS,\n A2UI_VERSION,\n type A2uiAction,\n type A2uiCatalogSchema,\n type A2uiCatalogTypeSchema,\n type A2uiElement,\n type A2uiError,\n type A2uiNode,\n type A2uiPropSchema,\n type A2uiSurfaceSpec,\n} from \"./spec\";\n\nexport type A2uiValidation =\n | { ok: true; spec: A2uiSurfaceSpec; errors: [] }\n | { ok: false; spec: A2uiSurfaceSpec | null; errors: A2uiError[] };\n\ntype Report = (e: Omit<A2uiError, \"node\">) => void;\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/** An element-shaped value: an object with a string `type`. */\nexport const isA2uiElement = (v: unknown): v is A2uiElement =>\n isRecord(v) && typeof v.type === \"string\";\n\n/** Reserved keys on an element — anything else is a typo, not a prop. */\nconst ELEMENT_KEYS = new Set([\"type\", \"id\", \"props\", \"children\", \"on\"]);\n\nfunction checkValue(\n value: unknown,\n schema: A2uiPropSchema,\n path: string,\n report: Report,\n errors: A2uiError[],\n catalog: A2uiCatalogSchema,\n): void {\n if (schema.enum) {\n if (!schema.enum.includes(value as string | number)) {\n report({\n path,\n code: \"invalid-value\",\n message: `must be one of ${schema.enum.map((e) => JSON.stringify(e)).join(\", \")}; got ${JSON.stringify(value)}`,\n });\n }\n return;\n }\n const t = schema.type;\n const bad = (expected: string) =>\n report({\n path,\n code: \"invalid-value\",\n message: `expected ${expected}; got ${Array.isArray(value) ? \"array\" : typeof value}`,\n });\n switch (t) {\n case \"string\":\n if (typeof value !== \"string\") bad(\"a string\");\n break;\n case \"number\":\n if (typeof value !== \"number\" || !Number.isFinite(value)) bad(\"a number\");\n break;\n case \"boolean\":\n if (typeof value !== \"boolean\") bad(\"a boolean\");\n break;\n case \"array\":\n if (!Array.isArray(value)) bad(\"an array\");\n break;\n case \"object\":\n if (!isRecord(value)) bad(\"an object\");\n break;\n case \"node\": {\n // Text, a number, one element, or a list of nodes — each element validated.\n const items = Array.isArray(value) ? value : [value];\n items.forEach((item, i) => {\n const p = Array.isArray(value) ? `${path}[${i}]` : path;\n if (typeof item === \"string\" || typeof item === \"number\") return;\n if (isA2uiElement(item)) return checkNode(item, p, errors, catalog);\n report({\n path: p,\n code: \"invalid-value\",\n message: \"expected text or a node ({ type, … })\",\n });\n });\n break;\n }\n case \"any\":\n break;\n }\n}\n\nfunction checkAction(value: unknown, path: string, report: Report): value is A2uiAction {\n if (!isRecord(value) || typeof value.name !== \"string\" || !value.name.trim()) {\n report({\n path,\n code: \"invalid-action\",\n message: 'an action is { \"name\": \"<host verb>\", \"payload\"?: <json> }',\n });\n return false;\n }\n return true;\n}\n\nfunction checkNode(\n node: unknown,\n path: string,\n errors: A2uiError[],\n catalog: A2uiCatalogSchema,\n): void {\n const report: Report = (e) => errors.push({ ...e, node: path });\n if (typeof node === \"string\") return;\n if (!isA2uiElement(node)) {\n report({\n path,\n code: \"invalid-node\",\n message: 'a node is a string or { \"type\": \"<catalog type>\", … }',\n });\n return;\n }\n const entry: A2uiCatalogTypeSchema | undefined = catalog[node.type];\n if (!entry) {\n report({\n path: `${path}.type`,\n code: \"unknown-type\",\n message: `\"${node.type}\" is not in the catalog (run \\`brand-ui a2ui catalog\\`)`,\n });\n return;\n }\n for (const key of Object.keys(node)) {\n if (!ELEMENT_KEYS.has(key)) {\n report({\n path: `${path}.${key}`,\n code: \"invalid-node\",\n message: `unknown key \"${key}\" — a node has type, id, props, children, on`,\n });\n }\n }\n if (node.id !== undefined && typeof node.id !== \"string\") {\n report({ path: `${path}.id`, code: \"invalid-value\", message: \"id must be a string\" });\n }\n const props = node.props;\n if (props !== undefined && !isRecord(props)) {\n report({ path: `${path}.props`, code: \"invalid-value\", message: \"props must be an object\" });\n } else {\n const allowed: Record<string, A2uiPropSchema> = entry.builtin\n ? entry.props\n : { ...A2UI_COMMON_PROPS, ...entry.props };\n for (const [name, schema] of Object.entries(entry.props)) {\n if (schema.required && (props === undefined || props[name] === undefined)) {\n report({\n path: `${path}.props.${name}`,\n code: \"missing-prop\",\n message: `\"${node.type}\" requires \"${name}\"`,\n });\n }\n }\n if (props) {\n for (const [name, value] of Object.entries(props)) {\n const schema = allowed[name];\n if (!schema) {\n report({\n path: `${path}.props.${name}`,\n code: \"unknown-prop\",\n message: `\"${name}\" is not a prop of \"${node.type}\" (allowed: ${Object.keys(allowed).join(\", \") || \"none\"})`,\n });\n continue;\n }\n checkValue(value, schema, `${path}.props.${name}`, report, errors, catalog);\n }\n }\n }\n if (node.children !== undefined) {\n if (!entry.children) {\n report({\n path: `${path}.children`,\n code: \"children-not-allowed\",\n message: `\"${node.type}\" does not take children`,\n });\n } else if (!Array.isArray(node.children)) {\n report({\n path: `${path}.children`,\n code: \"invalid-value\",\n message: \"children must be an array of nodes\",\n });\n } else {\n node.children.forEach((child, i) =>\n checkNode(child, `${path}.children[${i}]`, errors, catalog),\n );\n }\n }\n if (node.on !== undefined) {\n if (!isRecord(node.on)) {\n report({ path: `${path}.on`, code: \"invalid-value\", message: \"on must be an object\" });\n } else {\n for (const [event, action] of Object.entries(node.on)) {\n if (!entry.events[event]) {\n report({\n path: `${path}.on.${event}`,\n code: \"unknown-event\",\n message: `\"${node.type}\" has no \"${event}\" event (${Object.keys(entry.events).join(\", \") || \"none\"})`,\n });\n continue;\n }\n checkAction(action, `${path}.on.${event}`, report);\n }\n }\n }\n}\n\n/**\n * Validate an untrusted value (a parsed tool result, a streamed JSON prefix)\n * against `catalog`. `ok: false` carries every problem found, in document order.\n */\nexport function validateA2uiSurface(input: unknown, catalog: A2uiCatalogSchema): A2uiValidation {\n const errors: A2uiError[] = [];\n const report: Report = (e) => errors.push({ ...e, node: \"root\" });\n if (!isRecord(input)) {\n return {\n ok: false,\n spec: null,\n errors: [\n {\n path: \"\",\n node: \"root\",\n code: \"invalid-root\",\n message: 'expected { \"a2ui\": \"1\", \"root\": … }',\n },\n ],\n };\n }\n if (input.a2ui !== A2UI_VERSION) {\n report({\n path: \"a2ui\",\n code: \"unsupported-version\",\n message: `expected \"a2ui\": \"${A2UI_VERSION}\"; got ${JSON.stringify(input.a2ui)}`,\n });\n }\n if (input.title !== undefined && typeof input.title !== \"string\") {\n report({ path: \"title\", code: \"invalid-value\", message: \"title must be a string\" });\n }\n if (input.root === undefined) {\n report({ path: \"root\", code: \"invalid-root\", message: \"root is required\" });\n } else {\n checkNode(input.root, \"root\", errors, catalog);\n }\n const spec = input as unknown as A2uiSurfaceSpec;\n return errors.length ? { ok: false, spec, errors } : { ok: true, spec, errors: [] };\n}\n\n/**\n * The set of NODE paths (`root`, `root.children[1]`, …) that own at least one\n * error — the renderer drops exactly those subtrees while a surface is still\n * streaming, so a half-arrived node never blanks its finished siblings.\n */\nexport function invalidNodePaths(errors: A2uiError[]): Set<string> {\n return new Set(errors.map((e) => e.node));\n}\n\n/** Re-export for hosts that want the version without importing the whole spec module. */\nexport { A2UI_VERSION };\nexport type { A2uiNode };\n"],"mappings":";;;;;;;AAyBA,IAAM,WAAW,CAAC,MAChB,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAGlD,IAAM,gBAAgB,CAAC,MAC5B,SAAS,CAAC,KAAK,OAAO,EAAE,SAAS;AAGnC,IAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,MAAM,SAAS,YAAY,IAAI,CAAC;AAEtE,SAAS,WACP,OACA,QACA,MACA,QACA,QACA,SACM;AACN,MAAI,OAAO,MAAM;AACf,QAAI,CAAC,OAAO,KAAK,SAAS,KAAwB,GAAG;AACnD,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,SAAS,kBAAkB,OAAO,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,KAAK,UAAU,KAAK,CAAC;AAAA,MAC/G,CAAC;AAAA,IACH;AACA;AAAA,EACF;AACA,QAAM,IAAI,OAAO;AACjB,QAAM,MAAM,CAAC,aACX,OAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,SAAS,YAAY,QAAQ,SAAS,MAAM,QAAQ,KAAK,IAAI,UAAU,OAAO,KAAK;AAAA,EACrF,CAAC;AACH,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,UAAI,OAAO,UAAU,SAAU,KAAI,UAAU;AAC7C;AAAA,IACF,KAAK;AACH,UAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,KAAI,UAAU;AACxE;AAAA,IACF,KAAK;AACH,UAAI,OAAO,UAAU,UAAW,KAAI,WAAW;AAC/C;AAAA,IACF,KAAK;AACH,UAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,KAAI,UAAU;AACzC;AAAA,IACF,KAAK;AACH,UAAI,CAAC,SAAS,KAAK,EAAG,KAAI,WAAW;AACrC;AAAA,IACF,KAAK,QAAQ;AAEX,YAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AACnD,YAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,cAAM,IAAI,MAAM,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM;AACnD,YAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAAU;AAC1D,YAAI,cAAc,IAAI,EAAG,QAAO,UAAU,MAAM,GAAG,QAAQ,OAAO;AAClE,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH,CAAC;AACD;AAAA,IACF;AAAA,IACA,KAAK;AACH;AAAA,EACJ;AACF;AAEA,SAAS,YAAY,OAAgB,MAAc,QAAqC;AACtF,MAAI,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,CAAC,MAAM,KAAK,KAAK,GAAG;AAC5E,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AACD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,UACP,MACA,MACA,QACA,SACM;AACN,QAAM,SAAiB,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,GAAG,MAAM,KAAK,CAAC;AAC9D,MAAI,OAAO,SAAS,SAAU;AAC9B,MAAI,CAAC,cAAc,IAAI,GAAG;AACxB,WAAO;AAAA,MACL;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AACA,QAAM,QAA2C,QAAQ,KAAK,IAAI;AAClE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,MAAM,GAAG,IAAI;AAAA,MACb,MAAM;AAAA,MACN,SAAS,IAAI,KAAK,IAAI;AAAA,IACxB,CAAC;AACD;AAAA,EACF;AACA,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,CAAC,aAAa,IAAI,GAAG,GAAG;AAC1B,aAAO;AAAA,QACL,MAAM,GAAG,IAAI,IAAI,GAAG;AAAA,QACpB,MAAM;AAAA,QACN,SAAS,gBAAgB,GAAG;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AACA,MAAI,KAAK,OAAO,UAAa,OAAO,KAAK,OAAO,UAAU;AACxD,WAAO,EAAE,MAAM,GAAG,IAAI,OAAO,MAAM,iBAAiB,SAAS,sBAAsB,CAAC;AAAA,EACtF;AACA,QAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,UAAa,CAAC,SAAS,KAAK,GAAG;AAC3C,WAAO,EAAE,MAAM,GAAG,IAAI,UAAU,MAAM,iBAAiB,SAAS,0BAA0B,CAAC;AAAA,EAC7F,OAAO;AACL,UAAM,UAA0C,MAAM,UAClD,MAAM,QACN,EAAE,GAAG,mBAAmB,GAAG,MAAM,MAAM;AAC3C,eAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AACxD,UAAI,OAAO,aAAa,UAAU,UAAa,MAAM,IAAI,MAAM,SAAY;AACzE,eAAO;AAAA,UACL,MAAM,GAAG,IAAI,UAAU,IAAI;AAAA,UAC3B,MAAM;AAAA,UACN,SAAS,IAAI,KAAK,IAAI,eAAe,IAAI;AAAA,QAC3C,CAAC;AAAA,MACH;AAAA,IACF;AACA,QAAI,OAAO;AACT,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,cAAM,SAAS,QAAQ,IAAI;AAC3B,YAAI,CAAC,QAAQ;AACX,iBAAO;AAAA,YACL,MAAM,GAAG,IAAI,UAAU,IAAI;AAAA,YAC3B,MAAM;AAAA,YACN,SAAS,IAAI,IAAI,uBAAuB,KAAK,IAAI,eAAe,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,UAC3G,CAAC;AACD;AAAA,QACF;AACA,mBAAW,OAAO,QAAQ,GAAG,IAAI,UAAU,IAAI,IAAI,QAAQ,QAAQ,OAAO;AAAA,MAC5E;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,aAAa,QAAW;AAC/B,QAAI,CAAC,MAAM,UAAU;AACnB,aAAO;AAAA,QACL,MAAM,GAAG,IAAI;AAAA,QACb,MAAM;AAAA,QACN,SAAS,IAAI,KAAK,IAAI;AAAA,MACxB,CAAC;AAAA,IACH,WAAW,CAAC,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACxC,aAAO;AAAA,QACL,MAAM,GAAG,IAAI;AAAA,QACb,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AACL,WAAK,SAAS;AAAA,QAAQ,CAAC,OAAO,MAC5B,UAAU,OAAO,GAAG,IAAI,aAAa,CAAC,KAAK,QAAQ,OAAO;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,OAAO,QAAW;AACzB,QAAI,CAAC,SAAS,KAAK,EAAE,GAAG;AACtB,aAAO,EAAE,MAAM,GAAG,IAAI,OAAO,MAAM,iBAAiB,SAAS,uBAAuB,CAAC;AAAA,IACvF,OAAO;AACL,iBAAW,CAAC,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK,EAAE,GAAG;AACrD,YAAI,CAAC,MAAM,OAAO,KAAK,GAAG;AACxB,iBAAO;AAAA,YACL,MAAM,GAAG,IAAI,OAAO,KAAK;AAAA,YACzB,MAAM;AAAA,YACN,SAAS,IAAI,KAAK,IAAI,aAAa,KAAK,YAAY,OAAO,KAAK,MAAM,MAAM,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,UACpG,CAAC;AACD;AAAA,QACF;AACA,oBAAY,QAAQ,GAAG,IAAI,OAAO,KAAK,IAAI,MAAM;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,oBAAoB,OAAgB,SAA4C;AAC9F,QAAM,SAAsB,CAAC;AAC7B,QAAM,SAAiB,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,GAAG,MAAM,OAAO,CAAC;AAChE,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,SAAS,cAAc;AAC/B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,qBAAqB,YAAY,UAAU,KAAK,UAAU,MAAM,IAAI,CAAC;AAAA,IAChF,CAAC;AAAA,EACH;AACA,MAAI,MAAM,UAAU,UAAa,OAAO,MAAM,UAAU,UAAU;AAChE,WAAO,EAAE,MAAM,SAAS,MAAM,iBAAiB,SAAS,yBAAyB,CAAC;AAAA,EACpF;AACA,MAAI,MAAM,SAAS,QAAW;AAC5B,WAAO,EAAE,MAAM,QAAQ,MAAM,gBAAgB,SAAS,mBAAmB,CAAC;AAAA,EAC5E,OAAO;AACL,cAAU,MAAM,MAAM,QAAQ,QAAQ,OAAO;AAAA,EAC/C;AACA,QAAM,OAAO;AACb,SAAO,OAAO,SAAS,EAAE,IAAI,OAAO,MAAM,OAAO,IAAI,EAAE,IAAI,MAAM,MAAM,QAAQ,CAAC,EAAE;AACpF;AAOO,SAAS,iBAAiB,QAAkC;AACjE,SAAO,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC1C;","names":[]}
@@ -0,0 +1,266 @@
1
+ "use client";
2
+
3
+ // src/attachments.tsx
4
+ import { Button } from "@elabs-ai/components-ui";
5
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from "@elabs-ai/components-ui";
6
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
7
+ import {
8
+ FileTextIcon,
9
+ GlobeIcon,
10
+ ImageIcon,
11
+ Music2Icon,
12
+ PaperclipIcon,
13
+ VideoIcon,
14
+ XIcon
15
+ } from "lucide-react";
16
+ import { createContext, useCallback, useContext, useMemo } from "react";
17
+ import { jsx, jsxs } from "react/jsx-runtime";
18
+ var mediaCategoryIcons = {
19
+ audio: Music2Icon,
20
+ document: FileTextIcon,
21
+ image: ImageIcon,
22
+ source: GlobeIcon,
23
+ unknown: PaperclipIcon,
24
+ video: VideoIcon
25
+ };
26
+ var getMediaCategory = (data) => {
27
+ if (data.type === "source-document") {
28
+ return "source";
29
+ }
30
+ const mediaType = data.mediaType ?? "";
31
+ if (mediaType.startsWith("image/")) {
32
+ return "image";
33
+ }
34
+ if (mediaType.startsWith("video/")) {
35
+ return "video";
36
+ }
37
+ if (mediaType.startsWith("audio/")) {
38
+ return "audio";
39
+ }
40
+ if (mediaType.startsWith("application/") || mediaType.startsWith("text/")) {
41
+ return "document";
42
+ }
43
+ return "unknown";
44
+ };
45
+ var getAttachmentLabel = (data) => {
46
+ if (data.type === "source-document") {
47
+ return data.title || data.filename || "Source";
48
+ }
49
+ const category = getMediaCategory(data);
50
+ return data.filename || (category === "image" ? "Image" : "Attachment");
51
+ };
52
+ var renderAttachmentImage = (url, filename, isGrid) => isGrid ? /* @__PURE__ */ jsx(
53
+ "img",
54
+ {
55
+ alt: filename || "Image",
56
+ className: "size-full object-cover",
57
+ height: 96,
58
+ src: url,
59
+ width: 96
60
+ }
61
+ ) : /* @__PURE__ */ jsx(
62
+ "img",
63
+ {
64
+ alt: filename || "Image",
65
+ className: "size-full rounded object-cover",
66
+ height: 20,
67
+ src: url,
68
+ width: 20
69
+ }
70
+ );
71
+ var AttachmentsContext = createContext(null);
72
+ var AttachmentContext = createContext(null);
73
+ var useAttachmentsContext = () => useContext(AttachmentsContext) ?? { variant: "grid" };
74
+ var useAttachmentContext = () => {
75
+ const ctx = useContext(AttachmentContext);
76
+ if (!ctx) {
77
+ throw new Error("Attachment components must be used within <Attachment>");
78
+ }
79
+ return ctx;
80
+ };
81
+ var Attachments = ({
82
+ variant = "grid",
83
+ className,
84
+ children,
85
+ ...props
86
+ }) => {
87
+ const contextValue = useMemo(() => ({ variant }), [variant]);
88
+ return /* @__PURE__ */ jsx(AttachmentsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
89
+ "div",
90
+ {
91
+ className: cn(
92
+ "flex items-start",
93
+ variant === "list" ? "flex-col gap-2" : "flex-wrap gap-2",
94
+ variant === "grid" && "ms-auto w-fit",
95
+ className
96
+ ),
97
+ ...props,
98
+ children
99
+ }
100
+ ) });
101
+ };
102
+ var Attachment = ({ data, onRemove, className, children, ...props }) => {
103
+ const { variant } = useAttachmentsContext();
104
+ const mediaCategory = getMediaCategory(data);
105
+ const contextValue = useMemo(
106
+ () => ({ data, mediaCategory, onRemove, variant }),
107
+ [data, mediaCategory, onRemove, variant]
108
+ );
109
+ return /* @__PURE__ */ jsx(AttachmentContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
110
+ "div",
111
+ {
112
+ className: cn(
113
+ "group relative",
114
+ variant === "grid" && "size-24 overflow-hidden rounded-lg",
115
+ variant === "inline" && [
116
+ "flex h-8 cursor-pointer select-none items-center gap-1.5",
117
+ "rounded-md border border-border px-1.5",
118
+ "font-medium text-body transition-colors duration-fast ease-standard motion-reduce:transition-none",
119
+ "hover:bg-accent/50 hover:text-accent-foreground"
120
+ ],
121
+ variant === "list" && [
122
+ "flex w-full items-center gap-3 rounded-lg border p-3",
123
+ "hover:bg-accent/50"
124
+ ],
125
+ className
126
+ ),
127
+ ...props,
128
+ children
129
+ }
130
+ ) });
131
+ };
132
+ var AttachmentPreview = ({
133
+ fallbackIcon,
134
+ className,
135
+ ...props
136
+ }) => {
137
+ const { data, mediaCategory, variant } = useAttachmentContext();
138
+ const iconSize = variant === "inline" ? "size-3" : "size-4";
139
+ const renderIcon = (Icon) => /* @__PURE__ */ jsx(Icon, { className: cn(iconSize, "text-muted-foreground") });
140
+ const renderContent = () => {
141
+ if (mediaCategory === "image" && data.type === "file" && data.url) {
142
+ return renderAttachmentImage(data.url, data.filename, variant === "grid");
143
+ }
144
+ if (mediaCategory === "video" && data.type === "file" && data.url) {
145
+ return /* @__PURE__ */ jsx("video", { className: "size-full object-cover", muted: true, src: data.url });
146
+ }
147
+ const Icon = mediaCategoryIcons[mediaCategory];
148
+ return fallbackIcon ?? renderIcon(Icon);
149
+ };
150
+ return /* @__PURE__ */ jsx(
151
+ "div",
152
+ {
153
+ className: cn(
154
+ "flex shrink-0 items-center justify-center overflow-hidden",
155
+ variant === "grid" && "size-full bg-muted",
156
+ variant === "inline" && "size-5 rounded bg-background",
157
+ variant === "list" && "size-12 rounded bg-muted",
158
+ className
159
+ ),
160
+ ...props,
161
+ children: renderContent()
162
+ }
163
+ );
164
+ };
165
+ var AttachmentInfo = ({
166
+ showMediaType = false,
167
+ className,
168
+ ...props
169
+ }) => {
170
+ const { data, variant } = useAttachmentContext();
171
+ const label = getAttachmentLabel(data);
172
+ if (variant === "grid") {
173
+ return null;
174
+ }
175
+ return /* @__PURE__ */ jsxs("div", { className: cn("min-w-0 flex-1", className), ...props, children: [
176
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: label }),
177
+ showMediaType && data.mediaType && /* @__PURE__ */ jsx("span", { className: "block truncate text-muted-foreground text-meta", children: data.mediaType })
178
+ ] });
179
+ };
180
+ var AttachmentRemove = ({
181
+ label = "Remove",
182
+ className,
183
+ children,
184
+ ...props
185
+ }) => {
186
+ const { onRemove, variant } = useAttachmentContext();
187
+ const handleClick = useCallback(
188
+ (e) => {
189
+ e.stopPropagation();
190
+ onRemove?.();
191
+ },
192
+ [onRemove]
193
+ );
194
+ if (!onRemove) {
195
+ return null;
196
+ }
197
+ return /* @__PURE__ */ jsxs(
198
+ Button,
199
+ {
200
+ "aria-label": label,
201
+ className: cn(
202
+ variant === "grid" && [
203
+ "absolute top-2 end-2 size-6 rounded-full p-0",
204
+ "bg-background/80 backdrop-blur-sm",
205
+ "opacity-0 transition-opacity group-hover:opacity-100",
206
+ "hover:bg-background",
207
+ "[&>svg]:size-3"
208
+ ],
209
+ variant === "inline" && [
210
+ "size-5 rounded p-0",
211
+ "opacity-0 transition-opacity group-hover:opacity-100",
212
+ "[&>svg]:size-2.5"
213
+ ],
214
+ variant === "list" && ["size-8 shrink-0 rounded p-0", "[&>svg]:size-4"],
215
+ className
216
+ ),
217
+ onClick: handleClick,
218
+ type: "button",
219
+ variant: "ghost",
220
+ ...props,
221
+ children: [
222
+ children ?? /* @__PURE__ */ jsx(XIcon, {}),
223
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label })
224
+ ]
225
+ }
226
+ );
227
+ };
228
+ var AttachmentHoverCard = ({
229
+ openDelay = 0,
230
+ closeDelay = 0,
231
+ ...props
232
+ }) => /* @__PURE__ */ jsx(HoverCard, { closeDelay, openDelay, ...props });
233
+ var AttachmentHoverCardTrigger = (props) => /* @__PURE__ */ jsx(HoverCardTrigger, { ...props });
234
+ var AttachmentHoverCardContent = ({
235
+ align = "start",
236
+ className,
237
+ ...props
238
+ }) => /* @__PURE__ */ jsx(HoverCardContent, { align, className: cn("w-auto p-2", className), ...props });
239
+ var AttachmentEmpty = ({ className, children, ...props }) => /* @__PURE__ */ jsx(
240
+ "div",
241
+ {
242
+ className: cn(
243
+ "flex items-center justify-center p-4 text-muted-foreground text-body",
244
+ className
245
+ ),
246
+ ...props,
247
+ children: children ?? "No attachments"
248
+ }
249
+ );
250
+
251
+ export {
252
+ getMediaCategory,
253
+ getAttachmentLabel,
254
+ useAttachmentsContext,
255
+ useAttachmentContext,
256
+ Attachments,
257
+ Attachment,
258
+ AttachmentPreview,
259
+ AttachmentInfo,
260
+ AttachmentRemove,
261
+ AttachmentHoverCard,
262
+ AttachmentHoverCardTrigger,
263
+ AttachmentHoverCardContent,
264
+ AttachmentEmpty
265
+ };
266
+ //# sourceMappingURL=chunk-7RL6KZDF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/attachments.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button } from \"@elabs-ai/components-ui\";\nimport { HoverCard, HoverCardContent, HoverCardTrigger } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { FileUIPart, SourceDocumentUIPart } from \"ai\";\nimport {\n FileTextIcon,\n GlobeIcon,\n ImageIcon,\n Music2Icon,\n PaperclipIcon,\n VideoIcon,\n XIcon,\n} from \"lucide-react\";\nimport type { ComponentProps, HTMLAttributes, ReactNode } from \"react\";\nimport { createContext, useCallback, useContext, useMemo } from \"react\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type AttachmentData =\n | (FileUIPart & { id: string })\n | (SourceDocumentUIPart & { id: string });\n\nexport type AttachmentMediaCategory =\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"document\"\n | \"source\"\n | \"unknown\";\n\nexport type AttachmentVariant = \"grid\" | \"inline\" | \"list\";\n\nconst mediaCategoryIcons: Record<AttachmentMediaCategory, typeof ImageIcon> = {\n audio: Music2Icon,\n document: FileTextIcon,\n image: ImageIcon,\n source: GlobeIcon,\n unknown: PaperclipIcon,\n video: VideoIcon,\n};\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nexport const getMediaCategory = (data: AttachmentData): AttachmentMediaCategory => {\n if (data.type === \"source-document\") {\n return \"source\";\n }\n\n const mediaType = data.mediaType ?? \"\";\n\n if (mediaType.startsWith(\"image/\")) {\n return \"image\";\n }\n if (mediaType.startsWith(\"video/\")) {\n return \"video\";\n }\n if (mediaType.startsWith(\"audio/\")) {\n return \"audio\";\n }\n if (mediaType.startsWith(\"application/\") || mediaType.startsWith(\"text/\")) {\n return \"document\";\n }\n\n return \"unknown\";\n};\n\nexport const getAttachmentLabel = (data: AttachmentData): string => {\n if (data.type === \"source-document\") {\n return data.title || data.filename || \"Source\";\n }\n\n const category = getMediaCategory(data);\n return data.filename || (category === \"image\" ? \"Image\" : \"Attachment\");\n};\n\nconst renderAttachmentImage = (url: string, filename: string | undefined, isGrid: boolean) =>\n isGrid ? (\n <img\n alt={filename || \"Image\"}\n className=\"size-full object-cover\"\n height={96}\n src={url}\n width={96}\n />\n ) : (\n <img\n alt={filename || \"Image\"}\n className=\"size-full rounded object-cover\"\n height={20}\n src={url}\n width={20}\n />\n );\n\n// ============================================================================\n// Contexts\n// ============================================================================\n\ninterface AttachmentsContextValue {\n variant: AttachmentVariant;\n}\n\nconst AttachmentsContext = createContext<AttachmentsContextValue | null>(null);\n\ninterface AttachmentContextValue {\n data: AttachmentData;\n mediaCategory: AttachmentMediaCategory;\n onRemove?: () => void;\n variant: AttachmentVariant;\n}\n\nconst AttachmentContext = createContext<AttachmentContextValue | null>(null);\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\nexport const useAttachmentsContext = () =>\n useContext(AttachmentsContext) ?? { variant: \"grid\" as const };\n\nexport const useAttachmentContext = () => {\n const ctx = useContext(AttachmentContext);\n if (!ctx) {\n throw new Error(\"Attachment components must be used within <Attachment>\");\n }\n return ctx;\n};\n\n// ============================================================================\n// Attachments - Container\n// ============================================================================\n\nexport type AttachmentsProps = HTMLAttributes<HTMLDivElement> & {\n variant?: AttachmentVariant;\n};\n\nexport const Attachments = ({\n variant = \"grid\",\n className,\n children,\n ...props\n}: AttachmentsProps) => {\n const contextValue = useMemo(() => ({ variant }), [variant]);\n\n return (\n <AttachmentsContext.Provider value={contextValue}>\n <div\n className={cn(\n \"flex items-start\",\n variant === \"list\" ? \"flex-col gap-2\" : \"flex-wrap gap-2\",\n variant === \"grid\" && \"ms-auto w-fit\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </AttachmentsContext.Provider>\n );\n};\n\n// ============================================================================\n// Attachment - Item\n// ============================================================================\n\nexport type AttachmentProps = HTMLAttributes<HTMLDivElement> & {\n data: AttachmentData;\n onRemove?: () => void;\n};\n\nexport const Attachment = ({ data, onRemove, className, children, ...props }: AttachmentProps) => {\n const { variant } = useAttachmentsContext();\n const mediaCategory = getMediaCategory(data);\n\n const contextValue = useMemo<AttachmentContextValue>(\n () => ({ data, mediaCategory, onRemove, variant }),\n [data, mediaCategory, onRemove, variant],\n );\n\n return (\n <AttachmentContext.Provider value={contextValue}>\n <div\n className={cn(\n \"group relative\",\n variant === \"grid\" && \"size-24 overflow-hidden rounded-lg\",\n variant === \"inline\" && [\n \"flex h-8 cursor-pointer select-none items-center gap-1.5\",\n \"rounded-md border border-border px-1.5\",\n \"font-medium text-body transition-colors duration-fast ease-standard motion-reduce:transition-none\",\n \"hover:bg-accent/50 hover:text-accent-foreground\",\n ],\n variant === \"list\" && [\n \"flex w-full items-center gap-3 rounded-lg border p-3\",\n \"hover:bg-accent/50\",\n ],\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </AttachmentContext.Provider>\n );\n};\n\n// ============================================================================\n// AttachmentPreview - Media preview\n// ============================================================================\n\nexport type AttachmentPreviewProps = HTMLAttributes<HTMLDivElement> & {\n fallbackIcon?: ReactNode;\n};\n\nexport const AttachmentPreview = ({\n fallbackIcon,\n className,\n ...props\n}: AttachmentPreviewProps) => {\n const { data, mediaCategory, variant } = useAttachmentContext();\n\n const iconSize = variant === \"inline\" ? \"size-3\" : \"size-4\";\n\n const renderIcon = (Icon: typeof ImageIcon) => (\n <Icon className={cn(iconSize, \"text-muted-foreground\")} />\n );\n\n const renderContent = () => {\n if (mediaCategory === \"image\" && data.type === \"file\" && data.url) {\n return renderAttachmentImage(data.url, data.filename, variant === \"grid\");\n }\n\n if (mediaCategory === \"video\" && data.type === \"file\" && data.url) {\n return <video className=\"size-full object-cover\" muted src={data.url} />;\n }\n\n const Icon = mediaCategoryIcons[mediaCategory];\n return fallbackIcon ?? renderIcon(Icon);\n };\n\n return (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-center overflow-hidden\",\n variant === \"grid\" && \"size-full bg-muted\",\n variant === \"inline\" && \"size-5 rounded bg-background\",\n variant === \"list\" && \"size-12 rounded bg-muted\",\n className,\n )}\n {...props}\n >\n {renderContent()}\n </div>\n );\n};\n\n// ============================================================================\n// AttachmentInfo - Name and type display\n// ============================================================================\n\nexport type AttachmentInfoProps = HTMLAttributes<HTMLDivElement> & {\n showMediaType?: boolean;\n};\n\nexport const AttachmentInfo = ({\n showMediaType = false,\n className,\n ...props\n}: AttachmentInfoProps) => {\n const { data, variant } = useAttachmentContext();\n const label = getAttachmentLabel(data);\n\n if (variant === \"grid\") {\n return null;\n }\n\n return (\n <div className={cn(\"min-w-0 flex-1\", className)} {...props}>\n <span className=\"block truncate\">{label}</span>\n {showMediaType && data.mediaType && (\n <span className=\"block truncate text-muted-foreground text-meta\">{data.mediaType}</span>\n )}\n </div>\n );\n};\n\n// ============================================================================\n// AttachmentRemove - Remove button\n// ============================================================================\n\nexport type AttachmentRemoveProps = ComponentProps<typeof Button> & {\n label?: string;\n};\n\nexport const AttachmentRemove = ({\n label = \"Remove\",\n className,\n children,\n ...props\n}: AttachmentRemoveProps) => {\n const { onRemove, variant } = useAttachmentContext();\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onRemove?.();\n },\n [onRemove],\n );\n\n if (!onRemove) {\n return null;\n }\n\n return (\n <Button\n aria-label={label}\n className={cn(\n variant === \"grid\" && [\n \"absolute top-2 end-2 size-6 rounded-full p-0\",\n \"bg-background/80 backdrop-blur-sm\",\n \"opacity-0 transition-opacity group-hover:opacity-100\",\n \"hover:bg-background\",\n \"[&>svg]:size-3\",\n ],\n variant === \"inline\" && [\n \"size-5 rounded p-0\",\n \"opacity-0 transition-opacity group-hover:opacity-100\",\n \"[&>svg]:size-2.5\",\n ],\n variant === \"list\" && [\"size-8 shrink-0 rounded p-0\", \"[&>svg]:size-4\"],\n className,\n )}\n onClick={handleClick}\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <XIcon />}\n <span className=\"sr-only\">{label}</span>\n </Button>\n );\n};\n\n// ============================================================================\n// AttachmentHoverCard - Hover preview\n// ============================================================================\n\nexport type AttachmentHoverCardProps = ComponentProps<typeof HoverCard>;\n\nexport const AttachmentHoverCard = ({\n openDelay = 0,\n closeDelay = 0,\n ...props\n}: AttachmentHoverCardProps) => (\n <HoverCard closeDelay={closeDelay} openDelay={openDelay} {...props} />\n);\n\nexport type AttachmentHoverCardTriggerProps = ComponentProps<typeof HoverCardTrigger>;\n\nexport const AttachmentHoverCardTrigger = (props: AttachmentHoverCardTriggerProps) => (\n <HoverCardTrigger {...props} />\n);\n\nexport type AttachmentHoverCardContentProps = ComponentProps<typeof HoverCardContent>;\n\nexport const AttachmentHoverCardContent = ({\n align = \"start\",\n className,\n ...props\n}: AttachmentHoverCardContentProps) => (\n <HoverCardContent align={align} className={cn(\"w-auto p-2\", className)} {...props} />\n);\n\n// ============================================================================\n// AttachmentEmpty - Empty state\n// ============================================================================\n\nexport type AttachmentEmptyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const AttachmentEmpty = ({ className, children, ...props }: AttachmentEmptyProps) => (\n <div\n className={cn(\n \"flex items-center justify-center p-4 text-muted-foreground text-body\",\n className,\n )}\n {...props}\n >\n {children ?? \"No attachments\"}\n </div>\n);\n"],"mappings":"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","names":[]}