@elabs-ai/components-ai 4.2.0 → 5.0.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-AXMNJMMH.js +984 -0
  106. package/dist/chunk-AXMNJMMH.js.map +1 -0
  107. package/dist/chunk-BA3AEMOU.js +21 -0
  108. package/dist/chunk-BA3AEMOU.js.map +1 -0
  109. package/dist/chunk-BBHFOYML.js +336 -0
  110. package/dist/chunk-BBHFOYML.js.map +1 -0
  111. package/dist/chunk-BHUVISIY.js +221 -0
  112. package/dist/chunk-BHUVISIY.js.map +1 -0
  113. package/dist/chunk-BM2LWERA.js +100 -0
  114. package/dist/chunk-BM2LWERA.js.map +1 -0
  115. package/dist/chunk-CMOYXNPJ.js +211 -0
  116. package/dist/chunk-CMOYXNPJ.js.map +1 -0
  117. package/dist/chunk-CZP3RHC4.js +74 -0
  118. package/dist/chunk-CZP3RHC4.js.map +1 -0
  119. package/dist/chunk-DDG5JHQT.js +112 -0
  120. package/dist/chunk-DDG5JHQT.js.map +1 -0
  121. package/dist/chunk-DJODXO7I.js +38 -0
  122. package/dist/chunk-DJODXO7I.js.map +1 -0
  123. package/dist/chunk-DWJDJLPU.js +192 -0
  124. package/dist/chunk-DWJDJLPU.js.map +1 -0
  125. package/dist/chunk-DZW6LM22.js +45 -0
  126. package/dist/chunk-DZW6LM22.js.map +1 -0
  127. package/dist/chunk-ELGCZLZF.js +305 -0
  128. package/dist/chunk-ELGCZLZF.js.map +1 -0
  129. package/dist/chunk-EV3U6ZZB.js +209 -0
  130. package/dist/chunk-EV3U6ZZB.js.map +1 -0
  131. package/dist/chunk-EY7LVUKQ.js +87 -0
  132. package/dist/chunk-EY7LVUKQ.js.map +1 -0
  133. package/dist/chunk-F4C74F7M.js +230 -0
  134. package/dist/chunk-F4C74F7M.js.map +1 -0
  135. package/dist/chunk-FERYDFZA.js +108 -0
  136. package/dist/chunk-FERYDFZA.js.map +1 -0
  137. package/dist/chunk-FUIYG2DS.js +166 -0
  138. package/dist/chunk-FUIYG2DS.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-LMNSBOBG.js +19 -0
  156. package/dist/chunk-LMNSBOBG.js.map +1 -0
  157. package/dist/chunk-MBI7D6IL.js +42 -0
  158. package/dist/chunk-MBI7D6IL.js.map +1 -0
  159. package/dist/chunk-MLFMYCPH.js +192 -0
  160. package/dist/chunk-MLFMYCPH.js.map +1 -0
  161. package/dist/chunk-MOK66734.js +33 -0
  162. package/dist/chunk-MOK66734.js.map +1 -0
  163. package/dist/chunk-MXTAWPYM.js +196 -0
  164. package/dist/chunk-MXTAWPYM.js.map +1 -0
  165. package/dist/chunk-NCL2UZKI.js +96 -0
  166. package/dist/chunk-NCL2UZKI.js.map +1 -0
  167. package/dist/chunk-NET4YLRY.js +107 -0
  168. package/dist/chunk-NET4YLRY.js.map +1 -0
  169. package/dist/chunk-NIG67CFM.js +329 -0
  170. package/dist/chunk-NIG67CFM.js.map +1 -0
  171. package/dist/chunk-NMVNNO3L.js +10 -0
  172. package/dist/chunk-NMVNNO3L.js.map +1 -0
  173. package/dist/chunk-NP7VID4K.js +2 -0
  174. package/dist/chunk-NP7VID4K.js.map +1 -0
  175. package/dist/chunk-NPUCMAG2.js +382 -0
  176. package/dist/chunk-NPUCMAG2.js.map +1 -0
  177. package/dist/chunk-NSCLRHES.js +102 -0
  178. package/dist/chunk-NSCLRHES.js.map +1 -0
  179. package/dist/chunk-OEUXHVFW.js +86 -0
  180. package/dist/chunk-OEUXHVFW.js.map +1 -0
  181. package/dist/chunk-ONBHFIMZ.js +137 -0
  182. package/dist/chunk-ONBHFIMZ.js.map +1 -0
  183. package/dist/chunk-OPH2HHL2.js +228 -0
  184. package/dist/chunk-OPH2HHL2.js.map +1 -0
  185. package/dist/chunk-OQERHIQP.js +287 -0
  186. package/dist/chunk-OQERHIQP.js.map +1 -0
  187. package/dist/chunk-P6YJAZFG.js +103 -0
  188. package/dist/chunk-P6YJAZFG.js.map +1 -0
  189. package/dist/chunk-PG7ERDOD.js +65 -0
  190. package/dist/chunk-PG7ERDOD.js.map +1 -0
  191. package/dist/chunk-PIB5JBMA.js +90 -0
  192. package/dist/chunk-PIB5JBMA.js.map +1 -0
  193. package/dist/chunk-PQ5BPIWQ.js +22 -0
  194. package/dist/chunk-PQ5BPIWQ.js.map +1 -0
  195. package/dist/chunk-PQBF6ZIQ.js +55 -0
  196. package/dist/chunk-PQBF6ZIQ.js.map +1 -0
  197. package/dist/chunk-PTWCTSZL.js +173 -0
  198. package/dist/chunk-PTWCTSZL.js.map +1 -0
  199. package/dist/chunk-QJUNPVOS.js +101 -0
  200. package/dist/chunk-QJUNPVOS.js.map +1 -0
  201. package/dist/chunk-QUDZOTRV.js +43 -0
  202. package/dist/chunk-QUDZOTRV.js.map +1 -0
  203. package/dist/chunk-RB7G65JC.js +213 -0
  204. package/dist/chunk-RB7G65JC.js.map +1 -0
  205. package/dist/chunk-RPHAOR7P.js +45 -0
  206. package/dist/chunk-RPHAOR7P.js.map +1 -0
  207. package/dist/chunk-RTCSH2AN.js +331 -0
  208. package/dist/chunk-RTCSH2AN.js.map +1 -0
  209. package/dist/chunk-S3ISPW3A.js +28 -0
  210. package/dist/chunk-S3ISPW3A.js.map +1 -0
  211. package/dist/chunk-SEVN656N.js +36 -0
  212. package/dist/chunk-SEVN656N.js.map +1 -0
  213. package/dist/chunk-SKVG672B.js +64 -0
  214. package/dist/chunk-SKVG672B.js.map +1 -0
  215. package/dist/chunk-SPQIU7GA.js +236 -0
  216. package/dist/chunk-SPQIU7GA.js.map +1 -0
  217. package/dist/chunk-SSGJ6MEM.js +1076 -0
  218. package/dist/chunk-SSGJ6MEM.js.map +1 -0
  219. package/dist/chunk-SSKZ2AED.js +118 -0
  220. package/dist/chunk-SSKZ2AED.js.map +1 -0
  221. package/dist/chunk-T56JFGXI.js +561 -0
  222. package/dist/chunk-T56JFGXI.js.map +1 -0
  223. package/dist/chunk-TCB6O74A.js +137 -0
  224. package/dist/chunk-TCB6O74A.js.map +1 -0
  225. package/dist/chunk-TTEYPO6X.js +57 -0
  226. package/dist/chunk-TTEYPO6X.js.map +1 -0
  227. package/dist/chunk-TWPHAJNM.js +462 -0
  228. package/dist/chunk-TWPHAJNM.js.map +1 -0
  229. package/dist/chunk-TXJJLP4O.js +336 -0
  230. package/dist/chunk-TXJJLP4O.js.map +1 -0
  231. package/dist/chunk-TZ6TB7VM.js +245 -0
  232. package/dist/chunk-TZ6TB7VM.js.map +1 -0
  233. package/dist/chunk-UBLKJJ7K.js +278 -0
  234. package/dist/chunk-UBLKJJ7K.js.map +1 -0
  235. package/dist/chunk-UCJ6IUFS.js +52 -0
  236. package/dist/chunk-UCJ6IUFS.js.map +1 -0
  237. package/dist/chunk-UCKFJ3QF.js +197 -0
  238. package/dist/chunk-UCKFJ3QF.js.map +1 -0
  239. package/dist/chunk-UPXSLILN.js +20 -0
  240. package/dist/chunk-UPXSLILN.js.map +1 -0
  241. package/dist/chunk-V4DORGWJ.js +92 -0
  242. package/dist/chunk-V4DORGWJ.js.map +1 -0
  243. package/dist/chunk-V6E5DYZD.js +80 -0
  244. package/dist/chunk-V6E5DYZD.js.map +1 -0
  245. package/dist/chunk-VLLYKF3P.js +96 -0
  246. package/dist/chunk-VLLYKF3P.js.map +1 -0
  247. package/dist/chunk-VLNBTOH6.js +43 -0
  248. package/dist/chunk-VLNBTOH6.js.map +1 -0
  249. package/dist/chunk-WMDSMSPL.js +303 -0
  250. package/dist/chunk-WMDSMSPL.js.map +1 -0
  251. package/dist/chunk-WU5BLGTF.js +149 -0
  252. package/dist/chunk-WU5BLGTF.js.map +1 -0
  253. package/dist/chunk-WYTZVSGK.js +245 -0
  254. package/dist/chunk-WYTZVSGK.js.map +1 -0
  255. package/dist/chunk-X47QMM6K.js +187 -0
  256. package/dist/chunk-X47QMM6K.js.map +1 -0
  257. package/dist/chunk-XNBKO32Y.js +174 -0
  258. package/dist/chunk-XNBKO32Y.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 +5425 -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 +1006 -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,305 @@
