@keboola/design 15.0.0 → 16.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 (358) hide show
  1. package/AGENTS.md +6 -5
  2. package/CHANGELOG.md +94 -0
  3. package/COMPONENT-API.md +62 -61
  4. package/dist/{AIKit-CaAW4GLx.js → AIKit-Cf5plya2.js} +381 -224
  5. package/dist/AIKit-Cf5plya2.js.map +1 -0
  6. package/dist/{Alert-Chz6KZ7e.js → Alert-DziS8n1H.js} +12 -19
  7. package/dist/{Alert-Chz6KZ7e.js.map → Alert-DziS8n1H.js.map} +1 -1
  8. package/dist/{AlertModal-D4AtpvLS.js → AlertModal-De04fFoy.js} +16 -26
  9. package/dist/AlertModal-De04fFoy.js.map +1 -0
  10. package/dist/{AppShell-C8V1KRr_.js → AppShell-BUa3U7-e.js} +6 -9
  11. package/dist/{AppShell-C8V1KRr_.js.map → AppShell-BUa3U7-e.js.map} +1 -1
  12. package/dist/{AutoSaveTextarea-BbMhC5Aq.js → AutoSaveTextarea-CXHOQSun.js} +4 -5
  13. package/dist/{AutoSaveTextarea-BbMhC5Aq.js.map → AutoSaveTextarea-CXHOQSun.js.map} +1 -1
  14. package/dist/{Badge-5GHIsgRS.js → Badge-CFRhducL.js} +18 -23
  15. package/dist/Badge-CFRhducL.js.map +1 -0
  16. package/dist/{BrandEditor-CTGtQUFZ.js → BrandEditor-hiLBX7az.js} +16 -23
  17. package/dist/{BrandEditor-CTGtQUFZ.js.map → BrandEditor-hiLBX7az.js.map} +1 -1
  18. package/dist/{BrandLogo-DkESE19K.js → BrandLogo-Dn7hhp2c.js} +4 -5
  19. package/dist/{BrandLogo-DkESE19K.js.map → BrandLogo-Dn7hhp2c.js.map} +1 -1
  20. package/dist/{Breadcrumb-B2YSNON4.js → Breadcrumb-uGFEIjFF.js} +17 -28
  21. package/dist/{Breadcrumb-B2YSNON4.js.map → Breadcrumb-uGFEIjFF.js.map} +1 -1
  22. package/dist/{Button-BNkyYU8u.js → Button-DbvGzEDb.js} +24 -20
  23. package/dist/Button-DbvGzEDb.js.map +1 -0
  24. package/dist/{Calendar-BnKi1kPu.js → Calendar-lJBTETbk.js} +752 -905
  25. package/dist/Calendar-lJBTETbk.js.map +1 -0
  26. package/dist/{Card-DxjGiqH8.js → Card-VIPfOVW5.js} +8 -14
  27. package/dist/{Card-DxjGiqH8.js.map → Card-VIPfOVW5.js.map} +1 -1
  28. package/dist/{Checkbox-CHDDJyAA.js → Checkbox-B2jLlyaO.js} +6 -8
  29. package/dist/{Checkbox-CHDDJyAA.js.map → Checkbox-B2jLlyaO.js.map} +1 -1
  30. package/dist/{Clipboard-DlwVZS1P.js → Clipboard-fAkDdpEu.js} +4 -5
  31. package/dist/{Clipboard-DlwVZS1P.js.map → Clipboard-fAkDdpEu.js.map} +1 -1
  32. package/dist/{ClipboardButton-B1Hr_n_Z.js → ClipboardButton-71Ugbl8c.js} +6 -8
  33. package/dist/{ClipboardButton-B1Hr_n_Z.js.map → ClipboardButton-71Ugbl8c.js.map} +1 -1
  34. package/dist/{CodeEditor-DVSPdfdo.js → CodeEditor-D_b-ZCng.js} +19 -31
  35. package/dist/{CodeEditor-DVSPdfdo.js.map → CodeEditor-D_b-ZCng.js.map} +1 -1
  36. package/dist/{Collapsible-DD4xTL75.js → Collapsible-zsXk4Vpp.js} +5 -8
  37. package/dist/{Collapsible-DD4xTL75.js.map → Collapsible-zsXk4Vpp.js.map} +1 -1
  38. package/dist/{ColorInput-B_eZIu39.js → ColorInput-Cjr1jkvy.js} +9 -12
  39. package/dist/{ColorInput-B_eZIu39.js.map → ColorInput-Cjr1jkvy.js.map} +1 -1
  40. package/dist/{ColorModeSwitch-B6UEzG0H.js → ColorModeSwitch-CuPYnJ2V.js} +5 -6
  41. package/dist/{ColorModeSwitch-B6UEzG0H.js.map → ColorModeSwitch-CuPYnJ2V.js.map} +1 -1
  42. package/dist/{Combobox-CaKqgstG.js → Combobox-DYjvYgl3.js} +38 -67
  43. package/dist/Combobox-DYjvYgl3.js.map +1 -0
  44. package/dist/{Command-DhXmqFLT.js → Command-BcTb6GsR.js} +14 -24
  45. package/dist/{Command-DhXmqFLT.js.map → Command-BcTb6GsR.js.map} +1 -1
  46. package/dist/{CopyField-D0Pg4Z0R.js → CopyField-CnwAvQz9.js} +16 -28
  47. package/dist/{CopyField-D0Pg4Z0R.js.map → CopyField-CnwAvQz9.js.map} +1 -1
  48. package/dist/{DateInput-BgbMDJkm.js → DateInput-DJNX7Vdx.js} +8 -10
  49. package/dist/{DateInput-BgbMDJkm.js.map → DateInput-DJNX7Vdx.js.map} +1 -1
  50. package/dist/{DatePicker-BXpDRo-R.js → DatePicker-CI59gF3S.js} +4 -5
  51. package/dist/{DatePicker-BXpDRo-R.js.map → DatePicker-CI59gF3S.js.map} +1 -1
  52. package/dist/{DateRangeInput-BW0-_jV0.js → DateRangeInput-B3g8cyS0.js} +8 -10
  53. package/dist/{DateRangeInput-BW0-_jV0.js.map → DateRangeInput-B3g8cyS0.js.map} +1 -1
  54. package/dist/{DateRangePicker-C4-DoWac.js → DateRangePicker-48yOB2qV.js} +9 -10
  55. package/dist/{DateRangePicker-C4-DoWac.js.map → DateRangePicker-48yOB2qV.js.map} +1 -1
  56. package/dist/{DiffView-Dy4z-n-1.js → DiffView-DITZdVbh.js} +7 -12
  57. package/dist/{DiffView-Dy4z-n-1.js.map → DiffView-DITZdVbh.js.map} +1 -1
  58. package/dist/{DropdownMenu-CcVbZ_5u.js → DropdownMenu-Ba9atqDa.js} +21 -37
  59. package/dist/DropdownMenu-Ba9atqDa.js.map +1 -0
  60. package/dist/{FieldBox-BrxLkY9C.js → FieldBox-DdSdJ3ZN.js} +6 -10
  61. package/dist/{FieldBox-BrxLkY9C.js.map → FieldBox-DdSdJ3ZN.js.map} +1 -1
  62. package/dist/{FieldItem-BHUqgSO1.js → FieldItem-D7eCMfMB.js} +6 -8
  63. package/dist/{FieldItem-BHUqgSO1.js.map → FieldItem-D7eCMfMB.js.map} +1 -1
  64. package/dist/{FieldItem-CPN1xjN5.d.ts → FieldItem-fqm3CNR8.d.ts} +7 -6
  65. package/dist/{FileUpload-BYFONpEl.js → FileUpload-DskvxhAr.js} +25 -45
  66. package/dist/{FileUpload-BYFONpEl.js.map → FileUpload-DskvxhAr.js.map} +1 -1
  67. package/dist/{Form-CAofWyMI.js → Form-BUNW7nlt.js} +24 -38
  68. package/dist/{Form-CAofWyMI.js.map → Form-BUNW7nlt.js.map} +1 -1
  69. package/dist/{FormGroup-V5kIgQRN.js → FormGroup-QJB21LKp.js} +12 -20
  70. package/dist/{FormGroup-V5kIgQRN.js.map → FormGroup-QJB21LKp.js.map} +1 -1
  71. package/dist/{FullScreenModal-DAvvlGOz.js → FullScreenModal-RzY5XxiG.js} +8 -12
  72. package/dist/{FullScreenModal-DAvvlGOz.js.map → FullScreenModal-RzY5XxiG.js.map} +1 -1
  73. package/dist/HoverCard-OGWKRXJ7.js +24 -0
  74. package/dist/HoverCard-OGWKRXJ7.js.map +1 -0
  75. package/dist/{InlineEdit-D4P0SvCB.js → InlineEdit-CXL0ZslO.js} +7 -8
  76. package/dist/{InlineEdit-D4P0SvCB.js.map → InlineEdit-CXL0ZslO.js.map} +1 -1
  77. package/dist/{InputGroup-CZv_7QlM.js → InputGroup-BWeanEo7.js} +9 -15
  78. package/dist/{InputGroup-CZv_7QlM.js.map → InputGroup-BWeanEo7.js.map} +1 -1
  79. package/dist/{Kbd-CflKthfu.js → Kbd-BprYCICe.js} +8 -13
  80. package/dist/{Kbd-CflKthfu.js.map → Kbd-BprYCICe.js.map} +1 -1
  81. package/dist/{MarkedText-DlmlJO0u.js → MarkedText-BrganZ_V.js} +4 -6
  82. package/dist/{MarkedText-DlmlJO0u.js.map → MarkedText-BrganZ_V.js.map} +1 -1
  83. package/dist/{MermaidDiagram-Te-5gOCU.js → MermaidDiagram-E3azndPk.js} +9 -11
  84. package/dist/{MermaidDiagram-Te-5gOCU.js.map → MermaidDiagram-E3azndPk.js.map} +1 -1
  85. package/dist/{Modal-CbUz-5YH.js → Modal-Cf_kPEBW.js} +14 -22
  86. package/dist/Modal-Cf_kPEBW.js.map +1 -0
  87. package/dist/{ModalTitle-cy0Ht9VY.js → ModalTitle-7vgpfc6B.js} +6 -9
  88. package/dist/ModalTitle-7vgpfc6B.js.map +1 -0
  89. package/dist/{MultiActionButtonGroup-Dzig87s1.js → MultiActionButtonGroup-8WQwL4UQ.js} +6 -8
  90. package/dist/{MultiActionButtonGroup-Dzig87s1.js.map → MultiActionButtonGroup-8WQwL4UQ.js.map} +1 -1
  91. package/dist/{Navbar-DHUS7XiU.js → Navbar-CRjxVboE.js} +13 -22
  92. package/dist/{Navbar-DHUS7XiU.js.map → Navbar-CRjxVboE.js.map} +1 -1
  93. package/dist/{OtpInput-CY8yCaJk.js → OtpInput-C5plPzGU.js} +7 -11
  94. package/dist/{OtpInput-CY8yCaJk.js.map → OtpInput-C5plPzGU.js.map} +1 -1
  95. package/dist/{PageHeader-CL1A6jFM.js → PageHeader-DosMyar2.js} +6 -10
  96. package/dist/{PageHeader-CL1A6jFM.js.map → PageHeader-DosMyar2.js.map} +1 -1
  97. package/dist/{PageLayout-C9aXTpqV.js → PageLayout-LcvJccOW.js} +5 -8
  98. package/dist/{PageLayout-C9aXTpqV.js.map → PageLayout-LcvJccOW.js.map} +1 -1
  99. package/dist/{PageToolbar-DJ5tdYla.js → PageToolbar-By2HznxO.js} +8 -10
  100. package/dist/{PageToolbar-DJ5tdYla.js.map → PageToolbar-By2HznxO.js.map} +1 -1
  101. package/dist/{Pagination-D27x5KmH.js → Pagination-DrXTrvfD.js} +11 -18
  102. package/dist/{Pagination-D27x5KmH.js.map → Pagination-DrXTrvfD.js.map} +1 -1
  103. package/dist/{Popconfirm-DwLCYNaF.js → Popconfirm-BJuDOHdv.js} +46 -25
  104. package/dist/Popconfirm-BJuDOHdv.js.map +1 -0
  105. package/dist/{Popover-DtUDwUVO.js → Popover-DhOPlWgF.js} +5 -7
  106. package/dist/Popover-DhOPlWgF.js.map +1 -0
  107. package/dist/{RadioGroup-B0TwHjBb.js → RadioGroup-B9oC8P15.js} +12 -18
  108. package/dist/{RadioGroup-B0TwHjBb.js.map → RadioGroup-B9oC8P15.js.map} +1 -1
  109. package/dist/{Resizable-D8zs0kcq.js → Resizable-Co-L3qg7.js} +4 -6
  110. package/dist/{Resizable-D8zs0kcq.js.map → Resizable-Co-L3qg7.js.map} +1 -1
  111. package/dist/{Search-vyZwGKMU.js → Search-OgaNjqQM.js} +26 -21
  112. package/dist/Search-OgaNjqQM.js.map +1 -0
  113. package/dist/{SearchInput-DyYXyw3u.js → SearchInput-eLS-uvOn.js} +18 -29
  114. package/dist/SearchInput-eLS-uvOn.js.map +1 -0
  115. package/dist/{SectionNav-tLK3iF6c.js → SectionNav-L81iJBo3.js} +11 -14
  116. package/dist/{SectionNav-tLK3iF6c.js.map → SectionNav-L81iJBo3.js.map} +1 -1
  117. package/dist/{Select-B22hB_-w.js → Select-DRdkdzBp.js} +29 -26
  118. package/dist/Select-DRdkdzBp.js.map +1 -0
  119. package/dist/{Sheet-0TWKTqid.js → Sheet-DVb4XoJ5.js} +13 -20
  120. package/dist/Sheet-DVb4XoJ5.js.map +1 -0
  121. package/dist/{Sidebar-C5hdANBU.js → Sidebar-DYvodJWN.js} +43 -75
  122. package/dist/{Sidebar-C5hdANBU.js.map → Sidebar-DYvodJWN.js.map} +1 -1
  123. package/dist/{Slider-DrcsM8_G.js → Slider-B9IskDxf.js} +8 -12
  124. package/dist/{Slider-DrcsM8_G.js.map → Slider-B9IskDxf.js.map} +1 -1
  125. package/dist/{Stepper-CQrUPVFL.js → Stepper-D7VspVEt.js} +11 -19
  126. package/dist/{Stepper-CQrUPVFL.js.map → Stepper-D7VspVEt.js.map} +1 -1
  127. package/dist/{Switch-DccpSpzC.js → Switch-DONWW7ju.js} +4 -6
  128. package/dist/{Switch-DccpSpzC.js.map → Switch-DONWW7ju.js.map} +1 -1
  129. package/dist/{Table-CilEvpMq.js → Table-BwgBm3hJ.js} +12 -21
  130. package/dist/{Table-CilEvpMq.js.map → Table-BwgBm3hJ.js.map} +1 -1
  131. package/dist/{Tabs-Ck4uWf8U.js → Tabs-DmJB4l_N.js} +9 -14
  132. package/dist/{Tabs-Ck4uWf8U.js.map → Tabs-DmJB4l_N.js.map} +1 -1
  133. package/dist/{TextInput-CR0_USaY.js → TextInput--1CfZybC.js} +8 -10
  134. package/dist/TextInput--1CfZybC.js.map +1 -0
  135. package/dist/{ThemeProvider-BTK7AL-T.js → ThemeProvider-BCHllN7d.js} +8 -13
  136. package/dist/{ThemeProvider-BTK7AL-T.js.map → ThemeProvider-BCHllN7d.js.map} +1 -1
  137. package/dist/{TimePicker-CoRpiEM3.js → TimePicker-CCV3SOw5.js} +4 -6
  138. package/dist/{TimePicker-CoRpiEM3.js.map → TimePicker-CCV3SOw5.js.map} +1 -1
  139. package/dist/{Timeline-DUXgByUE.js → Timeline-EMOpTLAT.js} +8 -13
  140. package/dist/{Timeline-DUXgByUE.js.map → Timeline-EMOpTLAT.js.map} +1 -1
  141. package/dist/{Toast-937n7n8i.js → Toast-BOTINeTX.js} +4 -6
  142. package/dist/{Toast-937n7n8i.js.map → Toast-BOTINeTX.js.map} +1 -1
  143. package/dist/{ToggleAllTooltip-DEjbWFoj.js → ToggleAllTooltip-BFmA6TXf.js} +4 -6
  144. package/dist/{ToggleAllTooltip-DEjbWFoj.js.map → ToggleAllTooltip-BFmA6TXf.js.map} +1 -1
  145. package/dist/{ToggleGroup-BOz1yyz6.js → ToggleGroup-DsDS7k70.js} +3 -4
  146. package/dist/{ToggleGroup-BOz1yyz6.js.map → ToggleGroup-DsDS7k70.js.map} +1 -1
  147. package/dist/{Workbench-CxgNCs3I.js → Workbench-4s0xP6XU.js} +18 -32
  148. package/dist/{Workbench-CxgNCs3I.js.map → Workbench-4s0xP6XU.js.map} +1 -1
  149. package/dist/{ZoomableSvg-DnFXo2L4.js → ZoomableSvg-BRPGgaWJ.js} +9 -11
  150. package/dist/{ZoomableSvg-DnFXo2L4.js.map → ZoomableSvg-BRPGgaWJ.js.map} +1 -1
  151. package/dist/charts.d.ts +0 -16
  152. package/dist/charts.js +10 -19
  153. package/dist/charts.js.map +1 -1
  154. package/dist/{classNames-DcGnTh2N.js → classNames-DkX30VJU.js} +2 -3
  155. package/dist/{classNames-DcGnTh2N.js.map → classNames-DkX30VJU.js.map} +1 -1
  156. package/dist/editors.d.ts +2 -16
  157. package/dist/editors.js +16 -26
  158. package/dist/editors.js.map +1 -1
  159. package/dist/{findLiteralMatches-DgGLzyG0.js → findLiteralMatches-BaLZTPtx.js} +2 -3
  160. package/dist/{findLiteralMatches-DgGLzyG0.js.map → findLiteralMatches-BaLZTPtx.js.map} +1 -1
  161. package/dist/flint.d.ts +0 -2
  162. package/dist/flint.js +10 -14
  163. package/dist/flint.js.map +1 -1
  164. package/dist/{highlightCode-D354tCXO.js → highlightCode-2spZP7ZA.js} +2 -3
  165. package/dist/{highlightCode-D354tCXO.js.map → highlightCode-2spZP7ZA.js.map} +1 -1
  166. package/dist/{icons-ZIeZXXS7.js → icons-DDR9dFSr.js} +21 -40
  167. package/dist/{icons-ZIeZXXS7.js.map → icons-DDR9dFSr.js.map} +1 -1
  168. package/dist/icons.d.ts +1 -1
  169. package/dist/icons.js +1 -2
  170. package/dist/{index-D-itZ3VP.d.ts → index-BljYaTWL.d.ts} +1 -39
  171. package/dist/index.d.ts +452 -1296
  172. package/dist/index.js +76 -74
  173. package/dist/internal/blocks/AIKit.js +1 -2
  174. package/dist/internal/blocks/AppShell.js +1 -2
  175. package/dist/internal/blocks/AuthLayout.js +3 -4
  176. package/dist/internal/blocks/AutoSaveTextarea.js +1 -2
  177. package/dist/internal/blocks/BrandEditor.js +1 -2
  178. package/dist/internal/blocks/ChartPanel.js +3 -4
  179. package/dist/internal/blocks/ChipEditor.js +6 -7
  180. package/dist/internal/blocks/ClipboardButton.js +1 -2
  181. package/dist/internal/blocks/ColorInput.js +1 -2
  182. package/dist/internal/blocks/ColorModeSwitch.js +1 -2
  183. package/dist/internal/blocks/Command.js +1 -2
  184. package/dist/internal/blocks/CopyField.js +1 -2
  185. package/dist/internal/blocks/DashboardHero.js +2 -3
  186. package/dist/internal/blocks/DateInput.js +1 -2
  187. package/dist/internal/blocks/DateRangeInput.js +1 -2
  188. package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js +1 -2
  189. package/dist/internal/blocks/EmptyConfigurationActionCard.js +2 -3
  190. package/dist/internal/blocks/EmptyState.js +1 -2
  191. package/dist/internal/blocks/ErrorState.js +1 -2
  192. package/dist/internal/blocks/ExportMenu.js +5 -6
  193. package/dist/internal/blocks/FacebookButton.js +3 -4
  194. package/dist/internal/blocks/Form/connectors/ComboboxField.js +3 -4
  195. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +2 -3
  196. package/dist/internal/blocks/Form.js +3 -2
  197. package/dist/internal/blocks/FormGroup.js +1 -2
  198. package/dist/internal/blocks/GoogleButton.js +3 -4
  199. package/dist/internal/blocks/InlineEdit.js +1 -2
  200. package/dist/internal/blocks/MicrosoftButton.js +3 -4
  201. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -2
  202. package/dist/internal/blocks/MultiCombobox.js +7 -8
  203. package/dist/internal/blocks/NumberInput.js +2 -3
  204. package/dist/internal/blocks/OtpInput.js +1 -2
  205. package/dist/internal/blocks/PageHeader.js +1 -2
  206. package/dist/internal/blocks/PageLayout.js +1 -2
  207. package/dist/internal/blocks/PageToolbar.js +1 -2
  208. package/dist/internal/blocks/PasswordInput.js +5 -6
  209. package/dist/internal/blocks/SearchInput.js +1 -2
  210. package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
  211. package/dist/internal/blocks/SectionNav.js +1 -2
  212. package/dist/internal/blocks/SplitButton.js +4 -5
  213. package/dist/internal/blocks/StatCard.js +4 -6
  214. package/dist/internal/blocks/StatCard.js.map +1 -1
  215. package/dist/internal/blocks/TextInput.js +1 -2
  216. package/dist/internal/blocks/Textarea.js +3 -4
  217. package/dist/internal/blocks/TimeInput.js +6 -7
  218. package/dist/internal/components/Alert.js +1 -2
  219. package/dist/internal/components/AlertModal.js +1 -2
  220. package/dist/internal/components/Avatar.js +3 -4
  221. package/dist/internal/components/Badge.js +1 -2
  222. package/dist/internal/components/BrandLogo.js +1 -2
  223. package/dist/internal/components/Breadcrumb.js +1 -2
  224. package/dist/internal/components/Button.js +1 -2
  225. package/dist/internal/components/ButtonGroup.js +2 -3
  226. package/dist/internal/components/Calendar.js +1 -2
  227. package/dist/internal/components/Card.js +1 -2
  228. package/dist/internal/components/Checkbox.js +1 -2
  229. package/dist/internal/components/Clipboard.js +1 -2
  230. package/dist/internal/components/Collapsible.js +1 -2
  231. package/dist/internal/components/CollapsiblePanel.js +5 -6
  232. package/dist/internal/components/Combobox.js +1 -2
  233. package/dist/internal/components/DatePicker.js +1 -2
  234. package/dist/internal/components/DateRangePicker.js +1 -2
  235. package/dist/internal/components/DiffView.js +1 -2
  236. package/dist/internal/components/DotsLoader.js +2 -3
  237. package/dist/internal/components/DropdownMenu.js +1 -2
  238. package/dist/internal/components/EmptySearchContent.js +1 -2
  239. package/dist/internal/components/FileUpload.js +1 -2
  240. package/dist/internal/components/FullScreenModal.js +1 -2
  241. package/dist/internal/components/HelpBlock.js +1 -2
  242. package/dist/internal/components/HoverCard.js +1 -2
  243. package/dist/internal/components/InputGroup.js +1 -2
  244. package/dist/internal/components/Kbd.js +1 -2
  245. package/dist/internal/components/Label.js +2 -3
  246. package/dist/internal/components/Link.js +2 -3
  247. package/dist/internal/components/MarkedText.js +1 -2
  248. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +3 -4
  249. package/dist/internal/components/MergeEditor/PaneHeader.js +1 -2
  250. package/dist/internal/components/MergeEditor/constants.js +1 -2
  251. package/dist/internal/components/MergeEditor/useMergeDiff.js +1 -2
  252. package/dist/internal/components/Modal.js +1 -2
  253. package/dist/internal/components/Navbar.js +1 -2
  254. package/dist/internal/components/Pagination.js +1 -2
  255. package/dist/internal/components/PanelWithDetails.js +4 -5
  256. package/dist/internal/components/Popconfirm.js +1 -2
  257. package/dist/internal/components/Popover.js +1 -2
  258. package/dist/internal/components/Progress.js +2 -3
  259. package/dist/internal/components/RadioGroup.js +1 -2
  260. package/dist/internal/components/Resizable.js +1 -2
  261. package/dist/internal/components/ScrollArea.js +3 -5
  262. package/dist/internal/components/ScrollArea.js.map +1 -1
  263. package/dist/internal/components/Search.js +1 -2
  264. package/dist/internal/components/Select.js +1 -2
  265. package/dist/internal/components/Separator.js +2 -3
  266. package/dist/internal/components/Sheet.js +1 -2
  267. package/dist/internal/components/Sidebar.js +1 -2
  268. package/dist/internal/components/Skeleton/Skeleton.js +2 -3
  269. package/dist/internal/components/Skeleton/SkeletonList.js +2 -3
  270. package/dist/internal/components/Slider.js +1 -2
  271. package/dist/internal/components/SpotlightBackdrop.js +3 -5
  272. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  273. package/dist/internal/components/Stepper.js +1 -2
  274. package/dist/internal/components/Switch.js +1 -2
  275. package/dist/internal/components/Table.js +1 -2
  276. package/dist/internal/components/Tabs.js +1 -2
  277. package/dist/internal/components/ThemeProvider.js +2 -2
  278. package/dist/internal/components/TimePicker.js +1 -2
  279. package/dist/internal/components/Timeline.js +1 -2
  280. package/dist/internal/components/Toast.js +2 -2
  281. package/dist/internal/components/Toggle.js +2 -3
  282. package/dist/internal/components/ToggleGroup.js +1 -2
  283. package/dist/internal/components/Tooltip.js +1 -2
  284. package/dist/internal/components/Truncated.js +3 -4
  285. package/dist/internal/components/Workbench.js +1 -2
  286. package/dist/internal/components/ZoomableSvg.js +1 -2
  287. package/dist/internal/hooks/useAltDigitHotkey.js +1 -2
  288. package/dist/internal/hooks/useAutosizeInput.js +1 -2
  289. package/dist/internal/hooks/useScrollbarPosition.js +2 -3
  290. package/dist/internal/hooks/useStableCallback.js +1 -2
  291. package/dist/internal/hooks/useTimeout.js +18 -0
  292. package/dist/internal/hooks/useTimeout.js.map +1 -0
  293. package/dist/internal/utils/accessibleName.js +1 -2
  294. package/dist/internal/utils/mergeRefs.js +1 -2
  295. package/dist/internal/utils.js +3 -3
  296. package/dist/markdown-editor.d.ts +0 -4
  297. package/dist/markdown-editor.js +30 -49
  298. package/dist/markdown-editor.js.map +1 -1
  299. package/dist/mermaid.d.ts +0 -2
  300. package/dist/mermaid.js +1 -2
  301. package/dist/rjsf.d.ts +0 -8
  302. package/dist/rjsf.js +47 -78
  303. package/dist/rjsf.js.map +1 -1
  304. package/dist/{rolldown-runtime-Bdc48AWt.js → rolldown-runtime-BrwM56v-.js} +2 -3
  305. package/dist/{styles-T8xwr0sR.js → styles-BXXXosW_.js} +2 -3
  306. package/dist/{styles-T8xwr0sR.js.map → styles-BXXXosW_.js.map} +1 -1
  307. package/dist/{styles-DxazJ8Mz.js → styles-nwtCRF7y.js} +2 -3
  308. package/dist/{styles-DxazJ8Mz.js.map → styles-nwtCRF7y.js.map} +1 -1
  309. package/dist/styles.css +1 -1
  310. package/dist/{svgCache-Dhmbe-7i.js → svgCache-BzvN_fgr.js} +2 -3
  311. package/dist/{svgCache-Dhmbe-7i.js.map → svgCache-BzvN_fgr.js.map} +1 -1
  312. package/dist/{svgTransforms-Hnvev3Vs.js → svgTransforms-BBxxO9T6.js} +4 -6
  313. package/dist/{svgTransforms-Hnvev3Vs.js.map → svgTransforms-BBxxO9T6.js.map} +1 -1
  314. package/dist/testing.d.ts +0 -2
  315. package/dist/testing.js +2 -3
  316. package/dist/{themeScopeContext-CEVXbYvZ.js → themeScopeContext-BZGPdyG8.js} +6 -11
  317. package/dist/{themeScopeContext-CEVXbYvZ.js.map → themeScopeContext-BZGPdyG8.js.map} +1 -1
  318. package/dist/{themeTokens-DCeb62ap.js → themeTokens-B60cQtAY.js} +4 -6
  319. package/dist/{themeTokens-DCeb62ap.js.map → themeTokens-B60cQtAY.js.map} +1 -1
  320. package/dist/{toast-Y3cTMBW8.js → toast-Dzj1EFOb.js} +10 -17
  321. package/dist/{toast-Y3cTMBW8.js.map → toast-Dzj1EFOb.js.map} +1 -1
  322. package/dist/{types-BPcAjMG0.d.ts → types-CsZuwfxc.d.ts} +1 -3
  323. package/dist/{useControllableState-CUYXMsfz.js → useControllableState-BCvUOC6G.js} +2 -3
  324. package/dist/{useControllableState-CUYXMsfz.js.map → useControllableState-BCvUOC6G.js.map} +1 -1
  325. package/dist/{useElement-D-RjrGa4.js → useElement-Dcoo9Jlr.js} +2 -3
  326. package/dist/{useElement-D-RjrGa4.js.map → useElement-Dcoo9Jlr.js.map} +1 -1
  327. package/dist/{useMergeDiff-CvowEXJ1.js → useMergeDiff-DFIATaTw.js} +3 -5
  328. package/dist/{useMergeDiff-CvowEXJ1.js.map → useMergeDiff-DFIATaTw.js.map} +1 -1
  329. package/dist/{utils-DwC9u0tM.js → utils-DjFceY3H.js} +18 -34
  330. package/dist/utils-DjFceY3H.js.map +1 -0
  331. package/dist/vega.d.ts +1 -5
  332. package/dist/vega.js +3 -4
  333. package/dist/{vegaTheme-ISwGXvof.js → vegaTheme-BcTNRmVS.js} +3 -4
  334. package/dist/{vegaTheme-ISwGXvof.js.map → vegaTheme-BcTNRmVS.js.map} +1 -1
  335. package/dist/{vegaTokens-DCkvpIVE.js → vegaTokens-DnCcy7JY.js} +3 -4
  336. package/dist/{vegaTokens-DCkvpIVE.js.map → vegaTokens-DnCcy7JY.js.map} +1 -1
  337. package/package.json +40 -40
  338. package/src/styles.css +70 -4
  339. package/src/theme.css +117 -11
  340. package/dist/AIKit-CaAW4GLx.js.map +0 -1
  341. package/dist/AlertModal-D4AtpvLS.js.map +0 -1
  342. package/dist/Badge-5GHIsgRS.js.map +0 -1
  343. package/dist/Button-BNkyYU8u.js.map +0 -1
  344. package/dist/Calendar-BnKi1kPu.js.map +0 -1
  345. package/dist/Combobox-CaKqgstG.js.map +0 -1
  346. package/dist/DropdownMenu-CcVbZ_5u.js.map +0 -1
  347. package/dist/HoverCard-Cv5rmvJq.js +0 -26
  348. package/dist/HoverCard-Cv5rmvJq.js.map +0 -1
  349. package/dist/Modal-CbUz-5YH.js.map +0 -1
  350. package/dist/ModalTitle-cy0Ht9VY.js.map +0 -1
  351. package/dist/Popconfirm-DwLCYNaF.js.map +0 -1
  352. package/dist/Popover-DtUDwUVO.js.map +0 -1
  353. package/dist/Search-vyZwGKMU.js.map +0 -1
  354. package/dist/SearchInput-DyYXyw3u.js.map +0 -1
  355. package/dist/Select-B22hB_-w.js.map +0 -1
  356. package/dist/Sheet-0TWKTqid.js.map +0 -1
  357. package/dist/TextInput-CR0_USaY.js.map +0 -1
  358. package/dist/utils-DwC9u0tM.js.map +0 -1
