@mieweb/ui 0.9.0 → 0.10.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. package/MIGRATION.md +112 -0
  2. package/agent/mieweb-ui.instructions.md +2 -1
  3. package/dist/{Animated-Cs-naa2g.d.cts → Animated-XmH6k8pZ.d.cts} +16 -3
  4. package/dist/{Animated-Cs-naa2g.d.ts → Animated-XmH6k8pZ.d.ts} +16 -3
  5. package/dist/{CsvBlock-QXXZ7ZUM.cjs → CsvBlock-CVYA3HYS.cjs} +3 -2
  6. package/dist/{CsvBlock-QXXZ7ZUM.cjs.map → CsvBlock-CVYA3HYS.cjs.map} +1 -1
  7. package/dist/{CsvBlock-D7Z6ZCRP.js → CsvBlock-SM4NKSHA.js} +3 -2
  8. package/dist/{CsvBlock-D7Z6ZCRP.js.map → CsvBlock-SM4NKSHA.js.map} +1 -1
  9. package/dist/{HtmlPreviewBlock-F5VDM2EN.js → HtmlPreviewBlock-FAMF4W24.js} +3 -2
  10. package/dist/{HtmlPreviewBlock-F5VDM2EN.js.map → HtmlPreviewBlock-FAMF4W24.js.map} +1 -1
  11. package/dist/{HtmlPreviewBlock-AADG7MVB.cjs → HtmlPreviewBlock-JF454L2L.cjs} +3 -2
  12. package/dist/{HtmlPreviewBlock-AADG7MVB.cjs.map → HtmlPreviewBlock-JF454L2L.cjs.map} +1 -1
  13. package/dist/{MermaidBlock-6PLITRBZ.js → MermaidBlock-7V5G4K5A.js} +3 -2
  14. package/dist/{MermaidBlock-6PLITRBZ.js.map → MermaidBlock-7V5G4K5A.js.map} +1 -1
  15. package/dist/{MermaidBlock-TQ2O5CLV.cjs → MermaidBlock-FR5SQX4Q.cjs} +3 -2
  16. package/dist/{MermaidBlock-TQ2O5CLV.cjs.map → MermaidBlock-FR5SQX4Q.cjs.map} +1 -1
  17. package/dist/{SurveyBlock-W5PSQ62F.js → SurveyBlock-6K2POV7S.js} +3 -2
  18. package/dist/{SurveyBlock-W5PSQ62F.js.map → SurveyBlock-6K2POV7S.js.map} +1 -1
  19. package/dist/{SurveyBlock-OYL3VNU5.cjs → SurveyBlock-MCJVWR7H.cjs} +3 -2
  20. package/dist/{SurveyBlock-OYL3VNU5.cjs.map → SurveyBlock-MCJVWR7H.cjs.map} +1 -1
  21. package/dist/ag-grid.cjs +1 -0
  22. package/dist/ag-grid.cjs.map +1 -1
  23. package/dist/ag-grid.js +1 -0
  24. package/dist/ag-grid.js.map +1 -1
  25. package/dist/brands/bluehive.cjs +1 -0
  26. package/dist/brands/bluehive.js +1 -0
  27. package/dist/brands/ccme.cjs +1 -0
  28. package/dist/brands/ccme.js +1 -0
  29. package/dist/brands/index.cjs +3 -2
  30. package/dist/brands/index.js +2 -1
  31. package/dist/brands/ozwell.cjs +1 -0
  32. package/dist/brands/ozwell.js +1 -0
  33. package/dist/brands/types.cjs +1 -0
  34. package/dist/brands/types.js +1 -0
  35. package/dist/{chunk-XUVEF2RQ.js → chunk-24SEAAOH.js} +2 -2
  36. package/dist/{chunk-XUVEF2RQ.js.map → chunk-24SEAAOH.js.map} +1 -1
  37. package/dist/{chunk-IUDY6S7I.cjs → chunk-37UZHCLM.cjs} +35 -14
  38. package/dist/chunk-37UZHCLM.cjs.map +1 -0
  39. package/dist/{chunk-ODYQYLO2.js → chunk-7KWNY3HG.js} +9 -5
  40. package/dist/chunk-7KWNY3HG.js.map +1 -0
  41. package/dist/{chunk-L52N6BEN.cjs → chunk-AUOTJQGO.cjs} +7 -7
  42. package/dist/{chunk-L52N6BEN.cjs.map → chunk-AUOTJQGO.cjs.map} +1 -1
  43. package/dist/{chunk-O7XHHTTP.cjs → chunk-AZP3DDBT.cjs} +6 -6
  44. package/dist/{chunk-O7XHHTTP.cjs.map → chunk-AZP3DDBT.cjs.map} +1 -1
  45. package/dist/chunk-C6CTTLH2.js +44645 -0
  46. package/dist/chunk-C6CTTLH2.js.map +1 -0
  47. package/dist/{chunk-6XDPJWSC.cjs → chunk-E3KC2XLN.cjs} +34 -30
  48. package/dist/chunk-E3KC2XLN.cjs.map +1 -0
  49. package/dist/chunk-EUAMEVVI.cjs +41 -0
  50. package/dist/chunk-EUAMEVVI.cjs.map +1 -0
  51. package/dist/{chunk-DFYMIRMW.js → chunk-IGNWT6RP.js} +7 -2
  52. package/dist/chunk-IGNWT6RP.js.map +1 -0
  53. package/dist/{chunk-XEEVDZDK.cjs → chunk-IGSIWNX3.cjs} +7 -2
  54. package/dist/chunk-IGSIWNX3.cjs.map +1 -0
  55. package/dist/chunk-IIFQ6BSJ.js +1888 -0
  56. package/dist/chunk-IIFQ6BSJ.js.map +1 -0
  57. package/dist/{chunk-FUFBRKOG.cjs → chunk-KLJGJJHN.cjs} +24 -24
  58. package/dist/{chunk-FUFBRKOG.cjs.map → chunk-KLJGJJHN.cjs.map} +1 -1
  59. package/dist/chunk-LECJMLNE.js +15 -0
  60. package/dist/{chunk-CYMZ2QS5.js.map → chunk-LECJMLNE.js.map} +1 -1
  61. package/dist/{chunk-BJKAVWED.js → chunk-MBWF36DJ.js} +35 -14
  62. package/dist/chunk-MBWF36DJ.js.map +1 -0
  63. package/dist/chunk-NV2CWBI2.cjs +290 -0
  64. package/dist/chunk-NV2CWBI2.cjs.map +1 -0
  65. package/dist/{chunk-FQBTGS3E.cjs → chunk-OFUKTVBN.cjs} +363 -285
  66. package/dist/chunk-OFUKTVBN.cjs.map +1 -0
  67. package/dist/{chunk-7KN6J7XV.cjs → chunk-OMAACCFW.cjs} +7 -7
  68. package/dist/{chunk-7KN6J7XV.cjs.map → chunk-OMAACCFW.cjs.map} +1 -1
  69. package/dist/chunk-OYQ7GYAA.cjs +1921 -0
  70. package/dist/chunk-OYQ7GYAA.cjs.map +1 -0
  71. package/dist/{chunk-YJP6DUFO.cjs → chunk-PKD3JLS2.cjs} +6 -6
  72. package/dist/{chunk-YJP6DUFO.cjs.map → chunk-PKD3JLS2.cjs.map} +1 -1
  73. package/dist/chunk-PN2PIE2L.cjs +44670 -0
  74. package/dist/chunk-PN2PIE2L.cjs.map +1 -0
  75. package/dist/chunk-PX6F3LHL.js +37 -0
  76. package/dist/chunk-PX6F3LHL.js.map +1 -0
  77. package/dist/{chunk-CXDMZT45.cjs → chunk-PY7XAG4D.cjs} +27 -4
  78. package/dist/chunk-PY7XAG4D.cjs.map +1 -0
  79. package/dist/{chunk-5H7SAEQO.js → chunk-QKFJDQEK.js} +3 -3
  80. package/dist/{chunk-5H7SAEQO.js.map → chunk-QKFJDQEK.js.map} +1 -1
  81. package/dist/{chunk-XJTFZLWH.cjs → chunk-QO6PRHDX.cjs} +2 -2
  82. package/dist/{chunk-XJTFZLWH.cjs.map → chunk-QO6PRHDX.cjs.map} +1 -1
  83. package/dist/{chunk-ONNY7UO4.js → chunk-QSVQABXD.js} +4 -4
  84. package/dist/{chunk-ONNY7UO4.js.map → chunk-QSVQABXD.js.map} +1 -1
  85. package/dist/{chunk-OHDIJOGG.js → chunk-RD3JDFYJ.js} +3 -3
  86. package/dist/{chunk-OHDIJOGG.js.map → chunk-RD3JDFYJ.js.map} +1 -1
  87. package/dist/{chunk-4SM3I7WE.cjs → chunk-RXPEZXAB.cjs} +67 -38
  88. package/dist/chunk-RXPEZXAB.cjs.map +1 -0
  89. package/dist/{chunk-VTR2KGLY.cjs → chunk-S3BCHPXT.cjs} +9 -9
  90. package/dist/{chunk-VTR2KGLY.cjs.map → chunk-S3BCHPXT.cjs.map} +1 -1
  91. package/dist/{chunk-KU3XRHWA.js → chunk-TZX76ZNZ.js} +67 -38
  92. package/dist/chunk-TZX76ZNZ.js.map +1 -0
  93. package/dist/chunk-VNAREBLV.cjs +17 -0
  94. package/dist/{chunk-SNEQXSC5.cjs.map → chunk-VNAREBLV.cjs.map} +1 -1
  95. package/dist/{chunk-MXQ7J4BB.js → chunk-VSVGMMNO.js} +361 -284
  96. package/dist/chunk-VSVGMMNO.js.map +1 -0
  97. package/dist/{chunk-Q7G56ZIO.js → chunk-WUBMDOTG.js} +3 -3
  98. package/dist/{chunk-Q7G56ZIO.js.map → chunk-WUBMDOTG.js.map} +1 -1
  99. package/dist/{chunk-DGRXAIWK.js → chunk-X5YM3KXY.js} +27 -4
  100. package/dist/chunk-X5YM3KXY.js.map +1 -0
  101. package/dist/chunk-XCP454Q6.js +263 -0
  102. package/dist/chunk-XCP454Q6.js.map +1 -0
  103. package/dist/{chunk-I3DQXUSC.js → chunk-Y6DFMDMH.js} +3 -3
  104. package/dist/{chunk-I3DQXUSC.js.map → chunk-Y6DFMDMH.js.map} +1 -1
  105. package/dist/{chunk-D25WH7MH.js → chunk-ZX2XRFE5.js} +6 -6
  106. package/dist/{chunk-D25WH7MH.js.map → chunk-ZX2XRFE5.js.map} +1 -1
  107. package/dist/{collabKit-Q4A36LDA.cjs → collabKit-GCRHP25F.cjs} +3 -3
  108. package/dist/{collabKit-Q4A36LDA.cjs.map → collabKit-GCRHP25F.cjs.map} +1 -1
  109. package/dist/{collabKit-A643VH2I.js → collabKit-SJPDPXU4.js} +3 -3
  110. package/dist/{collabKit-A643VH2I.js.map → collabKit-SJPDPXU4.js.map} +1 -1
  111. package/dist/components/Accordion/index.cjs +1 -0
  112. package/dist/components/Accordion/index.js +1 -0
  113. package/dist/components/Alert/index.cjs +1 -0
  114. package/dist/components/Alert/index.js +1 -0
  115. package/dist/components/AlertDialog/index.cjs +5 -4
  116. package/dist/components/AlertDialog/index.js +4 -3
  117. package/dist/components/AudioPlayer/index.cjs +1 -0
  118. package/dist/components/AudioPlayer/index.js +1 -0
  119. package/dist/components/AudioRecorder/index.cjs +1 -0
  120. package/dist/components/AudioRecorder/index.js +1 -0
  121. package/dist/components/Autocomplete/index.cjs +1 -0
  122. package/dist/components/Autocomplete/index.js +1 -0
  123. package/dist/components/Avatar/index.cjs +1 -0
  124. package/dist/components/Avatar/index.js +1 -0
  125. package/dist/components/Badge/index.cjs +1 -0
  126. package/dist/components/Badge/index.js +1 -0
  127. package/dist/components/Breadcrumb/index.cjs +1 -0
  128. package/dist/components/Breadcrumb/index.js +1 -0
  129. package/dist/components/Button/index.cjs +1 -0
  130. package/dist/components/Button/index.js +1 -0
  131. package/dist/components/Card/index.cjs +1 -0
  132. package/dist/components/Card/index.js +1 -0
  133. package/dist/components/Checkbox/index.cjs +1 -0
  134. package/dist/components/Checkbox/index.js +1 -0
  135. package/dist/components/ClampedText/index.cjs +1 -0
  136. package/dist/components/ClampedText/index.js +1 -0
  137. package/dist/components/CollabStatus/index.cjs +1 -0
  138. package/dist/components/CollabStatus/index.js +1 -0
  139. package/dist/components/Collapsible/index.cjs +7 -4
  140. package/dist/components/Collapsible/index.js +4 -1
  141. package/dist/components/CopyButton/index.cjs +1 -0
  142. package/dist/components/CopyButton/index.js +1 -0
  143. package/dist/components/CountryCodeDropdown/index.cjs +1 -0
  144. package/dist/components/CountryCodeDropdown/index.js +1 -0
  145. package/dist/components/CustomizableDashboard/index.cjs +1 -0
  146. package/dist/components/CustomizableDashboard/index.js +1 -0
  147. package/dist/components/DateInput/index.cjs +1 -0
  148. package/dist/components/DateInput/index.js +1 -0
  149. package/dist/components/Dropdown/index.cjs +10 -8
  150. package/dist/components/Dropdown/index.js +3 -1
  151. package/dist/components/FilterSummaryBar/index.cjs +1 -0
  152. package/dist/components/FilterSummaryBar/index.js +1 -0
  153. package/dist/components/FloatingWindow/index.cjs +1 -0
  154. package/dist/components/FloatingWindow/index.js +1 -0
  155. package/dist/components/FreshnessBadge/index.cjs +1 -0
  156. package/dist/components/FreshnessBadge/index.js +1 -0
  157. package/dist/components/GlossaryTooltip/index.cjs +1 -0
  158. package/dist/components/GlossaryTooltip/index.js +1 -0
  159. package/dist/components/Input/index.cjs +1 -0
  160. package/dist/components/Input/index.js +1 -0
  161. package/dist/components/KeyboardShortcutsOverlay/index.cjs +6 -5
  162. package/dist/components/KeyboardShortcutsOverlay/index.js +4 -3
  163. package/dist/components/Label/index.cjs +1 -0
  164. package/dist/components/Label/index.js +1 -0
  165. package/dist/components/Markdown/index.cjs +6 -5
  166. package/dist/components/Markdown/index.js +2 -1
  167. package/dist/components/MediaEditor/index.cjs +10 -9
  168. package/dist/components/MediaEditor/index.js +5 -4
  169. package/dist/components/MediaPlayer/index.cjs +1 -0
  170. package/dist/components/MediaPlayer/index.js +1 -0
  171. package/dist/components/Modal/index.cjs +11 -10
  172. package/dist/components/Modal/index.js +3 -2
  173. package/dist/components/Pagination/index.cjs +1 -0
  174. package/dist/components/Pagination/index.js +1 -0
  175. package/dist/components/PhoneInput/index.cjs +1 -0
  176. package/dist/components/PhoneInput/index.js +1 -0
  177. package/dist/components/Progress/index.cjs +1 -0
  178. package/dist/components/Progress/index.js +1 -0
  179. package/dist/components/Q/index.cjs +1 -0
  180. package/dist/components/Q/index.js +1 -0
  181. package/dist/components/QuickAction/index.cjs +1 -0
  182. package/dist/components/QuickAction/index.js +1 -0
  183. package/dist/components/Radio/index.cjs +1 -0
  184. package/dist/components/Radio/index.js +1 -0
  185. package/dist/components/ReadingProgressBar/index.cjs +1 -0
  186. package/dist/components/ReadingProgressBar/index.js +1 -0
  187. package/dist/components/RecordButton/index.cjs +1 -0
  188. package/dist/components/RecordButton/index.js +1 -0
  189. package/dist/components/RichTextEditor/index.cjs +7 -5
  190. package/dist/components/RichTextEditor/index.js +4 -2
  191. package/dist/components/SchedulePicker/index.cjs +1 -0
  192. package/dist/components/SchedulePicker/index.js +1 -0
  193. package/dist/components/ScrollArea/index.cjs +1 -0
  194. package/dist/components/ScrollArea/index.js +1 -0
  195. package/dist/components/SectionSpyNav/index.cjs +1 -0
  196. package/dist/components/SectionSpyNav/index.js +1 -0
  197. package/dist/components/Select/index.cjs +4 -3
  198. package/dist/components/Select/index.js +2 -1
  199. package/dist/components/Separator/index.cjs +1 -0
  200. package/dist/components/Separator/index.js +1 -0
  201. package/dist/components/Sheet/index.cjs +1 -0
  202. package/dist/components/Sheet/index.js +1 -0
  203. package/dist/components/Skeleton/index.cjs +1 -0
  204. package/dist/components/Skeleton/index.js +1 -0
  205. package/dist/components/Slider/index.cjs +1 -0
  206. package/dist/components/Slider/index.js +1 -0
  207. package/dist/components/SourceTip/index.cjs +1 -0
  208. package/dist/components/SourceTip/index.js +1 -0
  209. package/dist/components/Sparkline/index.cjs +1 -0
  210. package/dist/components/Sparkline/index.js +1 -0
  211. package/dist/components/Spinner/index.cjs +1 -0
  212. package/dist/components/Spinner/index.js +1 -0
  213. package/dist/components/SuperChat/index.cjs +41 -17
  214. package/dist/components/SuperChat/index.cjs.map +1 -1
  215. package/dist/components/SuperChat/index.d.cts +20 -7
  216. package/dist/components/SuperChat/index.d.ts +20 -7
  217. package/dist/components/SuperChat/index.js +36 -12
  218. package/dist/components/SuperChat/index.js.map +1 -1
  219. package/dist/components/SuperChat/plugins/index.cjs +12 -4
  220. package/dist/components/SuperChat/plugins/index.cjs.map +1 -1
  221. package/dist/components/SuperChat/plugins/index.d.cts +3 -3
  222. package/dist/components/SuperChat/plugins/index.d.ts +3 -3
  223. package/dist/components/SuperChat/plugins/index.js +11 -3
  224. package/dist/components/SuperChat/plugins/index.js.map +1 -1
  225. package/dist/components/Switch/index.cjs +1 -0
  226. package/dist/components/Switch/index.js +1 -0
  227. package/dist/components/Table/index.cjs +1 -0
  228. package/dist/components/Table/index.js +1 -0
  229. package/dist/components/Tabs/index.cjs +1 -0
  230. package/dist/components/Tabs/index.js +1 -0
  231. package/dist/components/Text/index.cjs +1 -0
  232. package/dist/components/Text/index.js +1 -0
  233. package/dist/components/Textarea/index.cjs +1 -0
  234. package/dist/components/Textarea/index.js +1 -0
  235. package/dist/components/ThemeProvider/index.cjs +1 -0
  236. package/dist/components/ThemeProvider/index.js +1 -0
  237. package/dist/components/Toggle/index.cjs +1 -0
  238. package/dist/components/Toggle/index.js +1 -0
  239. package/dist/components/Tooltip/index.cjs +1 -0
  240. package/dist/components/Tooltip/index.js +1 -0
  241. package/dist/components/TranscriptView/index.cjs +1 -0
  242. package/dist/components/TranscriptView/index.js +1 -0
  243. package/dist/components/VisuallyHidden/index.cjs +1 -0
  244. package/dist/components/VisuallyHidden/index.js +1 -0
  245. package/dist/datavis.cjs +13 -8
  246. package/dist/datavis.cjs.map +1 -1
  247. package/dist/datavis.d.cts +647 -22
  248. package/dist/datavis.d.ts +647 -22
  249. package/dist/datavis.js +6 -5
  250. package/dist/datavis.js.map +1 -1
  251. package/dist/{default-BTEIFIZJ.cjs → default-CCMUBXP6.cjs} +3 -2
  252. package/dist/{default-BTEIFIZJ.cjs.map → default-CCMUBXP6.cjs.map} +1 -1
  253. package/dist/default-N2LW7ZFU.js +4 -0
  254. package/dist/{default-ORBRVZRZ.js.map → default-N2LW7ZFU.js.map} +1 -1
  255. package/dist/{enterprise-health-UDI25OCV.cjs → enterprise-health-75VYWAVG.cjs} +3 -2
  256. package/dist/{enterprise-health-UDI25OCV.cjs.map → enterprise-health-75VYWAVG.cjs.map} +1 -1
  257. package/dist/enterprise-health-CWLUB77O.js +4 -0
  258. package/dist/{enterprise-health-ORQQOLM3.js.map → enterprise-health-CWLUB77O.js.map} +1 -1
  259. package/dist/esheet.cjs +8 -7
  260. package/dist/esheet.cjs.map +1 -1
  261. package/dist/esheet.js +5 -4
  262. package/dist/esheet.js.map +1 -1
  263. package/dist/{hey-buddy-CLUVAY2X.cjs → hey-buddy-INNUFFJJ.cjs} +3 -2
  264. package/dist/hey-buddy-INNUFFJJ.cjs.map +1 -0
  265. package/dist/{hey-buddy-NMSWZ4TN.js → hey-buddy-V6FC5UKB.js} +3 -2
  266. package/dist/hey-buddy-V6FC5UKB.js.map +1 -0
  267. package/dist/hooks/index.cjs +14 -13
  268. package/dist/hooks/index.js +2 -1
  269. package/dist/index.cjs +753 -1703
  270. package/dist/index.cjs.map +1 -1
  271. package/dist/index.d.cts +347 -347
  272. package/dist/index.d.ts +347 -347
  273. package/dist/index.js +465 -1410
  274. package/dist/index.js.map +1 -1
  275. package/dist/kerebron.cjs +2 -1
  276. package/dist/kerebron.cjs.map +1 -1
  277. package/dist/kerebron.js +2 -1
  278. package/dist/kerebron.js.map +1 -1
  279. package/dist/{mieweb-6JCRWKSO.cjs → mieweb-72YOL44I.cjs} +3 -2
  280. package/dist/{mieweb-6JCRWKSO.cjs.map → mieweb-72YOL44I.cjs.map} +1 -1
  281. package/dist/mieweb-EZDLSSA6.js +4 -0
  282. package/dist/{mieweb-GIKY6EMN.js.map → mieweb-EZDLSSA6.js.map} +1 -1
  283. package/dist/motion.cjs +8 -7
  284. package/dist/motion.cjs.map +1 -1
  285. package/dist/motion.d.cts +1 -1
  286. package/dist/motion.d.ts +1 -1
  287. package/dist/motion.js +3 -2
  288. package/dist/motion.js.map +1 -1
  289. package/dist/{nitroTableGrid-SIMT7635.js → nitroTableGrid-LVYKKCGF.js} +5 -4
  290. package/dist/nitroTableGrid-LVYKKCGF.js.map +1 -0
  291. package/dist/{nitroTableGrid-3J2GY6CK.cjs → nitroTableGrid-SQADULEY.cjs} +5 -4
  292. package/dist/nitroTableGrid-SQADULEY.cjs.map +1 -0
  293. package/dist/q.cjs +1 -0
  294. package/dist/q.js +1 -0
  295. package/dist/styles.css +1 -1
  296. package/dist/tailwind-preset.cjs +5 -4
  297. package/dist/tailwind-preset.js +2 -1
  298. package/dist/{types-DZDroUW8.d.cts → types-B97JNRNQ.d.cts} +1 -1
  299. package/dist/{types-B2RLmdVd.d.ts → types-CnPEwzlp.d.cts} +6 -2
  300. package/dist/{types-B2RLmdVd.d.cts → types-CnPEwzlp.d.ts} +6 -2
  301. package/dist/{types-9vK_YdEb.d.ts → types-gZXrfLj6.d.ts} +1 -1
  302. package/dist/utils/index.cjs +1 -0
  303. package/dist/utils/index.js +1 -0
  304. package/dist/{waggleline-I7QWD3YX.cjs → waggleline-5CBT4MNN.cjs} +3 -2
  305. package/dist/{waggleline-I7QWD3YX.cjs.map → waggleline-5CBT4MNN.cjs.map} +1 -1
  306. package/dist/waggleline-JMPCNV3J.js +4 -0
  307. package/dist/{waggleline-2MLRNVCV.js.map → waggleline-JMPCNV3J.js.map} +1 -1
  308. package/dist/webchart-2CVQ2TT3.js +4 -0
  309. package/dist/{webchart-72YMJ45P.js.map → webchart-2CVQ2TT3.js.map} +1 -1
  310. package/dist/{webchart-37OYZ42V.cjs → webchart-AXXOQHU6.cjs} +3 -2
  311. package/dist/{webchart-37OYZ42V.cjs.map → webchart-AXXOQHU6.cjs.map} +1 -1
  312. package/package.json +9 -14
  313. package/dist/chunk-4SM3I7WE.cjs.map +0 -1
  314. package/dist/chunk-5BVFVXHN.cjs +0 -1244
  315. package/dist/chunk-5BVFVXHN.cjs.map +0 -1
  316. package/dist/chunk-6XDPJWSC.cjs.map +0 -1
  317. package/dist/chunk-BJKAVWED.js.map +0 -1
  318. package/dist/chunk-BN75TLUN.cjs +0 -163
  319. package/dist/chunk-BN75TLUN.cjs.map +0 -1
  320. package/dist/chunk-CXDMZT45.cjs.map +0 -1
  321. package/dist/chunk-CYMZ2QS5.js +0 -15
  322. package/dist/chunk-DFYMIRMW.js.map +0 -1
  323. package/dist/chunk-DGRXAIWK.js.map +0 -1
  324. package/dist/chunk-FQBTGS3E.cjs.map +0 -1
  325. package/dist/chunk-IUDY6S7I.cjs.map +0 -1
  326. package/dist/chunk-KU3XRHWA.js.map +0 -1
  327. package/dist/chunk-MXQ7J4BB.js.map +0 -1
  328. package/dist/chunk-O6GJ4IYS.js +0 -1210
  329. package/dist/chunk-O6GJ4IYS.js.map +0 -1
  330. package/dist/chunk-ODYQYLO2.js.map +0 -1
  331. package/dist/chunk-SNEQXSC5.cjs +0 -17
  332. package/dist/chunk-VJOVJTFP.cjs +0 -370
  333. package/dist/chunk-VJOVJTFP.cjs.map +0 -1
  334. package/dist/chunk-WYMO3IIK.js +0 -136
  335. package/dist/chunk-WYMO3IIK.js.map +0 -1
  336. package/dist/chunk-XEEVDZDK.cjs.map +0 -1
  337. package/dist/chunk-YBLIDESO.js +0 -365
  338. package/dist/chunk-YBLIDESO.js.map +0 -1
  339. package/dist/default-ORBRVZRZ.js +0 -3
  340. package/dist/enterprise-health-ORQQOLM3.js +0 -3
  341. package/dist/hey-buddy-CLUVAY2X.cjs.map +0 -1
  342. package/dist/hey-buddy-NMSWZ4TN.js.map +0 -1
  343. package/dist/mieweb-GIKY6EMN.js +0 -3
  344. package/dist/nitroTableGrid-3J2GY6CK.cjs.map +0 -1
  345. package/dist/nitroTableGrid-SIMT7635.js.map +0 -1
  346. package/dist/waggleline-2MLRNVCV.js +0 -3
  347. package/dist/webchart-72YMJ45P.js +0 -3