1
+ "use client";
2
+
3
+ // src/confirmation.tsx
4
+ import {
5
+ Alert,
6
+ AlertDescription,
7
+ AlertTitle,
8
+ APPROVAL_SCOPE_DESCRIPTION_KEYS,
9
+ Kbd,
10
+ Label,
11
+ RadioGroup,
12
+ RadioGroupItem,
13
+ StatusBadge,
14
+ Textarea,
15
+ useLocale
16
+ } from "@elabs-ai/components-ui";
17
+ import { Button } from "@elabs-ai/components-ui";
18
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
19
+ import { createContext, forwardRef, useContext, useId, useMemo, useState } from "react";
20
+ import { jsx, jsxs } from "react/jsx-runtime";
21
+ var ConfirmationContext = createContext(null);
22
+ var useConfirmation = () => {
23
+ const context = useContext(ConfirmationContext);
24
+ if (!context) {
25
+ throw new Error("Confirmation components must be used within Confirmation");
26
+ }
27
+ return context;
28
+ };
29
+ var Confirmation = ({
30
+ className,
31
+ approval,
32
+ state,
33
+ variant,
34
+ role,
35
+ children,
36
+ ...props
37
+ }) => {
38
+ const titleId = useId();
39
+ const [reason, setReason] = useState("");
40
+ const contextValue = useMemo(
41
+ () => ({ approval, state, titleId, reason, setReason }),
42
+ [approval, state, titleId, reason]
43
+ );
44
+ if (!approval || state === "input-streaming" || state === "input-available") {
45
+ return null;
46
+ }
47
+ const isResolved = state === "approval-responded" || state === "output-denied" || state === "output-available";
48
+ const isPending = state === "approval-requested";
49
+ const approved = isResolved ? approval.approved : void 0;
50
+ const railClass = approved === true ? "border-s-success" : approved === false ? "border-s-destructive" : isPending ? "border-s-border-strong" : "border-s-border";
51
+ return /* @__PURE__ */ jsx(ConfirmationContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
52
+ Alert,
53
+ {
54
+ variant: variant ?? "default",
55
+ role: role ?? (isPending ? "group" : "alert"),
56
+ "aria-labelledby": isPending ? titleId : void 0,
57
+ className: cn(
58
+ "flex flex-col gap-2 border-s-4 transition-colors duration-fast",
59
+ railClass,
60
+ isPending && "shadow-sm",
61
+ className
62
+ ),
63
+ ...props,
64
+ children: [
65
+ approved === true ? /* @__PURE__ */ jsx(
66
+ StatusBadge,
67
+ {
68
+ className: "animate-in fade-in-0 self-start duration-base ease-entrance",
69
+ status: "complete",
70
+ children: "Approved"
71
+ }
72
+ ) : null,
73
+ approved === false ? /* @__PURE__ */ jsx(
74
+ StatusBadge,
75
+ {
76
+ className: "animate-in fade-in-0 self-start duration-base ease-entrance",
77
+ status: "denied",
78
+ children: "Denied"
79
+ }
80
+ ) : null,
81
+ children
82
+ ]
83
+ }
84
+ ) });
85
+ };
86
+ var ConfirmationTitle = ({ className, id, ...props }) => {
87
+ const { titleId } = useConfirmation();
88
+ return /* @__PURE__ */ jsx(AlertTitle, { id: id ?? titleId, className: cn("text-subtitle", className), ...props });
89
+ };
90
+ var ConfirmationDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(AlertDescription, { className: cn("text-body text-muted-foreground", className), ...props });
91
+ var ConfirmationRequest = ({ children }) => {
92
+ const { state } = useConfirmation();
93
+ if (state !== "approval-requested") {
94
+ return null;
95
+ }
96
+ return children;
97
+ };
98
+ var ConfirmationAccepted = ({ children }) => {
99
+ const { approval, state } = useConfirmation();
100
+ if (!approval?.approved || state !== "approval-responded" && state !== "output-denied" && state !== "output-available") {
101
+ return null;
102
+ }
103
+ return children;
104
+ };
105
+ var ConfirmationRejected = ({ children }) => {
106
+ const { approval, state } = useConfirmation();
107
+ if (approval?.approved !== false || state !== "approval-responded" && state !== "output-denied" && state !== "output-available") {
108
+ return null;
109
+ }
110
+ return children;
111
+ };
112
+ var ConfirmationActions = ({ className, ...props }) => {
113
+ const { state } = useConfirmation();
114
+ if (state !== "approval-requested") {
115
+ return null;
116
+ }
117
+ return /* @__PURE__ */ jsx(
118
+ "div",
119
+ {
120
+ className: cn(
121
+ // The action band (research 11 §B.3 APPROVE-3): the divider is the SOLE
122
+ // cue between consequence and buttons, so `border-strong` is correct.
123
+ "flex w-full items-center justify-end gap-2 border-t border-border-strong pt-3",
124
+ className
125
+ ),
126
+ ...props
127
+ }
128
+ );
129
+ };
130
+ var ConfirmationAction = ({ className, ...props }) => /* @__PURE__ */ jsx(Button, { className: cn("h-8 px-3 text-body", className), type: "button", ...props });
131
+ var ConfirmationApprove = (props) => /* @__PURE__ */ jsx(ConfirmationAction, { variant: "default", ...props });
132
+ var ConfirmationDeny = (props) => /* @__PURE__ */ jsx(ConfirmationAction, { variant: "ghost", ...props });
133
+ var ApprovalCard = Confirmation;
134
+ var ApprovalCardTitle = ConfirmationTitle;
135
+ var ApprovalCardDescription = ConfirmationDescription;
136
+ var ApprovalCardRequest = ConfirmationRequest;
137
+ var ApprovalCardAccepted = ConfirmationAccepted;
138
+ var ApprovalCardRejected = ConfirmationRejected;
139
+ var ApprovalCardActions = ConfirmationActions;
140
+ var ApprovalCardAction = ConfirmationAction;
141
+ var ApprovalCardApprove = ConfirmationApprove;
142
+ var ApprovalCardDeny = ConfirmationDeny;
143
+ var ApprovalCardOptions = forwardRef(
144
+ function ApprovalCardOptions2({
145
+ options,
146
+ value,
147
+ defaultValue,
148
+ onValueChange,
149
+ onConfirm,
150
+ className,
151
+ dir,
152
+ "aria-labelledby": ariaLabelledBy,
153
+ ...props
154
+ }, ref) {
155
+ const { t } = useLocale();
156
+ const { titleId, reason } = useConfirmation();
157
+ const baseId = useId();
158
+ const handleValueChange = (id) => {
159
+ onValueChange?.(id);
160
+ const option = options.find((candidate) => candidate.id === id);
161
+ if (option) onConfirm?.(option, reason.trim() ? reason : void 0);
162
+ };
163
+ return /* @__PURE__ */ jsx(
164
+ RadioGroup,
165
+ {
166
+ ref,
167
+ dir,
168
+ defaultValue,
169
+ value,
170
+ onValueChange: handleValueChange,
171
+ "aria-labelledby": ariaLabelledBy ?? titleId,
172
+ "data-slot": "approval-card-options",
173
+ className: cn("grid gap-2", className),
174
+ ...props,
175
+ children: options.map((option) => {
176
+ const itemId = `${baseId}-${option.id}`;
177
+ const descriptionId = `${itemId}-description`;
178
+ const description = option.description ?? t(APPROVAL_SCOPE_DESCRIPTION_KEYS[option.scope]);
179
+ return /* @__PURE__ */ jsxs(
180
+ "div",
181
+ {
182
+ "data-slot": "approval-card-option",
183
+ "data-scope": option.scope,
184
+ className: cn(
185
+ "flex items-start gap-3 rounded-lg border border-border bg-card p-3",
186
+ "has-[[data-state=checked]]:border-primary"
187
+ ),
188
+ children: [
189
+ /* @__PURE__ */ jsx(
190
+ RadioGroupItem,
191
+ {
192
+ "aria-describedby": descriptionId,
193
+ className: "mt-1",
194
+ "data-slot": "approval-card-option-input",
195
+ id: itemId,
196
+ value: option.id
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 gap-1", children: [
200
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
201
+ /* @__PURE__ */ jsx(
202
+ Label,
203
+ {
204
+ className: "text-body flex items-center gap-2 font-medium",
205
+ "data-slot": "approval-card-option-label",
206
+ htmlFor: itemId,
207
+ children: option.label
208
+ }
209
+ ),
210
+ option.keyHint ? /* @__PURE__ */ jsx(Kbd, { "data-slot": "approval-card-option-key-hint", children: option.keyHint }) : null
211
+ ] }),
212
+ /* @__PURE__ */ jsx(
213
+ "p",
214
+ {
215
+ className: "text-meta text-muted-foreground",
216
+ "data-slot": "approval-card-option-description",
217
+ id: descriptionId,
218
+ children: description
219
+ }
220
+ )
221
+ ] })
222
+ ]
223
+ },
224
+ option.id
225
+ );
226
+ })
227
+ }
228
+ );
229
+ }
230
+ );
231
+ ApprovalCardOptions.displayName = "ApprovalCardOptions";
232
+ var ApprovalCardTarget = forwardRef(
233
+ function ApprovalCardTarget2({ className, ...props }, ref) {
234
+ return /* @__PURE__ */ jsx(
235
+ "div",
236
+ {
237
+ ref,
238
+ "data-slot": "approval-card-target",
239
+ className: cn("text-body rounded-md bg-muted/50 p-3", className),
240
+ ...props
241
+ }
242
+ );
243
+ }
244
+ );
245
+ ApprovalCardTarget.displayName = "ApprovalCardTarget";
246
+ var ApprovalCardReason = forwardRef(
247
+ function ApprovalCardReason2({ className, id, placeholder, ...props }, ref) {
248
+ const { t } = useLocale();
249
+ const { reason, setReason } = useConfirmation();
250
+ const generatedId = useId();
251
+ const textareaId = id ?? generatedId;
252
+ return /* @__PURE__ */ jsxs("div", { className: "grid gap-1.5", "data-slot": "approval-card-reason", children: [
253
+ /* @__PURE__ */ jsx(
254
+ Label,
255
+ {
256
+ className: "text-meta text-muted-foreground",
257
+ "data-slot": "approval-card-reason-label",
258
+ htmlFor: textareaId,
259
+ children: t("ai.approvalCard.reasonLabel")
260
+ }
261
+ ),
262
+ /* @__PURE__ */ jsx(
263
+ Textarea,
264
+ {
265
+ ref,
266
+ id: textareaId,
267
+ placeholder: placeholder ?? t("ai.approvalCard.reasonPlaceholder"),
268
+ value: reason,
269
+ onChange: (event) => setReason(event.target.value),
270
+ "data-slot": "approval-card-reason-input",
271
+ className: cn("min-h-16 text-body", className),
272
+ ...props
273
+ }
274
+ )
275
+ ] });
276
+ }
277
+ );
278
+ ApprovalCardReason.displayName = "ApprovalCardReason";
279
+
280
+ export {
281
+ Confirmation,
282
+ ConfirmationTitle,
283
+ ConfirmationDescription,
284
+ ConfirmationRequest,
285
+ ConfirmationAccepted,
286
+ ConfirmationRejected,
287
+ ConfirmationActions,
288
+ ConfirmationAction,
289
+ ConfirmationApprove,
290
+ ConfirmationDeny,
291
+ ApprovalCard,
292
+ ApprovalCardTitle,
293
+ ApprovalCardDescription,
294
+ ApprovalCardRequest,
295
+ ApprovalCardAccepted,
296
+ ApprovalCardRejected,
297
+ ApprovalCardActions,
298
+ ApprovalCardAction,
299
+ ApprovalCardApprove,
300
+ ApprovalCardDeny,
301
+ ApprovalCardOptions,
302
+ ApprovalCardTarget,
303
+ ApprovalCardReason
304
+ };
305
+ //# sourceMappingURL=chunk-ELGCZLZF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/confirmation.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Alert,\n AlertDescription,\n AlertTitle,\n APPROVAL_SCOPE_DESCRIPTION_KEYS,\n Kbd,\n Label,\n RadioGroup,\n RadioGroupItem,\n StatusBadge,\n Textarea,\n useLocale,\n type ApprovalOption,\n} from \"@elabs-ai/components-ui\";\nimport { Button } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport type { ToolUIPart } from \"ai\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { createContext, forwardRef, useContext, useId, useMemo, useState } from \"react\";\n\ntype ToolUIPartApproval =\n | {\n id: string;\n approved?: never;\n reason?: never;\n }\n | {\n id: string;\n approved: boolean;\n reason?: string;\n }\n | {\n id: string;\n approved: true;\n reason?: string;\n }\n | {\n id: string;\n approved: false;\n reason?: string;\n }\n | undefined;\n\ninterface ConfirmationContextValue {\n approval: ToolUIPartApproval;\n state: ToolUIPart[\"state\"];\n /** Default id wired from the card's `aria-labelledby` to `ConfirmationTitle`. */\n titleId: string;\n /**\n * Shared draft reason text (#103) — written by `ApprovalCardReason`, read by\n * `ApprovalCardOptions` at the moment a decision commits, so a typed\n * explanation reaches `onConfirm`'s second argument without threading a\n * prop between two sibling compound parts. Unused by the pre-existing\n * binary `Confirmation*` parts, so their rendered output is unaffected.\n */\n reason: string;\n setReason: (reason: string) => void;\n}\n\nconst ConfirmationContext = createContext<ConfirmationContextValue | null>(null);\n\nconst useConfirmation = () => {\n const context = useContext(ConfirmationContext);\n\n if (!context) {\n throw new Error(\"Confirmation components must be used within Confirmation\");\n }\n\n return context;\n};\n\nexport type ConfirmationProps = ComponentProps<typeof Alert> & {\n approval?: ToolUIPartApproval;\n state: ToolUIPart[\"state\"];\n};\n\nexport const Confirmation = ({\n className,\n approval,\n state,\n variant,\n role,\n children,\n ...props\n}: ConfirmationProps) => {\n const titleId = useId();\n const [reason, setReason] = useState(\"\");\n const contextValue = useMemo(\n () => ({ approval, state, titleId, reason, setReason }),\n [approval, state, titleId, reason],\n );\n\n if (!approval || state === \"input-streaming\" || state === \"input-available\") {\n return null;\n }\n\n const isResolved =\n state === \"approval-responded\" || state === \"output-denied\" || state === \"output-available\";\n const isPending = state === \"approval-requested\";\n const approved = isResolved ? approval.approved : undefined;\n\n // QUIET-RAIL treatment (supersedes research-11's warning/status WASH — a\n // deliberate design-authority decision to drop the filled \"AI card\" look):\n // a neutral card ground (Alert variant=\"default\") + ONE accent rail encoding\n // the outcome, plus the StatusBadge (icon + label, never color alone). The\n // rails are hue-independent enough to stay legible at high decoration / high-contrast.\n // A caller-supplied `variant` still wins (escape hatch).\n const railClass =\n approved === true\n ? \"border-s-success\"\n : approved === false\n ? \"border-s-destructive\"\n : isPending\n ? \"border-s-border-strong\"\n : \"border-s-border\";\n\n return (\n <ConfirmationContext.Provider value={contextValue}>\n <Alert\n variant={variant ?? \"default\"}\n // A pending decision containing focusable controls is a labelled\n // region, NOT an assertive live region (research 11 §B.3): pending =\n // role=\"group\" + aria-labelledby; resolved keeps role=\"alert\".\n role={role ?? (isPending ? \"group\" : \"alert\")}\n aria-labelledby={isPending ? titleId : undefined}\n className={cn(\n \"flex flex-col gap-2 border-s-4 transition-colors duration-fast\",\n railClass,\n isPending && \"shadow-sm\",\n className,\n )}\n {...props}\n >\n {/* The status line is the canonical StatusBadge (#189, research 10 §B.1). */}\n {approved === true ? (\n <StatusBadge\n className=\"animate-in fade-in-0 self-start duration-base ease-entrance\"\n status=\"complete\"\n >\n Approved\n </StatusBadge>\n ) : null}\n {approved === false ? (\n <StatusBadge\n className=\"animate-in fade-in-0 self-start duration-base ease-entrance\"\n status=\"denied\"\n >\n Denied\n </StatusBadge>\n ) : null}\n {children}\n </Alert>\n </ConfirmationContext.Provider>\n );\n};\n\nexport type ConfirmationTitleProps = ComponentProps<typeof AlertTitle>;\n\n/**\n * The question zone (research 11 §B.3 APPROVE-3) — out-ranks the surrounding\n * `text-body` and names the pending region via the card's `aria-labelledby`.\n */\nexport const ConfirmationTitle = ({ className, id, ...props }: ConfirmationTitleProps) => {\n const { titleId } = useConfirmation();\n return <AlertTitle id={id ?? titleId} className={cn(\"text-subtitle\", className)} {...props} />;\n};\n\nexport type ConfirmationDescriptionProps = ComponentProps<typeof AlertDescription>;\n\n/** The consequence zone — what approving will actually do (research 11 §B.3). */\nexport const ConfirmationDescription = ({ className, ...props }: ConfirmationDescriptionProps) => (\n <AlertDescription className={cn(\"text-body text-muted-foreground\", className)} {...props} />\n);\n\nexport interface ConfirmationRequestProps {\n children?: ReactNode;\n}\n\nexport const ConfirmationRequest = ({ children }: ConfirmationRequestProps) => {\n const { state } = useConfirmation();\n\n // Only show when approval is requested\n if (state !== \"approval-requested\") {\n return null;\n }\n\n return children;\n};\n\nexport interface ConfirmationAcceptedProps {\n children?: ReactNode;\n}\n\nexport const ConfirmationAccepted = ({ children }: ConfirmationAcceptedProps) => {\n const { approval, state } = useConfirmation();\n\n // Only show when approved and in response states\n if (\n !approval?.approved ||\n (state !== \"approval-responded\" && state !== \"output-denied\" && state !== \"output-available\")\n ) {\n return null;\n }\n\n return children;\n};\n\nexport interface ConfirmationRejectedProps {\n children?: ReactNode;\n}\n\nexport const ConfirmationRejected = ({ children }: ConfirmationRejectedProps) => {\n const { approval, state } = useConfirmation();\n\n // Only show when rejected and in response states\n if (\n approval?.approved !== false ||\n (state !== \"approval-responded\" && state !== \"output-denied\" && state !== \"output-available\")\n ) {\n return null;\n }\n\n return children;\n};\n\nexport type ConfirmationActionsProps = ComponentProps<\"div\">;\n\nexport const ConfirmationActions = ({ className, ...props }: ConfirmationActionsProps) => {\n const { state } = useConfirmation();\n\n // Only show when approval is requested\n if (state !== \"approval-requested\") {\n return null;\n }\n\n return (\n <div\n className={cn(\n // The action band (research 11 §B.3 APPROVE-3): the divider is the SOLE\n // cue between consequence and buttons, so `border-strong` is correct.\n \"flex w-full items-center justify-end gap-2 border-t border-border-strong pt-3\",\n className,\n )}\n {...props}\n />\n );\n};\n\nexport type ConfirmationActionProps = ComponentProps<typeof Button>;\n\nexport const ConfirmationAction = ({ className, ...props }: ConfirmationActionProps) => (\n <Button className={cn(\"h-8 px-3 text-body\", className)} type=\"button\" {...props} />\n);\n\nexport type ConfirmationApproveProps = ConfirmationActionProps;\n\n/**\n * The proceed action — presets the filled primary variant (research 11 §B.3\n * APPROVE-2). Role-named so the primary path cannot drift to `outline`.\n */\nexport const ConfirmationApprove = (props: ConfirmationApproveProps) => (\n <ConfirmationAction variant=\"default\" {...props} />\n);\n\nexport type ConfirmationDenyProps = ConfirmationActionProps;\n\n/** The decline action — presets the quiet `ghost` variant, never `outline`. */\nexport const ConfirmationDeny = (props: ConfirmationDenyProps) => (\n <ConfirmationAction variant=\"ghost\" {...props} />\n);\n\n/*\n * ApprovalCard — the promoted, semantically-named front door for the approval\n * interaction (research 11 §B.3). Same components, clearer name; the\n * `Confirmation*` exports stay for the AI-Elements-shaped API (non-breaking).\n * New code reaches for `ApprovalCard`.\n *\n * The `Confirmation*` family below is CLOSED — frozen at exactly the ten\n * names aliased here. New parts (#103 and beyond) are declared as real\n * `ApprovalCard*` implementations, never added to this alias block. See\n * `docs/decisions/2026-09-01-brainless-adoption-architecture.md` § 4 and the\n * `FROZEN_CONFIRMATION_EXPORTS` lock in `confirmation.test.tsx`.\n */\nexport const ApprovalCard = Confirmation;\nexport type ApprovalCardProps = ConfirmationProps;\nexport const ApprovalCardTitle = ConfirmationTitle;\nexport type ApprovalCardTitleProps = ConfirmationTitleProps;\nexport const ApprovalCardDescription = ConfirmationDescription;\nexport type ApprovalCardDescriptionProps = ConfirmationDescriptionProps;\nexport const ApprovalCardRequest = ConfirmationRequest;\nexport type ApprovalCardRequestProps = ConfirmationRequestProps;\nexport const ApprovalCardAccepted = ConfirmationAccepted;\nexport type ApprovalCardAcceptedProps = ConfirmationAcceptedProps;\nexport const ApprovalCardRejected = ConfirmationRejected;\nexport type ApprovalCardRejectedProps = ConfirmationRejectedProps;\nexport const ApprovalCardActions = ConfirmationActions;\nexport type ApprovalCardActionsProps = ConfirmationActionsProps;\nexport const ApprovalCardAction = ConfirmationAction;\nexport type ApprovalCardActionProps = ConfirmationActionProps;\nexport const ApprovalCardApprove = ConfirmationApprove;\nexport type ApprovalCardApproveProps = ConfirmationApproveProps;\nexport const ApprovalCardDeny = ConfirmationDeny;\nexport type ApprovalCardDenyProps = ConfirmationDenyProps;\n\n/*\n * ---------------------------------------------------------------------------\n * N-option, scoped approval (#103)\n * ---------------------------------------------------------------------------\n * Real coding-agent permission prompts are rarely a plain yes/no — they ask\n * an N-option question whose options encode SCOPE: \"Yes\", \"Yes, and don't ask\n * again this session\", \"No, and tell the agent what to do instead\". The\n * binary `Confirmation`/`ApprovalCard` pair above cannot express the middle\n * option; these three parts extend it additively, composed as CHILDREN of the\n * existing card (`ApprovalCard` / `ApprovalCardRequest`), never as a\n * replacement for it. Every new export here is a real `ApprovalCard*`\n * implementation — see the closed-family note above the alias block.\n *\n * Vocabulary note: this is the PER-CALL decision surface (\"may I run this\n * command?\"). `PermissionModeSelect` (#104) is the separate, standing POLICY\n * surface (\"how much may you do without asking?\") — the two compose rather\n * than merge into one boolean-flagged component, per\n * `.claude/rules/component-api.md` (\"Avoid boolean-prop proliferation\").\n */\n\n/**\n * `ApprovalScope`, `ApprovalOption` and `APPROVAL_SCOPE_DESCRIPTION_KEYS`\n * moved to `@elabs-ai/components-ui` (`lib/approval-option.ts`) — the\n * terminal CLI look-alike family's own permission row (issue #117) reuses\n * the same model, and `@elabs-ai/components-ai`/`@elabs-ai/components-terminal`\n * are layer-2 DAG siblings that may not import each other (T0; see\n * docs/decisions/2026-09-01-brainless-adoption-architecture.md § 4). Imported\n * above.\n */\n\nexport interface ApprovalCardOptionsProps extends ComponentProps<\"div\"> {\n options: ApprovalOption[];\n value?: string;\n defaultValue?: string;\n onValueChange?: (id: string) => void;\n /**\n * Fires when an option is selected — by click, or by ANY keyboard move\n * within the radio group (Home/End/arrow keys select immediately, per the\n * native/ARIA radiogroup pattern Radix implements; there is no separate\n * \"highlight vs commit\" step). Reports the full resolved `ApprovalOption`\n * plus whatever reason text is currently held by a sibling\n * `ApprovalCardReason` — type a reason BEFORE choosing an option to have it\n * included in this call.\n */\n onConfirm?: (option: ApprovalOption, reason?: string) => void;\n}\n\n/**\n * ApprovalCardOptions — the N-option, scoped decision (#103). Renders through\n * `@elabs-ai/components-ui`'s `RadioGroup` (Radix) for roving focus, arrow-key\n * wrap, Home/End and announcement — never a hand-rolled\n * `parentElement.children[i]` focus walk. Composed inside `ApprovalCardRequest`,\n * alongside the existing `ApprovalCardTitle`/`ApprovalCardDescription`.\n */\nexport const ApprovalCardOptions = forwardRef<HTMLDivElement, ApprovalCardOptionsProps>(\n function ApprovalCardOptions(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n onConfirm,\n className,\n dir,\n \"aria-labelledby\": ariaLabelledBy,\n ...props\n },\n ref,\n ) {\n const { t } = useLocale();\n const { titleId, reason } = useConfirmation();\n const baseId = useId();\n\n // Controlled/uncontrolled mirrors the platform (and `PermissionModeSelect`,\n // #104): `value`/`onValueChange` for a controlled caller, `defaultValue`\n // for an uncontrolled starting point — Radix's own `RadioGroup` already\n // implements both correctly. Hand-rolling a parallel `internalValue`\n // state here and always passing a (possibly `undefined`) `value` down\n // makes Radix's controllable-state hook see a spurious\n // uncontrolled-to-controlled transition the first time a selection is\n // made, which is exactly the warning this avoids.\n const handleValueChange = (id: string) => {\n onValueChange?.(id);\n const option = options.find((candidate) => candidate.id === id);\n if (option) onConfirm?.(option, reason.trim() ? reason : undefined);\n };\n\n return (\n <RadioGroup\n ref={ref}\n // `dir` on a plain <div> is a free-form HTML string; Radix's\n // RadioGroup narrows it to \"ltr\" | \"rtl\". Cast at this single call\n // site, matching `PermissionModeSelect` (#104), rather than widening\n // (and so weakening) the public prop type.\n dir={dir as \"ltr\" | \"rtl\" | undefined}\n defaultValue={defaultValue}\n value={value}\n onValueChange={handleValueChange}\n aria-labelledby={ariaLabelledBy ?? titleId}\n data-slot=\"approval-card-options\"\n className={cn(\"grid gap-2\", className)}\n {...props}\n >\n {options.map((option) => {\n const itemId = `${baseId}-${option.id}`;\n const descriptionId = `${itemId}-description`;\n const description =\n option.description ?? t(APPROVAL_SCOPE_DESCRIPTION_KEYS[option.scope]);\n\n return (\n <div\n key={option.id}\n data-slot=\"approval-card-option\"\n data-scope={option.scope}\n className={cn(\n \"flex items-start gap-3 rounded-lg border border-border bg-card p-3\",\n \"has-[[data-state=checked]]:border-primary\",\n )}\n >\n <RadioGroupItem\n aria-describedby={descriptionId}\n className=\"mt-1\"\n data-slot=\"approval-card-option-input\"\n id={itemId}\n value={option.id}\n />\n <div className=\"grid flex-1 gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <Label\n className=\"text-body flex items-center gap-2 font-medium\"\n data-slot=\"approval-card-option-label\"\n htmlFor={itemId}\n >\n {option.label}\n </Label>\n {option.keyHint ? (\n <Kbd data-slot=\"approval-card-option-key-hint\">{option.keyHint}</Kbd>\n ) : null}\n </div>\n <p\n className=\"text-meta text-muted-foreground\"\n data-slot=\"approval-card-option-description\"\n id={descriptionId}\n >\n {description}\n </p>\n </div>\n </div>\n );\n })}\n </RadioGroup>\n );\n },\n);\n\nApprovalCardOptions.displayName = \"ApprovalCardOptions\";\n\nexport type ApprovalCardTargetProps = ComponentProps<\"div\">;\n\n/**\n * ApprovalCardTarget — the preview slot for WHAT is being approved: a\n * command, a path, or a richer node such as a `DiffView` (#102). Accepts\n * arbitrary children — this file never imports `DiffView`, the composition\n * happens entirely in the consumer's tree. Ungated by state (unlike\n * `ApprovalCardRequest`/`Accepted`/`Rejected`): the subject of a decision\n * stays visible after it resolves, not only while pending.\n */\nexport const ApprovalCardTarget = forwardRef<HTMLDivElement, ApprovalCardTargetProps>(\n function ApprovalCardTarget({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-slot=\"approval-card-target\"\n className={cn(\"text-body rounded-md bg-muted/50 p-3\", className)}\n {...props}\n />\n );\n },\n);\n\nApprovalCardTarget.displayName = \"ApprovalCardTarget\";\n\nexport type ApprovalCardReasonProps = Omit<\n ComponentProps<typeof Textarea>,\n \"value\" | \"defaultValue\" | \"onChange\"\n>;\n\n/**\n * ApprovalCardReason — the deny-with-reason input, wired to the `reason`\n * field that already exists on `ToolUIPartApproval` and was previously\n * unreachable from the UI. Shares its value with `ApprovalCardOptions`\n * through `Confirmation`'s own context (not a prop threaded between the two\n * sibling parts) — type here BEFORE choosing an option to have the text\n * included in that option's `onConfirm` call.\n */\nexport const ApprovalCardReason = forwardRef<HTMLTextAreaElement, ApprovalCardReasonProps>(\n function ApprovalCardReason({ className, id, placeholder, ...props }, ref) {\n const { t } = useLocale();\n const { reason, setReason } = useConfirmation();\n const generatedId = useId();\n const textareaId = id ?? generatedId;\n\n return (\n <div className=\"grid gap-1.5\" data-slot=\"approval-card-reason\">\n <Label\n className=\"text-meta text-muted-foreground\"\n data-slot=\"approval-card-reason-label\"\n htmlFor={textareaId}\n >\n {t(\"ai.approvalCard.reasonLabel\")}\n </Label>\n <Textarea\n ref={ref}\n id={textareaId}\n placeholder={placeholder ?? t(\"ai.approvalCard.reasonPlaceholder\")}\n value={reason}\n onChange={(event) => setReason(event.target.value)}\n data-slot=\"approval-card-reason-input\"\n className={cn(\"min-h-16 text-body\", className)}\n {...props}\n />\n </div>\n );\n },\n);\n\nApprovalCardReason.displayName = \"ApprovalCardReason\";\n"],"mappings":"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","names":["ApprovalCardOptions","ApprovalCardTarget","ApprovalCardReason"]}
@@ -0,0 +1,209 @@
1
+ "use client";
2
+
3
+ // src/message-edit.tsx
4
+ import {
5
+ createContext,
6
+ forwardRef,
7
+ use,
8
+ useCallback,
9
+ useEffect,
10
+ useId,
11
+ useMemo,
12
+ useRef,
13
+ useState
14
+ } from "react";
15
+ import { Check, Pencil, X } from "lucide-react";
16
+ import { Button, Textarea } from "@elabs-ai/components-ui";
17
+ import { cn } from "@elabs-ai/components-ui/lib/cn";
18
+ import { useLocale } from "@elabs-ai/components-ui";
19
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
20
+ var MessageEditContext = createContext(null);
21
+ function useMessageEditContext() {
22
+ const ctx = use(MessageEditContext);
23
+ if (!ctx) {
24
+ throw new Error("MessageEdit sub-components must be rendered inside <MessageEditProvider>.");
25
+ }
26
+ return ctx;
27
+ }
28
+ function useMessageEdit() {
29
+ const { editing, draft, beginEdit, cancel, submit } = useMessageEditContext();
30
+ return { editing, draft, beginEdit, cancel, submit };
31
+ }
32
+ function MessageEditProvider({
33
+ value,
34
+ onEditSubmit,
35
+ editing: editingProp,
36
+ defaultEditing = false,
37
+ onEditingChange,
38
+ children
39
+ }) {
40
+ const editorId = useId();
41
+ const isControlled = editingProp !== void 0;
42
+ const [internalEditing, setInternalEditing] = useState(defaultEditing);
43
+ const editing = isControlled ? editingProp : internalEditing;
44
+ const [draft, setDraft] = useState(value);
45
+ const triggerRef = useRef(null);
46
+ const restoreFocus = useRef(false);
47
+ const setEditing = useCallback(
48
+ (next) => {
49
+ if (!isControlled) setInternalEditing(next);
50
+ onEditingChange?.(next);
51
+ },
52
+ [isControlled, onEditingChange]
53
+ );
54
+ const beginEdit = useCallback(() => {
55
+ setDraft(value);
56
+ setEditing(true);
57
+ }, [value, setEditing]);
58
+ const cancel = useCallback(() => {
59
+ setDraft(value);
60
+ restoreFocus.current = true;
61
+ setEditing(false);
62
+ }, [value, setEditing]);
63
+ const submit = useCallback(() => {
64
+ onEditSubmit?.(draft);
65
+ restoreFocus.current = true;
66
+ setEditing(false);
67
+ }, [draft, onEditSubmit, setEditing]);
68
+ useEffect(() => {
69
+ if (!editing && restoreFocus.current) {
70
+ restoreFocus.current = false;
71
+ triggerRef.current?.focus();
72
+ }
73
+ }, [editing]);
74
+ const contextValue = useMemo(
75
+ () => ({ editing, draft, setDraft, beginEdit, cancel, submit, triggerRef, editorId }),
76
+ [editing, draft, beginEdit, cancel, submit, editorId]
77
+ );
78
+ return /* @__PURE__ */ jsx(MessageEditContext.Provider, { value: contextValue, children });
79
+ }
80
+ var MessageEditForm = forwardRef(
81
+ function MessageEditForm2({ className, saveLabel = "Save", cancelLabel = "Cancel", ...props }, ref) {
82
+ const { t } = useLocale();
83
+ const { draft, setDraft, cancel, submit, editorId } = useMessageEditContext();
84
+ const textareaRef = useRef(null);
85
+ useEffect(() => {
86
+ const el = textareaRef.current;
87
+ if (el) {
88
+ el.focus();
89
+ el.setSelectionRange(el.value.length, el.value.length);
90
+ }
91
+ }, []);
92
+ const handleSubmit = (e) => {
93
+ e.preventDefault();
94
+ submit();
95
+ };
96
+ const handleKeyDown = (e) => {
97
+ if (e.key === "Escape") {
98
+ e.preventDefault();
99
+ cancel();
100
+ return;
101
+ }
102
+ if (e.key === "Enter" && !e.shiftKey && e.target === textareaRef.current) {
103
+ e.preventDefault();
104
+ submit();
105
+ }
106
+ };
107
+ return /* @__PURE__ */ jsxs(
108
+ "form",
109
+ {
110
+ ref,
111
+ onSubmit: handleSubmit,
112
+ onKeyDown: handleKeyDown,
113
+ className: cn("flex w-full flex-col gap-2", className),
114
+ ...props,
115
+ children: [
116
+ /* @__PURE__ */ jsx(
117
+ Textarea,
118
+ {
119
+ ref: textareaRef,
120
+ id: editorId,
121
+ value: draft,
122
+ "aria-label": t("ai.message.editMessage"),
123
+ onChange: (e) => setDraft(e.target.value),
124
+ className: "min-h-16"
125
+ }
126
+ ),
127
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
128
+ /* @__PURE__ */ jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: cancel, children: [
129
+ /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "size-4" }),
130
+ cancelLabel
131
+ ] }),
132
+ /* @__PURE__ */ jsxs(Button, { type: "submit", size: "sm", disabled: draft.trim().length === 0, children: [
133
+ /* @__PURE__ */ jsx(Check, { "aria-hidden": "true", className: "size-4" }),
134
+ saveLabel
135
+ ] })
136
+ ] })
137
+ ]
138
+ }
139
+ );
140
+ }
141
+ );
142
+ var MessageEditContent = forwardRef(
143
+ function MessageEditContent2({ className, children, ...props }, ref) {
144
+ const { editing } = useMessageEditContext();
145
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), ...props, children: editing ? /* @__PURE__ */ jsx(MessageEditForm, {}) : children });
146
+ }
147
+ );
148
+ var MessageEditTrigger = forwardRef(
149
+ function MessageEditTrigger2({ className, children, variant = "ghost", size = "sm", onClick, ...props }, ref) {
150
+ const { editing, beginEdit, triggerRef } = useMessageEditContext();
151
+ if (editing) return null;
152
+ return /* @__PURE__ */ jsx(
153
+ Button,
154
+ {
155
+ ref: (node) => {
156
+ triggerRef.current = node;
157
+ if (typeof ref === "function") ref(node);
158
+ else if (ref) ref.current = node;
159
+ },
160
+ variant,
161
+ size,
162
+ className,
163
+ onClick: (e) => {
164
+ onClick?.(e);
165
+ beginEdit();
166
+ },
167
+ ...props,
168
+ children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
169
+ /* @__PURE__ */ jsx(Pencil, { "aria-hidden": "true", className: "size-4" }),
170
+ "Edit"
171
+ ] })
172
+ }
173
+ );
174
+ }
175
+ );
176
+ var MessageEdit = forwardRef(function MessageEdit2({ value, onEditSubmit, editing, defaultEditing, onEditingChange, className, children, ...props }, ref) {
177
+ return /* @__PURE__ */ jsx(
178
+ MessageEditProvider,
179
+ {
180
+ value,
181
+ onEditSubmit,
182
+ editing,
183
+ defaultEditing,
184
+ onEditingChange,
185
+ children: /* @__PURE__ */ jsxs(
186
+ "div",
187
+ {
188
+ ref,
189
+ className: cn("group/message-edit flex w-full flex-col gap-1", className),
190
+ ...props,
191
+ children: [
192
+ /* @__PURE__ */ jsx(MessageEditContent, { children }),
193
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end opacity-0 transition-opacity duration-fast focus-within:opacity-100 group-hover/message-edit:opacity-100 motion-reduce:transition-none", children: /* @__PURE__ */ jsx(MessageEditTrigger, {}) })
194
+ ]
195
+ }
196
+ )
197
+ }
198
+ );
199
+ });
200
+
201
+ export {
202
+ useMessageEdit,
203
+ MessageEditProvider,
204
+ MessageEditForm,
205
+ MessageEditContent,
206
+ MessageEditTrigger,
207
+ MessageEdit
208
+ };
209
+ //# sourceMappingURL=chunk-EV3U6ZZB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/message-edit.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * MessageEdit — edit-in-place for a user message.\n *\n * Swaps a message bubble between its display content and an inline editor\n * (the composer's `Textarea` primitive) seeded with the original text.\n * `onEditSubmit(newText)` fires on save — the consumer then creates a branch\n * (compose with `MessageBranch*`). Presentational only: it never mutates the\n * message; the original is simply restored on cancel because the source text is\n * untouched until `onEditSubmit`.\n *\n * Behavior: Enter submits, Shift+Enter inserts a newline, Esc cancels. Focus\n * moves into the editor on begin, is trapped within it while editing, and is\n * restored to the trigger on cancel/submit.\n *\n * Compound structure (the ChangeReview convention — named parts, lifted state):\n * <MessageEditProvider> — lifted edit state (editing + draft + actions)\n * <MessageEditContent> — display children, or the inline editor\n * <MessageEditTrigger> — begins editing (focus is restored here on exit)\n */\n\nimport {\n createContext,\n forwardRef,\n use,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type FormEvent,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { Check, Pencil, X } from \"lucide-react\";\nimport { Button, Textarea } from \"@elabs-ai/components-ui\";\nimport { cn } from \"@elabs-ai/components-ui/lib/cn\";\nimport { useLocale } from \"@elabs-ai/components-ui\";\n\n// ─── Context ────────────────────────────────────────────────────────────────\n\ninterface MessageEditContextValue {\n editing: boolean;\n draft: string;\n setDraft: (value: string) => void;\n beginEdit: () => void;\n cancel: () => void;\n submit: () => void;\n /** Ref for the trigger element so focus can be restored to it on exit. */\n triggerRef: React.MutableRefObject<HTMLElement | null>;\n editorId: string;\n}\n\nconst MessageEditContext = createContext<MessageEditContextValue | null>(null);\n\nfunction useMessageEditContext(): MessageEditContextValue {\n const ctx = use(MessageEditContext);\n if (!ctx) {\n throw new Error(\"MessageEdit sub-components must be rendered inside <MessageEditProvider>.\");\n }\n return ctx;\n}\n\n/** Read-only access to the edit state (for a custom trigger/toolbar). */\nexport function useMessageEdit(): Pick<\n MessageEditContextValue,\n \"editing\" | \"draft\" | \"beginEdit\" | \"cancel\" | \"submit\"\n> {\n const { editing, draft, beginEdit, cancel, submit } = useMessageEditContext();\n return { editing, draft, beginEdit, cancel, submit };\n}\n\n// ─── Provider ───────────────────────────────────────────────────────────────\n\nexport interface MessageEditProviderProps {\n /** The editable source text (seeds the editor on begin). */\n value: string;\n /** Called with the new text on save. The consumer creates the branch. */\n onEditSubmit?: (newText: string) => void;\n /** Controlled editing state. When set, `onEditingChange` drives transitions. */\n editing?: boolean;\n /** Uncontrolled initial editing state. @default false */\n defaultEditing?: boolean;\n /** Called when editing begins/ends. */\n onEditingChange?: (editing: boolean) => void;\n children: ReactNode;\n}\n\n/** Lifts the edit state (editing + draft). Controlled or uncontrolled. */\nexport function MessageEditProvider({\n value,\n onEditSubmit,\n editing: editingProp,\n defaultEditing = false,\n onEditingChange,\n children,\n}: MessageEditProviderProps) {\n const editorId = useId();\n const isControlled = editingProp !== undefined;\n const [internalEditing, setInternalEditing] = useState(defaultEditing);\n const editing = isControlled ? (editingProp as boolean) : internalEditing;\n\n const [draft, setDraft] = useState(value);\n const triggerRef = useRef<HTMLElement | null>(null);\n const restoreFocus = useRef(false);\n\n const setEditing = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalEditing(next);\n onEditingChange?.(next);\n },\n [isControlled, onEditingChange],\n );\n\n const beginEdit = useCallback(() => {\n setDraft(value); // seed from the current source text\n setEditing(true);\n }, [value, setEditing]);\n\n const cancel = useCallback(() => {\n setDraft(value); // discard edits (original is restored)\n restoreFocus.current = true;\n setEditing(false);\n }, [value, setEditing]);\n\n const submit = useCallback(() => {\n onEditSubmit?.(draft);\n restoreFocus.current = true;\n setEditing(false);\n }, [draft, onEditSubmit, setEditing]);\n\n // Restore focus to the trigger once the editor has unmounted.\n useEffect(() => {\n if (!editing && restoreFocus.current) {\n restoreFocus.current = false;\n triggerRef.current?.focus();\n }\n }, [editing]);\n\n const contextValue = useMemo<MessageEditContextValue>(\n () => ({ editing, draft, setDraft, beginEdit, cancel, submit, triggerRef, editorId }),\n [editing, draft, beginEdit, cancel, submit, editorId],\n );\n\n return <MessageEditContext.Provider value={contextValue}>{children}</MessageEditContext.Provider>;\n}\n\n// ─── Inline editor ─────────────────────────────────────────────────────────────\n\nexport type MessageEditFormProps = Omit<HTMLAttributes<HTMLFormElement>, \"onSubmit\"> & {\n /** Save button label. @default \"Save\" */\n saveLabel?: string;\n /** Cancel button label. @default \"Cancel\" */\n cancelLabel?: string;\n};\n\n/** The inline editor: an autofocused textarea + Save/Cancel, Enter/Esc wired. */\nexport const MessageEditForm = forwardRef<HTMLFormElement, MessageEditFormProps>(\n function MessageEditForm(\n { className, saveLabel = \"Save\", cancelLabel = \"Cancel\", ...props },\n ref,\n ) {\n const { t } = useLocale();\n const { draft, setDraft, cancel, submit, editorId } = useMessageEditContext();\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n // Autofocus the textarea and place the caret at the end.\n useEffect(() => {\n const el = textareaRef.current;\n if (el) {\n el.focus();\n el.setSelectionRange(el.value.length, el.value.length);\n }\n }, []);\n\n const handleSubmit = (e: FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n submit();\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLElement>) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n cancel();\n return;\n }\n // Enter submits from the textarea; Shift+Enter inserts a newline.\n if (e.key === \"Enter\" && !e.shiftKey && e.target === textareaRef.current) {\n e.preventDefault();\n submit();\n }\n // NOTE: Tab is deliberately NOT trapped — this is an inline, non-modal\n // editor, and the repo a11y rule forbids trapping focus outside modals.\n // Tab flows naturally out of the editor; focus is restored to the trigger\n // only on cancel/submit.\n };\n\n return (\n <form\n ref={ref}\n onSubmit={handleSubmit}\n onKeyDown={handleKeyDown}\n className={cn(\"flex w-full flex-col gap-2\", className)}\n {...props}\n >\n <Textarea\n ref={textareaRef}\n id={editorId}\n value={draft}\n aria-label={t(\"ai.message.editMessage\")}\n onChange={(e) => setDraft(e.target.value)}\n className=\"min-h-16\"\n />\n <div className=\"flex items-center justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={cancel}>\n <X aria-hidden=\"true\" className=\"size-4\" />\n {cancelLabel}\n </Button>\n <Button type=\"submit\" size=\"sm\" disabled={draft.trim().length === 0}>\n <Check aria-hidden=\"true\" className=\"size-4\" />\n {saveLabel}\n </Button>\n </div>\n </form>\n );\n },\n);\n\n// ─── Content ──────────────────────────────────────────────────────────────────\n\nexport type MessageEditContentProps = HTMLAttributes<HTMLDivElement>;\n\n/** Renders `children` in display mode, or the inline editor while editing. */\nexport const MessageEditContent = forwardRef<HTMLDivElement, MessageEditContentProps>(\n function MessageEditContent({ className, children, ...props }, ref) {\n const { editing } = useMessageEditContext();\n return (\n <div ref={ref} className={cn(\"w-full\", className)} {...props}>\n {editing ? <MessageEditForm /> : children}\n </div>\n );\n },\n);\n\n// ─── Trigger ──────────────────────────────────────────────────────────────────\n\nexport type MessageEditTriggerProps = React.ComponentProps<typeof Button>;\n\n/** Begins editing. Focus is restored here on cancel/submit. Hidden while editing. */\nexport const MessageEditTrigger = forwardRef<HTMLButtonElement, MessageEditTriggerProps>(\n function MessageEditTrigger(\n { className, children, variant = \"ghost\", size = \"sm\", onClick, ...props },\n ref,\n ) {\n const { editing, beginEdit, triggerRef } = useMessageEditContext();\n if (editing) return null;\n return (\n <Button\n ref={(node) => {\n triggerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n variant={variant}\n size={size}\n className={className}\n onClick={(e) => {\n onClick?.(e);\n beginEdit();\n }}\n {...props}\n >\n {children ?? (\n <>\n <Pencil aria-hidden=\"true\" className=\"size-4\" />\n Edit\n </>\n )}\n </Button>\n );\n },\n);\n\n// ─── Root convenience ──────────────────────────────────────────────────────────\n\nexport interface MessageEditProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onSubmit\" | \"children\"\n> {\n /** The editable source text. */\n value: string;\n /** Called with the new text on save (consumer creates the branch). */\n onEditSubmit?: (newText: string) => void;\n /** Controlled editing state. */\n editing?: boolean;\n /** Uncontrolled initial editing state. */\n defaultEditing?: boolean;\n /** Called when editing begins/ends. */\n onEditingChange?: (editing: boolean) => void;\n /** The display content (usually the rendered message text). */\n children: ReactNode;\n}\n\n/**\n * Convenience composition: display `children` + an \"Edit\" trigger, swapping to\n * the inline editor while editing. For toolbar-placed triggers, compose the\n * parts (`MessageEditProvider` + `MessageEditTrigger` in your toolbar).\n */\nexport const MessageEdit = forwardRef<HTMLDivElement, MessageEditProps>(function MessageEdit(\n { value, onEditSubmit, editing, defaultEditing, onEditingChange, className, children, ...props },\n ref,\n) {\n return (\n <MessageEditProvider\n value={value}\n onEditSubmit={onEditSubmit}\n editing={editing}\n defaultEditing={defaultEditing}\n onEditingChange={onEditingChange}\n >\n <div\n ref={ref}\n className={cn(\"group/message-edit flex w-full flex-col gap-1\", className)}\n {...props}\n >\n <MessageEditContent>{children}</MessageEditContent>\n <div className=\"flex justify-end opacity-0 transition-opacity duration-fast focus-within:opacity-100 group-hover/message-edit:opacity-100 motion-reduce:transition-none\">\n <MessageEditTrigger />\n </div>\n </div>\n </MessageEditProvider>\n );\n});\n"],"mappings":"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","names":["MessageEditForm","MessageEditContent","MessageEditTrigger","MessageEdit"]}