@@ -1,24 +1,24 @@
1
- import { cn } from "./classNames-DcGnTh2N.js";
2
- import { Tooltip, TooltipProvider, isMac } from "./utils-DwC9u0tM.js";
3
- import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Ban, BarChart3, Bell, BookOpen, Bookmark, Box, Bug, Calendar, ChartBar, ChartPie, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CircleAlert, CircleCheck, CircleHelp, CirclePause, CirclePlay, CirclePlus, CircleStop, CircleX, Clock, Cloud, Cog, Copy, Database, Download, Ellipsis, ExternalLink, Eye, File, FilePen, FileText, Filter, Flag, Folder, Gauge, GitBranch, GitMerge, GitPullRequest, Globe, Hand, HardDrive, History, Hourglass, Info, Key, Layers, Lightbulb, LineChart, Link, List, ListChecks, Loader2, LoaderCircle, Lock, Mail, Maximize2, Minimize2, Minus, Package, Pause, Pencil, Pin, Play, Plus, Quote, RefreshCw, Rocket, RotateCcw, RotateCw, Save, Search, Send, Server, Settings, Shield, Sparkles, Star, Table, ThumbsDown, ThumbsUp, Trash2, TrendingDown, TrendingUp, TriangleAlert, Upload, User, Users, WandSparkles, Warehouse, Workflow, Wrench, X, XCircle, Zap } from "./icons-ZIeZXXS7.js";
4
- import { Button } from "./Button-BNkyYU8u.js";
1
+ import { cn } from "./classNames-DkX30VJU.js";
2
+ import { Tooltip, TooltipProvider, isMac } from "./utils-DjFceY3H.js";
3
+ import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Ban, BarChart3, Bell, BookOpen, Bookmark, Box, Bug, Calendar, ChartBar, ChartPie, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Circle, CircleAlert, CircleCheck, CircleHelp, CirclePause, CirclePlay, CirclePlus, CircleStop, CircleX, Clock, Cloud, Cog, Copy, Database, Download, Ellipsis, ExternalLink, Eye, File, FilePen, FileText, Filter, Flag, Folder, Gauge, GitBranch, GitMerge, GitPullRequest, Globe, Hand, HardDrive, History, Hourglass, Info, Key, Layers, Lightbulb, LineChart, Link, List, ListChecks, Loader2, LoaderCircle, Lock, Mail, Maximize2, Minimize2, Minus, Package, Pause, Pencil, Pin, Play, Plus, Quote, RefreshCw, Rocket, RotateCcw, RotateCw, Save, Search, Send, Server, Settings, Shield, Sparkles, Star, Table, ThumbsDown, ThumbsUp, Trash2, TrendingDown, TrendingUp, TriangleAlert, Upload, User, Users, WandSparkles, Warehouse, Workflow, Wrench, X, XCircle, Zap } from "./icons-DDR9dFSr.js";
4
+ import { Button } from "./Button-DbvGzEDb.js";
5
5
  import { ButtonGroup } from "./internal/components/ButtonGroup.js";
