@keboola/design 11.6.1 → 12.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 (365) hide show
  1. package/AGENTS.md +50 -9
  2. package/CHANGELOG.md +241 -0
  3. package/COMPONENT-API.md +337 -288
  4. package/README.md +12 -2
  5. package/dist/{AIKit-CQxVwyAk.js → AIKit-BD4r7ff-.js} +807 -199
  6. package/dist/AIKit-BD4r7ff-.js.map +1 -0
  7. package/dist/{Alert-C4Y9IwMI.js → Alert-UI-CIs-1.js} +16 -16
  8. package/dist/Alert-UI-CIs-1.js.map +1 -0
  9. package/dist/{AlertModal-BGJdaRRj.js → AlertModal-Th2khjPi.js} +5 -5
  10. package/dist/AlertModal-Th2khjPi.js.map +1 -0
  11. package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
  12. package/dist/AppShell-WSQabK8r.js.map +1 -0
  13. package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
  14. package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
  15. package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
  16. package/dist/Badge-DIjhwPvh.js.map +1 -0
  17. package/dist/{BrandEditor-CS9P4r2p.js → BrandEditor-BU23Vl8V.js} +7 -7
  18. package/dist/{BrandEditor-CS9P4r2p.js.map → BrandEditor-BU23Vl8V.js.map} +1 -1
  19. package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
  20. package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
  21. package/dist/{Breadcrumb-D1id7YXd.js → Breadcrumb-p9HtMLCc.js} +8 -14
  22. package/dist/Breadcrumb-p9HtMLCc.js.map +1 -0
  23. package/dist/{Button-DsRrU5F1.js → Button-Ca4Q3VJU.js} +31 -13
  24. package/dist/Button-Ca4Q3VJU.js.map +1 -0
  25. package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
  26. package/dist/Calendar-DFtmZzbF.js.map +1 -0
  27. package/dist/{Card-Dyo7055Q.js → Card-Cr9MBNHu.js} +4 -4
  28. package/dist/Card-Cr9MBNHu.js.map +1 -0
  29. package/dist/{Checkbox-Bqr6zXcW.js → Checkbox-8yIIgY7g.js} +4 -4
  30. package/dist/Checkbox-8yIIgY7g.js.map +1 -0
  31. package/dist/{Clipboard-C2YBRfD8.js → Clipboard-_xf6hMDD.js} +2 -2
  32. package/dist/{Clipboard-C2YBRfD8.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
  33. package/dist/{ClipboardButton-CrljClL1.js → ClipboardButton-DHa1trtI.js} +4 -4
  34. package/dist/{ClipboardButton-CrljClL1.js.map → ClipboardButton-DHa1trtI.js.map} +1 -1
  35. package/dist/{CodeEditor-C9AS8Ch0.js → CodeEditor-BSo-oLFG.js} +55 -165
  36. package/dist/CodeEditor-BSo-oLFG.js.map +1 -0
  37. package/dist/{ColorInput-Dg87lKcR.js → ColorInput-DSMqrs2-.js} +12 -27
  38. package/dist/ColorInput-DSMqrs2-.js.map +1 -0
  39. package/dist/{ColorModeSwitch-CsWLiTBX.js → ColorModeSwitch-D7EuWyJz.js} +7 -17
  40. package/dist/ColorModeSwitch-D7EuWyJz.js.map +1 -0
  41. package/dist/Combobox-CxRAYOBt.js +1069 -0
  42. package/dist/Combobox-CxRAYOBt.js.map +1 -0
  43. package/dist/{Command-CqxoI_De.js → Command-BU_cVurn.js} +4 -4
  44. package/dist/{Command-CqxoI_De.js.map → Command-BU_cVurn.js.map} +1 -1
  45. package/dist/{CopyField-Rx9HPTbJ.js → CopyField-6_c-NdLO.js} +17 -53
  46. package/dist/{CopyField-Rx9HPTbJ.js.map → CopyField-6_c-NdLO.js.map} +1 -1
  47. package/dist/{DateInput-DpifECUQ.js → DateInput-DyEErfJf.js} +6 -6
  48. package/dist/{DateInput-DpifECUQ.js.map → DateInput-DyEErfJf.js.map} +1 -1
  49. package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
  50. package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
  51. package/dist/{DateRangeInput-9MIw7P6L.js → DateRangeInput-Dg7-VUd9.js} +10 -14
  52. package/dist/DateRangeInput-Dg7-VUd9.js.map +1 -0
  53. package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BoPnh4aH.js} +9 -13
  54. package/dist/DateRangePicker-BoPnh4aH.js.map +1 -0
  55. package/dist/DiffView-ppTIzh2h.js.map +1 -1
  56. package/dist/{DropdownMenu-CASr-jgl.js → DropdownMenu-gRM-A8qU.js} +11 -6
  57. package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
  58. package/dist/{FieldItem-DtPTzNef.js → FieldItem-2wMXQ0Qw.js} +12 -25
  59. package/dist/FieldItem-2wMXQ0Qw.js.map +1 -0
  60. package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
  61. package/dist/{FileUpload-DYQCTGjU.js → FileUpload-C83tXuE2.js} +11 -16
  62. package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-C83tXuE2.js.map} +1 -1
  63. package/dist/{Form-DAaatlBk.js → Form-95rVLfX8.js} +15 -23
  64. package/dist/{Form-DAaatlBk.js.map → Form-95rVLfX8.js.map} +1 -1
  65. package/dist/{FormGroup-Bl8JmnzJ.js → FormGroup-CmNiAtU6.js} +11 -17
  66. package/dist/FormGroup-CmNiAtU6.js.map +1 -0
  67. package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-CD7mYeTz.js} +15 -29
  68. package/dist/FullScreenModal-CD7mYeTz.js.map +1 -0
  69. package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
  70. package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
  71. package/dist/{InputGroup-DcZRlVnN.js → InputGroup-B4QOPxHl.js} +12 -13
  72. package/dist/InputGroup-B4QOPxHl.js.map +1 -0
  73. package/dist/{Kbd-D1Azcc4g.js → Kbd-J4n1J6i4.js} +23 -13
  74. package/dist/Kbd-J4n1J6i4.js.map +1 -0
  75. package/dist/{MarkedText-DNGEUVWc.js → MarkedText-DlmlJO0u.js} +2 -2
  76. package/dist/{MarkedText-DNGEUVWc.js.map → MarkedText-DlmlJO0u.js.map} +1 -1
  77. package/dist/{MermaidDiagram-CujFxVzk.js → MermaidDiagram-BQvz6bhv.js} +16 -34
  78. package/dist/MermaidDiagram-BQvz6bhv.js.map +1 -0
  79. package/dist/{Modal-Coj-H02o.js → Modal-Driyqs_N.js} +17 -34
  80. package/dist/Modal-Driyqs_N.js.map +1 -0
  81. package/dist/{ModalTitle-C76ke2eo.js → ModalTitle-BxopkIoQ.js} +3 -3
  82. package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
  83. package/dist/{MultiActionButtonGroup-CNNoBQbv.js → MultiActionButtonGroup-BPnmzBtw.js} +3 -3
  84. package/dist/{MultiActionButtonGroup-CNNoBQbv.js.map → MultiActionButtonGroup-BPnmzBtw.js.map} +1 -1
  85. package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
  86. package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
  87. package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
  88. package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
  89. package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
  90. package/dist/PageHeader-CgfyXpf1.js.map +1 -0
  91. package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
  92. package/dist/PageLayout-DiAAILuS.js.map +1 -0
  93. package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-DOAtAnfL.js} +12 -42
  94. package/dist/PageToolbar-DOAtAnfL.js.map +1 -0
  95. package/dist/{Pagination-C_b7Xhey.js → Pagination-LaSg-5cl.js} +3 -3
  96. package/dist/{Pagination-C_b7Xhey.js.map → Pagination-LaSg-5cl.js.map} +1 -1
  97. package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-SLz0zodk.js} +3 -3
  98. package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-SLz0zodk.js.map} +1 -1
  99. package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
  100. package/dist/Popover-CEk915I1.js.map +1 -0
  101. package/dist/{RadioGroup-CUBsuP7r.js → RadioGroup-CBPRLRN0.js} +4 -4
  102. package/dist/{RadioGroup-CUBsuP7r.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
  103. package/dist/{Search-DVpJuzr9.js → Search-DmkQo716.js} +3 -3
  104. package/dist/{Search-DVpJuzr9.js.map → Search-DmkQo716.js.map} +1 -1
  105. package/dist/{SearchInput-Q85p8Ews.js → SearchInput-CEfQDNl3.js} +8 -13
  106. package/dist/SearchInput-CEfQDNl3.js.map +1 -0
  107. package/dist/{SectionNav-mpmSM3OC.js → SectionNav-B_qf0AXi.js} +10 -42
  108. package/dist/SectionNav-B_qf0AXi.js.map +1 -0
  109. package/dist/{Select-DV3Hak_l.js → Select-ByRvkZ3D.js} +8 -11
  110. package/dist/{Select-DV3Hak_l.js.map → Select-ByRvkZ3D.js.map} +1 -1
  111. package/dist/{Sheet-Chf0kX1E.js → Sheet-C-yXk5Da.js} +5 -9
  112. package/dist/Sheet-C-yXk5Da.js.map +1 -0
  113. package/dist/{Sidebar-CTWsHZhF.js → Sidebar-Ds0E6PbR.js} +181 -33
  114. package/dist/Sidebar-Ds0E6PbR.js.map +1 -0
  115. package/dist/{Slider-Bv0B6lI0.js → Slider-DWdu9NuM.js} +3 -3
  116. package/dist/{Slider-Bv0B6lI0.js.map → Slider-DWdu9NuM.js.map} +1 -1
  117. package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
  118. package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
  119. package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
  120. package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
  121. package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
  122. package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
  123. package/dist/{Tabs-eB974xJf.js → Tabs-Dt9oLYHC.js} +3 -3
  124. package/dist/{Tabs-eB974xJf.js.map → Tabs-Dt9oLYHC.js.map} +1 -1
  125. package/dist/{TextInput-DiEMxVF6.js → TextInput-CDG2XpBl.js} +12 -15
  126. package/dist/TextInput-CDG2XpBl.js.map +1 -0
  127. package/dist/{ThemeProvider-BI6JWBdJ.js → ThemeProvider-DXsxFg1U.js} +13 -31
  128. package/dist/ThemeProvider-DXsxFg1U.js.map +1 -0
  129. package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
  130. package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
  131. package/dist/{Timeline-BG5Xogxh.js → Timeline-B-I6sb0M.js} +2 -2
  132. package/dist/{Timeline-BG5Xogxh.js.map → Timeline-B-I6sb0M.js.map} +1 -1
  133. package/dist/{Toast-Dr6Uw7ao.js → Toast-PfQf3vj-.js} +2 -2
  134. package/dist/{Toast-Dr6Uw7ao.js.map → Toast-PfQf3vj-.js.map} +1 -1
  135. package/dist/{Workbench-UR2FBC7I.js → Workbench-DmZzpkj7.js} +2 -2
  136. package/dist/{Workbench-UR2FBC7I.js.map → Workbench-DmZzpkj7.js.map} +1 -1
  137. package/dist/{ZoomableSvg-U_VH3QRO.js → ZoomableSvg-BzXVfgnI.js} +5 -19
  138. package/dist/ZoomableSvg-BzXVfgnI.js.map +1 -0
  139. package/dist/charts.d.ts +21 -52
  140. package/dist/charts.js +13 -39
  141. package/dist/charts.js.map +1 -1
  142. package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
  143. package/dist/context-U293r3v-.js.map +1 -0
  144. package/dist/editors.d.ts +27 -124
  145. package/dist/editors.js +29 -71
  146. package/dist/editors.js.map +1 -1
  147. package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
  148. package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
  149. package/dist/flint.d.ts +3 -6
  150. package/dist/flint.js +31 -80
  151. package/dist/flint.js.map +1 -1
  152. package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
  153. package/dist/icons-wcA70iQx.js.map +1 -0
  154. package/dist/icons.d.ts +2 -2
  155. package/dist/icons.js +2 -2
  156. package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
  157. package/dist/index.d.ts +1461 -1809
  158. package/dist/index.js +70 -67
  159. package/dist/internal/blocks/AIKit.js +2 -2
  160. package/dist/internal/blocks/AppShell.js +1 -1
  161. package/dist/internal/blocks/AuthLayout.js +7 -27
  162. package/dist/internal/blocks/AuthLayout.js.map +1 -1
  163. package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
  164. package/dist/internal/blocks/BrandEditor.js +1 -1
  165. package/dist/internal/blocks/ChartPanel.js +4 -8
  166. package/dist/internal/blocks/ChartPanel.js.map +1 -1
  167. package/dist/internal/blocks/ChipEditor.js +129 -0
  168. package/dist/internal/blocks/ChipEditor.js.map +1 -0
  169. package/dist/internal/blocks/ClipboardButton.js +1 -1
  170. package/dist/internal/blocks/ColorInput.js +1 -1
  171. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  172. package/dist/internal/blocks/Command.js +1 -1
  173. package/dist/internal/blocks/CopyField.js +1 -1
  174. package/dist/internal/blocks/DashboardHero.js +4 -7
  175. package/dist/internal/blocks/DashboardHero.js.map +1 -1
  176. package/dist/internal/blocks/DateInput.js +1 -1
  177. package/dist/internal/blocks/DateRangeInput.js +1 -1
  178. package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
  179. package/dist/internal/blocks/EmptyState.js +5 -9
  180. package/dist/internal/blocks/EmptyState.js.map +1 -1
  181. package/dist/internal/blocks/ErrorState.js +5 -9
  182. package/dist/internal/blocks/ErrorState.js.map +1 -1
  183. package/dist/internal/blocks/ExportMenu.js +6 -10
  184. package/dist/internal/blocks/ExportMenu.js.map +1 -1
  185. package/dist/internal/blocks/Form/connectors/ComboboxField.js +40 -0
  186. package/dist/internal/blocks/Form/connectors/ComboboxField.js.map +1 -0
  187. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +5 -22
  188. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -1
  189. package/dist/internal/blocks/Form.js +1 -1
  190. package/dist/internal/blocks/FormGroup.js +1 -1
  191. package/dist/internal/blocks/GoogleButton.js +1 -1
  192. package/dist/internal/blocks/MicrosoftButton.js +1 -1
  193. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  194. package/dist/internal/blocks/MultiCombobox.js +162 -165
  195. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  196. package/dist/internal/blocks/NumberInput.js +1 -1
  197. package/dist/internal/blocks/OtpInput.js +1 -1
  198. package/dist/internal/blocks/PageHeader.js +1 -1
  199. package/dist/internal/blocks/PageLayout.js +1 -1
  200. package/dist/internal/blocks/PageToolbar.js +1 -1
  201. package/dist/internal/blocks/PasswordInput.js +4 -4
  202. package/dist/internal/blocks/PasswordInput.js.map +1 -1
  203. package/dist/internal/blocks/SearchInput.js +1 -1
  204. package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
  205. package/dist/internal/blocks/SectionNav.js +1 -1
  206. package/dist/internal/blocks/SplitButton.js +3 -3
  207. package/dist/internal/blocks/StatCard.js +4 -8
  208. package/dist/internal/blocks/StatCard.js.map +1 -1
  209. package/dist/internal/blocks/TextInput.js +1 -1
  210. package/dist/internal/blocks/Textarea.js +2 -2
  211. package/dist/internal/blocks/TimeInput.js +5 -5
  212. package/dist/internal/blocks/TimeInput.js.map +1 -1
  213. package/dist/internal/components/Alert.js +1 -1
  214. package/dist/internal/components/AlertModal.js +1 -1
  215. package/dist/internal/components/Avatar.js +1 -1
  216. package/dist/internal/components/Badge.js +1 -1
  217. package/dist/internal/components/BrandLogo.js +1 -1
  218. package/dist/internal/components/Breadcrumb.js +1 -1
  219. package/dist/internal/components/Button.js +1 -1
  220. package/dist/internal/components/ButtonGroup.js.map +1 -1
  221. package/dist/internal/components/Calendar.js +1 -1
  222. package/dist/internal/components/Card.js +1 -1
  223. package/dist/internal/components/Checkbox.js +1 -1
  224. package/dist/internal/components/Clipboard.js +1 -1
  225. package/dist/internal/components/CollapsiblePanel.js +2 -2
  226. package/dist/internal/components/Combobox.js +2 -2
  227. package/dist/internal/components/DatePicker.js +1 -1
  228. package/dist/internal/components/DateRangePicker.js +1 -1
  229. package/dist/internal/components/DropdownMenu.js +1 -1
  230. package/dist/internal/components/FileUpload.js +1 -1
  231. package/dist/internal/components/FullScreenModal.js +1 -1
  232. package/dist/internal/components/HoverCard.js +1 -1
  233. package/dist/internal/components/InputGroup.js +1 -1
  234. package/dist/internal/components/Kbd.js +1 -1
  235. package/dist/internal/components/MarkedText.js +1 -1
  236. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
  237. package/dist/internal/components/Modal.js +1 -1
  238. package/dist/internal/components/Navbar.js +1 -1
  239. package/dist/internal/components/Pagination.js +1 -1
  240. package/dist/internal/components/PanelWithDetails.js +1 -1
  241. package/dist/internal/components/Popconfirm.js +1 -1
  242. package/dist/internal/components/Popover.js +1 -1
  243. package/dist/internal/components/RadioGroup.js +1 -1
  244. package/dist/internal/components/Search.js +1 -1
  245. package/dist/internal/components/Select.js +1 -1
  246. package/dist/internal/components/Separator.js.map +1 -1
  247. package/dist/internal/components/Sheet.js +1 -1
  248. package/dist/internal/components/Sidebar.js +1 -1
  249. package/dist/internal/components/Skeleton/Skeleton.js +5 -9
  250. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
  251. package/dist/internal/components/Slider.js +1 -1
  252. package/dist/internal/components/SpotlightBackdrop.js +3 -8
  253. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  254. package/dist/internal/components/StatusDot.js +60 -0
  255. package/dist/internal/components/StatusDot.js.map +1 -0
  256. package/dist/internal/components/Stepper.js +1 -1
  257. package/dist/internal/components/Switch.js +1 -1
  258. package/dist/internal/components/Table.js +1 -1
  259. package/dist/internal/components/Tabs.js +1 -1
  260. package/dist/internal/components/ThemeProvider.js +3 -3
  261. package/dist/internal/components/TimePicker.js +1 -1
  262. package/dist/internal/components/Timeline.js +1 -1
  263. package/dist/internal/components/Toast.js +2 -2
  264. package/dist/internal/components/Tooltip.js +2 -2
  265. package/dist/internal/components/Truncated.js +4 -8
  266. package/dist/internal/components/Truncated.js.map +1 -1
  267. package/dist/internal/components/Workbench.js +1 -1
  268. package/dist/internal/components/ZoomableSvg.js +1 -1
  269. package/dist/internal/hooks/useScrollbarPosition.js +1 -1
  270. package/dist/internal/hooks/useStableCallback.js +4 -13
  271. package/dist/internal/hooks/useStableCallback.js.map +1 -1
  272. package/dist/internal/utils/mergeRefs.js +27 -9
  273. package/dist/internal/utils/mergeRefs.js.map +1 -1
  274. package/dist/internal/utils.js +3 -3
  275. package/dist/markdown-editor.d.ts +15 -37
  276. package/dist/markdown-editor.js +17 -23
  277. package/dist/markdown-editor.js.map +1 -1
  278. package/dist/mermaid.d.ts +4 -6
  279. package/dist/mermaid.js +1 -1
  280. package/dist/rjsf.d.ts +9 -19
  281. package/dist/rjsf.js +44 -84
  282. package/dist/rjsf.js.map +1 -1
  283. package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
  284. package/dist/styles-gzcjOyKv.js.map +1 -0
  285. package/dist/styles.css +1 -1
  286. package/dist/svgTransforms-Dw2hRA-i.js +51 -0
  287. package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
  288. package/dist/testing.d.ts +3 -10
  289. package/dist/testing.js +5 -12
  290. package/dist/testing.js.map +1 -1
  291. package/dist/themeTokens-7DEab0kp.js +31 -0
  292. package/dist/themeTokens-7DEab0kp.js.map +1 -0
  293. package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
  294. package/dist/toast-CyXEdaCZ.js.map +1 -0
  295. package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
  296. package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
  297. package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
  298. package/dist/useControllableState-CUYXMsfz.js.map +1 -0
  299. package/dist/useElement-D-RjrGa4.js +21 -0
  300. package/dist/useElement-D-RjrGa4.js.map +1 -0
  301. package/dist/useThemeAttributes-B199Regy.js +67 -0
  302. package/dist/useThemeAttributes-B199Regy.js.map +1 -0
  303. package/dist/{utils-DnkrFYqY.js → utils-Bd28bWgm.js} +53 -20
  304. package/dist/utils-Bd28bWgm.js.map +1 -0
  305. package/dist/vega.d.ts +8 -30
  306. package/dist/vega.js +5 -13
  307. package/dist/vega.js.map +1 -1
  308. package/dist/{vegaTheme-CSvFEMBl.js → vegaTheme-VQMWTlBw.js} +7 -21
  309. package/dist/vegaTheme-VQMWTlBw.js.map +1 -0
  310. package/package.json +11 -9
  311. package/src/styles.css +120 -14
  312. package/src/theme.css +126 -6
  313. package/dist/AIKit-CQxVwyAk.js.map +0 -1
  314. package/dist/Alert-C4Y9IwMI.js.map +0 -1
  315. package/dist/AlertModal-BGJdaRRj.js.map +0 -1
  316. package/dist/AppShell-DRgJxpXW.js.map +0 -1
  317. package/dist/Badge-o5jURtpB.js.map +0 -1
  318. package/dist/BrandLogo-CoKBk4MI.js.map +0 -1
  319. package/dist/Breadcrumb-D1id7YXd.js.map +0 -1
  320. package/dist/Button-DsRrU5F1.js.map +0 -1
  321. package/dist/Calendar-cG5NIJ4O.js.map +0 -1
  322. package/dist/Card-Dyo7055Q.js.map +0 -1
  323. package/dist/Checkbox-Bqr6zXcW.js.map +0 -1
  324. package/dist/CodeEditor-C9AS8Ch0.js.map +0 -1
  325. package/dist/ColorInput-Dg87lKcR.js.map +0 -1
  326. package/dist/ColorModeSwitch-CsWLiTBX.js.map +0 -1
  327. package/dist/Combobox-BfanUAqY.js +0 -619
  328. package/dist/Combobox-BfanUAqY.js.map +0 -1
  329. package/dist/DateRangeInput-9MIw7P6L.js.map +0 -1
  330. package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
  331. package/dist/DropdownMenu-CASr-jgl.js.map +0 -1
  332. package/dist/FieldItem-DtPTzNef.js.map +0 -1
  333. package/dist/FormGroup-Bl8JmnzJ.js.map +0 -1
  334. package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
  335. package/dist/InputGroup-DcZRlVnN.js.map +0 -1
  336. package/dist/Kbd-D1Azcc4g.js.map +0 -1
  337. package/dist/MermaidDiagram-CujFxVzk.js.map +0 -1
  338. package/dist/Modal-Coj-H02o.js.map +0 -1
  339. package/dist/ModalTitle-C76ke2eo.js.map +0 -1
  340. package/dist/PageHeader-Q3IpCnQd.js.map +0 -1
  341. package/dist/PageLayout-DSVM-ASz.js.map +0 -1
  342. package/dist/PageToolbar-BKVJiDAL.js.map +0 -1
  343. package/dist/Popover-BEbQrC_P.js.map +0 -1
  344. package/dist/SearchInput-Q85p8Ews.js.map +0 -1
  345. package/dist/SectionNav-mpmSM3OC.js.map +0 -1
  346. package/dist/Sheet-Chf0kX1E.js.map +0 -1
  347. package/dist/Sidebar-CTWsHZhF.js.map +0 -1
  348. package/dist/TextInput-DiEMxVF6.js.map +0 -1
  349. package/dist/ThemeProvider-BI6JWBdJ.js.map +0 -1
  350. package/dist/ZoomableSvg-U_VH3QRO.js.map +0 -1
  351. package/dist/context-D7X470dy.js.map +0 -1
  352. package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
  353. package/dist/icons-Cek151jC.js.map +0 -1
  354. package/dist/styles-BAFscjSV.js.map +0 -1
  355. package/dist/svgTransforms-CJAYPk7o.js +0 -81
  356. package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
  357. package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
  358. package/dist/themeTokens-qP1-55O7.js +0 -119
  359. package/dist/themeTokens-qP1-55O7.js.map +0 -1
  360. package/dist/toast-DIC0iNRf.js.map +0 -1
  361. package/dist/useControllableState-M6494mCT.js.map +0 -1
  362. package/dist/useElement-DkF6esWL.js +0 -15
  363. package/dist/useElement-DkF6esWL.js.map +0 -1
  364. package/dist/utils-DnkrFYqY.js.map +0 -1
  365. package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
package/AGENTS.md CHANGED
@@ -93,11 +93,11 @@ This file answers **which** component to use; [`COMPONENT-API.md`](./COMPONENT-A
93
93
 
94
94
  **Never** build custom label + input combinations — compose `Label` + `FormGroup.TextInput` + `FormGroup.Help` inside `FormGroup`.
95
95
 
96
- **`Select` and `Select.Trigger` will not compile without an accessible name** — one of `aria-label`, `aria-labelledby`, or an `id` is required (the JSDoc on the prop says why). Pass `id` and point a `<Label htmlFor>` at it where the field has a visible label, `aria-labelledby` where that label is some other node, and `aria-label` for a bare control — a toolbar filter, a repeated row. `field.SelectField` needs none of the three: `FieldItem` owns the label and hands the control its `id`.
96
+ **Every select-shaped control needs an accessible name, and it goes on the control itself** — pass `id` and point a `<Label htmlFor>` at it where the field has a visible label, `aria-labelledby` where that label is some other node, and `aria-label` for a bare control — a toolbar filter, a repeated row. A name set on a surrounding wrapper (an `InputGroup`, a `<div>`) reaches nothing: the role is on the trigger or the input. `Select` and `Select.Trigger` **will not compile** without one of the three (the JSDoc on the prop says why); `Combobox` and `MultiCombobox` will, and then fall back to their `placeholder`, which the name calculation reaches only as a last resort. The `field.*` connectors need none of it: `FieldItem` owns the label and hands the control its `id`.
97
97
 
98
98
  `FileUpload` composes `FileUpload.DropZone` (the dashed box, owning the drag / error visuals) with `FileUpload.FileList` (selected files; `invalid` tints the rows). It deliberately ships **no** rejection copy — the wording is product copy, so read the current rejections with `useFileUploadRejections()` inside `FileUpload` and write the sentence yourself. Reach for `useFileDropTarget` only when there is no box to render: it returns `getRootProps()` / `isDragActive` for an affordance you style, and `noClick` / `noKeyboard` keep an already-interactive subtree (a composer, a form) from opening the file dialog on every click.
99
99
 
100
- **`InputGroup.Addon` (`align="inline-start"` / `"inline-end"`) keeps its own content width** — it no longer gives up space to the input, so a badge or a rendered selection stays fully visible instead of being squeezed to an ellipsis. Bound long, caller-controlled content yourself (a `max-w-[…] overflow-hidden` on the addon) if it isn't a fixed-size icon or button. `InputGroup`'s padding/sizing rules reach any descendant `input`/`textarea`, not just a direct child, so a consumer that wraps the input in its own layout (chips, an overlay) picks up that padding automatically — cancel it with `!px-0`/`!py-0` where the wrapping layout already owns its own edge padding (see `MultiCombobox`).
100
+ **`InputGroup.Addon` (`align="inline-start"` / `"inline-end"`) keeps its own content width** — it no longer gives up space to the input, so a badge or a rendered selection stays fully visible instead of being squeezed to an ellipsis. Bound long, caller-controlled content yourself (a `max-w-[…] overflow-hidden` on the addon) if it isn't a fixed-size icon or button. The exception is `TextInput`'s `rightSuffixVariant="addon"` suffix, which shrinks and ellipsizes inline content instead. `InputGroup`'s padding/sizing rules reach any descendant `input`/`textarea`, not just a direct child, so a consumer that wraps the input in its own layout (chips, an overlay) picks up that padding automatically — cancel it with `!px-0`/`!py-0` where the wrapping layout already owns its own edge padding (see `MultiCombobox`).
101
101
 
102
102
  ### Status surfaces
103
103
 
@@ -107,9 +107,16 @@ This file answers **which** component to use; [`COMPONENT-API.md`](./COMPONENT-A
107
107
  | `Toaster` | Mount once at app root |
108
108
  | `Alert` | Persistent contextual message in page layout |
109
109
  | `FormGroup state="error"` | Field-level validation errors inline below input |
110
+ | `StatusDot` | One entity's state as a coloured dot beside its name |
110
111
 
111
112
  **Never** use `Alert` for ephemeral success (use `toast()`) or `toast()` for blocking errors (use `Alert`).
112
113
 
114
+ **Never** paint a state with a hue of your own — no `tw:bg-amber-400` span, no `color` prop taking a
115
+ hue. `StatusDot`'s `status` (`success` / `warning` / `info` / `destructive` / `neutral`) is its whole
116
+ colour API, so it reads the themeable status tokens and a customer brand recolours every dot at once.
117
+ Colour never carries the meaning alone: pair the dot with the text, or give it a `label` so a screen
118
+ reader gets the state too.
119
+
113
120
  ### Loading
114
121
 
115
122
  | Use | When |
@@ -120,6 +127,10 @@ This file answers **which** component to use; [`COMPONENT-API.md`](./COMPONENT-A
120
127
  | `DotsLoader` | Indeterminate background work without a layout slot (small inline progress signal) |
121
128
  | `ThinkingIndicator` | An agent turn that is in flight with nothing to show yet — every Keboola chat says it the same way |
122
129
 
130
+ A `Combobox` or `MultiCombobox` whose options come from a request takes **`isLoading`**, never an
131
+ `empty` whose text switches to "Loading…". It does not disable the control — pass `disabled` too
132
+ only where the user must wait. `Select` has no counterpart: it is for a short, known enum.
133
+
123
134
  **Never** build a new "Loader" / "BoxLoader" / "ActionLoader" wrapper component. Compose `Skeleton` directly into the slot the real content will occupy.
124
135
 
125
136
  ### Tooltips
@@ -230,6 +241,8 @@ Vertical rhythm: prefer `tw:gap-*` on a flex column parent over `tw:mt-*` on chi
230
241
 
231
242
  **`SectionNav` is not `Sidebar`.** `Sidebar` is the app's left rail — global, one per shell, outside `PageLayout`, with `SidebarProvider` state and icon-collapse. `SectionNav` is scoped to a single page's sections, lives in `PageLayout.Content nav`, and holds nothing but an open/closed flag per group. Reach for `SectionNav` when a page has more sections than a tab row can hold, or sections that group; `Tabs` when they don't.
232
243
 
244
+ **`Sidebar` can become a `Sheet` under 768px — opt in per side.** `SidebarProvider` takes `leftMobileSheet` / `rightMobileSheet`; both default to off, because a `Sidebar` is also the shape of a container rail nested in a modal or a builder canvas, where a full-screen phone sheet means nothing. A side that opts in occupies no grid column below the breakpoint — the page takes the full width — and the rail opens as a sheet, with the focus trap, the Escape handling and the overlay that come with one. An app that opts in owes the sheet a way in: put a `Sidebar.Trigger` in the header and let it be the only one, since the provider swaps what `toggle` does and the same control collapses the column above the breakpoint and opens the sheet below it. Choosing a destination dismisses the sheet; a button that opens a popup or that is itself a `Sidebar.Trigger` does not. Read `isMobile` off `useSidebar(side)` only for a call site whose whole purpose is the collapse axis (a mode picker) — everything else composes unchanged, and a call site's own `mode` prop is never written. `keepMounted` and `mountAfterEnter` describe the column's transition and do not apply to a side that is a sheet — its content mounts on open and unmounts on close, so state worth surviving a close lives above the panel.
245
+
233
246
  ### Separators
234
247
 
235
248
  | Use | When |
@@ -250,10 +263,16 @@ The `label` prop implies `orientation="horizontal"` — labels are not rendered
250
263
  | `ColorInput` | Design-token-driven brand color picker |
251
264
  | `Combobox` | Single selection from a searchable list |
252
265
  | `MultiCombobox` | Multiple selections from a searchable list |
266
+ | `ChipEditor` | Several free-text values the user types — there is no list |
253
267
  | `Select` | Single selection from a short enum (≤ ~10 options, no search) |
254
268
  | `CodeEditor` | Generic code editing (JSON, YAML, shell) |
255
269
  | `SqlEditor` | SQL editing (syntax + autocomplete) |
256
270
 
271
+ `ChipEditor` is the chip row without the popup — tags, feature flags, permitted email domains, any
272
+ list of strings the user writes rather than picks. A `MultiCombobox` with `allowCreate` is still the
273
+ right call the moment there is a list worth searching, even an open-ended one; **never** hand-roll an
274
+ input-plus-chips row from `InputGroup` + `Badge`.
275
+
257
276
  `Select` is wrong above ~10 items — use `Combobox`. How richly the **selected** value has to render decides nothing here: both controls carry a rich selection (see below), so a short enum whose selection is a badge is still a `Select`. `CodeEditor`/`SqlEditor` load the full CodeMirror bundle and ship from the `@keboola/design/editors` subpath (not the root); reserve for real code editing.
258
277
 
259
278
  #### Clear affordance
@@ -268,7 +287,7 @@ whose empty state the surrounding form cannot represent. The button only mounts
268
287
  value, so an empty control renders identically either way. A **required multi** field keeps
269
288
  clear-all — the chips are individually removable, so the empty state is reachable regardless and
270
289
  withholding the button removes convenience without preventing anything. That is why the schema-driven
271
- `SelectWidget` derives `allowClear={!required}` while `MultiComboboxField` does not.
290
+ `SelectWidget` and `ComboboxField` derive `allowClear={!required}` while `MultiComboboxField` does not.
272
291
 
273
292
  #### Chip content in a `MultiCombobox`
274
293
 
@@ -361,11 +380,12 @@ one of these instead:
361
380
  Some predicates are about blankness itself: "this Storage column equals the empty string" versus
362
381
  "equals a single space". Whether a control can carry those depends on the primitive under it.
363
382
 
364
- | Control | `''` / `' '` as a value |
365
- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
366
- | `MultiCombobox` | **Genuine values** — the selection shows as chips, so a blank one is nameable |
367
- | `Combobox` | Genuine values; add `itemToSelectedLabel={namedLabel}` to name a blank selection in the closed control |
368
- | `Select` | **Impossible** — Radix reads an empty root value as "nothing selected", so an item carrying it renders a blank trigger. Use a named sentinel item (`'none'`) and map it at the call site |
383
+ | Control | `''` / `' '` as a value |
384
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
385
+ | `MultiCombobox` | **Genuine values** — the selection shows as chips, so a blank one is nameable |
386
+ | `Combobox` | Genuine values; add `itemToSelectedLabel={namedLabel}` to name a blank selection in the closed control |
387
+ | `ComboboxField` | **`''` is no selection**, `' '` a genuine value — the form value maps `''` to an empty control, so a `withBlankValues` `[empty string]` row cannot be picked. Use a named sentinel item, as with `Select` |
388
+ | `Select` | **Impossible** — Radix reads an empty root value as "nothing selected", so an item carrying it renders a blank trigger. Use a named sentinel item (`'none'`) and map it at the call site |
369
389
 
370
390
  `withBlankValues` offers both blanks ahead of a value list and collapses duplicates — a column's
371
391
  distinct values can already hold a blank, and two `Object.is`-equal rows both report `aria-selected`
@@ -701,6 +721,27 @@ takes the node, and the chip lets it have the keyboard.
701
721
 
702
722
  **Select All in a `MultiCombobox`** — `allowSelectAll` means the **whole item set**, never the filtered one, so the row hides itself as soon as a query narrows the list. Don't reach for it to mean "select the matches" — a filtered bulk select needs its own labelled affordance stating the count, not a row whose meaning changes with the input.
703
723
 
724
+ **Collapsible, selectable groups** — a two-level list where the parent is picked as well as its children (a bucket and its tables). `collapsibleGroups` turns each group's label into a row with a chevron that folds the group; `selectableGroups` (`MultiCombobox`) makes a press on that row select the group's items the query matches, and `groupToValue` (`Combobox`) makes the row a value of its own.
725
+
726
+ ```tsx
727
+ <MultiCombobox
728
+ items={buckets} // [{ id, items: tableIds }]
729
+ value={tableIds}
730
+ onValueChange={setTableIds}
731
+ groupToLabel={(bucket) => bucket.id}
732
+ collapsibleGroups
733
+ selectableGroups
734
+ virtualized="auto"
735
+ />
736
+ ```
737
+
738
+ - A query overrides folding: every match shows, and a group with none disappears — so the group's row always stands for something the user can see.
739
+ - `value` holds items only. The row reads checked / mixed from them and never becomes a chip, so `allowSelectAll` and `renderChips` count what they always count.
740
+ - Without `selectableGroups` / `groupToValue` a press on the row folds the group; with them, the chevron and `ArrowRight` / `ArrowLeft` do.
741
+ - Don't hand-roll it from a flat list and an `onValueChange` that expands a parent into its children — the control owns the fold, the query override and the mixed state.
742
+
743
+ **Long lists** — a `Combobox` or `MultiCombobox` whose options can run into the hundreds (tables, configurations, users) takes `virtualized="auto"`: past 30 options, grouped or not, only the rows in view reach the DOM. It is opt-in because a test that clicks a far row needs every option rendered.
744
+
704
745
  **Sheet** — use `Sheet.Header title="…" description="…"` for a styled title + close icon; do **not** hand-roll with the raw `Sheet.Title`, which renders an unstyled `<h2>`. `Sheet.Body` provides horizontal padding only (`tw:px-4`) — add your own vertical rhythm/gap:
705
746
 
706
747
  ```tsx
@@ -725,7 +766,7 @@ import { ChevronDown, Keboola, Loader2 } from '@keboola/design/icons';
725
766
  ```
726
767
 
727
768
  - **One import surface**: Lucide icons and Keboola-custom icons (e.g. `Keboola`) both export from `@keboola/design/icons` and share the `LucideIcon` type, so they're interchangeable in any API typed `icon: LucideIcon` (Button, etc.).
728
- - **Vendor marks** also ship from `@keboola/design/icons` — `Aws`, `Azure`, `ChatGpt`, `Claude`, `Cursor`, `Devin`, `Gcp`, `Google`, `Keboola`, `Make`, `Microsoft` — in their own brand colours by default; pass **`mono`** to render one in `currentColor` instead. The `Eu` / `Us` flags are colour-only.
769
+ - **Vendor marks** also ship from `@keboola/design/icons` — `Auth0`, `Aws`, `Azure`, `ChatGpt`, `Claude`, `Cursor`, `Devin`, `Gcp`, `GitHub`, `GitLab`, `Google`, `Keboola`, `Make`, `Microsoft`, `Okta` — in their own brand colours by default; pass **`mono`** to render one in `currentColor` instead. The `Eu` / `Us` flags are colour-only.
729
770
  - **Sizing**: prefixed Tailwind `tw:size-*` utility — `tw:size-4` = 16px (default for inline icons), `tw:size-5` = 20px, `tw:size-6` = 24px.
730
771
  - **Spinner animation**: explicit via `tw:animate-spin`.
731
772
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,246 @@
1
1
  # @keboola/design
2
2
 
3
+ ## 12.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Remove the `break-anywhere` custom utility from `@keboola/design/theme`
8
+
9
+ Tailwind v4.1 shipped `wrap-anywhere` as a core utility emitting the same `overflow-wrap: anywhere`, and the repo compiles against v4.3. A custom utility that duplicates a core one only adds a second name for the same declaration.
10
+
11
+ Replace `tw:break-anywhere` with `tw:wrap-anywhere`. No other change — the emitted CSS is identical.
12
+
13
+ ### Minor Changes
14
+
15
+ - `Combobox` and `MultiCombobox` give a group a row of its own that folds it and can select it.
16
+ - `collapsibleGroups` folds a group from its row's chevron, or with `ArrowRight` / `ArrowLeft` on the highlighted row. A query shows every match whatever is folded.
17
+ - `MultiCombobox` `selectableGroups` makes the row select the group's items the query matches, and reads checked, mixed or empty. `value` only ever holds items.
18
+ - `Combobox` `groupToValue` makes the row a value of its own, so a group is picked whole beside its items.
19
+
20
+ - `ComboboxField`: a `useAppForm` connector for the single `Combobox`, holding a `string` (`''` for no selection), imported by name and composed inside `form.AppField`. `Combobox` takes `name`, `onBlur`, `aria-invalid` and `aria-required` and forwards them to its input, and the rjsf `SelectWidget` / `DynamicSelectWidget` mark a field with errors through `aria-invalid` and revalidate on blur, so a fixed value clears its error.
21
+
22
+ - `MultiCombobox` takes `virtualized` like `Combobox`, and in both it now windows grouped lists too.
23
+ - `'auto'` windows a list of more than 30 options, grouped or not, collapsible and selectable groups included; `true` always does. The default stays `false`.
24
+ - A windowed option carries `aria-setsize` / `aria-posinset`, so the list's length stays known with most rows out of the DOM.
25
+ - A grouped `MultiCombobox` with `allowSelectAll` filters by the query; it used to show no match.
26
+
27
+ - `Combobox` and `MultiCombobox` take `isLoading` for options that are still arriving.
28
+ - The open button's chevron turns into a spinner, and the input reports `aria-busy`.
29
+ - The popup says "Loading…" where it would otherwise show `empty`, so a fetch no longer reads as an empty list.
30
+ - Items already present stay listed and selectable, and the control stays typeable and creatable — pass `disabled` as well where the user has to wait.
31
+
32
+ - `FileDownloadChip` offers a file an agent wrote, inside the answer that names it.
33
+
34
+ An agent that has just built a spreadsheet can otherwise only name it in prose, leaving the reader a filename and no way to reach it. The chip is the answer's own answer to "where did my report go": the file name, its size when the caller knows it, and a download, drawn where the sentence mentions the file. The whole chip is the control rather than an icon at the end of it — it sits in a transcript column, where a small target beside a truncating filename is the hardest thing on the page to hit — and it is named `Download <file>` rather than by the file alone, because a reader hearing only `revenue.csv` has no way to know that activating it takes the file. The path goes on `title`, which is what tells two `report.pdf`s in different folders apart, and stays a hover affordance rather than the accessible name. It neither fetches nor saves: the transport is the host's, which is what lets one chip serve two apps whose markdown stacks and auth pipelines are separate, and `isPending` is the only thing it says about a download in flight.
35
+
36
+ - `Auth0`, `GitHub`, `GitLab` and `Okta` join the vendor marks in `@keboola/design/icons`, so a sign-in or identity-provider picker can show each vendor by its own mark.
37
+
38
+ `Auth0` and `GitLab` render in their brand colours, and `mono` flattens them to `currentColor` like every vendor mark. `GitHub` and `Okta` draw in `currentColor` always: both vendors ship their marks in black and white only, so the text colour is the brand colour and keeps them visible on light and dark surfaces. Each comes from the vendor's own brand or press source — the Okta Aura lifted out of the lockup on okta.com — and is recorded with its restriction in `icons/vendors/README.md`.
39
+
40
+ - `Button` gains a `kai` variant: Kai's gradient with three light pools drifting behind the label, for Kai's own actions.
41
+
42
+ - The reading rhythm of an answer is one definition
43
+ - `tw:prose`'s `--tw-prose-*` slots point at theme tokens, so prose follows the colour scheme and the brand without a call site reaching for `prose-invert`. The `[data-theme='dark'] .tw:prose → prose-invert` patch is gone with them. This is not additive: every `.tw:prose` surface takes the new palette, tooltips and docs included.
44
+ - `tw:prose-answer` is the new measure, heading scale, heading margins and paragraph/list rhythm a Keboola answer reads on. `AIKit/Markdown` wears it, so every chat gets the same one.
45
+ - `Markdown` takes a `rhythm` prop: `answer` (the default) is the new rhythm, `chrome` is `tw:prose` on the dense `tw:prose-sm` scale for content a model did not write — a dashboard text widget, a vendor's app description.
46
+ - `tw:prose-code-chip` paints inline code as a chip on the `--muted` / `--foreground` pair, and both rhythms wear it. It is its own utility because it is palette, not rhythm: without it a surface keeps Typography's pinned `#c7254e`, which measures 3.36:1 on the dark page.
47
+ - `Markdown.Root` / `Markdown.Block` split one prose surface from the N blocks a streaming renderer paints into it — the rhythm then resolves `:first-child` / `:last-child` across the whole reply.
48
+ - `tw:prose-answer`'s wider values apply inside an `@container/messages` at 640px and up; where no consumer declares that container it keeps its narrow ones.
49
+
50
+ - Add `Popover.Anchor` to position a controlled popover against an element that is not its trigger.
51
+
52
+ - `PromptInput`: a `PromptCommand` may carry `onSelect` and act instead of inserting its value, and a `panel` takes the popup's place for a small form opened from such a row — Escape and the × close it. `commandsGroupAction` puts a control on a `/` group's heading line, for whatever that group's rows come from. A `PromptCommand` may also carry an `icon`, for a list whose rows are things rather than commands.
53
+
54
+ - `PromptInput`'s `/` menu is about the leading token, not the whole message: it opens while the caret is on a `/token` at the head of the text even when a message follows, and a pick replaces only that token. `findSlashToken` is exported for a host that needs the same reading.
55
+
56
+ - `PromptInput` takes `mentions` and `onMentionSelect`: an `@` typed anywhere in the message opens a
57
+ command popup filtered by the word after it. Picking an item removes the token and hands the pick to
58
+ the host, which attaches whatever it stands for — nothing is inserted as text. `findMentionToken` is
59
+ exported for a host that needs to reopen the menu at the caret.
60
+
61
+ - A status dot and a chip editor, so nobody paints a state or a chip row by hand
62
+
63
+ `StatusDot` is one entity's state as a coloured dot. `status` — `success`, `warning`, `info`,
64
+ `destructive`, `neutral` — is its whole colour API: there is no `color` prop taking a hue, so the
65
+ dot reads the themeable status tokens and a customer brand recolours every dot on the platform at
66
+ once. `pulse` says the work is still moving, and `label` names the dot for a screen reader where the
67
+ text beside it does not.
68
+
69
+ `ChipEditor` is the chip row without the popup — tags, feature flags, permitted email domains, any
70
+ list of strings the user writes rather than picks. Enter, the separator and blur each commit what is
71
+ typed; Backspace in an empty field removes the last chip. It shares `MultiCombobox`'s vocabulary, so
72
+ a pasted list becomes one chip per value (`separator`, `null` for a value that contains one) and
73
+ `canAdd` gates each value's format, keeping the ones that pass and leaving the rest in the field to
74
+ fix. Values are compared case-insensitively, so one already held is never added twice.
75
+
76
+ Reach for `MultiCombobox` the moment there is a list worth searching, even an open-ended one.
77
+
78
+ ### Patch Changes
79
+
80
+ - Refresh AIKit Markdown visual baselines for the answer rhythm.
81
+
82
+ - Refresh AIKit PromptInput visual baselines for the compact composer.
83
+
84
+ - Make legacy Alert tints scheme-aware so dark mode uses legible semantic status tokens.
85
+
86
+ - Add two brands to the registry: `agnes` (the "paper" light theme shipped by the Agnes AI-analyst harness, with the emerald/navy dark palette such an instance actually renders) and `harbor` (a fictional consulting/advisory showcase brand, navy + steel blue + gold, clean against AA in both palettes). Both are re-exported from `@keboola/design`, offered in the Storybook brand toolbar, and available as theme-generator presets.
87
+
88
+ Also mark the frozen `brands` array `@__PURE__`. Without the annotation a bundler reads the top-level `Object.freeze(...)` as a side effect and keeps every brand — logo SVGs included — in any bundle that imports a single one; `@keboola/design/testing` shrinks from 88.27 kB to 86.31 kB as a result. Its budget moves 88 kB -> 92 KB so the next brand does not land on the limit again.
89
+
90
+ - `Button` honours an explicit `aria-disabled` instead of overwriting it.
91
+
92
+ The attribute was written from the `disabled` prop after the caller's own props were spread, so a button passing `aria-disabled` alone reported `aria-disabled="false"` — the opposite of what it asked for, and silently. That shape is the one a focus-preserving pending state needs: `disabled` removes the control from the tab order, so a reader who tabs to a button and activates it loses their place on the page for as long as the action runs. Passing `aria-disabled` and ignoring activation in the handler keeps the control focusable and still says it is unavailable. `disabled` alone behaves exactly as before.
93
+
94
+ - Card's border follows the theme in every brand, not only argo
95
+
96
+ - Seed ChipEditor and StatusDot visual baselines.
97
+
98
+ - `Combobox` and `MultiCombobox` forward `aria-label` and `aria-labelledby` to the input.
99
+
100
+ Both accepted the props and dropped them, so a control with no visible label had no accessible name — its `placeholder` was all a screen reader had to go on, and only as the last resort of the name calculation. The `combobox` role is on the input itself, so nothing set on the surrounding `InputGroup` would have reached assistive tech either. `Combobox` also forwards `name` and `aria-describedby`, which `MultiCombobox` already did. UT-5474.
101
+
102
+ - - `Combobox` rows show `itemToStringLabel`'s text, a blank one named, where no `itemToLabel` is passed — as `MultiCombobox` rows do. An item without a `label` field needs only `itemToStringLabel`.
103
+ - `MultiCombobox` without `value` holds its own selection: `defaultValue` seeds it, and `onValueChange` reports each change.
104
+ - In a grouped `Combobox` or `MultiCombobox` with `allowCreate`, `groupToLabel` receives only the groups in `items`. The created values sit in a group of their own with no label.
105
+ - `MultiCombobox`'s `itemToLabel` receives the typed query as its second argument, as `Combobox`'s does, so a row can mark the match with `MarkedText`. A chip receives `''`.
106
+ - `Combobox` and `MultiCombobox` label each group from its `label` field where no `groupToLabel` is passed, as `Select` does. A `label` that is not a string, a number or an element reads as none.
107
+
108
+ - `Combobox` shows an empty input for a selected item whose `label` and `value` are both `''`.
109
+ - Such an item reads as `''` for the input text, the default search text and the accessible value, like the string item `''`.
110
+ - Its row is still named `[empty string]`.
111
+
112
+ - `Combobox` with `allowCreate` lists a created value only while it is the selection and `items` does not hold it, so an adder pinned to `null`, a later pick, or an owner that adds the value to `items` leaves no extra created row.
113
+
114
+ - A collapsible group row in `Combobox` and `MultiCombobox` states its fold as the accessible description `Expanded` / `Collapsed`. It carries no `aria-expanded`, which `role="option"` does not allow.
115
+
116
+ - Add linux visual baselines for the Combobox and MultiCombobox loading and collapsible-group stories and the PromptInput attachments story.
117
+
118
+ - `Combobox` and `MultiCombobox` key the rows of a fully rendered list, so opening one logs no React "unique key" warning.
119
+
120
+ - `Combobox` and `MultiCombobox` without group rows (`collapsibleGroups`, `groupToValue`, `selectableGroups`) re-filter their list only when `items`, `filter`, a label accessor or, for `MultiCombobox`'s default filter, `value` changes. A caller that keeps those stable no longer re-filters on an unrelated re-render; a list with group rows still re-filters on every render.
121
+
122
+ - `FileDownloadChip` spins while a download is in flight.
123
+
124
+ It only greyed out before, so a slow or large file gave the reader nothing to watch and no way to tell a working download from a dead control. `Button` already owns the in-flight contract — `isLoading` draws the spinner and disables the control — so the chip passes it rather than inventing a second convention. Its own file and download glyphs are suppressed for that moment: `Button` renders the spinner _beside_ its children rather than in place of them, so leaving them in would stack three icons in a row barely wider than the filename.
125
+
126
+ - `FileDownloadChip` names the file by its path in the accessible name.
127
+
128
+ `aria-label` replaces a button's descendant text and `title` plays no part in the accessible name, so the label was the only thing a screen reader announced — and it carried the bare filename. Two files named `report.pdf` from different folders were announced identically, leaving no way to tell which download was about to be activated. The label now carries `filePath` when there is one, falling back to `fileName`. The visible chip is unchanged: it still shows the name alone, since the path is what truncates badly in a transcript column.
129
+
130
+ - Dark mode: text selection is a translucent primary wash instead of the browser's solid fill.
131
+
132
+ - InputGroup, Select/overlay triggers and base h1 use theme tokens so text and secondary controls stay readable in dark mode
133
+
134
+ - `MultiCombobox` works on React 19.3: a press beside the chips focuses the input and opens the list, and the chip row takes the toolbar role once it holds chips.
135
+
136
+ - A narrow `MultiCombobox` keeps its clear and open buttons inside its border.
137
+ - The input row wraps below the chips when there is less than 120px of room for the input beside them.
138
+ - On a row of its own it shrinks to the control's width, so a value field in a three-column filter row keeps both buttons reachable.
139
+
140
+ - `PromptInput` eases its height as attachments are added or removed.
141
+
142
+ - `PromptInput`'s `inline` row folds into the stacked layout below 480px of the container a host names with `PROMPT_INPUT_CONTAINER`, so a composer beside a panel that narrows it keeps its text on a line of its own instead of squeezing.
143
+
144
+ - `Question` renders its footer only when something would be in it, and drops the step widget on a one-question card. A single step showed "1 of 1" over a full progress bar with both chevrons dead, and a card with no Skip and no submit action was left with a bordered strip containing nothing — which reads as a control that failed to render.
145
+
146
+ - -
147
+
148
+ - Bound the SQL editor's active-query highlight to the document it highlights, so a splitter whose fragments do not re-join to the input can no longer crash the editor with `RangeError: Invalid position N in document of length M`.
149
+
150
+ - `Tooltip` renders the argo chrome when its trigger sits inside `Navbar` or `Sidebar` DOM, even under a legacy brand — those components exist only in the new design, so a black legacy tooltip inside them was the anomaly. The rule is keyed on the trigger's DOM ancestry, so an overlay a nav item portals out of the nav (a dialog, a menu) keeps following the brand. `chrome="argo" | "legacy"` forces one explicitly.
151
+
152
+ - `Tooltip` casing follows the chrome, not the brand: the legacy dark pill keeps its uppercase label, the argo popover reads standard case. `Kbd` renders its key uppercase by default; `casing="as-written"` keeps a layout-printed label as it is.
153
+
154
+ - Updated dependencies:
155
+ - @keboola/brand-registry@1.10.0
156
+ - @keboola/tailwind-config@1.2.0
157
+
158
+ ## 11.9.0
159
+
160
+ ### Minor Changes
161
+
162
+ - `InlineStepGroup` joins the AI Kit: the collapsible frame an assistant turn draws a run of steps in — header, animated collapse, and the connector rule the step icons mask themselves against. It takes the rows as children, so a product supplies its own vocabulary and its own step components; `surface` names the colour the icons mask against, for a transcript that does not sit on the page background.
163
+
164
+ A closed group is `inert` and `aria-hidden`: `grid-template-rows: 0fr` is layout only, so without them a screen reader reads out steps nobody can see and Tab lands inside a closed run. `CollapsibleStepHeader` carries its outcome as `data-variant` too — the outcome is otherwise carried by the icon's shape and ink alone, which no test and no E2E selector reads. The same outcome joins the header's accessible name as a short sr-only phrase, so a closed group announces how the run came out and not only what it was called.
165
+
166
+ The frame carries `role="group"` rather than the `<section>`'s own landmark semantics: a transcript draws one group per run of steps, so a long conversation would hand a screen reader a landmark list of dozens of identically named regions. A named `group` still announces its name, and it is the role the grounding panel already gives its repeated named answer sections.
167
+
168
+ - `Markdown` draws inline `icon:<name>` tokens, and `ChatInlineIcon` ships the name→Lucide registry behind them.
169
+
170
+ A Kai prompt teaches the model the `@keboola/agent-vocabulary` icon names, so any chat rendering its answers has to draw them — until now only kbc-ui could, from a fork of the map. The base `code` renderer turns an inline token into the icon it names and leaves every other inline code alone, and `getChatInlineIconName` + `ChatInlineIcon` are the seam for a caller that overrides `code` itself. Producing the token stays the app's: the remark plugin that finds bare `icon:…` text lives in `@keboola/kai-chat`. The glyph is `aria-hidden`: it replaces the token's text and carries no label of its own, so exposing it would announce an unnamed graphic ahead of every phrase it decorates. `icon:spinner` spins, which `MAINTAINING.md` makes part of the mapping rather than the caller's job — a still `Loader2` is an arc, and reads as a damaged ring rather than as waiting. A name the registry cannot draw is not a token: `getChatInlineIconName` answers `undefined` for it, so the code the author typed survives. A name that is only the start of one it can draw is the other state: an answer streams `icon:t`, `icon:ta`, `icon:tab` before `icon:table` lands, so that half-name draws nothing rather than flashing as a code chip that reflows the line. `Markdown` renders more than agent answers — vendor component descriptions, dashboard text widgets — and `icon:` is an ordinary way to name a property there.
171
+
172
+ - `SidebarProvider`'s `leftMobileSheet` / `rightMobileSheet` now take a width as well as a flag.
173
+ - `boolean` keeps the shared 768px breakpoint; a number names the width under which that side is a sheet.
174
+ - Per side, because the width at which a rail stops fitting is the rail's own — a 320px context panel beside a capped reading column runs out of room long before a navigation rail does.
175
+
176
+ ## 11.8.1
177
+
178
+ ### Patch Changes
179
+
180
+ - Keep a long `Modal.Header` description inside the modal frame
181
+
182
+ `ModalDescription` now breaks anywhere, like `ModalTitle` already did. The slot routinely carries an identifier — a Storage table id, a fully-qualified name — which offers no break opportunity and paints outside the frame at narrow viewports.
183
+
184
+ ## 11.8.0
185
+
186
+ ### Minor Changes
187
+
188
+ - `AnswerActions` takes a `split` layout and an `actions` slot, so a chat can put the verdict under
189
+ the left edge of an answer and its own controls under the right.
190
+
191
+ It also takes `size`, `labels` and `confirmation`: a roomier row for a panel a reader sits in, the
192
+ noun the surface rates ("response" or "answer"), and a word back once the vote lands.
193
+
194
+ - `Sidebar` can become a `Sheet` under 768px, so a phone gets the page's full width.
195
+ - Opt-in per side on `SidebarProvider`: `leftMobileSheet` / `rightMobileSheet`, both off by default. A `Sidebar` is also the shape of a container rail nested in a modal or a builder canvas, where a full-screen phone sheet means nothing — so no existing call site changes until it asks.
196
+ - An opted-in side renders no grid column below the breakpoint — `calcEffectiveWidths` reports zero, and the shell's sidebar slot collapses. The rail opens as a `Sheet`, which brings the focus trap, the Escape handling and the overlay. Closing it returns focus to whatever opened it.
197
+ - `Sidebar.Trigger` opens and closes that sheet instead of toggling the collapse axis, so a header trigger is one control rather than a mobile fork. Choosing a destination closes the sheet; a menu button that opens a popup (`aria-haspopup` / `aria-expanded`) or that is wrapped in a `Sidebar.Trigger` does not.
198
+ - Above the breakpoint the rail behaves exactly as before: `mode`, `collapsible` and `variant` are untouched. Two things do change for every call site — `Sidebar.Trigger` now states `aria-expanded` on both axes (the sheet's open state on a phone, the column's mode above it), so a trigger child must not supply its own; and `mergeRefs` passes a callback ref's cleanup through instead of dropping it, which is what lets a merged ref release its element on React 19. On a rail that is currently a sheet the collapse axis has nothing to act on, so `setMode` is inert — a stored desktop preference survives the trip through a narrow viewport.
199
+ - New on the `useSidebar(side)` value: `isMobile`, `isMobileOpen`, `setMobileOpen`. New on `Sidebar`: `mobileTitle`, the sheet's accessible name (defaults to `Navigation` / `Side panel`).
200
+
201
+ - `PromptCommand` loses its `icon`: the `/` menu has not drawn one since its rows became label-and-description only, so the field was dead weight on every caller.
202
+
203
+ - `PromptInput` gains an `attachments` slot: images and chips already attached to a message, drawn in
204
+ rows above the text rather than crowded onto its first line. Both variants are columns now, and only
205
+ the line itself differs — `inline` keeps the prefix beside the text, `default` stacks the text over
206
+ its toolbar.
207
+
208
+ `PromptInput.MenuTrigger` is the composer's "add to message" button: a plus that rotates into a cross
209
+ while its menu is open, with `aria-expanded` following.
210
+
211
+ The `/` command popup opens below the composer when there is no room above it, is capped in width,
212
+ sentence-cased, and carries a close button. `DropdownMenu.SubTrigger` and `DropdownMenu.CheckboxItem`
213
+ accept an `icon` drawn through the same slot as `DropdownMenu.Item`, so a mixed menu keeps one icon
214
+ column and one icon colour.
215
+
216
+ ### Patch Changes
217
+
218
+ - `AnswerActions`: the recorded vote is green for thumbs up and red for thumbs down, instead of the same blue for both.
219
+
220
+ - Addon-variant `rightSuffix` now shrinks instead of forcing the row to overflow, truncating inline content with an ellipsis when the group is narrower than its content.
221
+
222
+ - `UsageStats`' ring is a `<button>`: it opens a card, so it takes a pointer and a focus ring, and it
223
+ answers the hover it has always responded to. Hosts that wrapped it in a control of their own would
224
+ now nest two — none in this repo does.
225
+
226
+ ## 11.7.0
227
+
228
+ ### Minor Changes
229
+
230
+ - `Tooltip` gains a `hintUnderline` prop that marks its trigger with the shared "this text has a tooltip" affordance — a dashed `neutral-300` underline at `underline-offset-2` with `cursor-help`. It works in both trigger modes, and leaves the trigger's own text colour alone so a coloured label keeps its colour. The same classes are exported as `HINT_UNDERLINE_CLASS_NAME` for triggers that are not a `Tooltip`.
231
+
232
+ ### Patch Changes
233
+
234
+ - `AnswerActions` takes an `onCopy` callback, so a host can record that a reader took an answer away.
235
+
236
+ - `MultiCombobox` renders the value itself when `itemToStringLabel` has no label for it, instead of throwing. The projection is typed to return a string but can still come up empty at runtime: Base UI reports the outgoing selection for the render after `items` and `itemToStringLabel` change together, so a chip is asked for a label the incoming projection cannot produce. That threw a `TypeError` out of `namedLabel` and took the surrounding page down with it.
237
+
238
+ - `InputGroup` can shrink below its content's intrinsic width instead of overflowing its row. A flex item's default `min-width: auto` floored the group at the width of its input plus its addons, so several side by side — a custom timeout's days/hours/minutes row — pushed past their container rather than sharing it. The group already clips its own content, and the input inside already carried `min-w-0`.
239
+
240
+ - Add `UsageBar` to the AI kit — a budget as a labelled row over a `Progress`, filling with what is spent and reading out what is left. `variant` is the host's to pass, so a surface whose product rules forbid a warning meter draws an untoned one.
241
+
242
+ - `UsageStats`' ring keeps its size in a flex row. It is a fixed `size-8` with no content to give, so a sibling carrying `shrink-0` — every `Button` — used to squash it first.
243
+
3
244
  ## 11.6.1
4
245
 
5
246
  ### Patch Changes