@@ -0,0 +1,1888 @@
1
+ import { Dropdown, DropdownItem, DropdownSeparator } from './chunk-TZX76ZNZ.js';
2
+ import { AlertTriangle, X2, Paperclip, Plus, Mic, Square, Loader2, ArrowUp, Check, Bot, ChevronUp } from './chunk-BKSPDTX4.js';
3
+ import { cn } from './chunk-TQONQSJO.js';
4
+ import { useEscapeKey } from './chunk-T4ME7QCT.js';
5
+ import { useClickOutside } from './chunk-62ZOA6PX.js';
6
+ import { useAnchoredPosition } from './chunk-WSNMQQ4P.js';
7
+ import * as React from 'react';
8
+ import { createPortal } from 'react-dom';
9
+ import { ChevronUp as ChevronUp$1, Check as Check$1, ChevronRight, ChevronLeft } from 'lucide-react';
10
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
11
+
12
+ var MENU_OFFSET_PX = 6;
13
+ var MENU_MAX_HEIGHT_PX = 320;
14
+ function optionKey(option) {
15
+ return `${option.provider}\0${option.model}`;
16
+ }
17
+ function renderedOptionKey(option, index) {
18
+ return `${option.id ?? optionKey(option)}\0${index}`;
19
+ }
20
+ function groupByProvider(models) {
21
+ const groups = /* @__PURE__ */ new Map();
22
+ for (const model of models) {
23
+ const group = groups.get(model.provider);
24
+ if (group) {
25
+ group.push(model);
26
+ } else {
27
+ groups.set(model.provider, [model]);
28
+ }
29
+ }
30
+ return Array.from(groups, ([provider, options]) => ({ provider, options }));
31
+ }
32
+ function getProviderLabel(models, provider) {
33
+ return models.find((model) => model.provider === provider && model.providerLabel)?.providerLabel ?? provider;
34
+ }
35
+ function ComposerModelSelector({
36
+ models,
37
+ value,
38
+ providerFilter,
39
+ onProviderFilterChange,
40
+ onChange,
41
+ disabled = false,
42
+ variant = "default",
43
+ className,
44
+ boundaryRef,
45
+ placeholder = "Model",
46
+ anyLabel = "Any",
47
+ emptyLabel = "No models",
48
+ ariaLabel = "Model",
49
+ effortOptions,
50
+ effort = null,
51
+ defaultEffort,
52
+ onEffortChange,
53
+ effortLabel = "Effort",
54
+ effortHint,
55
+ defaultBadgeLabel = "Default",
56
+ backLabel = "Back"
57
+ }) {
58
+ const [open, setOpen] = React.useState(false);
59
+ const [view, setView] = React.useState("models");
60
+ const [effortHighlight, setEffortHighlight] = React.useState(0);
61
+ const [internalProviderFilter, setInternalProviderFilter] = React.useState(null);
62
+ const [highlightedIndex, setHighlightedIndex] = React.useState(0);
63
+ const listRef = React.useRef(null);
64
+ const effortListRef = React.useRef(null);
65
+ const menuId = React.useId();
66
+ const {
67
+ anchorRef: triggerRef,
68
+ floatingRef: menuRef,
69
+ style: menuStyle
70
+ } = useAnchoredPosition({
71
+ open,
72
+ placement: "top-start",
73
+ offset: MENU_OFFSET_PX,
74
+ matchMinWidth: true,
75
+ maxHeight: MENU_MAX_HEIGHT_PX,
76
+ allowFlip: false,
77
+ boundaryRef
78
+ });
79
+ const activeProviderFilter = providerFilter === void 0 ? internalProviderFilter : providerFilter;
80
+ const selectedKey = value ? optionKey(value) : null;
81
+ const selectedOption = models.find(
82
+ (model) => optionKey(model) === selectedKey
83
+ );
84
+ const providers = React.useMemo(
85
+ () => Array.from(new Set(models.map((model) => model.provider))),
86
+ [models]
87
+ );
88
+ const providerLabels = React.useMemo(
89
+ () => new Map(
90
+ providers.map((provider) => [
91
+ provider,
92
+ getProviderLabel(models, provider)
93
+ ])
94
+ ),
95
+ [models, providers]
96
+ );
97
+ const filteredModels = React.useMemo(
98
+ () => activeProviderFilter === null ? models : models.filter((model) => model.provider === activeProviderFilter),
99
+ [activeProviderFilter, models]
100
+ );
101
+ const groupedModels = React.useMemo(
102
+ () => groupByProvider(filteredModels),
103
+ [filteredModels]
104
+ );
105
+ const groupedRenderedModels = React.useMemo(() => {
106
+ let index = 0;
107
+ return groupedModels.map((group) => ({
108
+ provider: group.provider,
109
+ options: group.options.map((option) => {
110
+ const rendered = {
111
+ option,
112
+ index,
113
+ key: renderedOptionKey(option, index)
114
+ };
115
+ index += 1;
116
+ return rendered;
117
+ })
118
+ }));
119
+ }, [groupedModels]);
120
+ const renderedModels = React.useMemo(
121
+ () => groupedRenderedModels.flatMap((group) => group.options),
122
+ [groupedRenderedModels]
123
+ );
124
+ const getOptionId = React.useCallback(
125
+ (index) => `${menuId}-option-${index}`,
126
+ [menuId]
127
+ );
128
+ const getEffortOptionId = React.useCallback(
129
+ (index) => `${menuId}-effort-option-${index}`,
130
+ [menuId]
131
+ );
132
+ const activeOptionId = open && renderedModels[highlightedIndex] ? getOptionId(highlightedIndex) : void 0;
133
+ const selectedRenderedIndex = React.useMemo(
134
+ () => selectedKey ? renderedModels.findIndex(
135
+ (renderedModel) => optionKey(renderedModel.option) === selectedKey
136
+ ) : -1,
137
+ [renderedModels, selectedKey]
138
+ );
139
+ const setProvider = React.useCallback(
140
+ (provider) => {
141
+ if (providerFilter === void 0) {
142
+ setInternalProviderFilter(provider);
143
+ }
144
+ onProviderFilterChange?.(provider);
145
+ },
146
+ [onProviderFilterChange, providerFilter]
147
+ );
148
+ const close = React.useCallback(
149
+ (restoreFocus = true) => {
150
+ setOpen(false);
151
+ if (restoreFocus) {
152
+ triggerRef.current?.focus({ preventScroll: true });
153
+ }
154
+ },
155
+ [triggerRef]
156
+ );
157
+ const selectModel = React.useCallback(
158
+ (model) => {
159
+ onChange({ provider: model.provider, model: model.model });
160
+ close();
161
+ },
162
+ [close, onChange]
163
+ );
164
+ const efforts = React.useMemo(() => effortOptions ?? [], [effortOptions]);
165
+ const activeEffortOptionId = open && efforts[effortHighlight] ? getEffortOptionId(effortHighlight) : void 0;
166
+ const selectedEffortOption = efforts.find(
167
+ (option) => option.value === effort
168
+ );
169
+ const selectEffort = React.useCallback(
170
+ (value2) => {
171
+ onEffortChange?.(value2);
172
+ close();
173
+ },
174
+ [close, onEffortChange]
175
+ );
176
+ const handleEffortKeyDown = (event) => {
177
+ if (efforts.length === 0) return;
178
+ if (event.key === "ArrowDown") {
179
+ event.preventDefault();
180
+ setEffortHighlight((current) => (current + 1) % efforts.length);
181
+ }
182
+ if (event.key === "ArrowUp") {
183
+ event.preventDefault();
184
+ setEffortHighlight(
185
+ (current) => (current - 1 + efforts.length) % efforts.length
186
+ );
187
+ }
188
+ if (event.key === "Home") {
189
+ event.preventDefault();
190
+ setEffortHighlight(0);
191
+ }
192
+ if (event.key === "End") {
193
+ event.preventDefault();
194
+ setEffortHighlight(efforts.length - 1);
195
+ }
196
+ if (event.key === "ArrowLeft" || event.key === "Backspace") {
197
+ event.preventDefault();
198
+ setView("models");
199
+ }
200
+ if (event.key === "Enter" || event.key === " ") {
201
+ event.preventDefault();
202
+ const highlighted = efforts[effortHighlight];
203
+ if (highlighted) selectEffort(highlighted.value);
204
+ }
205
+ };
206
+ const outsideRefs = React.useMemo(
207
+ () => [triggerRef, menuRef],
208
+ [triggerRef, menuRef]
209
+ );
210
+ useClickOutside(outsideRefs, () => close(false), open);
211
+ useEscapeKey(close, open);
212
+ React.useEffect(() => {
213
+ if (!open) return;
214
+ setHighlightedIndex(selectedRenderedIndex >= 0 ? selectedRenderedIndex : 0);
215
+ }, [activeProviderFilter, open, selectedRenderedIndex]);
216
+ React.useEffect(() => {
217
+ if (!open) return;
218
+ setView("models");
219
+ }, [open]);
220
+ React.useEffect(() => {
221
+ if (!open) return;
222
+ const current = efforts.findIndex((option) => option.value === effort);
223
+ setEffortHighlight(current >= 0 ? current : 0);
224
+ }, [effort, efforts, open]);
225
+ React.useEffect(() => {
226
+ if (!open) return;
227
+ setHighlightedIndex(
228
+ (current) => Math.min(current, Math.max(renderedModels.length - 1, 0))
229
+ );
230
+ }, [open, renderedModels.length]);
231
+ React.useEffect(() => {
232
+ if (!open) return;
233
+ requestAnimationFrame(() => {
234
+ const target = view === "effort" ? effortListRef.current : listRef.current;
235
+ target?.focus({ preventScroll: true });
236
+ });
237
+ }, [open, view]);
238
+ const handleTriggerKeyDown = (event) => {
239
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
240
+ event.preventDefault();
241
+ setOpen(true);
242
+ }
243
+ };
244
+ const handleMenuKeyDown = (event) => {
245
+ if (renderedModels.length === 0) return;
246
+ if (event.key === "ArrowDown") {
247
+ event.preventDefault();
248
+ setHighlightedIndex((current) => (current + 1) % renderedModels.length);
249
+ }
250
+ if (event.key === "ArrowUp") {
251
+ event.preventDefault();
252
+ setHighlightedIndex(
253
+ (current) => (current - 1 + renderedModels.length) % renderedModels.length
254
+ );
255
+ }
256
+ if (event.key === "Home") {
257
+ event.preventDefault();
258
+ setHighlightedIndex(0);
259
+ }
260
+ if (event.key === "End") {
261
+ event.preventDefault();
262
+ setHighlightedIndex(renderedModels.length - 1);
263
+ }
264
+ if (event.key === "Enter" || event.key === " ") {
265
+ event.preventDefault();
266
+ const highlightedModel = renderedModels[highlightedIndex]?.option;
267
+ if (highlightedModel) {
268
+ selectModel(highlightedModel);
269
+ }
270
+ }
271
+ };
272
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
273
+ /* @__PURE__ */ jsxs(
274
+ "button",
275
+ {
276
+ ref: triggerRef,
277
+ type: "button",
278
+ disabled,
279
+ "aria-haspopup": "listbox",
280
+ "aria-expanded": open,
281
+ "aria-controls": open ? menuId : void 0,
282
+ onClick: () => setOpen((current) => !current),
283
+ onKeyDown: handleTriggerKeyDown,
284
+ "data-slot": "composer-model-selector-trigger",
285
+ className: cn(
286
+ variant === "ghost" ? [
287
+ "inline-flex max-w-full min-w-0 items-center gap-1 rounded-md px-2 py-1 text-xs",
288
+ "text-neutral-600 dark:text-neutral-400",
289
+ "transition-colors duration-150",
290
+ "hover:bg-neutral-100 hover:text-neutral-900 dark:hover:bg-neutral-700 dark:hover:text-white",
291
+ "focus-visible:ring-primary-500 focus-visible:ring-2 focus-visible:outline-none",
292
+ "disabled:pointer-events-none disabled:opacity-40"
293
+ ] : [
294
+ "inline-flex h-8 max-w-full items-center gap-1.5 rounded-full border px-2.5 text-sm font-medium",
295
+ "border-border bg-background text-foreground shadow-sm",
296
+ "hover:bg-muted/50",
297
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none",
298
+ "disabled:cursor-not-allowed disabled:opacity-50"
299
+ ],
300
+ className
301
+ ),
302
+ children: [
303
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: selectedOption?.label ?? selectedOption?.model ?? placeholder }),
304
+ selectedEffortOption && /* @__PURE__ */ jsx(
305
+ "span",
306
+ {
307
+ "data-slot": "composer-model-selector-trigger-effort",
308
+ className: "text-muted-foreground min-w-0 truncate font-normal",
309
+ children: selectedEffortOption.label
310
+ }
311
+ ),
312
+ /* @__PURE__ */ jsx(
313
+ ChevronUp$1,
314
+ {
315
+ "aria-hidden": "true",
316
+ className: cn(
317
+ "shrink-0",
318
+ variant === "ghost" ? "h-3 w-3" : "h-3.5 w-3.5"
319
+ )
320
+ }
321
+ )
322
+ ]
323
+ }
324
+ ),
325
+ open && createPortal(
326
+ /* @__PURE__ */ jsxs(
327
+ "div",
328
+ {
329
+ ref: menuRef,
330
+ style: menuStyle,
331
+ "data-slot": "composer-model-selector-menu",
332
+ className: cn(
333
+ "border-border bg-card text-card-foreground flex w-80 max-w-full flex-col rounded-lg border shadow-lg",
334
+ "animate-in fade-in overflow-hidden duration-100"
335
+ ),
336
+ children: [
337
+ view === "models" && /* @__PURE__ */ jsxs(Fragment, { children: [
338
+ /* @__PURE__ */ jsx(
339
+ "div",
340
+ {
341
+ "data-slot": "composer-model-selector-provider-filter",
342
+ className: "border-border flex min-h-9 items-center gap-1 overflow-x-auto overflow-y-hidden border-b p-2",
343
+ children: [null, ...providers].map((provider) => {
344
+ const selected = activeProviderFilter === provider;
345
+ return /* @__PURE__ */ jsx(
346
+ "button",
347
+ {
348
+ type: "button",
349
+ "aria-pressed": selected,
350
+ onMouseDown: (event) => event.preventDefault(),
351
+ onClick: () => setProvider(provider),
352
+ className: cn(
353
+ "inline-flex h-6 shrink-0 items-center justify-center rounded-full px-2.5 text-xs font-medium whitespace-nowrap transition-colors",
354
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none",
355
+ selected ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"
356
+ ),
357
+ children: provider === null ? anyLabel : providerLabels.get(provider) ?? provider
358
+ },
359
+ provider ?? "all-providers"
360
+ );
361
+ })
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx(
365
+ "div",
366
+ {
367
+ ref: listRef,
368
+ id: menuId,
369
+ role: "listbox",
370
+ "aria-label": ariaLabel,
371
+ "aria-activedescendant": activeOptionId,
372
+ tabIndex: -1,
373
+ onKeyDown: handleMenuKeyDown,
374
+ className: "min-h-0 flex-1 overflow-y-auto p-1",
375
+ children: groupedModels.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground px-3 py-4 text-center text-sm", children: emptyLabel }) : groupedRenderedModels.map((group) => /* @__PURE__ */ jsxs(
376
+ "div",
377
+ {
378
+ role: "group",
379
+ "aria-label": providerLabels.get(group.provider) ?? group.provider,
380
+ children: [
381
+ /* @__PURE__ */ jsx("div", { className: "text-muted-foreground px-3 py-1.5 text-xs font-semibold uppercase", children: providerLabels.get(group.provider) ?? group.provider }),
382
+ group.options.map((renderedModel) => {
383
+ const { index, key, option: model } = renderedModel;
384
+ const selected = optionKey(model) === selectedKey;
385
+ const highlighted = index === highlightedIndex;
386
+ return /* @__PURE__ */ jsxs(
387
+ "button",
388
+ {
389
+ id: getOptionId(index),
390
+ type: "button",
391
+ role: "option",
392
+ "aria-selected": selected,
393
+ onMouseDown: (event) => event.preventDefault(),
394
+ onClick: () => selectModel(model),
395
+ onMouseEnter: () => setHighlightedIndex(index),
396
+ className: cn(
397
+ "flex w-full items-center gap-2 rounded-md px-3 py-2 text-start text-sm",
398
+ "focus-visible:ring-ring transition-colors focus-visible:ring-2 focus-visible:outline-none",
399
+ highlighted && "bg-muted",
400
+ selected && "bg-primary/10 text-primary"
401
+ ),
402
+ children: [
403
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: model.label ?? model.model }),
404
+ selected && /* @__PURE__ */ jsx(
405
+ Check$1,
406
+ {
407
+ "aria-hidden": "true",
408
+ className: "text-primary h-4 w-4 shrink-0"
409
+ }
410
+ )
411
+ ]
412
+ },
413
+ key
414
+ );
415
+ })
416
+ ]
417
+ },
418
+ group.provider
419
+ ))
420
+ }
421
+ ),
422
+ efforts.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-border border-t p-1", children: /* @__PURE__ */ jsxs(
423
+ "button",
424
+ {
425
+ type: "button",
426
+ "data-slot": "composer-model-selector-effort-row",
427
+ "aria-haspopup": "listbox",
428
+ onMouseDown: (event) => event.preventDefault(),
429
+ onClick: () => setView("effort"),
430
+ className: cn(
431
+ "flex w-full items-center gap-2 rounded-md px-3 py-2 text-start text-sm",
432
+ "hover:bg-muted transition-colors",
433
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none"
434
+ ),
435
+ children: [
436
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: effortLabel }),
437
+ selectedEffortOption && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground min-w-0 truncate", children: selectedEffortOption.label }),
438
+ /* @__PURE__ */ jsx(
439
+ ChevronRight,
440
+ {
441
+ "aria-hidden": "true",
442
+ className: "text-muted-foreground h-4 w-4 shrink-0 rtl:-scale-x-100"
443
+ }
444
+ )
445
+ ]
446
+ }
447
+ ) })
448
+ ] }),
449
+ view === "effort" && /* @__PURE__ */ jsxs(Fragment, { children: [
450
+ /* @__PURE__ */ jsx("div", { className: "border-border flex items-center gap-1 border-b p-2", children: /* @__PURE__ */ jsxs(
451
+ "button",
452
+ {
453
+ type: "button",
454
+ "data-slot": "composer-model-selector-effort-back",
455
+ "aria-label": backLabel,
456
+ onMouseDown: (event) => event.preventDefault(),
457
+ onClick: () => setView("models"),
458
+ className: cn(
459
+ "inline-flex h-6 shrink-0 items-center gap-1 rounded-full px-2 text-xs font-medium",
460
+ "text-muted-foreground hover:bg-muted hover:text-foreground transition-colors",
461
+ "focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none"
462
+ ),
463
+ children: [
464
+ /* @__PURE__ */ jsx(
465
+ ChevronLeft,
466
+ {
467
+ "aria-hidden": "true",
468
+ className: "h-3.5 w-3.5 rtl:-scale-x-100"
469
+ }
470
+ ),
471
+ effortLabel
472
+ ]
473
+ }
474
+ ) }),
475
+ effortHint && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground px-3 pt-2 text-xs", children: effortHint }),
476
+ /* @__PURE__ */ jsx(
477
+ "div",
478
+ {
479
+ ref: effortListRef,
480
+ id: menuId,
481
+ role: "listbox",
482
+ "aria-label": effortLabel,
483
+ "aria-activedescendant": activeEffortOptionId,
484
+ tabIndex: -1,
485
+ onKeyDown: handleEffortKeyDown,
486
+ className: "min-h-0 flex-1 overflow-y-auto p-1",
487
+ children: efforts.map((option, index) => {
488
+ const selected = option.value === effort;
489
+ const highlighted = index === effortHighlight;
490
+ return /* @__PURE__ */ jsxs(
491
+ "button",
492
+ {
493
+ id: getEffortOptionId(index),
494
+ type: "button",
495
+ role: "option",
496
+ "aria-selected": selected,
497
+ onMouseDown: (event) => event.preventDefault(),
498
+ onClick: () => selectEffort(option.value),
499
+ onMouseEnter: () => setEffortHighlight(index),
500
+ className: cn(
501
+ "flex w-full items-center gap-2 rounded-md px-3 py-2 text-start text-sm",
502
+ "focus-visible:ring-ring transition-colors focus-visible:ring-2 focus-visible:outline-none",
503
+ highlighted && "bg-muted",
504
+ selected && "bg-primary/10 text-primary"
505
+ ),
506
+ children: [
507
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
508
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: option.label }),
509
+ option.description && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground block truncate text-xs", children: option.description })
510
+ ] }),
511
+ option.value === defaultEffort && /* @__PURE__ */ jsx("span", { className: "bg-muted text-muted-foreground shrink-0 rounded px-1.5 py-0.5 text-xs", children: defaultBadgeLabel }),
512
+ selected && /* @__PURE__ */ jsx(
513
+ Check$1,
514
+ {
515
+ "aria-hidden": "true",
516
+ className: "text-primary h-4 w-4 shrink-0"
517
+ }
518
+ )
519
+ ]
520
+ },
521
+ option.value
522
+ );
523
+ })
524
+ }
525
+ )
526
+ ] })
527
+ ]
528
+ }
529
+ ),
530
+ document.body
531
+ )
532
+ ] });
533
+ }
534
+ ComposerModelSelector.displayName = "ComposerModelSelector";
535
+ function getFileType(mimeType) {
536
+ if (mimeType.startsWith("image/")) return "image";
537
+ if (mimeType.startsWith("video/")) return "video";
538
+ if (mimeType.startsWith("audio/")) return "audio";
539
+ if (mimeType.includes("pdf") || mimeType.includes("document") || mimeType.includes("text")) {
540
+ return "document";
541
+ }
542
+ return "file";
543
+ }
544
+ function formatFileSize(bytes) {
545
+ if (bytes < 1024) return `${bytes} B`;
546
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
547
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
548
+ }
549
+ function validateFile(file, acceptedTypes, maxSize) {
550
+ if (acceptedTypes && acceptedTypes.length > 0) {
551
+ const isAccepted = acceptedTypes.some((type) => {
552
+ if (type.startsWith(".")) {
553
+ return file.name.toLowerCase().endsWith(type.toLowerCase());
554
+ }
555
+ if (type.endsWith("/*")) {
556
+ return file.type.startsWith(type.replace("/*", "/"));
557
+ }
558
+ return file.type === type;
559
+ });
560
+ if (!isAccepted) {
561
+ return { valid: false, error: "File type not supported" };
562
+ }
563
+ }
564
+ if (maxSize && file.size > maxSize) {
565
+ return {
566
+ valid: false,
567
+ error: `File too large (max ${formatFileSize(maxSize)})`
568
+ };
569
+ }
570
+ return { valid: true };
571
+ }
572
+ function generateAttachmentId() {
573
+ return `attachment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
574
+ }
575
+ var DEFAULT_ACCEPTED_FILE_TYPES = [
576
+ "image/*",
577
+ "video/*",
578
+ ".pdf",
579
+ ".doc",
580
+ ".docx"
581
+ ];
582
+ var DEFAULT_MAX_FILE_SIZE = 25 * 1024 * 1024;
583
+ function AttachmentPreviewItem({
584
+ attachment,
585
+ onRemove,
586
+ onRetry,
587
+ disabled = false,
588
+ className
589
+ }) {
590
+ const { file, previewUrl, type, state, progress } = attachment;
591
+ const isImage = type === "image";
592
+ const isVideo = type === "video";
593
+ const isUploading = state === "uploading";
594
+ const isFailed = state === "failed";
595
+ return /* @__PURE__ */ jsxs(
596
+ "div",
597
+ {
598
+ className: cn(
599
+ "group relative overflow-hidden rounded-lg",
600
+ "bg-neutral-100 dark:bg-neutral-800",
601
+ "border border-neutral-200 dark:border-neutral-700",
602
+ isFailed && "border-red-500",
603
+ className
604
+ ),
605
+ children: [
606
+ (isImage || isVideo) && previewUrl ? /* @__PURE__ */ jsxs("div", { className: "relative h-20 w-20", children: [
607
+ isVideo ? /* @__PURE__ */ jsx(
608
+ "video",
609
+ {
610
+ src: previewUrl,
611
+ "aria-label": file.name,
612
+ muted: true,
613
+ playsInline: true,
614
+ preload: "metadata",
615
+ className: cn(
616
+ "h-full w-full object-cover",
617
+ (isUploading || isFailed) && "opacity-50"
618
+ )
619
+ }
620
+ ) : /* @__PURE__ */ jsx(
621
+ "img",
622
+ {
623
+ src: previewUrl,
624
+ alt: file.name,
625
+ className: cn(
626
+ "h-full w-full object-cover",
627
+ (isUploading || isFailed) && "opacity-50"
628
+ )
629
+ }
630
+ ),
631
+ isVideo && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
632
+ "svg",
633
+ {
634
+ "aria-hidden": "true",
635
+ className: "h-6 w-6 text-white drop-shadow",
636
+ fill: "currentColor",
637
+ viewBox: "0 0 24 24",
638
+ children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" })
639
+ }
640
+ ) })
641
+ ] }) : (
642
+ /* File preview */
643
+ /* @__PURE__ */ jsxs("div", { className: "flex h-20 w-20 flex-col items-center justify-center p-2", children: [
644
+ /* @__PURE__ */ jsx(
645
+ "svg",
646
+ {
647
+ "aria-hidden": "true",
648
+ className: "h-8 w-8 text-neutral-500",
649
+ fill: "none",
650
+ viewBox: "0 0 24 24",
651
+ stroke: "currentColor",
652
+ children: /* @__PURE__ */ jsx(
653
+ "path",
654
+ {
655
+ strokeLinecap: "round",
656
+ strokeLinejoin: "round",
657
+ strokeWidth: 2,
658
+ d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
659
+ }
660
+ )
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsx("span", { className: "mt-1 max-w-full truncate px-1 text-xs text-neutral-600 dark:text-neutral-400", children: file.name.split(".").pop()?.toUpperCase() })
664
+ ] })
665
+ ),
666
+ isUploading && progress !== void 0 && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxs("div", { className: "text-center text-white", children: [
667
+ /* @__PURE__ */ jsxs(
668
+ "svg",
669
+ {
670
+ "aria-hidden": "true",
671
+ className: "mx-auto h-6 w-6 animate-spin",
672
+ fill: "none",
673
+ viewBox: "0 0 24 24",
674
+ children: [
675
+ /* @__PURE__ */ jsx(
676
+ "circle",
677
+ {
678
+ className: "opacity-25",
679
+ cx: "12",
680
+ cy: "12",
681
+ r: "10",
682
+ stroke: "currentColor",
683
+ strokeWidth: "4"
684
+ }
685
+ ),
686
+ /* @__PURE__ */ jsx(
687
+ "path",
688
+ {
689
+ className: "opacity-75",
690
+ fill: "currentColor",
691
+ d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
692
+ }
693
+ )
694
+ ]
695
+ }
696
+ ),
697
+ /* @__PURE__ */ jsxs("span", { className: "mt-1 text-xs", children: [
698
+ progress,
699
+ "%"
700
+ ] })
701
+ ] }) }),
702
+ isFailed && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
703
+ /* @__PURE__ */ jsx(
704
+ "svg",
705
+ {
706
+ "aria-hidden": "true",
707
+ className: "mx-auto h-6 w-6 text-red-400",
708
+ fill: "none",
709
+ viewBox: "0 0 24 24",
710
+ stroke: "currentColor",
711
+ children: /* @__PURE__ */ jsx(
712
+ "path",
713
+ {
714
+ strokeLinecap: "round",
715
+ strokeLinejoin: "round",
716
+ strokeWidth: 2,
717
+ d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
718
+ }
719
+ )
720
+ }
721
+ ),
722
+ onRetry && /* @__PURE__ */ jsx(
723
+ "button",
724
+ {
725
+ type: "button",
726
+ onClick: onRetry,
727
+ disabled,
728
+ className: "mt-1 text-xs text-white underline hover:no-underline disabled:no-underline disabled:opacity-50",
729
+ children: "Retry"
730
+ }
731
+ )
732
+ ] }) }),
733
+ /* @__PURE__ */ jsx(
734
+ "button",
735
+ {
736
+ type: "button",
737
+ onClick: onRemove,
738
+ disabled,
739
+ className: cn(
740
+ "absolute -end-1 -top-1 z-10",
741
+ "rounded-full p-1",
742
+ "bg-neutral-900 text-white",
743
+ "opacity-0 group-hover:opacity-100",
744
+ "focus:ring-primary-500 focus:opacity-100 focus:ring-2 focus:outline-none",
745
+ "transition-opacity",
746
+ "disabled:cursor-not-allowed disabled:group-hover:opacity-0"
747
+ ),
748
+ "aria-label": `Remove ${file.name}`,
749
+ children: /* @__PURE__ */ jsx(
750
+ "svg",
751
+ {
752
+ "aria-hidden": "true",
753
+ className: "h-3 w-3",
754
+ fill: "none",
755
+ viewBox: "0 0 24 24",
756
+ stroke: "currentColor",
757
+ children: /* @__PURE__ */ jsx(
758
+ "path",
759
+ {
760
+ strokeLinecap: "round",
761
+ strokeLinejoin: "round",
762
+ strokeWidth: 2,
763
+ d: "M6 18L18 6M6 6l12 12"
764
+ }
765
+ )
766
+ }
767
+ )
768
+ }
769
+ ),
770
+ /* @__PURE__ */ jsx(
771
+ "div",
772
+ {
773
+ className: cn(
774
+ "absolute start-0 end-0 bottom-0",
775
+ "bg-black/70 px-1 py-0.5",
776
+ "opacity-0 group-hover:opacity-100",
777
+ "transition-opacity"
778
+ ),
779
+ children: /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-white", children: file.name })
780
+ }
781
+ )
782
+ ]
783
+ }
784
+ );
785
+ }
786
+ AttachmentPreviewItem.displayName = "AttachmentPreviewItem";
787
+ var AttachmentPicker = React.forwardRef(
788
+ ({
789
+ onFilesSelected,
790
+ acceptedTypes = DEFAULT_ACCEPTED_FILE_TYPES,
791
+ maxFileSize = DEFAULT_MAX_FILE_SIZE,
792
+ maxFiles = 10,
793
+ multiple = true,
794
+ disabled = false,
795
+ onError,
796
+ className,
797
+ children
798
+ }, ref) => {
799
+ const inputRef = React.useRef(null);
800
+ React.useImperativeHandle(ref, () => inputRef.current);
801
+ const handleClick = () => {
802
+ inputRef.current?.click();
803
+ };
804
+ const handleChange = (event) => {
805
+ const files = Array.from(event.target.files || []);
806
+ if (files.length === 0) return;
807
+ const validFiles = [];
808
+ for (const file of files.slice(0, maxFiles)) {
809
+ const validation = validateFile(file, acceptedTypes, maxFileSize);
810
+ if (validation.valid) {
811
+ validFiles.push(file);
812
+ } else if (onError) {
813
+ onError(`${file.name}: ${validation.error}`);
814
+ }
815
+ }
816
+ if (files.length > maxFiles && onError) {
817
+ onError(`Maximum ${maxFiles} files allowed`);
818
+ }
819
+ if (validFiles.length > 0) {
820
+ onFilesSelected(validFiles);
821
+ }
822
+ event.target.value = "";
823
+ };
824
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
825
+ /* @__PURE__ */ jsx(
826
+ "input",
827
+ {
828
+ ref: inputRef,
829
+ type: "file",
830
+ accept: acceptedTypes.join(","),
831
+ multiple,
832
+ onChange: handleChange,
833
+ disabled,
834
+ className: "sr-only",
835
+ "aria-label": "Select files to attach"
836
+ }
837
+ ),
838
+ /* @__PURE__ */ jsx(
839
+ "button",
840
+ {
841
+ type: "button",
842
+ onClick: handleClick,
843
+ disabled,
844
+ "data-slot": "attachment-picker-button",
845
+ className: cn(
846
+ "inline-flex items-center justify-center",
847
+ "rounded-full p-2",
848
+ "text-neutral-500 hover:text-neutral-700",
849
+ "dark:text-neutral-400 dark:hover:text-neutral-200",
850
+ "hover:bg-neutral-100 dark:hover:bg-neutral-800",
851
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none",
852
+ "disabled:cursor-not-allowed disabled:opacity-50",
853
+ "transition-colors",
854
+ className
855
+ ),
856
+ "aria-label": "Attach files",
857
+ children: children || /* @__PURE__ */ jsx(
858
+ "svg",
859
+ {
860
+ "aria-hidden": "true",
861
+ className: "h-5 w-5",
862
+ fill: "none",
863
+ viewBox: "0 0 24 24",
864
+ stroke: "currentColor",
865
+ children: /* @__PURE__ */ jsx(
866
+ "path",
867
+ {
868
+ strokeLinecap: "round",
869
+ strokeLinejoin: "round",
870
+ strokeWidth: 2,
871
+ d: "M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"
872
+ }
873
+ )
874
+ }
875
+ )
876
+ }
877
+ )
878
+ ] });
879
+ }
880
+ );
881
+ AttachmentPicker.displayName = "AttachmentPicker";
882
+ function DragDropZone({
883
+ onFilesDropped,
884
+ acceptedTypes,
885
+ maxFileSize,
886
+ maxFiles = 10,
887
+ disabled = false,
888
+ onError,
889
+ overlayLabel = "Drop files here",
890
+ children,
891
+ className
892
+ }) {
893
+ const [isDragging, setIsDragging] = React.useState(false);
894
+ const dragCounterRef = React.useRef(0);
895
+ const handleDragEnter = (event) => {
896
+ event.preventDefault();
897
+ event.stopPropagation();
898
+ if (disabled) return;
899
+ dragCounterRef.current++;
900
+ if (event.dataTransfer.items && event.dataTransfer.items.length > 0) {
901
+ setIsDragging(true);
902
+ }
903
+ };
904
+ const handleDragLeave = (event) => {
905
+ event.preventDefault();
906
+ event.stopPropagation();
907
+ if (disabled) return;
908
+ dragCounterRef.current--;
909
+ if (dragCounterRef.current === 0) {
910
+ setIsDragging(false);
911
+ }
912
+ };
913
+ const handleDragOver = (event) => {
914
+ event.preventDefault();
915
+ event.stopPropagation();
916
+ };
917
+ const handleDrop = (event) => {
918
+ event.preventDefault();
919
+ event.stopPropagation();
920
+ if (disabled) return;
921
+ setIsDragging(false);
922
+ dragCounterRef.current = 0;
923
+ const files = Array.from(event.dataTransfer.files);
924
+ if (files.length === 0) return;
925
+ const validFiles = [];
926
+ for (const file of files.slice(0, maxFiles)) {
927
+ const validation = validateFile(file, acceptedTypes, maxFileSize);
928
+ if (validation.valid) {
929
+ validFiles.push(file);
930
+ } else if (onError) {
931
+ onError(`${file.name}: ${validation.error}`);
932
+ }
933
+ }
934
+ if (files.length > maxFiles && onError) {
935
+ onError(`Maximum ${maxFiles} files allowed`);
936
+ }
937
+ if (validFiles.length > 0) {
938
+ onFilesDropped(validFiles);
939
+ }
940
+ };
941
+ return /* @__PURE__ */ jsxs(
942
+ "div",
943
+ {
944
+ onDragEnter: handleDragEnter,
945
+ onDragLeave: handleDragLeave,
946
+ onDragOver: handleDragOver,
947
+ onDrop: handleDrop,
948
+ className: cn("relative", className),
949
+ children: [
950
+ children,
951
+ isDragging && /* @__PURE__ */ jsx(
952
+ "div",
953
+ {
954
+ className: cn(
955
+ "absolute inset-0 z-50",
956
+ "flex items-center justify-center",
957
+ "bg-primary-50/90 dark:bg-primary-900/90",
958
+ "border-primary-500 border-2 border-dashed",
959
+ "rounded-lg"
960
+ ),
961
+ children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
962
+ /* @__PURE__ */ jsx(
963
+ "svg",
964
+ {
965
+ "aria-hidden": "true",
966
+ className: "text-primary-800 mx-auto h-12 w-12",
967
+ fill: "none",
968
+ viewBox: "0 0 24 24",
969
+ stroke: "currentColor",
970
+ children: /* @__PURE__ */ jsx(
971
+ "path",
972
+ {
973
+ strokeLinecap: "round",
974
+ strokeLinejoin: "round",
975
+ strokeWidth: 2,
976
+ d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
977
+ }
978
+ )
979
+ }
980
+ ),
981
+ /* @__PURE__ */ jsx("p", { className: "text-primary-700 dark:text-primary-300 mt-2 text-sm font-medium", children: overlayLabel })
982
+ ] })
983
+ }
984
+ )
985
+ ]
986
+ }
987
+ );
988
+ }
989
+ DragDropZone.displayName = "DragDropZone";
990
+ function CameraButton({
991
+ onCapture,
992
+ useFrontCamera = false,
993
+ disabled = false,
994
+ className
995
+ }) {
996
+ const inputRef = React.useRef(null);
997
+ const handleClick = () => {
998
+ inputRef.current?.click();
999
+ };
1000
+ const handleChange = (event) => {
1001
+ const file = event.target.files?.[0];
1002
+ if (file) {
1003
+ onCapture(file);
1004
+ }
1005
+ event.target.value = "";
1006
+ };
1007
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1008
+ /* @__PURE__ */ jsx(
1009
+ "input",
1010
+ {
1011
+ ref: inputRef,
1012
+ type: "file",
1013
+ accept: "image/*",
1014
+ capture: useFrontCamera ? "user" : "environment",
1015
+ onChange: handleChange,
1016
+ disabled,
1017
+ className: "sr-only",
1018
+ "aria-label": "Take a photo"
1019
+ }
1020
+ ),
1021
+ /* @__PURE__ */ jsx(
1022
+ "button",
1023
+ {
1024
+ type: "button",
1025
+ onClick: handleClick,
1026
+ disabled,
1027
+ className: cn(
1028
+ "inline-flex items-center justify-center",
1029
+ "rounded-full p-2",
1030
+ "text-neutral-500 hover:text-neutral-700",
1031
+ "dark:text-neutral-400 dark:hover:text-neutral-200",
1032
+ "hover:bg-neutral-100 dark:hover:bg-neutral-800",
1033
+ "focus:ring-primary-500 focus:ring-2 focus:outline-none",
1034
+ "disabled:cursor-not-allowed disabled:opacity-50",
1035
+ "transition-colors",
1036
+ className
1037
+ ),
1038
+ "aria-label": "Take a photo",
1039
+ children: /* @__PURE__ */ jsxs(
1040
+ "svg",
1041
+ {
1042
+ "aria-hidden": "true",
1043
+ className: "h-5 w-5",
1044
+ fill: "none",
1045
+ viewBox: "0 0 24 24",
1046
+ stroke: "currentColor",
1047
+ children: [
1048
+ /* @__PURE__ */ jsx(
1049
+ "path",
1050
+ {
1051
+ strokeLinecap: "round",
1052
+ strokeLinejoin: "round",
1053
+ strokeWidth: 2,
1054
+ d: "M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"
1055
+ }
1056
+ ),
1057
+ /* @__PURE__ */ jsx(
1058
+ "path",
1059
+ {
1060
+ strokeLinecap: "round",
1061
+ strokeLinejoin: "round",
1062
+ strokeWidth: 2,
1063
+ d: "M15 13a3 3 0 11-6 0 3 3 0 016 0z"
1064
+ }
1065
+ )
1066
+ ]
1067
+ }
1068
+ )
1069
+ }
1070
+ )
1071
+ ] });
1072
+ }
1073
+ CameraButton.displayName = "CameraButton";
1074
+ function activeMentionQuery(value, caret) {
1075
+ const upToCaret = value.slice(0, caret);
1076
+ const match = /(^|\s)@([^\s@]*)$/.exec(upToCaret);
1077
+ if (!match) return null;
1078
+ const query = match[2];
1079
+ return { query, start: caret - query.length - 1 };
1080
+ }
1081
+ function useMentionAutocomplete({
1082
+ options,
1083
+ value,
1084
+ setValue,
1085
+ textareaRef
1086
+ }) {
1087
+ const enabled = !!options && options.length > 0;
1088
+ const [mention, setMention] = React.useState(null);
1089
+ const [highlight, setHighlight] = React.useState(0);
1090
+ const listId = React.useId();
1091
+ const optionId = React.useCallback(
1092
+ (index) => `${listId}-option-${index}`,
1093
+ [listId]
1094
+ );
1095
+ const suggestions = React.useMemo(() => {
1096
+ if (!mention || !options) return [];
1097
+ const q = mention.query.toLowerCase();
1098
+ return options.filter((o) => o.label.toLowerCase().includes(q));
1099
+ }, [mention, options]);
1100
+ const menuOpen = enabled && mention !== null && suggestions.length > 0;
1101
+ const {
1102
+ anchorRef,
1103
+ floatingRef,
1104
+ style: menuStyle
1105
+ } = useAnchoredPosition({
1106
+ open: menuOpen,
1107
+ placement: "top-start",
1108
+ maxHeight: 224
1109
+ });
1110
+ const clampedHighlight = menuOpen ? Math.min(highlight, suggestions.length - 1) : -1;
1111
+ const activeOptionId = menuOpen ? optionId(clampedHighlight) : void 0;
1112
+ const sync = React.useCallback(
1113
+ (nextValue, caret) => {
1114
+ if (!enabled) return;
1115
+ setMention(activeMentionQuery(nextValue, caret));
1116
+ setHighlight(0);
1117
+ },
1118
+ [enabled]
1119
+ );
1120
+ const insert = (option) => {
1121
+ if (!mention) return;
1122
+ const insertValue = option.value ?? option.label.split(" ")[0];
1123
+ const before = value.slice(0, mention.start);
1124
+ const after = value.slice(mention.start + 1 + mention.query.length);
1125
+ const insertText = `@${insertValue} `;
1126
+ setValue(before + insertText + after);
1127
+ setMention(null);
1128
+ const caret = before.length + insertText.length;
1129
+ requestAnimationFrame(() => {
1130
+ const el = textareaRef.current;
1131
+ if (el) {
1132
+ el.focus();
1133
+ el.setSelectionRange(caret, caret);
1134
+ }
1135
+ });
1136
+ };
1137
+ const handleKeyDown = (event) => {
1138
+ if (!menuOpen) return false;
1139
+ if (event.key === "ArrowDown") {
1140
+ event.preventDefault();
1141
+ setHighlight(
1142
+ (h) => (Math.min(h, suggestions.length - 1) + 1) % suggestions.length
1143
+ );
1144
+ return true;
1145
+ }
1146
+ if (event.key === "ArrowUp") {
1147
+ event.preventDefault();
1148
+ setHighlight(
1149
+ (h) => (Math.min(h, suggestions.length - 1) - 1 + suggestions.length) % suggestions.length
1150
+ );
1151
+ return true;
1152
+ }
1153
+ if (event.key === "Enter" || event.key === "Tab") {
1154
+ event.preventDefault();
1155
+ const chosen = suggestions[clampedHighlight];
1156
+ if (chosen) insert(chosen);
1157
+ return true;
1158
+ }
1159
+ if (event.key === "Escape") {
1160
+ event.preventDefault();
1161
+ setMention(null);
1162
+ return true;
1163
+ }
1164
+ return false;
1165
+ };
1166
+ const inputProps = enabled ? {
1167
+ "aria-controls": menuOpen ? listId : void 0,
1168
+ "aria-activedescendant": activeOptionId,
1169
+ "aria-autocomplete": "list"
1170
+ } : {};
1171
+ return {
1172
+ enabled,
1173
+ menuOpen,
1174
+ suggestions,
1175
+ highlight: clampedHighlight,
1176
+ listId,
1177
+ optionId,
1178
+ anchorRef,
1179
+ floatingRef,
1180
+ menuStyle,
1181
+ sync,
1182
+ insert,
1183
+ setHighlight,
1184
+ handleKeyDown,
1185
+ inputProps
1186
+ };
1187
+ }
1188
+ function MentionMenu({
1189
+ mention,
1190
+ label = "Mention",
1191
+ dataSlot = "composer-mention-list"
1192
+ }) {
1193
+ if (!mention.menuOpen) return null;
1194
+ return createPortal(
1195
+ /* @__PURE__ */ jsx(
1196
+ "ul",
1197
+ {
1198
+ ref: mention.floatingRef,
1199
+ style: mention.menuStyle,
1200
+ id: mention.listId,
1201
+ role: "listbox",
1202
+ "aria-label": label,
1203
+ "data-slot": dataSlot,
1204
+ className: "w-64 overflow-y-auto rounded-lg border border-neutral-200 bg-white py-1 shadow-lg dark:border-neutral-700 dark:bg-neutral-800",
1205
+ children: mention.suggestions.map((option, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
1206
+ "button",
1207
+ {
1208
+ type: "button",
1209
+ id: mention.optionId(i),
1210
+ role: "option",
1211
+ "aria-selected": i === mention.highlight,
1212
+ onMouseDown: (e) => {
1213
+ e.preventDefault();
1214
+ mention.insert(option);
1215
+ },
1216
+ onMouseEnter: () => mention.setHighlight(i),
1217
+ className: cn(
1218
+ "flex w-full items-center gap-2 px-3 py-1.5 text-start text-sm",
1219
+ i === mention.highlight ? "bg-primary-100 text-primary-900 dark:bg-primary-900/40 dark:text-primary-100" : "text-neutral-700 dark:text-neutral-200"
1220
+ ),
1221
+ children: [
1222
+ option.icon,
1223
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate", children: [
1224
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: option.label }),
1225
+ option.description && /* @__PURE__ */ jsx("span", { className: "ms-1 text-xs text-neutral-400", children: option.description })
1226
+ ] }),
1227
+ option.meta && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-400", children: option.meta })
1228
+ ]
1229
+ }
1230
+ ) }, option.id))
1231
+ }
1232
+ ),
1233
+ document.body
1234
+ );
1235
+ }
1236
+ MentionMenu.displayName = "MentionMenu";
1237
+ var iconButtonClasses = cn(
1238
+ "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg",
1239
+ "text-neutral-500 dark:text-neutral-400",
1240
+ "transition-colors duration-150",
1241
+ "hover:bg-neutral-100 hover:text-neutral-900 dark:hover:bg-neutral-700 dark:hover:text-white",
1242
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500",
1243
+ "disabled:pointer-events-none disabled:opacity-40"
1244
+ );
1245
+ var selectorTriggerClasses = cn(
1246
+ "flex min-w-0 items-center gap-1 rounded-md px-2 py-1 text-xs",
1247
+ "text-neutral-600 dark:text-neutral-400",
1248
+ "transition-colors duration-150",
1249
+ "hover:bg-neutral-100 hover:text-neutral-900 dark:hover:bg-neutral-700 dark:hover:text-white",
1250
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-500",
1251
+ "disabled:pointer-events-none disabled:opacity-40"
1252
+ );
1253
+ var MAX_INPUT_HEIGHT = 160;
1254
+ var ChatComposer = React.forwardRef(function ChatComposer2({
1255
+ onSend,
1256
+ value: controlledValue,
1257
+ onValueChange,
1258
+ placeholder = "Type a message\u2026",
1259
+ disabled = false,
1260
+ isSending = false,
1261
+ autoFocus = false,
1262
+ maxLength,
1263
+ showCharacterCount = false,
1264
+ canSendWhenEmpty = false,
1265
+ maxHeight = MAX_INPUT_HEIGHT,
1266
+ textareaProps,
1267
+ addMenuItems,
1268
+ allowAttachments = true,
1269
+ acceptedFileTypes,
1270
+ maxFileSize,
1271
+ maxAttachments = 10,
1272
+ mentionOptions,
1273
+ replyTo = null,
1274
+ onCancelReply,
1275
+ showMic = false,
1276
+ onMicClick,
1277
+ micSlot,
1278
+ micBehavior = "always",
1279
+ isStreaming = false,
1280
+ onStop,
1281
+ showAgentSelector = false,
1282
+ agents = [],
1283
+ selectedAgent = null,
1284
+ onAgentChange,
1285
+ showModelSelector = false,
1286
+ modelSelectorProps,
1287
+ readOnly = false,
1288
+ readOnlyMessage = "You have read-only access and cannot send messages.",
1289
+ onError,
1290
+ attachmentLimitLabel,
1291
+ sendFailedLabel = "Failed to send message",
1292
+ sendingLabel = "Sending message\u2026",
1293
+ inputLabel = "Message input",
1294
+ addMenuLabel = "Add to message",
1295
+ attachFilesLabel = "Attach files",
1296
+ micLabel = "Start voice input",
1297
+ sendLabel = "Send message",
1298
+ stopLabel = "Stop generating",
1299
+ agentSelectorLabel = "Select agent",
1300
+ mentionListLabel = "Mention",
1301
+ dropFilesLabel = "Drop files here",
1302
+ replyingToLabel = "Replying to",
1303
+ cancelReplyLabel = "Cancel reply",
1304
+ className
1305
+ }, ref) {
1306
+ const [internalValue, setInternalValue] = React.useState("");
1307
+ const isControlled = controlledValue !== void 0;
1308
+ const value = isControlled ? controlledValue : internalValue;
1309
+ const [attachments, setAttachments] = React.useState([]);
1310
+ const attachmentsRef = React.useRef(attachments);
1311
+ attachmentsRef.current = attachments;
1312
+ const textareaRef = React.useRef(null);
1313
+ const fileInputRef = React.useRef(null);
1314
+ const [addMenuOpen, setAddMenuOpen] = React.useState(false);
1315
+ const [agentMenuOpen, setAgentMenuOpen] = React.useState(false);
1316
+ const replyToId = replyTo?.id;
1317
+ React.useEffect(() => {
1318
+ if (replyToId !== void 0) {
1319
+ textareaRef.current?.focus();
1320
+ }
1321
+ }, [replyToId]);
1322
+ const hasText = value.trim().length > 0;
1323
+ const hasContent = hasText || attachments.length > 0;
1324
+ const isOverLimit = maxLength !== void 0 && value.length > maxLength;
1325
+ const canSend = (hasContent || canSendWhenEmpty) && onSend !== void 0 && !disabled && !isSending && !isStreaming && !isOverLimit;
1326
+ const setValue = React.useCallback(
1327
+ (next) => {
1328
+ if (!isControlled) setInternalValue(next);
1329
+ onValueChange?.(next);
1330
+ },
1331
+ [isControlled, onValueChange]
1332
+ );
1333
+ const mention = useMentionAutocomplete({
1334
+ options: mentionOptions,
1335
+ value,
1336
+ setValue,
1337
+ textareaRef
1338
+ });
1339
+ const resizeTextarea = React.useCallback(() => {
1340
+ const textarea = textareaRef.current;
1341
+ if (!textarea) return;
1342
+ textarea.style.height = "auto";
1343
+ if (textarea.scrollHeight === 0) return;
1344
+ textarea.style.height = `${textarea.scrollHeight}px`;
1345
+ }, []);
1346
+ React.useLayoutEffect(resizeTextarea, [resizeTextarea, value]);
1347
+ React.useEffect(() => {
1348
+ const textarea = textareaRef.current;
1349
+ if (!textarea || typeof ResizeObserver === "undefined") return;
1350
+ let frame = 0;
1351
+ const observer = new ResizeObserver(() => {
1352
+ cancelAnimationFrame(frame);
1353
+ frame = requestAnimationFrame(resizeTextarea);
1354
+ });
1355
+ observer.observe(textarea);
1356
+ return () => {
1357
+ cancelAnimationFrame(frame);
1358
+ observer.disconnect();
1359
+ };
1360
+ }, [resizeTextarea]);
1361
+ const addFiles = React.useCallback(
1362
+ (files) => {
1363
+ if (files.length === 0) return;
1364
+ const limitMessage = attachmentLimitLabel ?? `Attachment limit reached (max ${maxAttachments})`;
1365
+ const room = maxAttachments - attachmentsRef.current.length;
1366
+ if (files.length > room) {
1367
+ onError?.(limitMessage, { reason: "attachment-limit" });
1368
+ if (room <= 0) return;
1369
+ }
1370
+ const staged = [];
1371
+ for (const file of files.slice(0, Math.max(room, 0))) {
1372
+ const typeCheck = validateFile(file, acceptedFileTypes, void 0);
1373
+ if (!typeCheck.valid) {
1374
+ onError?.(`${file.name}: ${typeCheck.error}`, {
1375
+ reason: "file-type",
1376
+ file
1377
+ });
1378
+ continue;
1379
+ }
1380
+ const sizeCheck = validateFile(file, void 0, maxFileSize);
1381
+ if (!sizeCheck.valid) {
1382
+ onError?.(`${file.name}: ${sizeCheck.error}`, {
1383
+ reason: "file-size",
1384
+ file
1385
+ });
1386
+ continue;
1387
+ }
1388
+ const type = getFileType(file.type);
1389
+ staged.push({
1390
+ id: generateAttachmentId(),
1391
+ file,
1392
+ type,
1393
+ previewUrl: type === "image" || type === "video" ? URL.createObjectURL(file) : void 0
1394
+ });
1395
+ }
1396
+ if (staged.length > 0) {
1397
+ attachmentsRef.current = [...attachmentsRef.current, ...staged];
1398
+ setAttachments((current) => [...current, ...staged]);
1399
+ }
1400
+ },
1401
+ [
1402
+ maxAttachments,
1403
+ acceptedFileTypes,
1404
+ maxFileSize,
1405
+ onError,
1406
+ attachmentLimitLabel
1407
+ ]
1408
+ );
1409
+ const removeAttachment = React.useCallback((id) => {
1410
+ const target = attachmentsRef.current.find(
1411
+ (attachment) => attachment.id === id
1412
+ );
1413
+ if (target?.previewUrl) URL.revokeObjectURL(target.previewUrl);
1414
+ attachmentsRef.current = attachmentsRef.current.filter(
1415
+ (attachment) => attachment.id !== id
1416
+ );
1417
+ setAttachments(
1418
+ (current) => current.filter((attachment) => attachment.id !== id)
1419
+ );
1420
+ }, []);
1421
+ React.useEffect(() => {
1422
+ return () => {
1423
+ for (const attachment of attachmentsRef.current) {
1424
+ if (attachment.previewUrl) URL.revokeObjectURL(attachment.previewUrl);
1425
+ }
1426
+ };
1427
+ }, []);
1428
+ const handleFileInputChange = (event) => {
1429
+ const files = Array.from(event.target.files ?? []);
1430
+ addFiles(files);
1431
+ event.target.value = "";
1432
+ };
1433
+ const handlePaste = (event) => {
1434
+ if (!allowAttachments) return;
1435
+ const files = Array.from(event.clipboardData.files);
1436
+ if (files.length > 0) {
1437
+ event.preventDefault();
1438
+ addFiles(files);
1439
+ }
1440
+ };
1441
+ React.useImperativeHandle(
1442
+ ref,
1443
+ () => ({
1444
+ addFiles,
1445
+ focus: () => textareaRef.current?.focus(),
1446
+ getTextarea: () => textareaRef.current
1447
+ }),
1448
+ [addFiles]
1449
+ );
1450
+ const handleSend = () => {
1451
+ if (!canSend || !onSend) return;
1452
+ const message = {
1453
+ content: value.trim(),
1454
+ attachments: attachments.map((attachment) => attachment.file),
1455
+ // Only add the key when replying — hosts may key-check the payload.
1456
+ ...replyTo ? { replyToId: replyTo.id } : {}
1457
+ };
1458
+ for (const attachment of attachments) {
1459
+ if (attachment.previewUrl) URL.revokeObjectURL(attachment.previewUrl);
1460
+ }
1461
+ attachmentsRef.current = [];
1462
+ setAttachments([]);
1463
+ setValue("");
1464
+ try {
1465
+ Promise.resolve(onSend(message)).catch(() => {
1466
+ onError?.(sendFailedLabel, { reason: "send-failed" });
1467
+ });
1468
+ } catch {
1469
+ onError?.(sendFailedLabel, { reason: "send-failed" });
1470
+ }
1471
+ textareaRef.current?.focus();
1472
+ };
1473
+ const handleKeyDown = (event) => {
1474
+ if (mention.handleKeyDown(event)) return;
1475
+ if (event.key === "Enter" && !event.shiftKey) {
1476
+ event.preventDefault();
1477
+ handleSend();
1478
+ }
1479
+ };
1480
+ if (readOnly) {
1481
+ return /* @__PURE__ */ jsxs(
1482
+ "div",
1483
+ {
1484
+ "data-slot": "chat-composer",
1485
+ role: "status",
1486
+ className: cn(
1487
+ "flex items-center gap-2 rounded-xl border px-4 py-3 text-sm",
1488
+ "border-amber-300 bg-amber-50 text-amber-900",
1489
+ "dark:border-amber-700 dark:bg-amber-950 dark:text-amber-200",
1490
+ className
1491
+ ),
1492
+ children: [
1493
+ /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
1494
+ /* @__PURE__ */ jsx("span", { "data-slot": "chat-composer-readonly", children: readOnlyMessage })
1495
+ ]
1496
+ }
1497
+ );
1498
+ }
1499
+ const showAddMenu = allowAttachments || addMenuItems && addMenuItems.length > 0;
1500
+ const micVisible = (showMic || onMicClick !== void 0 || micSlot !== void 0) && (micBehavior === "always" || !hasContent);
1501
+ const showSelectorRow = showAgentSelector || showModelSelector;
1502
+ const selectedAgentOption = agents.find((agent) => agent.id === selectedAgent) ?? null;
1503
+ const cells = {
1504
+ input: "col-span-3 col-start-1 row-start-1 px-1 pt-1 md:col-span-1 md:col-start-2 md:self-end md:px-0 md:py-1.5",
1505
+ textarea: "px-2 pt-2 pb-1 md:py-1.5",
1506
+ add: "col-start-1 row-start-2 pb-2 ps-2 md:row-start-1 md:self-end md:p-1.5 md:pe-0.5",
1507
+ actions: "col-start-3 row-start-2 flex items-center gap-1 pb-2 pe-2 md:row-start-1 md:self-end md:gap-0.5 md:p-1.5 md:ps-0.5"
1508
+ };
1509
+ const composerCard = /* @__PURE__ */ jsxs(Fragment, { children: [
1510
+ replyTo && /* @__PURE__ */ jsxs(
1511
+ "div",
1512
+ {
1513
+ "data-slot": "chat-composer-reply-preview",
1514
+ className: cn(
1515
+ "flex items-center gap-2 rounded-t-2xl px-4 py-2",
1516
+ "bg-neutral-50 dark:bg-neutral-800/50",
1517
+ "border-b border-neutral-200 dark:border-neutral-700",
1518
+ "border-s-primary-500 border-s-4"
1519
+ ),
1520
+ children: [
1521
+ /* @__PURE__ */ jsxs("div", { role: "status", className: "min-w-0 flex-1", children: [
1522
+ /* @__PURE__ */ jsxs("span", { className: "text-primary-800 dark:text-primary-400 block text-xs font-medium", children: [
1523
+ replyingToLabel,
1524
+ " ",
1525
+ replyTo.senderName
1526
+ ] }),
1527
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm text-neutral-600 dark:text-neutral-300", children: replyTo.content })
1528
+ ] }),
1529
+ /* @__PURE__ */ jsx(
1530
+ "button",
1531
+ {
1532
+ type: "button",
1533
+ "data-slot": "chat-composer-cancel-reply",
1534
+ "aria-label": cancelReplyLabel,
1535
+ disabled,
1536
+ onClick: onCancelReply,
1537
+ className: iconButtonClasses,
1538
+ children: /* @__PURE__ */ jsx(X2, { className: "h-4 w-4", "aria-hidden": "true" })
1539
+ }
1540
+ )
1541
+ ]
1542
+ }
1543
+ ),
1544
+ attachments.length > 0 && /* @__PURE__ */ jsx(
1545
+ "div",
1546
+ {
1547
+ "data-slot": "chat-composer-attachments",
1548
+ className: "flex flex-wrap gap-2 px-3 pt-3",
1549
+ children: attachments.map((attachment) => /* @__PURE__ */ jsx(
1550
+ AttachmentPreviewItem,
1551
+ {
1552
+ attachment: { ...attachment, state: "pending" },
1553
+ onRemove: () => removeAttachment(attachment.id),
1554
+ disabled
1555
+ },
1556
+ attachment.id
1557
+ ))
1558
+ }
1559
+ ),
1560
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_minmax(0,1fr)_auto]", children: [
1561
+ /* @__PURE__ */ jsxs("div", { className: cells.input, ref: mention.anchorRef, children: [
1562
+ /* @__PURE__ */ jsx(
1563
+ MentionMenu,
1564
+ {
1565
+ mention,
1566
+ label: mentionListLabel,
1567
+ dataSlot: "chat-composer-mention-list"
1568
+ }
1569
+ ),
1570
+ /* @__PURE__ */ jsx(
1571
+ "textarea",
1572
+ {
1573
+ ...textareaProps,
1574
+ ref: textareaRef,
1575
+ "data-slot": "chat-composer-input",
1576
+ value,
1577
+ onChange: (event) => {
1578
+ textareaProps?.onChange?.(event);
1579
+ setValue(event.target.value);
1580
+ mention.sync(
1581
+ event.target.value,
1582
+ event.target.selectionStart ?? event.target.value.length
1583
+ );
1584
+ },
1585
+ onKeyDown: (event) => {
1586
+ textareaProps?.onKeyDown?.(event);
1587
+ if (event.defaultPrevented) return;
1588
+ handleKeyDown(event);
1589
+ },
1590
+ onClick: (event) => {
1591
+ textareaProps?.onClick?.(event);
1592
+ if (event.defaultPrevented) return;
1593
+ const el = event.currentTarget;
1594
+ mention.sync(el.value, el.selectionStart ?? el.value.length);
1595
+ },
1596
+ onPaste: (event) => {
1597
+ textareaProps?.onPaste?.(event);
1598
+ if (event.defaultPrevented) return;
1599
+ handlePaste(event);
1600
+ },
1601
+ placeholder,
1602
+ disabled,
1603
+ autoFocus,
1604
+ rows: 1,
1605
+ "aria-label": inputLabel,
1606
+ ...mention.inputProps,
1607
+ style: {
1608
+ ...textareaProps?.style,
1609
+ maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight
1610
+ },
1611
+ className: cn(
1612
+ "block w-full resize-none bg-transparent",
1613
+ "rounded-lg text-sm",
1614
+ cells.textarea,
1615
+ "text-neutral-900 placeholder:text-neutral-400 dark:text-white dark:placeholder:text-neutral-500",
1616
+ // Ring the input itself on focus rather than the whole shell.
1617
+ "focus:ring-primary-500 focus:ring-1 focus:outline-none",
1618
+ "disabled:cursor-not-allowed",
1619
+ textareaProps?.className
1620
+ )
1621
+ }
1622
+ )
1623
+ ] }),
1624
+ showAddMenu && /* @__PURE__ */ jsx("div", { className: cells.add, children: /* @__PURE__ */ jsxs(
1625
+ Dropdown,
1626
+ {
1627
+ placement: "top-start",
1628
+ open: addMenuOpen,
1629
+ onOpenChange: setAddMenuOpen,
1630
+ trigger: /* @__PURE__ */ jsx(
1631
+ "button",
1632
+ {
1633
+ type: "button",
1634
+ "data-slot": "chat-composer-add-button",
1635
+ "aria-label": addMenuLabel,
1636
+ disabled,
1637
+ className: iconButtonClasses,
1638
+ children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" })
1639
+ }
1640
+ ),
1641
+ children: [
1642
+ allowAttachments && /* @__PURE__ */ jsx(
1643
+ DropdownItem,
1644
+ {
1645
+ icon: /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4", "aria-hidden": "true" }),
1646
+ onClick: () => {
1647
+ setAddMenuOpen(false);
1648
+ fileInputRef.current?.click();
1649
+ },
1650
+ children: attachFilesLabel
1651
+ }
1652
+ ),
1653
+ allowAttachments && addMenuItems && addMenuItems.length > 0 && /* @__PURE__ */ jsx(DropdownSeparator, {}),
1654
+ addMenuItems?.map((item) => /* @__PURE__ */ jsx(
1655
+ DropdownItem,
1656
+ {
1657
+ icon: item.icon,
1658
+ disabled: item.disabled,
1659
+ variant: item.variant,
1660
+ checked: item.checked,
1661
+ onClick: () => {
1662
+ setAddMenuOpen(false);
1663
+ item.onSelect?.();
1664
+ },
1665
+ children: /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: item.label })
1666
+ },
1667
+ item.id
1668
+ ))
1669
+ ]
1670
+ }
1671
+ ) }),
1672
+ allowAttachments && /* @__PURE__ */ jsx(
1673
+ "input",
1674
+ {
1675
+ ref: fileInputRef,
1676
+ type: "file",
1677
+ multiple: true,
1678
+ accept: acceptedFileTypes?.join(","),
1679
+ onChange: handleFileInputChange,
1680
+ className: "hidden",
1681
+ "aria-hidden": "true",
1682
+ tabIndex: -1
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsxs("div", { className: cells.actions, children: [
1686
+ showCharacterCount && maxLength !== void 0 && /* @__PURE__ */ jsxs(
1687
+ "span",
1688
+ {
1689
+ "data-slot": "chat-composer-char-count",
1690
+ "aria-live": "polite",
1691
+ className: cn(
1692
+ "pe-1 text-xs tabular-nums",
1693
+ isOverLimit ? "font-medium text-red-700 dark:text-red-400" : "text-neutral-500 dark:text-neutral-400"
1694
+ ),
1695
+ children: [
1696
+ value.length,
1697
+ "/",
1698
+ maxLength
1699
+ ]
1700
+ }
1701
+ ),
1702
+ micVisible && (micSlot != null ? (
1703
+ // Normalize slot content (e.g. a RecordButton) to the 32px
1704
+ // control row: taller content overflow-centers instead of
1705
+ // inflating the pill and pushing the other cells apart. A div
1706
+ // so block-level slot content stays valid HTML.
1707
+ /* @__PURE__ */ jsx(
1708
+ "div",
1709
+ {
1710
+ "data-slot": "chat-composer-mic-slot",
1711
+ className: "flex h-8 shrink-0 items-center",
1712
+ children: micSlot
1713
+ }
1714
+ )
1715
+ ) : /* @__PURE__ */ jsx(
1716
+ "button",
1717
+ {
1718
+ type: "button",
1719
+ "data-slot": "chat-composer-mic-button",
1720
+ "aria-label": micLabel,
1721
+ disabled,
1722
+ onClick: onMicClick,
1723
+ className: iconButtonClasses,
1724
+ children: /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4", "aria-hidden": "true" })
1725
+ }
1726
+ )),
1727
+ isStreaming && onStop ? /* @__PURE__ */ jsx(
1728
+ "button",
1729
+ {
1730
+ type: "button",
1731
+ "data-slot": "chat-composer-stop-button",
1732
+ "aria-label": stopLabel,
1733
+ disabled,
1734
+ onClick: onStop,
1735
+ className: cn(
1736
+ iconButtonClasses,
1737
+ "text-neutral-700 dark:text-neutral-200"
1738
+ ),
1739
+ children: /* @__PURE__ */ jsx(
1740
+ Square,
1741
+ {
1742
+ className: "h-3.5 w-3.5 fill-current",
1743
+ "aria-hidden": "true"
1744
+ }
1745
+ )
1746
+ }
1747
+ ) : /* @__PURE__ */ jsx(
1748
+ "button",
1749
+ {
1750
+ type: "button",
1751
+ "data-slot": "chat-composer-send-button",
1752
+ "aria-label": isSending ? sendingLabel : sendLabel,
1753
+ "aria-busy": isSending || void 0,
1754
+ disabled: !canSend,
1755
+ onClick: handleSend,
1756
+ className: cn(
1757
+ iconButtonClasses,
1758
+ canSend && "bg-primary-800 hover:bg-primary-700 dark:bg-primary-600 dark:hover:bg-primary-500 text-white hover:text-white dark:hover:text-white"
1759
+ ),
1760
+ children: isSending ? /* @__PURE__ */ jsx(
1761
+ Loader2,
1762
+ {
1763
+ className: "h-4 w-4 animate-spin",
1764
+ "aria-hidden": "true"
1765
+ }
1766
+ ) : /* @__PURE__ */ jsx(ArrowUp, { className: "h-4 w-4", "aria-hidden": "true" })
1767
+ }
1768
+ )
1769
+ ] })
1770
+ ] })
1771
+ ] });
1772
+ const selectorsRow = showSelectorRow && /* @__PURE__ */ jsxs(
1773
+ "div",
1774
+ {
1775
+ "data-slot": "chat-composer-selectors",
1776
+ className: "flex items-center justify-between gap-2 px-2 pt-1",
1777
+ children: [
1778
+ showAgentSelector ? /* @__PURE__ */ jsx(
1779
+ Dropdown,
1780
+ {
1781
+ placement: "top-start",
1782
+ open: agentMenuOpen,
1783
+ onOpenChange: setAgentMenuOpen,
1784
+ trigger: /* @__PURE__ */ jsxs(
1785
+ "button",
1786
+ {
1787
+ type: "button",
1788
+ "data-slot": "chat-composer-agent-trigger",
1789
+ "aria-label": selectedAgentOption ? `${agentSelectorLabel}: ${selectedAgentOption.label}` : agentSelectorLabel,
1790
+ disabled,
1791
+ className: selectorTriggerClasses,
1792
+ children: [
1793
+ selectedAgentOption?.icon ?? /* @__PURE__ */ jsx(Bot, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
1794
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: selectedAgentOption?.label ?? agentSelectorLabel }),
1795
+ /* @__PURE__ */ jsx(ChevronUp, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" })
1796
+ ]
1797
+ }
1798
+ ),
1799
+ children: agents.map((agent) => /* @__PURE__ */ jsx(
1800
+ DropdownItem,
1801
+ {
1802
+ icon: agent.icon,
1803
+ role: "menuitemradio",
1804
+ "aria-checked": agent.id === selectedAgent,
1805
+ onClick: () => {
1806
+ setAgentMenuOpen(false);
1807
+ onAgentChange?.(agent.id);
1808
+ },
1809
+ children: /* @__PURE__ */ jsxs("span", { className: "flex w-full items-center justify-between gap-2", children: [
1810
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
1811
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: agent.label }),
1812
+ agent.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-neutral-500 dark:text-neutral-400", children: agent.description })
1813
+ ] }),
1814
+ agent.id === selectedAgent && /* @__PURE__ */ jsx(
1815
+ Check,
1816
+ {
1817
+ className: "text-primary-600 dark:text-primary-400 h-4 w-4 shrink-0",
1818
+ "aria-hidden": "true"
1819
+ }
1820
+ )
1821
+ ] })
1822
+ },
1823
+ agent.id
1824
+ ))
1825
+ }
1826
+ ) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true" }),
1827
+ showModelSelector && modelSelectorProps && /* @__PURE__ */ jsx(
1828
+ ComposerModelSelector,
1829
+ {
1830
+ variant: "ghost",
1831
+ ...modelSelectorProps,
1832
+ disabled: disabled || modelSelectorProps.disabled
1833
+ }
1834
+ )
1835
+ ]
1836
+ }
1837
+ );
1838
+ const card = /* @__PURE__ */ jsx(
1839
+ "div",
1840
+ {
1841
+ "data-slot": "chat-composer-card",
1842
+ className: cn(
1843
+ "rounded-2xl border border-neutral-200 bg-white shadow-sm",
1844
+ "dark:border-[#2e2e30] dark:bg-[#1c1c1e]"
1845
+ ),
1846
+ children: composerCard
1847
+ }
1848
+ );
1849
+ return /* @__PURE__ */ jsxs(
1850
+ "div",
1851
+ {
1852
+ "data-slot": "chat-composer",
1853
+ className: cn(
1854
+ "flex w-full flex-col",
1855
+ disabled && "opacity-60",
1856
+ className
1857
+ ),
1858
+ children: [
1859
+ allowAttachments ? /* @__PURE__ */ jsx(
1860
+ DragDropZone,
1861
+ {
1862
+ onFilesDropped: addFiles,
1863
+ maxFiles: Number.MAX_SAFE_INTEGER,
1864
+ disabled,
1865
+ overlayLabel: dropFilesLabel,
1866
+ children: card
1867
+ }
1868
+ ) : card,
1869
+ selectorsRow
1870
+ ]
1871
+ }
1872
+ );
1873
+ });
1874
+ ChatComposer.displayName = "ChatComposer";
1875
+
1876
+ // src/components/ChatComposer/migration-notice.ts
1877
+ var didNotify = false;
1878
+ function notifyComposerMigrationOnce(surface) {
1879
+ if (process.env.NODE_ENV === "production" || didNotify) return;
1880
+ didNotify = true;
1881
+ console.warn(
1882
+ `[@mieweb/ui] ${surface} renders the shared ChatComposer \u2014 the standalone MessageComposer was retired in 0.10.0. If your CSS or tests reach into composer internals, see MIGRATION.md#chat-composer (https://github.com/mieweb/ui/blob/main/MIGRATION.md#chat-composer). This dev-only notice will be removed in 0.11.0.`
1883
+ );
1884
+ }
1885
+
1886
+ export { AttachmentPicker, AttachmentPreviewItem, CameraButton, ChatComposer, ComposerModelSelector, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_MAX_FILE_SIZE, DragDropZone, generateAttachmentId, getFileType, notifyComposerMigrationOnce, validateFile };
1887
+ //# sourceMappingURL=chunk-IIFQ6BSJ.js.map
1888
+ //# sourceMappingURL=chunk-IIFQ6BSJ.js.map