6
- import { ClipboardButton } from "./ClipboardButton-B1Hr_n_Z.js";
7
- import { FullScreenModal, FullScreenModalBody, FullScreenModalHeader } from "./FullScreenModal-DAvvlGOz.js";
6
+ import { ClipboardButton } from "./ClipboardButton-71Ugbl8c.js";
7
+ import { FullScreenModal, FullScreenModalBody, FullScreenModalHeader } from "./FullScreenModal-RzY5XxiG.js";
8
8
  import { Truncated } from "./internal/components/Truncated.js";
9
9
  import { useStableCallback } from "./internal/hooks/useStableCallback.js";
10
- import { HoverCard } from "./HoverCard-Cv5rmvJq.js";
11
- import { Command } from "./Command-DhXmqFLT.js";
12
- import { TextInput } from "./TextInput-CR0_USaY.js";
13
- import { Badge } from "./Badge-5GHIsgRS.js";
10
+ import { HoverCard } from "./HoverCard-OGWKRXJ7.js";
11
+ import { Command } from "./Command-BcTb6GsR.js";
12
+ import { TextInput } from "./TextInput--1CfZybC.js";
13
+ import { Badge } from "./Badge-CFRhducL.js";
14
14
  import { Textarea } from "./internal/blocks/Textarea.js";
15
- import { Kbd, keys } from "./Kbd-CflKthfu.js";
16
- import { Collapsible } from "./Collapsible-DD4xTL75.js";
17
- import { Alert } from "./Alert-Chz6KZ7e.js";
18
- import { Table as Table$1, tableAriaSort } from "./Table-CilEvpMq.js";
15
+ import { Kbd, keys } from "./Kbd-BprYCICe.js";
16
+ import { Collapsible } from "./Collapsible-zsXk4Vpp.js";
17
+ import { Alert } from "./Alert-DziS8n1H.js";
18
+ import { Table as Table$1, tableAriaSort } from "./Table-BwgBm3hJ.js";
19
19
  import { DiagramSkeleton } from "./internal/blocks/DiagramShared/DiagramSkeleton.js";
20
- import { DiagramSource, makeResponsive } from "./svgTransforms-Hnvev3Vs.js";
21
- import { ZoomableSvg, toSvgFileContent } from "./ZoomableSvg-DnFXo2L4.js";
20
+ import { DiagramSource, makeResponsive } from "./svgTransforms-BBxxO9T6.js";
21
+ import { ZoomableSvg, toSvgFileContent } from "./ZoomableSvg-BRPGgaWJ.js";
22
22
  import { Progress } from "./internal/components/Progress.js";
23
23
  import { digitFromKeyCode, useAltDigitHotkey } from "./internal/hooks/useAltDigitHotkey.js";
24
24
  import { createContext, isValidElement, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -29,7 +29,7 @@ import TextareaAutosize from "react-textarea-autosize";
29
29
  import ReactMarkdown from "react-markdown";
30
30
  import remarkGfm from "remark-gfm";
31
31
  import DOMPurify from "dompurify";
32
- //#region src/blocks/AIKit/AnswerCommentInput.tsx
32
+ // src/blocks/AIKit/AnswerCommentInput.tsx
33
33
  const MAX_COMMENT_LENGTH = 2e3;
34
34
  /**
35
35
  * One-line follow-up to a thumbs-down.
@@ -62,8 +62,7 @@ const AnswerCommentInput = ({ placeholder, onSubmit }) => {
62
62
  className: "tw:w-64 tw:max-w-full tw:[&_input]:text-ellipsis"
63
63
  });
64
64
  };
65
- //#endregion
66
- //#region src/blocks/AIKit/AnswerActions.tsx
65
+ // src/blocks/AIKit/AnswerActions.tsx
67
66
  const VOTE_BUTTONS = [{
68
67
  vote: "up",
69
68
  icon: /* @__PURE__ */ jsx(ThumbsUp, { className: "tw:size-4" })
@@ -75,6 +74,16 @@ const DEFAULT_LABELS = {
75
74
  up: "Good answer",
76
75
  down: "Bad answer"
77
76
  };
77
+ const RECORDED_VOTE_CLASSES = {
78
+ tinted: {
79
+ up: "tw:bg-success/10 tw:text-success tw:hover:not-disabled:bg-success/20 tw:hover:not-disabled:text-success",
80
+ down: "tw:bg-destructive/10 tw:text-destructive tw:hover:not-disabled:bg-destructive/20 tw:hover:not-disabled:text-destructive"
81
+ },
82
+ quiet: {
83
+ up: "tw:text-primary tw:hover:not-disabled:text-primary",
84
+ down: "tw:text-primary tw:hover:not-disabled:text-primary"
85
+ }
86
+ };
78
87
  /** Roomier for a panel; compact for a dense transcript. */
79
88
  const SIZES = {
80
89
  small: {
@@ -93,7 +102,7 @@ const SIZES = {
93
102
  * - A vote can be changed but not withdrawn; pressing the pressed one re-sends it.
94
103
  * - The caller owns the recorded vote and the write.
95
104
  */
96
- const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAULT_LABELS, confirmation, size = "small", layout = "inline", onDownComment, commentPlaceholder = "What was wrong? (optional)", onRegenerate, regenerateLabel = "Ask again" }) => {
105
+ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, extraActions = [], labels = DEFAULT_LABELS, confirmation, size = "small", layout = "inline", onDownComment, commentPlaceholder = "What was wrong? (optional)", onRegenerate, regenerateLabel = "Ask again", groupDivider = false, timestamp, voteStyle = "tinted" }) => {
97
106
  const { button, gap } = SIZES[size];
98
107
  const votes = VOTE_BUTTONS.map(({ vote: candidate, icon }) => {
99
108
  const isRecorded = vote === candidate;
@@ -105,7 +114,7 @@ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAU
105
114
  children: /* @__PURE__ */ jsx(Button, {
106
115
  size: button,
107
116
  variant: "invisible",
108
- className: cn(isRecorded && candidate === "up" && "tw:bg-success/10 tw:text-success tw:hover:not-disabled:bg-success/20 tw:hover:not-disabled:text-success", isRecorded && candidate === "down" && "tw:bg-destructive/10 tw:text-destructive tw:hover:not-disabled:bg-destructive/20 tw:hover:not-disabled:text-destructive"),
117
+ className: cn(isRecorded && RECORDED_VOTE_CLASSES[voteStyle][candidate]),
109
118
  "aria-label": label,
110
119
  "aria-pressed": isRecorded,
111
120
  onClick: () => onVote(candidate),
@@ -132,6 +141,35 @@ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAU
132
141
  children: /* @__PURE__ */ jsx(RotateCcw, { className: "tw:size-4" })
133
142
  })
134
143
  }) : null;
144
+ const extras = extraActions.map(({ id, label, icon, onSelect, disabled }) => /* @__PURE__ */ jsx(Tooltip, {
145
+ tooltip: label,
146
+ placement: "top",
147
+ triggerAsChild: true,
148
+ children: /* @__PURE__ */ jsx(Button, {
149
+ size: button,
150
+ variant: "invisible",
151
+ "aria-label": label,
152
+ disabled,
153
+ onClick: onSelect,
154
+ children: icon
155
+ })
156
+ }, id));
157
+ const time = timestamp ? /* @__PURE__ */ jsx(Tooltip, {
158
+ tooltip: timestamp,
159
+ placement: "top",
160
+ triggerAsChild: true,
161
+ children: /* @__PURE__ */ jsx(Button, {
162
+ size: button,
163
+ variant: "invisible",
164
+ "aria-label": timestamp,
165
+ className: "tw:cursor-default tw:text-muted-foreground",
166
+ children: /* @__PURE__ */ jsx(Clock, { className: "tw:size-3.5" })
167
+ })
168
+ }) : null;
169
+ const divider = groupDivider && (regenerate || actions) ? /* @__PURE__ */ jsx("span", {
170
+ "aria-hidden": true,
171
+ className: "tw:mx-1 tw:h-4 tw:w-px tw:bg-border"
172
+ }) : null;
135
173
  const comment = onDownComment && vote === "down" ? /* @__PURE__ */ jsx(AnswerCommentInput, {
136
174
  placeholder: commentPlaceholder,
137
175
  onSubmit: onDownComment
@@ -155,7 +193,9 @@ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAU
155
193
  children: [
156
194
  actions,
157
195
  regenerate,
158
- copy
196
+ copy,
197
+ extras,
198
+ time
159
199
  ]
160
200
  })
161
201
  ]
@@ -165,10 +205,13 @@ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAU
165
205
  "aria-label": "Answer actions",
166
206
  children: [
167
207
  copy,
208
+ extras,
168
209
  votes,
210
+ divider,
169
211
  regenerate,
170
212
  actions,
171
- said
213
+ said,
214
+ time
172
215
  ]
173
216
  });
174
217
  if (!comment) return group;
@@ -177,8 +220,7 @@ const AnswerActions = ({ copyText, vote, onVote, onCopy, actions, labels = DEFAU
177
220
  children: [group, comment]
178
221
  });
179
222
  };
180
- //#endregion
181
- //#region src/blocks/AIKit/SourceChip.tsx
223
+ // src/blocks/AIKit/SourceChip.tsx
182
224
  const STATE_CLASSES = {
183
225
  verified: "tw:border-solid tw:border-success/30 tw:bg-success/10 tw:text-foreground",
184
226
  unverified: "tw:border-dashed tw:border-warning/60 tw:bg-warning/10 tw:text-foreground",
@@ -197,8 +239,8 @@ const accessibleName = ({ kind, label, state = "neutral" }) => [[kind, label].fi
197
239
  * - A plain left click goes to `onClick`; modified clicks keep the link's own behaviour.
198
240
  */
199
241
  const SourceChip = (props) => {
200
- const { label, state = "neutral", icon, href, external, onClick, title, className } = props;
201
- const classes = cn("tailwindcss-preflight tw:inline-flex tw:h-6 tw:max-w-64 tw:min-w-0 tw:items-center tw:gap-1 tw:rounded-md tw:border tw:px-2 tw:text-xs tw:no-underline", STATE_CLASSES[state], (href || onClick) && "tw:cursor-pointer tw:hover:bg-hover tw:focus-visible:outline-none tw:focus-visible:ring-2 tw:focus-visible:ring-ring", className);
242
+ const { label, state = "neutral", verifiedStyle = "tinted", icon, href, external, onClick, title, className } = props;
243
+ const classes = cn("tailwindcss-preflight tw:inline-flex tw:h-6 tw:max-w-64 tw:min-w-0 tw:items-center tw:gap-1 tw:rounded-md tw:border tw:px-2 tw:text-xs tw:no-underline", STATE_CLASSES[state === "verified" && verifiedStyle === "quiet" ? "neutral" : state], (href || onClick) && "tw:cursor-pointer tw:hover:bg-hover tw:focus-visible:outline-none tw:focus-visible:ring-2 tw:focus-visible:ring-ring", className);
202
244
  const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [icon && /* @__PURE__ */ jsx("span", {
203
245
  "aria-hidden": true,
204
246
  className: "tw:inline-flex tw:shrink-0 tw:[&_svg]:size-3.5",
@@ -239,8 +281,7 @@ const SourceChip = (props) => {
239
281
  children: content
240
282
  });
241
283
  };
242
- //#endregion
243
- //#region src/blocks/AIKit/AnswerSources.tsx
284
+ // src/blocks/AIKit/AnswerSources.tsx
244
285
  const ANSWER_SOURCES_VISIBLE = 6;
245
286
  /**
246
287
  * The provenance row under an answer: where its figures came from.
@@ -249,7 +290,7 @@ const ANSWER_SOURCES_VISIBLE = 6;
249
290
  * - Collapses past `visibleCount` behind a "+N more" toggle.
250
291
  * - Empty `sources` states that none were declared, which is itself information.
251
292
  */
252
- const AnswerSources = ({ sources, label = "Sources", emptyLabel = "none declared", visibleCount = 6, footnote, className }) => {
293
+ const AnswerSources = ({ sources, label = "Sources", emptyLabel = "none declared", visibleCount = 6, footnote, trailing, verifiedStyle, className }) => {
253
294
  const [isExpanded, setIsExpanded] = useState(false);
254
295
  const isCollapsible = sources.length > visibleCount;
255
296
  const shown = isCollapsible && !isExpanded ? sources.slice(0, visibleCount) : sources;
@@ -267,7 +308,10 @@ const AnswerSources = ({ sources, label = "Sources", emptyLabel = "none declared
267
308
  className: "tw:text-muted-foreground",
268
309
  children: emptyLabel
269
310
  }),
270
- shown.map(({ id, ...chip }) => /* @__PURE__ */ jsx(SourceChip, { ...chip }, id)),
311
+ shown.map(({ id, ...chip }) => /* @__PURE__ */ jsx(SourceChip, {
312
+ verifiedStyle,
313
+ ...chip
314
+ }, id)),
271
315
  isCollapsible && /* @__PURE__ */ jsx("button", {
272
316
  type: "button",
273
317
  "aria-expanded": isExpanded,
@@ -286,13 +330,16 @@ const AnswerSources = ({ sources, label = "Sources", emptyLabel = "none declared
286
330
  unverifiedCount,
287
331
  " unverified"
288
332
  ]
333
+ }),
334
+ trailing && /* @__PURE__ */ jsx("span", {
335
+ className: "tw:inline-flex tw:shrink-0 tw:items-center tw:gap-1.5",
336
+ children: trailing
289
337
  })
290
338
  ]
291
339
  }), footnote]
292
340
  });
293
341
  };
294
- //#endregion
295
- //#region src/blocks/AIKit/CollapsibleBody.tsx
342
+ // src/blocks/AIKit/CollapsibleBody.tsx
296
343
  const CollapsibleBody = ({ isExpanded, isClosing, onClosed, children }) => {
297
344
  const handleTransitionEnd = (event) => {
298
345
  if (event.target !== event.currentTarget) return;
@@ -308,8 +355,7 @@ const CollapsibleBody = ({ isExpanded, isClosing, onClosed, children }) => {
308
355
  })
309
356
  });
310
357
  };
311
- //#endregion
312
- //#region src/blocks/AIKit/CollapsibleStepHeader.tsx
358
+ // src/blocks/AIKit/CollapsibleStepHeader.tsx
313
359
  const variantClasses = {
314
360
  success: "tw:text-muted-foreground tw:focus-visible:outline-ring tw:not-disabled:hover:text-foreground",
315
361
  error: "tw:text-destructive tw:focus-visible:outline-destructive tw:not-disabled:hover:text-destructive",
@@ -328,14 +374,14 @@ const renderVariantIcon$1 = (variant) => {
328
374
  if (variant === "error" || variant === "dismissed") return /* @__PURE__ */ jsx(XCircle, { className: iconClasses });
329
375
  return /* @__PURE__ */ jsx(CircleCheck, { className: iconClasses });
330
376
  };
331
- const CollapsibleStepHeader = ({ isExpanded, onToggle, label, variant = "success" }) => {
377
+ const CollapsibleStepHeader = ({ isExpanded, onToggle, label, variant = "success", statusMark = true }) => {
332
378
  return /* @__PURE__ */ jsxs("button", {
333
379
  type: "button",
334
380
  "aria-expanded": isExpanded,
335
381
  onClick: onToggle,
336
382
  "data-variant": variant,
337
383
  className: cn("tw:flex tw:w-fit tw:items-center tw:gap-1.5 tw:text-left tw:text-xs tw:font-medium tw:transition-colors tw:focus-visible:outline tw:focus-visible:outline-2 tw:focus-visible:outline-offset-2 tw:disabled:opacity-40", variantClasses[variant]),
338
- children: [renderVariantIcon$1(variant), /* @__PURE__ */ jsxs("span", {
384
+ children: [statusMark && renderVariantIcon$1(variant), /* @__PURE__ */ jsxs("span", {
339
385
  className: "tw:min-w-0",
340
386
  children: [
341
387
  label,
@@ -351,36 +397,49 @@ const CollapsibleStepHeader = ({ isExpanded, onToggle, label, variant = "success
351
397
  })]
352
398
  });
353
399
  };
354
- //#endregion
355
- //#region src/blocks/AIKit/hasMotion.ts
400
+ // src/blocks/AIKit/hasMotion.ts
356
401
  const hasMotion = () => typeof window.matchMedia === "function" && !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
357
- //#endregion
358
- //#region src/blocks/AIKit/InlineStepDetail.tsx
402
+ // src/blocks/AIKit/InlineStepDetail.tsx
359
403
  const InlineStepDetail = ({ children }) => /* @__PURE__ */ jsx("div", {
360
404
  className: "tw:ml-2.5 tw:whitespace-pre-wrap tw:border-l tw:border-border tw:pl-3 tw:text-xs tw:text-muted-foreground",
361
405
  children
362
406
  });
363
- //#endregion
364
- //#region src/blocks/AIKit/InlineStepLabel.tsx
407
+ // src/blocks/AIKit/InlineStepLabel.tsx
408
+ const STATUS_WORD = {
409
+ processing: "running",
410
+ success: "finished",
411
+ error: "failed",
412
+ dismissed: "not run"
413
+ };
414
+ const isQuietOutcome = (variant) => variant === "error" || variant === "dismissed";
365
415
  const renderVariantIcon = (variant) => {
366
416
  if (variant === "processing") return /* @__PURE__ */ jsx(Loader2, { className: "tw:size-3.5 tw:animate-spin tw:text-muted-foreground" });
367
417
  if (variant === "error") return /* @__PURE__ */ jsx(XCircle, { className: "tw:size-3.5 tw:text-destructive" });
368
418
  if (variant === "dismissed") return /* @__PURE__ */ jsx(XCircle, { className: "tw:size-3.5 tw:text-muted-foreground/50" });
369
419
  return /* @__PURE__ */ jsx(CircleCheck, { className: "tw:size-3.5 tw:text-muted-foreground/50" });
370
420
  };
371
- const InlineStepLabel = ({ variant, children, meta, detail, defaultExpanded = false }) => {
421
+ const InlineStepLabel = ({ variant, children, meta, detail, defaultExpanded = false, icon }) => {
372
422
  const [isExpanded, setIsExpanded] = useState(defaultExpanded);
423
+ const mark = icon ? /* @__PURE__ */ jsx("span", {
424
+ "aria-hidden": true,
425
+ className: cn("tw:inline-flex tw:text-muted-foreground tw:[&_svg]:size-3.5", isQuietOutcome(variant) && "tw:opacity-50"),
426
+ children: icon
427
+ }) : renderVariantIcon(variant);
373
428
  const row = /* @__PURE__ */ jsxs("div", {
374
429
  className: "tw:flex tw:min-w-0 tw:items-center tw:gap-1",
375
430
  children: [/* @__PURE__ */ jsx("div", {
376
431
  className: "tw:relative tw:flex tw:size-5 tw:shrink-0 tw:items-center tw:justify-center tw:[background:var(--inline-step-surface,transparent)]",
377
- children: renderVariantIcon(variant)
432
+ children: mark
378
433
  }), /* @__PURE__ */ jsxs("div", {
379
- className: "tw:flex tw:min-w-0 tw:flex-wrap tw:items-center tw:gap-x-1.5 tw:gap-y-1 tw:text-xs tw:font-medium tw:text-muted-foreground",
434
+ className: cn("tw:flex tw:min-w-0 tw:flex-wrap tw:items-center tw:gap-x-1.5 tw:gap-y-1 tw:text-xs tw:font-medium tw:text-muted-foreground", icon && isQuietOutcome(variant) && "tw:text-muted-foreground/70"),
380
435
  children: [
381
436
  children,
437
+ icon && /* @__PURE__ */ jsx("span", {
438
+ className: "tw:sr-only",
439
+ children: ` (${STATUS_WORD[variant]})`
440
+ }),
382
441
  meta && /* @__PURE__ */ jsx("span", {
383
- className: "tw:font-normal tw:text-muted-foreground/70",
442
+ className: "tw:font-normal tw:text-muted-foreground",
384
443
  children: meta
385
444
  }),
386
445
  detail && /* @__PURE__ */ jsx(Button, {
@@ -403,8 +462,7 @@ const InlineStepLabel = ({ variant, children, meta, detail, defaultExpanded = fa
403
462
  })]
404
463
  });
405
464
  };
406
- //#endregion
407
- //#region src/blocks/AIKit/AnswerSummary.tsx
465
+ // src/blocks/AIKit/AnswerSummary.tsx
408
466
  const SECTION_LABELS = {
409
467
  success: "Answered questions",
410
468
  dismissed: "Dismissed questions",
@@ -465,9 +523,8 @@ const AnswerSummary = ({ items, variant = "success", statusLabel = DEFAULT_STATU
465
523
  })]
466
524
  });
467
525
  };
468
- //#endregion
469
- //#region src/blocks/AIKit/AttachmentChip.tsx
470
- const Lead = ({ status, thumbnailUrl }) => {
526
+ // src/blocks/AIKit/AttachmentChip.tsx
527
+ const Lead = ({ status, thumbnailUrl, lead }) => {
471
528
  if (status === "uploading") return /* @__PURE__ */ jsx(LoaderCircle, {
472
529
  "aria-hidden": true,
473
530
  className: "tw:size-4 tw:shrink-0 tw:animate-spin"
@@ -476,6 +533,7 @@ const Lead = ({ status, thumbnailUrl }) => {
476
533
  "aria-hidden": true,
477
534
  className: "tw:size-4 tw:shrink-0 tw:text-destructive"
478
535
  });
536
+ if (lead) return lead;
479
537
  if (thumbnailUrl) return /* @__PURE__ */ jsx("img", {
480
538
  src: thumbnailUrl,
481
539
  alt: "",
@@ -492,16 +550,17 @@ const Lead = ({ status, thumbnailUrl }) => {
492
550
  * - Capped width with a truncating name, so a long filename cannot push the text away.
493
551
  * - `error` explains itself in a tooltip; the remove control stays available in every status.
494
552
  */
495
- const AttachmentChip = ({ name, thumbnailUrl, status, error, onRemove, trailing, className }) => {
553
+ const AttachmentChip = ({ name, thumbnailUrl, lead, label, status, error, onRemove, trailing, className }) => {
496
554
  const chip = /* @__PURE__ */ jsxs("span", {
497
555
  "data-status": status,
498
556
  className: cn("tailwindcss-preflight tw:inline-flex tw:h-6 tw:min-w-0 tw:max-w-48 tw:items-center tw:gap-1 tw:rounded-md tw:bg-muted tw:px-2 tw:text-xs tw:text-muted-foreground", status === "error" && "tw:text-destructive", className),
499
557
  children: [
500
558
  /* @__PURE__ */ jsx(Lead, {
501
559
  status,
502
- thumbnailUrl
560
+ thumbnailUrl,
561
+ lead
503
562
  }),
504
- /* @__PURE__ */ jsx("span", {
563
+ label ?? /* @__PURE__ */ jsx("span", {
505
564
  className: "tw:min-w-0 tw:truncate",
506
565
  children: name
507
566
  }),
@@ -523,8 +582,7 @@ const AttachmentChip = ({ name, thumbnailUrl, status, error, onRemove, trailing,
523
582
  children: chip
524
583
  });
525
584
  };
526
- //#endregion
527
- //#region src/blocks/AIKit/ChatInlineIcon.tsx
585
+ // src/blocks/AIKit/ChatInlineIcon.tsx
528
586
  /** Every drawable name; read through `Object.hasOwn`, or `icon:constructor` hits `Object.prototype`. */
529
587
  const ICON_REGISTRY = {
530
588
  "book-open": BookOpen,
@@ -706,8 +764,7 @@ const ChatInlineIcon = ({ name }) => {
706
764
  strokeWidth: 2.25
707
765
  });
708
766
  };
709
- //#endregion
710
- //#region src/blocks/AIKit/useCountdown.ts
767
+ // src/blocks/AIKit/useCountdown.ts
711
768
  const TICK_MS = 1e3;
712
769
  /** Whole seconds left of a countdown that starts at `seconds`; `undefined` when there is none. */
713
770
  const useCountdown = (seconds) => {
@@ -729,8 +786,7 @@ const useCountdown = (seconds) => {
729
786
  const elapsed = ticks.start === seconds ? ticks.elapsed : 0;
730
787
  return Math.max(seconds - elapsed, 0);
731
788
  };
732
- //#endregion
733
- //#region src/blocks/AIKit/ChatNotice.tsx
789
+ // src/blocks/AIKit/ChatNotice.tsx
734
790
  const ALERT_VARIANT = {
735
791
  error: "error",
736
792
  warn: "warning",
@@ -744,12 +800,12 @@ const countdownLabel = (remaining) => remaining > 0 ? `Try again in ${remaining}
744
800
  * - `details` stays collapsed so a stack trace never crowds the message.
745
801
  * - `retryAfter` appends a live countdown; `action` is always rendered, so the host decides whether to gate it.
746
802
  */
747
- const ChatNotice = ({ tone, children, action, details, retryAfter, className }) => {
803
+ const ChatNotice = ({ tone, children, action, details, retryAfter, bordered = true, className }) => {
748
804
  const remaining = useCountdown(retryAfter);
749
805
  return /* @__PURE__ */ jsx(Alert, {
750
806
  variant: ALERT_VARIANT[tone],
751
807
  role: "status",
752
- className,
808
+ className: cn(!bordered && "tw:border-0!", className),
753
809
  children: /* @__PURE__ */ jsxs("div", {
754
810
  className: "tw:flex tw:flex-wrap tw:items-start tw:gap-x-3 tw:gap-y-2",
755
811
  children: [/* @__PURE__ */ jsxs("div", {
@@ -779,8 +835,7 @@ const ChatNotice = ({ tone, children, action, details, retryAfter, className })
779
835
  })
780
836
  });
781
837
  };
782
- //#endregion
783
- //#region src/blocks/AIKit/ContextChip.tsx
838
+ // src/blocks/AIKit/ContextChip.tsx
784
839
  const CONTEXT_CHIP_EXPANDABLE_LENGTH = 120;
785
840
  /**
786
841
  * A quote or reference attached to a message being composed.
@@ -788,7 +843,7 @@ const CONTEXT_CHIP_EXPANDABLE_LENGTH = 120;
788
843
  * - The excerpt is clamped to two lines; "Show all" appears once it is long enough to be cut.
789
844
  * - Images sit under the excerpt as small thumbnails.
790
845
  */
791
- const ContextChip = ({ label, excerpt, images = [], onRemove, className }) => {
846
+ const ContextChip = ({ label, excerpt = "", images = [], number, onRemove, className }) => {
792
847
  const [isExpanded, setIsExpanded] = useState(false);
793
848
  const isExpandable = excerpt.length > 120;
794
849
  return /* @__PURE__ */ jsxs("div", {
@@ -797,24 +852,28 @@ const ContextChip = ({ label, excerpt, images = [], onRemove, className }) => {
797
852
  /* @__PURE__ */ jsxs("div", {
798
853
  className: "tw:flex tw:items-center tw:gap-1 tw:text-muted-foreground",
799
854
  children: [
800
- /* @__PURE__ */ jsx(Quote, {
855
+ number === void 0 ? /* @__PURE__ */ jsx(Quote, {
801
856
  "aria-hidden": true,
802
857
  className: "tw:size-3.5 tw:shrink-0"
858
+ }) : /* @__PURE__ */ jsx("span", {
859
+ "aria-hidden": true,
860
+ className: "tw:inline-flex tw:size-4 tw:shrink-0 tw:items-center tw:justify-center tw:rounded-full tw:bg-primary tw:text-[10px] tw:font-semibold tw:text-primary-foreground",
861
+ children: number
803
862
  }),
804
863
  /* @__PURE__ */ jsx("span", {
805
864
  className: "tw:min-w-0 tw:flex-1 tw:truncate tw:font-medium",
806
865
  children: label
807
866
  }),
808
- /* @__PURE__ */ jsx("button", {
867
+ onRemove && /* @__PURE__ */ jsx("button", {
809
868
  type: "button",
810
- "aria-label": `Remove ${label}`,
869
+ "aria-label": number === void 0 ? `Remove ${label}` : `Remove ${number}, ${label}`,
811
870
  onClick: onRemove,
812
871
  className: "tw:shrink-0 tw:cursor-pointer tw:rounded-sm tw:border-0 tw:bg-transparent tw:p-0 tw:text-muted-foreground tw:hover:text-foreground tw:focus-visible:outline-none tw:focus-visible:ring-2 tw:focus-visible:ring-ring",
813
872
  children: /* @__PURE__ */ jsx(X, { className: "tw:size-3.5" })
814
873
  })
815
874
  ]
816
875
  }),
817
- /* @__PURE__ */ jsx("p", {
876
+ excerpt && /* @__PURE__ */ jsx("p", {
818
877
  className: cn("tw:m-0 tw:whitespace-pre-wrap tw:break-words tw:text-foreground", !isExpanded && "tw:line-clamp-2"),
819
878
  children: excerpt
820
879
  }),
@@ -836,8 +895,7 @@ const ContextChip = ({ label, excerpt, images = [], onRemove, className }) => {
836
895
  ]
837
896
  });
838
897
  };
839
- //#endregion
840
- //#region src/blocks/AIKit/FileDownloadChip.tsx
898
+ // src/blocks/AIKit/FileDownloadChip.tsx
841
899
  /**
842
900
  * A file the agent wrote, offered inside its own answer.
843
901
  *
@@ -902,8 +960,7 @@ const FileDownloadChip = ({ fileName, filePath, size, isPending = false, onDownl
902
960
  ]
903
961
  });
904
962
  };
905
- //#endregion
906
- //#region src/blocks/AIKit/FileGalleryTile.tsx
963
+ // src/blocks/AIKit/FileGalleryTile.tsx
907
964
  const VISIBLE_MARGIN = "200px";
908
965
  /**
909
966
  * One image in a `FileGallery`.
@@ -968,8 +1025,7 @@ const FileGalleryTile = ({ image, onOpen, onRetry, onVisible }) => {
968
1025
  ]
969
1026
  });
970
1027
  };
971
- //#endregion
972
- //#region src/blocks/AIKit/FileGallery.tsx
1028
+ // src/blocks/AIKit/FileGallery.tsx
973
1029
  const DEFAULT_MAX_TILES = 12;
974
1030
  /**
975
1031
  * Image files the agent wrote, as a grid of thumbnails.
@@ -1003,8 +1059,7 @@ const FileGallery = ({ images, onOpen, onRetry, onImageVisible, maxTiles = DEFAU
1003
1059
  })]
1004
1060
  });
1005
1061
  };
1006
- //#endregion
1007
- //#region src/blocks/AIKit/InlineStepGroup.tsx
1062
+ // src/blocks/AIKit/InlineStepGroup.tsx
1008
1063
  /** The surface colour, as the custom property the step icons mask against. */
1009
1064
  const surfaceStyle = (surface) => ({ "--inline-step-surface": surface });
1010
1065
  /**
@@ -1015,7 +1070,7 @@ const surfaceStyle = (surface) => ({ "--inline-step-surface": surface });
1015
1070
  * - Animates `grid-template-rows`; children stay mounted while closed.
1016
1071
  * - `role="group"`, not a `region` landmark: dozens per transcript would drown real landmarks.
1017
1072
  */
1018
- const InlineStepGroup = ({ label, variant = "success", isExpanded, onToggle, surface = "rgb(var(--background))", "aria-label": ariaLabel, "data-testid": testId, className, footer, children }) => /* @__PURE__ */ jsxs("section", {
1073
+ const InlineStepGroup = ({ label, variant = "success", statusMark = true, isExpanded, onToggle, surface = "rgb(var(--background))", "aria-label": ariaLabel, "data-testid": testId, className, footer, children }) => /* @__PURE__ */ jsxs("section", {
1019
1074
  role: "group",
1020
1075
  className: cn("tw:flex tw:flex-col", className),
1021
1076
  "aria-label": ariaLabel,
@@ -1024,7 +1079,8 @@ const InlineStepGroup = ({ label, variant = "success", isExpanded, onToggle, sur
1024
1079
  isExpanded,
1025
1080
  onToggle,
1026
1081
  label,
1027
- variant
1082
+ variant,
1083
+ statusMark
1028
1084
  }), /* @__PURE__ */ jsx("div", {
1029
1085
  className: cn("tw:grid tw:transition-[grid-template-rows] tw:duration-200 tw:ease-out tw:motion-reduce:transition-none", isExpanded ? "tw:grid-rows-[1fr]" : "tw:grid-rows-[0fr]"),
1030
1086
  children: /* @__PURE__ */ jsx("div", {
@@ -1049,17 +1105,16 @@ const InlineStepGroup = ({ label, variant = "success", isExpanded, onToggle, sur
1049
1105
  })
1050
1106
  })]
1051
1107
  });
1052
- //#endregion
1053
- //#region src/blocks/AIKit/JumpToLatest.tsx
1108
+ // src/blocks/AIKit/JumpToLatest.tsx
1054
1109
  /**
1055
1110
  * Scrolls a transcript back to its newest message.
1056
1111
  *
1057
1112
  * - Renders nothing while `visible` is false.
1058
1113
  * - Positioning is the host's: pass `className` to pin it over the list.
1059
1114
  */
1060
- const JumpToLatest = ({ visible, working = false, onClick, label, className }) => {
1115
+ const JumpToLatest = ({ visible, working = false, onClick, label, tooltip, className }) => {
1061
1116
  if (!visible) return null;
1062
- return /* @__PURE__ */ jsxs(Button, {
1117
+ const button = /* @__PURE__ */ jsxs(Button, {
1063
1118
  variant: "outline",
1064
1119
  size: label ? "small" : "icon-sm",
1065
1120
  "aria-label": label ?? "Scroll to bottom",
@@ -1068,9 +1123,15 @@ const JumpToLatest = ({ visible, working = false, onClick, label, className }) =
1068
1123
  className: cn("tw:rounded-full tw:shadow-md", working && "tw:animate-pulse tw:motion-reduce:animate-none", className),
1069
1124
  children: [/* @__PURE__ */ jsx(ArrowDown, { className: "tw:size-4" }), label]
1070
1125
  });
1126
+ if (!tooltip) return button;
1127
+ return /* @__PURE__ */ jsx(Tooltip, {
1128
+ tooltip,
1129
+ placement: "left",
1130
+ triggerAsChild: true,
1131
+ children: button
1132
+ });
1071
1133
  };
1072
- //#endregion
1073
- //#region src/blocks/AIKit/DiagramBlock.tsx
1134
+ // src/blocks/AIKit/DiagramBlock.tsx
1074
1135
  /**
1075
1136
  * One diagram block: a skeleton while its chunk loads, the fence source plus a retry if it fails.
1076
1137
  *
@@ -1116,8 +1177,7 @@ const DiagramBlock = ({ load, code, renderActions }) => {
1116
1177
  })] });
1117
1178
  return /* @__PURE__ */ jsx(DiagramSkeleton, {});
1118
1179
  };
1119
- //#endregion
1120
- //#region src/blocks/AIKit/diagramChunk.ts
1180
+ // src/blocks/AIKit/diagramChunk.ts
1121
1181
  /**
1122
1182
  * An on-demand diagram chunk, shared between mounts and retryable.
1123
1183
  *
@@ -1137,8 +1197,7 @@ const diagramChunk = (name, load) => {
1137
1197
  return pending;
1138
1198
  };
1139
1199
  };
1140
- //#endregion
1141
- //#region src/blocks/AIKit/downloadSvgFile.ts
1200
+ // src/blocks/AIKit/downloadSvgFile.ts
1142
1201
  /** How long the object URL outlives the click; the download has started by then. */
1143
1202
  const REVOKE_DELAY_MS = 1e3;
1144
1203
  /** Saves sanitized SVG markup as a standalone `.svg` file. */
@@ -1153,8 +1212,7 @@ const downloadSvgFile = (svg, filename = "diagram.svg") => {
1153
1212
  anchor.remove();
1154
1213
  setTimeout(() => URL.revokeObjectURL(url), REVOKE_DELAY_MS);
1155
1214
  };
1156
- //#endregion
1157
- //#region src/blocks/AIKit/DiagramDownloadButton.tsx
1215
+ // src/blocks/AIKit/DiagramDownloadButton.tsx
1158
1216
  /** A diagram toolbar action that saves the drawn diagram as an SVG file. */
1159
1217
  const DiagramDownloadButton = ({ safeSvg }) => /* @__PURE__ */ jsx(Tooltip, {
1160
1218
  tooltip: "Download SVG",
@@ -1168,8 +1226,7 @@ const DiagramDownloadButton = ({ safeSvg }) => /* @__PURE__ */ jsx(Tooltip, {
1168
1226
  children: /* @__PURE__ */ jsx(Download, { className: "tw:size-4" })
1169
1227
  })
1170
1228
  });
1171
- //#endregion
1172
- //#region src/blocks/AIKit/highlightChunk.ts
1229
+ // src/blocks/AIKit/highlightChunk.ts
1173
1230
  let pending = null;
1174
1231
  /**
1175
1232
  * The syntax highlighter, loaded on first use and shared between blocks.
@@ -1178,15 +1235,14 @@ let pending = null;
1178
1235
  * - A failed import is logged and resolves `null`; the next block retries.
1179
1236
  */
1180
1237
  const loadHighlighter = () => {
1181
- pending ??= import("./highlightCode-D354tCXO.js").then((module) => module.highlightCode, (error) => {
1238
+ pending ??= import("./highlightCode-2spZP7ZA.js").then((module) => module.highlightCode, (error) => {
1182
1239
  console.error("[AIKit] failed to load the syntax highlighter chunk", error);
1183
1240
  pending = null;
1184
1241
  return null;
1185
1242
  });
1186
1243
  return pending;
1187
1244
  };
1188
- //#endregion
1189
- //#region src/blocks/AIKit/HighlightedCode.tsx
1245
+ // src/blocks/AIKit/HighlightedCode.tsx
1190
1246
  /**
1191
1247
  * A fenced block's `<code>`, coloured once the highlighter chunk loads.
1192
1248
  *
@@ -1217,8 +1273,7 @@ const HighlightedCode = ({ code, grammar, className, children }) => {
1217
1273
  }, index) : token.text)
1218
1274
  });
1219
1275
  };
1220
- //#endregion
1221
- //#region src/blocks/AIKit/highlightLanguages.ts
1276
+ // src/blocks/AIKit/highlightLanguages.ts
1222
1277
  /**
1223
1278
  * Fence language → the grammar that highlights it.
1224
1279
  *
@@ -1249,15 +1304,13 @@ const getHighlightGrammar = (language) => {
1249
1304
  const key = language?.toLowerCase();
1250
1305
  return key !== void 0 && Object.hasOwn(HIGHLIGHT_GRAMMARS, key) ? HIGHLIGHT_GRAMMARS[key] : void 0;
1251
1306
  };
1252
- //#endregion
1253
- //#region src/blocks/AIKit/markdownOptions.ts
1307
+ // src/blocks/AIKit/markdownOptions.ts
1254
1308
  const MarkdownOptionsContext = createContext({
1255
1309
  highlight: false,
1256
1310
  sortable: false,
1257
1311
  renderDiagramActions: void 0
1258
1312
  });
1259
- //#endregion
1260
- //#region src/blocks/AIKit/tableSort.ts
1313
+ // src/blocks/AIKit/tableSort.ts
1261
1314
  /** Characters a number cell carries for the reader: grouping, currency, percent, sign, spaces. */
1262
1315
  const NUMBER_NOISE = /[\s,_%$€£¥+]/g;
1263
1316
  /** A trailing magnitude: `142k`, `1.2M`, `3B`. */
@@ -1318,14 +1371,12 @@ const getRowCellText = (row, column) => {
1318
1371
  const cell = getRowCells(row)[column];
1319
1372
  return cell ? getHastText(cell) : "";
1320
1373
  };
1321
- //#endregion
1322
- //#region src/blocks/AIKit/tableSortContext.ts
1374
+ // src/blocks/AIKit/tableSortContext.ts
1323
1375
  /** The sort of the table being rendered; `null` outside a sortable table. */
1324
1376
  const TableSortContext = createContext(null);
1325
1377
  /** The hast cells of the row being rendered; a cell finds its column by identity. */
1326
1378
  const RowCellsContext = createContext([]);
1327
- //#endregion
1328
- //#region src/blocks/AIKit/TableSortProvider.tsx
1379
+ // src/blocks/AIKit/TableSortProvider.tsx
1329
1380
  /** Holds one table's sort; the `Markdown` header, row and body renderers read it. */
1330
1381
  const TableSortProvider = ({ children }) => {
1331
1382
  const [sort, setSort] = useState(null);
@@ -1338,8 +1389,7 @@ const TableSortProvider = ({ children }) => {
1338
1389
  children
1339
1390
  });
1340
1391
  };
1341
- //#endregion
1342
- //#region src/blocks/AIKit/MarkdownGrid.tsx
1392
+ // src/blocks/AIKit/MarkdownGrid.tsx
1343
1393
  /** The `table` renderer; a sortable block gives each table its own sort. */
1344
1394
  const MarkdownGrid = (props) => {
1345
1395
  const { className, node: _node, ...rest } = props;
@@ -1354,8 +1404,7 @@ const MarkdownGrid = (props) => {
1354
1404
  });
1355
1405
  return sortable ? /* @__PURE__ */ jsx(TableSortProvider, { children: grid }) : grid;
1356
1406
  };
1357
- //#endregion
1358
- //#region src/blocks/AIKit/MarkdownTableBody.tsx
1407
+ // src/blocks/AIKit/MarkdownTableBody.tsx
1359
1408
  /**
1360
1409
  * The body of an answer's table, in the order its sorted column puts the rows.
1361
1410
  *
@@ -1376,8 +1425,7 @@ const MarkdownTableBody = (props) => {
1376
1425
  children: order.map((index) => rows[index])
1377
1426
  });
1378
1427
  };
1379
- //#endregion
1380
- //#region src/blocks/AIKit/MarkdownTableHead.tsx
1428
+ // src/blocks/AIKit/MarkdownTableHead.tsx
1381
1429
  /**
1382
1430
  * A header cell in an answer's table; a sort control inside a sortable table.
1383
1431
  *
@@ -1403,8 +1451,7 @@ const MarkdownTableHead = (props) => {
1403
1451
  })
1404
1452
  });
1405
1453
  };
1406
- //#endregion
1407
- //#region src/blocks/AIKit/MarkdownTableRow.tsx
1454
+ // src/blocks/AIKit/MarkdownTableRow.tsx
1408
1455
  /** A row in an answer's table; inside a sortable table its cells can find their column. */
1409
1456
  const MarkdownTableRow = (props) => {
1410
1457
  const { node, ...rest } = props;
@@ -1415,8 +1462,105 @@ const MarkdownTableRow = (props) => {
1415
1462
  children: row
1416
1463
  });
1417
1464
  };
1418
- //#endregion
1419
- //#region src/blocks/AIKit/svgFence.ts
1465
+ // src/blocks/AIKit/remarkCitations.ts
1466
+ const CITATION_TAG = "citation-marker";
1467
+ const CITATION = /\[(\d+)\]/g;
1468
+ const OPAQUE = /* @__PURE__ */ new Set([
1469
+ "code",
1470
+ "inlineCode",
1471
+ "link",
1472
+ "linkReference",
1473
+ "definition"
1474
+ ]);
1475
+ const split = (text) => {
1476
+ const parts = [];
1477
+ let last = 0;
1478
+ for (const match of text.matchAll(CITATION)) {
1479
+ if (match.index > last) parts.push({
1480
+ type: "text",
1481
+ value: text.slice(last, match.index)
1482
+ });
1483
+ parts.push({
1484
+ type: "citation",
1485
+ data: {
1486
+ hName: CITATION_TAG,
1487
+ hProperties: { id: match[1] ?? "" }
1488
+ }
1489
+ });
1490
+ last = match.index + match[0].length;
1491
+ }
1492
+ if (last < text.length) parts.push({
1493
+ type: "text",
1494
+ value: text.slice(last)
1495
+ });
1496
+ return parts;
1497
+ };
1498
+ const rewrite = (node) => {
1499
+ if (OPAQUE.has(node.type) || !node.children) return;
1500
+ node.children = node.children.flatMap((child) => {
1501
+ if (child.type === "text" && child.value !== void 0) return split(child.value);
1502
+ rewrite(child);
1503
+ return [child];
1504
+ });
1505
+ };
1506
+ /**
1507
+ * Turns `[n]` in running text into a `citation-marker` element carrying `id`.
1508
+ *
1509
+ * - Code, inline code and links are left alone.
1510
+ * - Draws nothing itself: `Markdown` maps the element to the host's `renderCitation`.
1511
+ */
1512
+ const remarkCitations = () => (tree) => {
1513
+ rewrite(tree);
1514
+ };
1515
+ // src/blocks/AIKit/remarkStreamingCaret.ts
1516
+ const CARET_TAG = "streaming-caret";
1517
+ const caretNode = () => ({
1518
+ type: "streamingCaret",
1519
+ data: { hName: CARET_TAG }
1520
+ });
1521
+ const PHRASING_BLOCKS = /* @__PURE__ */ new Set([
1522
+ "paragraph",
1523
+ "heading",
1524
+ "tableCell"
1525
+ ]);
1526
+ const CONTAINERS = /* @__PURE__ */ new Set([
1527
+ "list",
1528
+ "listItem",
1529
+ "blockquote",
1530
+ "table",
1531
+ "tableRow"
1532
+ ]);
1533
+ const lastBlockOf = (node) => {
1534
+ const last = node.children?.at(-1);
1535
+ if (!last) return void 0;
1536
+ if (PHRASING_BLOCKS.has(last.type)) return last;
1537
+ if (CONTAINERS.has(last.type)) return lastBlockOf(last);
1538
+ };
1539
+ /**
1540
+ * Puts a `streaming-caret` element where the next words of a streamed answer land.
1541
+ *
1542
+ * - Inside the last paragraph, heading or table cell, descending through lists, quotes and tables.
1543
+ * - After the block when the answer ends in something else, e.g. a code fence.
1544
+ * - Draws nothing itself: `Markdown` maps the element to its caret.
1545
+ */
1546
+ const remarkStreamingCaret = () => (tree) => {
1547
+ const target = lastBlockOf(tree) ?? tree;
1548
+ target.children = [...target.children ?? [], caretNode()];
1549
+ };
1550
+ // src/blocks/AIKit/StreamingCaret.tsx
1551
+ /** The mark at the end of a streamed answer; still under reduced motion. */
1552
+ const StreamingCaret = ({ moment, finishingLabel }) => /* @__PURE__ */ jsxs("span", {
1553
+ "data-streaming-caret": moment,
1554
+ className: "tw:whitespace-nowrap",
1555
+ children: [/* @__PURE__ */ jsx("span", {
1556
+ "aria-hidden": true,
1557
+ className: cn("tw:ml-0.5 tw:inline-block tw:h-[1em] tw:w-0.5 tw:translate-y-[0.15em] tw:rounded-full tw:bg-foreground", moment === "writing" && "tw:animate-pulse tw:motion-reduce:animate-none")
1558
+ }), moment === "finishing" && /* @__PURE__ */ jsx("span", {
1559
+ className: "tw:ml-1.5 tw:text-sm tw:text-muted-foreground",
1560
+ children: finishingLabel
1561
+ })]
1562
+ });
1563
+ // src/blocks/AIKit/svgFence.ts
1420
1564
  /** Fence languages whose body may be a single SVG document. */
1421
1565
  const SVG_FENCE_LANGUAGES = [
1422
1566
  "svg",
@@ -1500,8 +1644,7 @@ const svgFenceDocument = (language, body) => {
1500
1644
  if (!SVG_ROOT.test(text.slice(at, at + 5))) return null;
1501
1645
  return svgEndTagEnd(text, at) === text.length ? text.slice(at) : null;
1502
1646
  };
1503
- //#endregion
1504
- //#region src/blocks/AIKit/scopeSvgReferences.ts
1647
+ // src/blocks/AIKit/scopeSvgReferences.ts
1505
1648
  /** More cloned nodes than any honest chart needs; matplotlib's glyphs stay well under it. */
1506
1649
  const MAX_CLONED_NODES = 2e4;
1507
1650
  const LINK_ATTRIBUTES = ["href", "xlink:href"];
@@ -1598,8 +1741,7 @@ const scopeSvgReferences = (root) => {
1598
1741
  }
1599
1742
  }
1600
1743
  };
1601
- //#endregion
1602
- //#region src/blocks/AIKit/filterSvgStyle.ts
1744
+ // src/blocks/AIKit/filterSvgStyle.ts
1603
1745
  /** The CSS properties a fenced chart may set inline: nothing that loads a URL or leaves the box. */
1604
1746
  const SAFE_PROPERTIES = /* @__PURE__ */ new Set([
1605
1747
  "alignment-baseline",
@@ -1669,8 +1811,7 @@ const filterSvgStyle = (style) => style.split(";").flatMap((declaration) => {
1669
1811
  const value = declaration.slice(colon + 1).trim();
1670
1812
  return isSafeDeclaration(property, value) ? [`${property}: ${value}`] : [];
1671
1813
  }).join("; ");
1672
- //#endregion
1673
- //#region src/blocks/AIKit/sanitizeSvgFence.ts
1814
+ // src/blocks/AIKit/sanitizeSvgFence.ts
1674
1815
  /**
1675
1816
  * Elements a fenced chart never keeps.
1676
1817
  *
@@ -1724,12 +1865,10 @@ const sanitizeSvgFence = (svg) => {
1724
1865
  scopeSvgReferences(template.content);
1725
1866
  return template.innerHTML;
1726
1867
  };
1727
- //#endregion
1728
- //#region src/blocks/AIKit/SvgFencesContext.ts
1868
+ // src/blocks/AIKit/SvgFencesContext.ts
1729
1869
  /** Whether the `Markdown.Block` being rendered draws ```svg fences; off by default. */
1730
1870
  const SvgFencesContext = createContext(false);
1731
- //#endregion
1732
- //#region src/blocks/AIKit/SvgFenceChart.tsx
1871
+ // src/blocks/AIKit/SvgFenceChart.tsx
1733
1872
  /** A fenced SVG chart, sanitized and drawn responsive, in a block that opted in. */
1734
1873
  const SvgFenceChart = ({ svg, source, children }) => {
1735
1874
  const allowed = use(SvgFencesContext);
@@ -1742,25 +1881,28 @@ const SvgFenceChart = ({ svg, source, children }) => {
1742
1881
  allowUse: true
1743
1882
  });
1744
1883
  };
1745
- /**
1746
- * The fence languages `Markdown` draws instead of printing.
1747
- *
1748
- * - Streaming callers hold an open fence back as plain code, or every keystroke fetches the chunk.
1749
- * - Frozen: it is shared across every app in the bundle.
1750
- */
1751
- const DIAGRAM_LANGUAGES = Object.freeze([...[
1752
- "mermaid",
1753
- "flint",
1754
- "flint-chart"
1755
- ]]);
1756
- //#endregion
1757
- //#region src/blocks/AIKit/Markdown.tsx
1884
+ // src/blocks/AIKit/Markdown.tsx
1758
1885
  const loadMermaid = diagramChunk("MermaidDiagram", () => import("@keboola/design/mermaid").then((module) => module.MermaidDiagram));
1759
1886
  const loadFlint = diagramChunk("FlintChart", () => import("@keboola/design/flint").then((module) => module.FlintChart));
1760
1887
  const PROSE_CLASS = {
1761
1888
  answer: "tw:prose tw:prose-answer tw:prose-code-chip tw:break-words",
1762
1889
  chrome: "tw:prose tw:prose-sm tw:prose-code-chip tw:break-words"
1763
1890
  };
1891
+ /**
1892
+ * How large an answer's headings run.
1893
+ *
1894
+ * - `default`: the prose scale.
1895
+ * - `compact`: answer-sized, so a heading in a chat bubble does not outweigh the reply around it.
1896
+ * - Utilities carry `!`: `tw:prose-answer` rules sit above any plain utility.
1897
+ */
1898
+ const HEADING_CLASS = {
1899
+ default: void 0,
1900
+ compact: [
1901
+ "tw:[&_h1]:text-lg! tw:[&_h2]:text-base! tw:[&_h3]:text-[0.9375rem]! tw:[&_h4]:text-sm!",
1902
+ "tw:[&_:is(h1,h2,h3,h4)]:mt-4! tw:[&_:is(h1,h2,h3,h4)]:mb-1.5! tw:[&_:is(h1,h2,h3,h4)]:leading-snug!",
1903
+ "tw:[&_:is(h1,h2,h3,h4):first-child]:mt-0!"
1904
+ ].join(" ")
1905
+ };
1764
1906
  const getText = (node) => {
1765
1907
  if (typeof node === "string") return node;
1766
1908
  if (typeof node === "number") return String(node);
@@ -1900,9 +2042,10 @@ const baseComponents = {
1900
2042
  * - `data-prose` is `MessageBubble`'s colour hook; Tailwind can't target `tw:prose` directly.
1901
2043
  * - Spacing overrides need `!`: `tw:prose-answer` rules are `(0,2,1)`, above `[&_p]:mb-1`.
1902
2044
  */
1903
- const MarkdownRoot = ({ children, className, rhythm = "answer" }) => /* @__PURE__ */ jsx("div", {
2045
+ const MarkdownRoot = ({ children, className, rhythm = "answer", headingScale = "default" }) => /* @__PURE__ */ jsx("div", {
1904
2046
  "data-prose": true,
1905
- className: cn(PROSE_CLASS[rhythm], className),
2047
+ "data-heading-scale": headingScale,
2048
+ className: cn(PROSE_CLASS[rhythm], HEADING_CLASS[headingScale], className),
1906
2049
  children
1907
2050
  });
1908
2051
  /** The diagram toolbar a block asks for: the caller's actions, then the built-in download. */
@@ -1911,7 +2054,7 @@ const composeDiagramActions = (diagramActions, diagramDownload) => {
1911
2054
  return (safeSvg) => /* @__PURE__ */ jsxs(Fragment$1, { children: [diagramActions?.(safeSvg), /* @__PURE__ */ jsx(DiagramDownloadButton, { safeSvg })] });
1912
2055
  };
1913
2056
  /** One parsed piece of an answer, with no surface of its own; memoise at the call site. */
1914
- const MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides, highlight = false, sortable = false, diagramActions, diagramDownload = false, allowSvgFences = false }) => {
2057
+ const MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides, highlight = false, sortable = false, diagramActions, diagramDownload = false, allowSvgFences = false, renderCitation, caret, finishingLabel = "Finishing…" }) => {
1915
2058
  const options = useMemo(() => ({
1916
2059
  highlight,
1917
2060
  sortable,
@@ -1922,16 +2065,37 @@ const MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides
1922
2065
  diagramActions,
1923
2066
  diagramDownload
1924
2067
  ]);
2068
+ const plugins = useMemo(() => [
2069
+ ...baseRemarkPlugins,
2070
+ ...renderCitation ? [remarkCitations] : [],
2071
+ ...remarkPlugins ?? [],
2072
+ ...caret ? [remarkStreamingCaret] : []
2073
+ ], [
2074
+ renderCitation,
2075
+ remarkPlugins,
2076
+ caret
2077
+ ]);
2078
+ const components = useMemo(() => ({
2079
+ ...baseComponents,
2080
+ ...renderCitation && { ["citation-marker"]: ({ id }) => renderCitation(id ?? "") },
2081
+ ...caret && { ["streaming-caret"]: () => /* @__PURE__ */ jsx(StreamingCaret, {
2082
+ moment: caret,
2083
+ finishingLabel
2084
+ }) },
2085
+ ...componentOverrides
2086
+ }), [
2087
+ renderCitation,
2088
+ componentOverrides,
2089
+ caret,
2090
+ finishingLabel
2091
+ ]);
1925
2092
  return /* @__PURE__ */ jsx(MarkdownOptionsContext, {
1926
2093
  value: options,
1927
2094
  children: /* @__PURE__ */ jsx(SvgFencesContext, {
1928
2095
  value: allowSvgFences,
1929
2096
  children: /* @__PURE__ */ jsx(ReactMarkdown, {
1930
- remarkPlugins: remarkPlugins === void 0 ? baseRemarkPlugins : [...baseRemarkPlugins, ...remarkPlugins],
1931
- components: componentOverrides === void 0 ? baseComponents : {
1932
- ...baseComponents,
1933
- ...componentOverrides
1934
- },
2097
+ remarkPlugins: plugins,
2098
+ components,
1935
2099
  children
1936
2100
  })
1937
2101
  })
@@ -1942,16 +2106,17 @@ const MarkdownBlock = ({ children, remarkPlugins, components: componentOverrides
1942
2106
  *
1943
2107
  * - Needs a `TooltipProvider` at the app root (code copy button).
1944
2108
  * - Pass `rhythm="chrome"` for content a model did not write.
2109
+ * - Pass `headingScale="compact"` for headings sized to a chat answer.
1945
2110
  */
1946
- const Markdown = ({ className, rhythm, ...blockProps }) => /* @__PURE__ */ jsx(MarkdownRoot, {
2111
+ const Markdown = ({ className, rhythm, headingScale, ...blockProps }) => /* @__PURE__ */ jsx(MarkdownRoot, {
1947
2112
  className,
1948
2113
  rhythm,
2114
+ headingScale,
1949
2115
  children: /* @__PURE__ */ jsx(MarkdownBlock, { ...blockProps })
1950
2116
  });
1951
2117
  Markdown.Root = MarkdownRoot;
1952
2118
  Markdown.Block = MarkdownBlock;
1953
- //#endregion
1954
- //#region src/blocks/AIKit/MarkdownTable.tsx
2119
+ // src/blocks/AIKit/MarkdownTable.tsx
1955
2120
  /** How much wider than its column a table has to be before the column is the wrong surface. */
1956
2121
  const EXPAND_RATIO = 1.5;
1957
2122
  /**
@@ -2030,8 +2195,7 @@ const MarkdownTable = ({ children, actions, onExpand, surface = "card", sortable
2030
2195
  })]
2031
2196
  });
2032
2197
  };
2033
- //#endregion
2034
- //#region src/blocks/AIKit/CollapsedMessageBody.tsx
2198
+ // src/blocks/AIKit/CollapsedMessageBody.tsx
2035
2199
  /**
2036
2200
  * Clips tall content at `maxHeight` behind a fade, with a Show more / Show less toggle.
2037
2201
  *
@@ -2072,8 +2236,7 @@ const CollapsedMessageBody = ({ maxHeight, fadeClassName, children }) => {
2072
2236
  })]
2073
2237
  });
2074
2238
  };
2075
- //#endregion
2076
- //#region src/blocks/AIKit/MessageDeliveryStatus.tsx
2239
+ // src/blocks/AIKit/MessageDeliveryStatus.tsx
2077
2240
  /**
2078
2241
  * Where a sent message stands, until it is delivered.
2079
2242
  *
@@ -2097,8 +2260,7 @@ const MessageDeliveryStatus = ({ status, onRetry }) => {
2097
2260
  })]
2098
2261
  });
2099
2262
  };
2100
- //#endregion
2101
- //#region src/blocks/AIKit/MessageTimestamp.tsx
2263
+ // src/blocks/AIKit/MessageTimestamp.tsx
2102
2264
  const TIME_FORMAT = {
2103
2265
  hour: "2-digit",
2104
2266
  minute: "2-digit"
@@ -2119,8 +2281,7 @@ const MessageTimestamp = ({ createdAt }) => {
2119
2281
  children: date.toLocaleTimeString([], TIME_FORMAT)
2120
2282
  });
2121
2283
  };
2122
- //#endregion
2123
- //#region src/blocks/AIKit/MessageBubble.tsx
2284
+ // src/blocks/AIKit/MessageBubble.tsx
2124
2285
  const containerClasses = cva([
2125
2286
  "tw:flex",
2126
2287
  "tw:max-w-full",
@@ -2174,7 +2335,7 @@ const contentClasses = cva([
2174
2335
  } },
2175
2336
  defaultVariants: { variant: "assistant" }
2176
2337
  });
2177
- const MessageBubble = ({ variant, children, actions, createdAt, timestamp = "tooltip", quote, status, onRetry, author, collapseAfterPx, avatar }) => {
2338
+ const MessageBubble = ({ variant, children, actions, createdAt, timestamp = "tooltip", quote, status, onRetry, author, collapseAfterPx, footer, avatar }) => {
2178
2339
  const isTimestampVisible = timestamp === "visible" && createdAt !== void 0;
2179
2340
  const isSending = variant === "user" && status === "sending";
2180
2341
  const deliveryStatus = variant === "user" && status ? /* @__PURE__ */ jsx(MessageDeliveryStatus, {
@@ -2207,6 +2368,7 @@ const MessageBubble = ({ variant, children, actions, createdAt, timestamp = "too
2207
2368
  children: quote
2208
2369
  }), body]
2209
2370
  }),
2371
+ footer,
2210
2372
  hasActionsRow ? /* @__PURE__ */ jsxs("div", {
2211
2373
  className: "tw:flex tw:items-center tw:gap-2",
2212
2374
  children: [
@@ -2221,8 +2383,7 @@ const MessageBubble = ({ variant, children, actions, createdAt, timestamp = "too
2221
2383
  ]
2222
2384
  });
2223
2385
  };
2224
- //#endregion
2225
- //#region src/blocks/AIKit/ModeChip.tsx
2386
+ // src/blocks/AIKit/ModeChip.tsx
2226
2387
  /**
2227
2388
  * A removable pill naming a mode the composer is in.
2228
2389
  *
@@ -2257,8 +2418,7 @@ const ModeChip = ({ children, visible = true, tooltip, removeLabel, color = "amb
2257
2418
  })
2258
2419
  });
2259
2420
  };
2260
- //#endregion
2261
- //#region src/blocks/AIKit/PlanApproval.tsx
2421
+ // src/blocks/AIKit/PlanApproval.tsx
2262
2422
  const defaultStepCountLabel = (count) => `${count} step${count === 1 ? "" : "s"}`;
2263
2423
  const STATUS_PILL_COLOR = {
2264
2424
  pending: "green",
@@ -2566,8 +2726,7 @@ const PlanApproval = ({ status, statusLabel, statusMessage, title, summary, step
2566
2726
  ]
2567
2727
  })] });
2568
2728
  };
2569
- //#endregion
2570
- //#region src/blocks/AIKit/PlanRewritingIndicator.tsx
2729
+ // src/blocks/AIKit/PlanRewritingIndicator.tsx
2571
2730
  const PlanRewritingIndicator = ({ label = "Rewriting the plan..." }) => /* @__PURE__ */ jsxs("div", {
2572
2731
  className: "tw:flex tw:items-center tw:gap-2",
2573
2732
  role: "status",
@@ -2577,8 +2736,7 @@ const PlanRewritingIndicator = ({ label = "Rewriting the plan..." }) => /* @__PU
2577
2736
  children: label
2578
2737
  })]
2579
2738
  });
2580
- //#endregion
2581
- //#region src/blocks/AIKit/constants.ts
2739
+ // src/blocks/AIKit/constants.ts
2582
2740
  /**
2583
2741
  * Names the container query `PromptInput`'s `inline` row reads to fold into the stacked layout.
2584
2742
  *
@@ -2587,8 +2745,7 @@ const PlanRewritingIndicator = ({ label = "Rewriting the plan..." }) => /* @__PU
2587
2745
  * never names it keeps the one-line row at every width.
2588
2746
  */
2589
2747
  const PROMPT_INPUT_CONTAINER = "tw:@container/composer";
2590
- //#endregion
2591
- //#region src/blocks/AIKit/AnimatedHeight.tsx
2748
+ // src/blocks/AIKit/AnimatedHeight.tsx
2592
2749
  /**
2593
2750
  * A box whose height eases to whatever its content measures.
2594
2751
  *
@@ -2629,8 +2786,7 @@ const AnimatedHeight = ({ children, className }) => {
2629
2786
  })
2630
2787
  });
2631
2788
  };
2632
- //#endregion
2633
- //#region src/blocks/AIKit/PromptInputAction.tsx
2789
+ // src/blocks/AIKit/PromptInputAction.tsx
2634
2790
  const PromptInputAction = ({ ref, onMouseDown, ...rest }) => {
2635
2791
  const handleOnMouseDown = (event) => {
2636
2792
  event.stopPropagation();
@@ -2642,8 +2798,7 @@ const PromptInputAction = ({ ref, onMouseDown, ...rest }) => {
2642
2798
  onMouseDown: handleOnMouseDown
2643
2799
  });
2644
2800
  };
2645
- //#endregion
2646
- //#region src/blocks/AIKit/PromptInputCommands.tsx
2801
+ // src/blocks/AIKit/PromptInputCommands.tsx
2647
2802
  /** What the menu needs above or below the composer before it will open on that side. */
2648
2803
  const MENU_HEIGHT = 440;
2649
2804
  /** As tall as the list ever gets, however much room there is. */
@@ -2806,8 +2961,7 @@ const PromptInputCommands = ({ items, open, onSelect, filterValue, tabPicks = fa
2806
2961
  }), children]
2807
2962
  });
2808
2963
  };
2809
- //#endregion
2810
- //#region src/blocks/AIKit/PromptInputMenuTrigger.tsx
2964
+ // src/blocks/AIKit/PromptInputMenuTrigger.tsx
2811
2965
  /**
2812
2966
  * The composer's "add to message" button.
2813
2967
  *
@@ -2827,18 +2981,18 @@ const PromptInputMenuTrigger = ({ open = false, large = false, className, ref, .
2827
2981
  ...props,
2828
2982
  children: /* @__PURE__ */ jsx(Plus, { className: cn(large ? "tw:size-5" : "tw:size-4", "tw:transition-transform tw:duration-300 tw:ease-out tw:motion-reduce:transition-none", open && "tw:rotate-135") })
2829
2983
  }) });
2830
- //#endregion
2831
- //#region src/blocks/AIKit/PromptInputSubmit.tsx
2984
+ // src/blocks/AIKit/PromptInputSubmit.tsx
2832
2985
  const ARIA_LABEL_BY_STATUS = {
2833
2986
  ready: "Send message",
2834
2987
  streaming: "Stop",
2835
2988
  interrupted: "Continue",
2836
2989
  submitted: "Sending…"
2837
2990
  };
2838
- const PromptInputSubmit = ({ ref, disabled, status = "ready" }) => {
2991
+ const PromptInputSubmit = ({ ref, disabled, status = "ready", sendIcon = "plane" }) => {
2839
2992
  const icon = (() => {
2840
2993
  if (status === "streaming") return /* @__PURE__ */ jsx(CirclePause, { className: "tw:size-4" });
2841
2994
  if (status === "interrupted") return /* @__PURE__ */ jsx(Play, { className: "tw:size-4" });
2995
+ if (sendIcon === "arrow-up") return /* @__PURE__ */ jsx(ArrowUp, { className: "tw:size-4" });
2842
2996
  return /* @__PURE__ */ jsx(Send, { className: "tw:size-4 tw:translate-x-[-1px] tw:translate-y-[1px]" });
2843
2997
  })();
2844
2998
  const getTooltipText = () => {
@@ -2864,8 +3018,7 @@ const PromptInputSubmit = ({ ref, disabled, status = "ready" }) => {
2864
3018
  children: getTooltipText()
2865
3019
  })] });
2866
3020
  };
2867
- //#endregion
2868
- //#region src/blocks/AIKit/usePromptHistory.ts
3021
+ // src/blocks/AIKit/usePromptHistory.ts
2869
3022
  /** The prompts ↑ steps through: blanks dropped, a prompt sent twice in a row kept once. */
2870
3023
  const toRecallStack = (history) => history.reduce((stack, prompt) => {
2871
3024
  if (prompt.trim() && stack.at(-1) !== prompt) stack.push(prompt);
@@ -2926,8 +3079,7 @@ const usePromptHistory = ({ history, value, onRecall }) => {
2926
3079
  stop
2927
3080
  };
2928
3081
  };
2929
- //#endregion
2930
- //#region src/blocks/AIKit/PromptInput.tsx
3082
+ // src/blocks/AIKit/PromptInput.tsx
2931
3083
  const CMDK_HIJACKED_KEYS = /* @__PURE__ */ new Set([
2932
3084
  "ArrowUp",
2933
3085
  "ArrowDown",
@@ -3016,11 +3168,17 @@ const wrapperVariants = cva(null, {
3016
3168
  inline: ""
3017
3169
  } }
3018
3170
  });
3019
- const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, attachments, className, disabled, disableSubmit, busy = false, blurOnEscape = false, onKeyDown, onPasteFiles, canSubmitEmpty = false, allowSendWhileBusy = false, canAbort = true, value = "", onValueChange, status = "ready", maxRows = 6, minRows, commands, commandsEmptyText = "No commands found", commandsLoading = false, slashTrigger = "value", commandsGroupAction, panel, mentions, onMentionSelect, mentionsEmptyText = "Nothing to attach", mentionsGroupHeading, mentionsMultiple = false, history, autoFocus, textareaRef: publishedRef, ...textareaProps }) => {
3171
+ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, attachments, className, shellClassName, onFocusChange, disabled, disableSubmit, busy = false, blurOnEscape = false, onKeyDown, onPasteFiles, canSubmitEmpty = false, allowSendWhileBusy = false, canAbort = true, value = "", onValueChange, status = "ready", sendIcon, maxRows = 6, minRows, commands, commandsEmptyText = "No commands found", commandsLoading = false, slashTrigger = "value", commandsGroupAction, panel, mentions, onMentionSelect, mentionInsert, mentionsEmptyText = "Nothing to attach", mentionsGroupHeading, mentionsMultiple = false, history, autoFocus, textareaRef: publishedRef, ...textareaProps }) => {
3020
3172
  const defaultMinRows = variant === "inline" ? 1 : 2;
3021
3173
  const canSendWhileBusy = allowSendWhileBusy && (status === "streaming" || status === "submitted") && !busy && !disabled && !disableSubmit && value.trim() !== "";
3022
3174
  const showSeparateStop = allowSendWhileBusy && canAbort && (canSendWhileBusy || status === "submitted");
3023
3175
  const isDisabled = busy || !canSendWhileBusy && (disabled || disableSubmit || !canSubmitEmpty && !value.trim()) && status !== "streaming" && status !== "interrupted";
3176
+ const [isFocused, setIsFocused] = useState(false);
3177
+ const changeFocus = (next) => {
3178
+ if (next === isFocused) return;
3179
+ setIsFocused(next);
3180
+ onFocusChange?.(next);
3181
+ };
3024
3182
  const textareaId = useId();
3025
3183
  const textareaRef = useRef(null);
3026
3184
  const setTextareaNode = useCallback((node) => {
@@ -3104,7 +3262,7 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
3104
3262
  return;
3105
3263
  }
3106
3264
  if (mentionToken) {
3107
- const keep = mentionsMultiple ? "@" : "";
3265
+ const keep = mentionsMultiple ? "@" : mentionInsert?.(item) ?? "";
3108
3266
  const next = value.slice(0, mentionToken.start) + keep + value.slice(mentionToken.end);
3109
3267
  const nextCaret = mentionToken.start + keep.length;
3110
3268
  onValueChange?.(next);
@@ -3179,11 +3337,16 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
3179
3337
  textareaRef.current?.focus();
3180
3338
  };
3181
3339
  const formEl = /* @__PURE__ */ jsx("div", {
3182
- className: wrapperVariants({ variant }),
3340
+ className: cn(wrapperVariants({ variant }), shellClassName),
3341
+ "data-focused": isFocused ? "" : void 0,
3183
3342
  children: /* @__PURE__ */ jsxs("form", {
3184
3343
  "data-testid": "prompt-input",
3185
3344
  "data-status": status,
3186
3345
  onKeyDown: handleOnFormKeyDown,
3346
+ onFocus: () => changeFocus(true),
3347
+ onBlur: (event) => {
3348
+ if (!event.currentTarget.contains(event.relatedTarget)) changeFocus(false);
3349
+ },
3187
3350
  onMouseDown: handleOnMouseDown,
3188
3351
  onSubmit: handleOnSubmit,
3189
3352
  className: cn(promptInputVariants({ variant }), disabled && "tw:bg-none tw:border-border tw:shadow-[inset_0_100vw_rgb(var(--muted))] tw:cursor-default", className),
@@ -3248,7 +3411,8 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
3248
3411
  })] }),
3249
3412
  /* @__PURE__ */ jsx(PromptInputSubmit, {
3250
3413
  disabled: isDisabled,
3251
- status: canSendWhileBusy ? "ready" : status
3414
+ status: canSendWhileBusy ? "ready" : status,
3415
+ sendIcon
3252
3416
  })
3253
3417
  ]
3254
3418
  })
@@ -3272,8 +3436,7 @@ const PromptInput = ({ onSend, onAbort, onContinue, prefix, variant, suffix, att
3272
3436
  };
3273
3437
  PromptInput.Action = PromptInputAction;
3274
3438
  PromptInput.MenuTrigger = PromptInputMenuTrigger;
3275
- //#endregion
3276
- //#region src/blocks/AIKit/Question.tsx
3439
+ // src/blocks/AIKit/Question.tsx
3277
3440
  const isEditableTarget$1 = (target) => target instanceof HTMLElement && (target.isContentEditable || [
3278
3441
  "INPUT",
3279
3442
  "TEXTAREA",
@@ -3687,8 +3850,7 @@ const Question = ({ question, header, options, multiSelect = true, selectedOptio
3687
3850
  ]
3688
3851
  });
3689
3852
  };
3690
- //#endregion
3691
- //#region src/blocks/AIKit/QuestionBlock.tsx
3853
+ // src/blocks/AIKit/QuestionBlock.tsx
3692
3854
  const QuestionBlock = ({ steps, showSkip = true, onSubmit, onClose, renderPreview, className }) => {
3693
3855
  const [currentStep, setCurrentStep] = useState(1);
3694
3856
  const [selections, setSelections] = useState({});
@@ -3731,8 +3893,18 @@ const QuestionBlock = ({ steps, showSkip = true, onSubmit, onClose, renderPrevie
3731
3893
  className
3732
3894
  }, currentStep);
3733
3895
  };
3734
- //#endregion
3735
- //#region src/blocks/AIKit/streamingMarkdown.ts
3896
+ /**
3897
+ * The fence languages `Markdown` draws instead of printing.
3898
+ *
3899
+ * - Streaming callers hold an open fence back as plain code, or every keystroke fetches the chunk.
3900
+ * - Frozen: it is shared across every app in the bundle.
3901
+ */
3902
+ const DIAGRAM_LANGUAGES = Object.freeze([...[
3903
+ "mermaid",
3904
+ "flint",
3905
+ "flint-chart"
3906
+ ]]);
3907
+ // src/blocks/AIKit/streamingMarkdown.ts
3736
3908
  /** A fence delimiter line: up to three spaces, then three or more backticks or tildes. */
3737
3909
  const FENCE_LINE = /^ {0,3}(`{3,}|~{3,})/;
3738
3910
  /** A list-item marker: a bullet or a `1.`/`1)` ordinal, then a space or the line end. */
@@ -3883,8 +4055,7 @@ const withholdOpenTail = (text, { diagram = false, tableHead = false } = {}) =>
3883
4055
  if (visible === null) return text;
3884
4056
  return tableHead ? withholdTableHead(visible) : visible;
3885
4057
  };
3886
- //#endregion
3887
- //#region src/blocks/AIKit/SuggestedPrompt.tsx
4058
+ // src/blocks/AIKit/SuggestedPrompt.tsx
3888
4059
  const SuggestedPrompt = ({ label, disabled, onClick, icon, description, trailing, "aria-label": ariaLabel, variant = "row", className }) => {
3889
4060
  return /* @__PURE__ */ jsxs("button", {
3890
4061
  type: "button",
@@ -3916,8 +4087,7 @@ const SuggestedPrompt = ({ label, disabled, onClick, icon, description, trailing
3916
4087
  ]
3917
4088
  });
3918
4089
  };
3919
- //#endregion
3920
- //#region src/blocks/AIKit/ThinkingIndicator.tsx
4090
+ // src/blocks/AIKit/ThinkingIndicator.tsx
3921
4091
  /**
3922
4092
  * The agent's turn is in flight and has nothing to show yet.
3923
4093
  *
@@ -3941,8 +4111,7 @@ const ThinkingIndicator = ({ label = "Thinking..." }) => {
3941
4111
  })]
3942
4112
  });
3943
4113
  };
3944
- //#endregion
3945
- //#region src/blocks/AIKit/ToolCall/ToolCallApprovalActions.tsx
4114
+ // src/blocks/AIKit/ToolCall/ToolCallApprovalActions.tsx
3946
4115
  const ShortcutHint = ({ shortcutKey }) => /* @__PURE__ */ jsxs(Kbd.Group, {
3947
4116
  separator: "+",
3948
4117
  children: [shortcutKey === "mod-enter" && /* @__PURE__ */ jsx(Kbd, {
@@ -3998,8 +4167,7 @@ const ToolCallApprovalActions = ({ onApprove, onReject, extraAction, approveLabe
3998
4167
  ]
3999
4168
  });
4000
4169
  };
4001
- //#endregion
4002
- //#region src/blocks/AIKit/ToolCall/ToolCallApprovalNotice.tsx
4170
+ // src/blocks/AIKit/ToolCall/ToolCallApprovalNotice.tsx
4003
4171
  const TONE = {
4004
4172
  warning: {
4005
4173
  icon: TriangleAlert,
@@ -4029,8 +4197,7 @@ const ToolCallApprovalNotice = ({ tone, content, icon }) => {
4029
4197
  })]
4030
4198
  });
4031
4199
  };
4032
- //#endregion
4033
- //#region src/blocks/AIKit/ToolCall/ToolCallApprovalRecord.tsx
4200
+ // src/blocks/AIKit/ToolCall/ToolCallApprovalRecord.tsx
4034
4201
  const ToolCallApprovalRecord = ({ status, label, subject, resolvedBy, resolvedAt, className }) => {
4035
4202
  const isApproved = status === "approved";
4036
4203
  const Icon = isApproved ? CircleCheck : CircleX;
@@ -4062,8 +4229,7 @@ const ToolCallApprovalRecord = ({ status, label, subject, resolvedBy, resolvedAt
4062
4229
  })]
4063
4230
  });
4064
4231
  };
4065
- //#endregion
4066
- //#region src/blocks/AIKit/ToolCall/toolCallApprovalStatus.ts
4232
+ // src/blocks/AIKit/ToolCall/toolCallApprovalStatus.ts
4067
4233
  const STATUS_BADGE = {
4068
4234
  pending: {
4069
4235
  label: "Needs approval",
@@ -4094,8 +4260,7 @@ const STATUS_BADGE = {
4094
4260
  color: "gray"
4095
4261
  }
4096
4262
  };
4097
- //#endregion
4098
- //#region src/blocks/AIKit/ToolCall/useApprovalShortcut.ts
4263
+ // src/blocks/AIKit/ToolCall/useApprovalShortcut.ts
4099
4264
  const isEditableTarget = (target) => target instanceof HTMLElement && (target.isContentEditable || target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT");
4100
4265
  const isModPressed = (event) => isMac ? event.metaKey : event.ctrlKey;
4101
4266
  const matchesShortcut = (event, shortcutKey) => {
@@ -4126,8 +4291,7 @@ const useApprovalShortcut = ({ shortcutKey, isEnabled, onApprove }) => {
4126
4291
  onApprove
4127
4292
  ]);
4128
4293
  };
4129
- //#endregion
4130
- //#region src/blocks/AIKit/ToolCall/ToolCallApproval.tsx
4294
+ // src/blocks/AIKit/ToolCall/ToolCallApproval.tsx
4131
4295
  /**
4132
4296
  * Per-tool-call approve/reject frame — the granular sibling of `PlanApproval`.
4133
4297
  *
@@ -4230,8 +4394,7 @@ const ToolCallApproval = ({ status, statusLabel, statusMessage, density = "card"
4230
4394
  })]
4231
4395
  });
4232
4396
  };
4233
- //#endregion
4234
- //#region src/blocks/AIKit/ToolCall/ToolCallChip.tsx
4397
+ // src/blocks/AIKit/ToolCall/ToolCallChip.tsx
4235
4398
  const chipClasses = cva(["tw:inline-flex tw:items-center tw:gap-1.5 tw:rounded-md tw:border tw:border-solid", "tw:border-border tw:bg-muted tw:px-2 tw:py-1 tw:text-xs tw:text-foreground"], {
4236
4399
  variants: { interactive: {
4237
4400
  true: "tw:cursor-pointer tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-ring tw:not-disabled:hover:bg-hover",
@@ -4276,8 +4439,7 @@ const ToolCallChip = ({ label, state, icon, trailing, onClick, className }) => {
4276
4439
  children: content
4277
4440
  });
4278
4441
  };
4279
- //#endregion
4280
- //#region src/blocks/AIKit/ToolCallStatusHeader.tsx
4442
+ // src/blocks/AIKit/ToolCallStatusHeader.tsx
4281
4443
  const headerVariants = cva("tw:flex tw:items-center tw:justify-between tw:gap-2 tw:px-2.5 tw:py-1.5", {
4282
4444
  variants: { status: {
4283
4445
  processing: "tw:border-b tw:border-border/60",
@@ -4333,8 +4495,7 @@ const ToolCallStatusHeader = ({ icon: IconComponent, iconSpin, status, text, nee
4333
4495
  })]
4334
4496
  });
4335
4497
  };
4336
- //#endregion
4337
- //#region src/blocks/AIKit/usageStatsHelpers.ts
4498
+ // src/blocks/AIKit/usageStatsHelpers.ts
4338
4499
  /**
4339
4500
  * Clamp a percentage to 0–100 and normalize non-finite input to 0.
4340
4501
  *
@@ -4356,8 +4517,7 @@ const formatPercentage = (value) => {
4356
4517
  const rounded = Math.round(value);
4357
4518
  return `${value < 100 ? Math.min(rounded, 99) : rounded}%`;
4358
4519
  };
4359
- //#endregion
4360
- //#region src/blocks/AIKit/UsageBar.tsx
4520
+ // src/blocks/AIKit/UsageBar.tsx
4361
4521
  /**
4362
4522
  * One budget, as a labelled row over a bar.
4363
4523
  *
@@ -4375,8 +4535,7 @@ const UsageBar = ({ value, label, variant, className, ...props }) => /* @__PURE_
4375
4535
  value: clampPercentage(value)
4376
4536
  })]
4377
4537
  });
4378
- //#endregion
4379
- //#region src/blocks/AIKit/UsageStatsRing.tsx
4538
+ // src/blocks/AIKit/UsageStatsRing.tsx
4380
4539
  const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }) => {
4381
4540
  const radius = Math.max(0, (size - strokeWidth) / 2 - 1);
4382
4541
  const circumference = 2 * Math.PI * radius;
@@ -4407,8 +4566,7 @@ const UsageStatsRing = ({ value, size = 16, strokeWidth = 2.5, className }) => {
4407
4566
  })]
4408
4567
  });
4409
4568
  };
4410
- //#endregion
4411
- //#region src/blocks/AIKit/UsageStats.tsx
4569
+ // src/blocks/AIKit/UsageStats.tsx
4412
4570
  const UsageStats = ({ value, alert = false, children, className, ariaLabel, align = "end", side = "top", sideOffset = 8, open, onOpenChange }) => {
4413
4571
  const hasAlert = Boolean(alert);
4414
4572
  const isWarning = alert === "warning";
@@ -4435,7 +4593,6 @@ const UsageStats = ({ value, alert = false, children, className, ariaLabel, alig
4435
4593
  })]
4436
4594
  });
4437
4595
  };
4438
- //#endregion
4439
- export { ANSWER_SOURCES_VISIBLE, AnswerActions, AnswerSources, AnswerSummary, AttachmentChip, CONTEXT_CHIP_EXPANDABLE_LENGTH, ChatInlineIcon, ChatNotice, CollapsibleStepHeader, ContextChip, DIAGRAM_LANGUAGES, FileDownloadChip, FileGallery, InlineStepDetail, InlineStepGroup, InlineStepLabel, JumpToLatest, Markdown, MarkdownTable, MessageBubble, ModeChip, PROMPT_INPUT_CONTAINER, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SourceChip, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageBar, UsageStats, UsageStatsRing, clampPercentage, findMentionToken, findSlashToken, formatPercentage, getChatInlineIconName, splitSealedBlocks, withholdOpenTail };
4596
+ export { ANSWER_SOURCES_VISIBLE, AnswerActions, AnswerSources, AnswerSummary, AttachmentChip, CONTEXT_CHIP_EXPANDABLE_LENGTH, ChatInlineIcon, ChatNotice, CollapsibleStepHeader, ContextChip, FileDownloadChip, FileGallery, InlineStepDetail, InlineStepGroup, InlineStepLabel, JumpToLatest, Markdown, MarkdownTable, MessageBubble, ModeChip, PROMPT_INPUT_CONTAINER, PlanApproval, PlanRewritingIndicator, PromptInput, Question, QuestionBlock, SourceChip, SuggestedPrompt, ThinkingIndicator, ToolCallApproval, ToolCallChip, ToolCallStatusHeader, UsageBar, UsageStats, clampPercentage, findMentionToken, findSlashToken, formatPercentage, getChatInlineIconName, splitSealedBlocks, withholdOpenTail };
4440
4597
 
4441
- //# sourceMappingURL=AIKit-CaAW4GLx.js.map
4598
+ //# sourceMappingURL=AIKit-Cf5plya2.js.map