@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/COMPONENT-API.md CHANGED
@@ -20,7 +20,7 @@ Source: `src/components/Button/Button.tsx`
20
20
  | `block` | `boolean \| null` | no | `false` | |
21
21
  | `isLoading` | `boolean` | no | `false` | Replaces the leading content with a spinner and disables the button visually. The caller still controls `disabled`. |
22
22
  | `size` | `"small" \| "medium" \| "large" \| "icon-lg" \| "icon" \| "icon-sm" \| "icon-xs" \| "icon-2xs" \| "icon-3xs" \| null` | no | `medium` | |
23
- | `variant` | `"primary" \| "secondary" \| "danger" \| "invisible" \| "outline" \| "inline" \| null` | no | `primary` | |
23
+ | `variant` | `"primary" \| "secondary" \| "kai" \| "danger" \| "invisible" \| "outline" \| "inline" \| null` | no | `primary` | |
24
24
 
25
25
  ### `ButtonInline`
26
26
 
@@ -73,44 +73,44 @@ Source: `src/blocks/TextInput/TextInput.tsx`
73
73
 
74
74
  > Bare input. Plus all native `<input>` attributes.
75
75
 
76
- | Prop | Type | Required | Default | Description |
77
- | -------------------- | --------------------------------------------------------------- | -------- | --------- | ----------------------------------------------------------------------------------------- |
78
- | `allowClear` | `boolean` | no | `false` | |
79
- | `defaultValue` | `string \| null` | no | — | |
80
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | `default` | |
81
- | `leftSuffix` | `ReactNode` | no | `null` | |
82
- | `onClear` | `(() => void)` | no | — | |
83
- | `onValueBlur` | `((value: string) => void)` | no | — | Called with the unwrapped string value on blur. For the raw event use `onBlur`. |
84
- | `onValueChange` | `((value: string) => void)` | no | — | Called with the unwrapped string value on every change. For the raw event use `onChange`. |
85
- | `prefix` | `ReactNode` | no | `null` | |
86
- | `rightSuffix` | `ReactNode` | no | `null` | |
87
- | `rightSuffixVariant` | `"default" \| "addon"` | no | `default` | |
88
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | `default` | |
89
- | `state` | `"warning" \| "error" \| "default" \| null` | no | `default` | |
90
- | `testId` | `string` | no | — | |
91
- | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | `text` | |
92
- | `value` | `string \| null` | no | — | |
93
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
76
+ | Prop | Type | Required | Default | Description |
77
+ | -------------------- | --------------------------------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------ |
78
+ | `allowClear` | `boolean` | no | `false` | |
79
+ | `defaultValue` | `string \| null` | no | — | |
80
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | `default` | |
81
+ | `leftSuffix` | `ReactNode` | no | `null` | |
82
+ | `onClear` | `(() => void)` | no | — | |
83
+ | `onValueBlur` | `((value: string) => void)` | no | — | Receives the string value; `onBlur` gets the raw event. |
84
+ | `onValueChange` | `((value: string) => void)` | no | — | Receives the string value; `onChange` gets the raw event. |
85
+ | `prefix` | `ReactNode` | no | `null` | |
86
+ | `rightSuffix` | `ReactNode` | no | `null` | `rightSuffixVariant="addon"` truncates it; the ellipsis needs inline content (text or `<span>`). |
87
+ | `rightSuffixVariant` | `"default" \| "addon"` | no | `default` | |
88
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | `default` | |
89
+ | `state` | `"warning" \| "error" \| "default" \| null` | no | `default` | |
90
+ | `testId` | `string` | no | — | |
91
+ | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | `text` | |
92
+ | `value` | `string \| null` | no | — | |
93
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
94
94
 
95
95
  ### `PasswordInput`
96
96
 
97
97
  Source: `src/blocks/PasswordInput/PasswordInput.tsx`
98
98
 
99
- | Prop | Type | Required | Default | Description |
100
- | --------------------------- | ----------------------------------------------- | -------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
101
- | `allowClear` | `boolean` | no | `false` | |
102
- | `allowPasswordToggle` | `boolean` | no | `false` | |
103
- | `autoComplete` | `"off" \| "current-password" \| "new-password"` | no | `new-password` | |
104
- | `defaultPasswordVisibility` | `boolean` | no | `false` | |
105
- | `defaultValue` | `string \| null` | no | — | |
106
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
107
- | `onValueBlur` | `((value: string) => void)` | no | — | |
108
- | `onValueChange` | `((value: string) => void)` | no | — | |
109
- | `passwordToggleLabel` | `string` | no | — | Suffix appended to the reveal button's accessible name, e.g. the field title. Use it to disambiguate multiple password fields on one form — "Show password: API token" / "Hide password: API token". Omit for a single field. |
110
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
111
- | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
112
- | `value` | `string \| null` | no | — | |
113
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
99
+ | Prop | Type | Required | Default | Description |
100
+ | --------------------------- | ----------------------------------------------- | -------- | -------------- | ------------------------------------------------------------------------------------- |
101
+ | `allowClear` | `boolean` | no | `false` | |
102
+ | `allowPasswordToggle` | `boolean` | no | `false` | |
103
+ | `autoComplete` | `"off" \| "current-password" \| "new-password"` | no | `new-password` | |
104
+ | `defaultPasswordVisibility` | `boolean` | no | `false` | |
105
+ | `defaultValue` | `string \| null` | no | — | |
106
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
107
+ | `onValueBlur` | `((value: string) => void)` | no | — | |
108
+ | `onValueChange` | `((value: string) => void)` | no | — | |
109
+ | `passwordToggleLabel` | `string` | no | — | Suffix of the reveal button's accessible name, to tell several password fields apart. |
110
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
111
+ | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
112
+ | `value` | `string \| null` | no | — | |
113
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
114
114
 
115
115
  ### `Textarea`
116
116
 
@@ -148,23 +148,23 @@ Source: `src/blocks/FormGroup/FormGroupTextInput.tsx`
148
148
 
149
149
  > NO `error` prop — error styling comes from the parent `FormGroup state="error"` via context. `state` is omitted from the surface for the same reason. Plus native `<input>` attributes.
150
150
 
151
- | Prop | Type | Required | Default | Description |
152
- | -------------------- | --------------------------------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------- |
153
- | `allowClear` | `boolean` | no | — | |
154
- | `defaultValue` | `string \| null` | no | — | |
155
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
156
- | `leftSuffix` | `ReactNode` | no | — | |
157
- | `onClear` | `(() => void)` | no | — | |
158
- | `onValueBlur` | `((value: string) => void)` | no | — | Called with the unwrapped string value on blur. For the raw event use `onBlur`. |
159
- | `onValueChange` | `((value: string) => void)` | no | — | Called with the unwrapped string value on every change. For the raw event use `onChange`. |
160
- | `prefix` | `ReactNode` | no | — | |
161
- | `rightSuffix` | `ReactNode` | no | — | |
162
- | `rightSuffixVariant` | `"default" \| "addon"` | no | — | |
163
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
164
- | `testId` | `string` | no | — | |
165
- | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | — | |
166
- | `value` | `string \| null` | no | — | |
167
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
151
+ | Prop | Type | Required | Default | Description |
152
+ | -------------------- | --------------------------------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------ |
153
+ | `allowClear` | `boolean` | no | — | |
154
+ | `defaultValue` | `string \| null` | no | — | |
155
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
156
+ | `leftSuffix` | `ReactNode` | no | — | |
157
+ | `onClear` | `(() => void)` | no | — | |
158
+ | `onValueBlur` | `((value: string) => void)` | no | — | Receives the string value; `onBlur` gets the raw event. |
159
+ | `onValueChange` | `((value: string) => void)` | no | — | Receives the string value; `onChange` gets the raw event. |
160
+ | `prefix` | `ReactNode` | no | — | |
161
+ | `rightSuffix` | `ReactNode` | no | — | `rightSuffixVariant="addon"` truncates it; the ellipsis needs inline content (text or `<span>`). |
162
+ | `rightSuffixVariant` | `"default" \| "addon"` | no | — | |
163
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
164
+ | `testId` | `string` | no | — | |
165
+ | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | — | |
166
+ | `value` | `string \| null` | no | — | |
167
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
168
168
 
169
169
  ### `FormGroup.Help`
170
170
 
@@ -178,9 +178,9 @@ Source: `src/blocks/FormGroup/FormGroupError.tsx`
178
178
 
179
179
  > Field validation error — carries `role="alert"` (announced on appearance). Pass `children` or an `errors` array (TanStack `string` / `{ message }` entries); a single message renders inline, several as a `<ul>`. Plus native `<div>` attributes.
180
180
 
181
- | Prop | Type | Required | Default | Description |
182
- | -------- | ----------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
183
- | `errors` | `readonly (string \| { message?: string; })[] \| undefined` | no | — | Field validation errors. TanStack Form errors are strings (function validators) or `{ message }` objects (Standard Schema / zod). A single message renders inline; several render as a list. Ignored when `children` is provided. |
181
+ | Prop | Type | Required | Default | Description |
182
+ | -------- | ----------------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------- |
183
+ | `errors` | `readonly (string \| { message?: string; })[] \| undefined` | no | — | TanStack Form errors: strings or `{ message }` objects; several render as a list. Ignored when `children` is provided. |
184
184
 
185
185
  ## Forms — useAppForm field connectors (accessed as `field.X` inside `form.AppField`)
186
186
 
@@ -190,128 +190,172 @@ Source: `src/blocks/Form/connectors/TextField.tsx`
190
190
 
191
191
  > Value/onChange/onBlur/id/name are wired from the field — do not pass them. Forwards remaining `FormGroup.TextInput` props.
192
192
 
193
- | Prop | Type | Required | Default | Description |
194
- | -------------------- | --------------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
195
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
196
- | `allowClear` | `boolean` | no | — | |
197
- | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
198
- | `className` | `string` | no | — | |
199
- | `defaultValue` | `string \| null` | no | — | |
200
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
201
- | `help` | `ReactNode` | no | — | |
202
- | `label` | `ReactNode` | no | — | |
203
- | `leftSuffix` | `ReactNode` | no | — | |
204
- | `onClear` | `(() => void)` | no | — | |
205
- | `onValueBlur` | `((value: string) => void)` | no | — | Called with the unwrapped string value on blur. For the raw event use `onBlur`. |
206
- | `onValueChange` | `((value: string) => void)` | no | — | Called with the unwrapped string value on every change. For the raw event use `onChange`. |
207
- | `prefix` | `ReactNode` | no | — | |
208
- | `required` | `boolean` | no | — | |
209
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
210
- | `rightSuffix` | `ReactNode` | no | — | |
211
- | `rightSuffixVariant` | `"default" \| "addon"` | no | — | |
212
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
213
- | `testId` | `string` | no | — | |
214
- | `tooltip` | `ReactNode` | no | — | |
215
- | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | — | |
216
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
193
+ | Prop | Type | Required | Default | Description |
194
+ | -------------------- | --------------------------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
195
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
196
+ | `allowClear` | `boolean` | no | — | |
197
+ | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
198
+ | `className` | `string` | no | — | |
199
+ | `defaultValue` | `string \| null` | no | — | |
200
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
201
+ | `help` | `ReactNode` | no | — | |
202
+ | `label` | `ReactNode` | no | — | |
203
+ | `leftSuffix` | `ReactNode` | no | — | |
204
+ | `onClear` | `(() => void)` | no | — | |
205
+ | `onValueBlur` | `((value: string) => void)` | no | — | Receives the string value; `onBlur` gets the raw event. |
206
+ | `onValueChange` | `((value: string) => void)` | no | — | Receives the string value; `onChange` gets the raw event. |
207
+ | `prefix` | `ReactNode` | no | — | |
208
+ | `required` | `boolean` | no | — | |
209
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
210
+ | `rightSuffix` | `ReactNode` | no | — | `rightSuffixVariant="addon"` truncates it; the ellipsis needs inline content (text or `<span>`). |
211
+ | `rightSuffixVariant` | `"default" \| "addon"` | no | — | |
212
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
213
+ | `testId` | `string` | no | — | |
214
+ | `tooltip` | `ReactNode` | no | — | |
215
+ | `type` | `"text" \| "email" \| "date" \| "password" \| "datetime-local"` | no | — | |
216
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
217
217
 
218
218
  ### `field.PasswordField`
219
219
 
220
220
  Source: `src/blocks/Form/connectors/PasswordField.tsx`
221
221
 
222
- | Prop | Type | Required | Default | Description |
223
- | --------------------------- | ----------------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
225
- | `allowClear` | `boolean` | no | — | |
226
- | `allowPasswordToggle` | `boolean` | no | — | |
227
- | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
228
- | `autoComplete` | `"off" \| "current-password" \| "new-password"` | no | — | |
229
- | `className` | `string` | no | — | |
230
- | `defaultPasswordVisibility` | `boolean` | no | — | |
231
- | `defaultValue` | `string \| null` | no | — | |
232
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
233
- | `help` | `ReactNode` | no | — | |
234
- | `label` | `ReactNode` | no | — | |
235
- | `onValueBlur` | `((value: string) => void)` | no | — | |
236
- | `passwordToggleLabel` | `string` | no | — | Suffix appended to the reveal button's accessible name, e.g. the field title. Use it to disambiguate multiple password fields on one form — "Show password: API token" / "Hide password: API token". Omit for a single field. |
237
- | `required` | `boolean` | no | — | |
238
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
239
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
240
- | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
241
- | `tooltip` | `ReactNode` | no | — | |
242
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
222
+ | Prop | Type | Required | Default | Description |
223
+ | --------------------------- | ----------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
224
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
225
+ | `allowClear` | `boolean` | no | — | |
226
+ | `allowPasswordToggle` | `boolean` | no | — | |
227
+ | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
228
+ | `autoComplete` | `"off" \| "current-password" \| "new-password"` | no | — | |
229
+ | `className` | `string` | no | — | |
230
+ | `defaultPasswordVisibility` | `boolean` | no | — | |
231
+ | `defaultValue` | `string \| null` | no | — | |
232
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
233
+ | `help` | `ReactNode` | no | — | |
234
+ | `label` | `ReactNode` | no | — | |
235
+ | `onValueBlur` | `((value: string) => void)` | no | — | |
236
+ | `passwordToggleLabel` | `string` | no | — | Suffix of the reveal button's accessible name, to tell several password fields apart. |
237
+ | `required` | `boolean` | no | — | |
238
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
239
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
240
+ | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
241
+ | `tooltip` | `ReactNode` | no | — | |
242
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
243
243
 
244
244
  ### `field.NumberField`
245
245
 
246
246
  Source: `src/blocks/Form/connectors/NumberField.tsx`
247
247
 
248
- | Prop | Type | Required | Default | Description |
249
- | ------------------ | ------------------------------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
250
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
251
- | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
252
- | `className` | `string` | no | — | |
253
- | `defaultValue` | `number \| null` | no | — | |
254
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
255
- | `help` | `ReactNode` | no | — | |
256
- | `label` | `ReactNode` | no | — | |
257
- | `onValueBlur` | `((value: number \| null) => void)` | no | — | |
258
- | `prefix` | `ReactNode` | no | — | |
259
- | `required` | `boolean` | no | — | |
260
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
261
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
262
- | `suffix` | `ReactNode` | no | — | |
263
- | `tooltip` | `ReactNode` | no | — | |
264
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
248
+ | Prop | Type | Required | Default | Description |
249
+ | ------------------ | ------------------------------------------ | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
250
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
251
+ | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
252
+ | `className` | `string` | no | — | |
253
+ | `defaultValue` | `number \| null` | no | — | |
254
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
255
+ | `help` | `ReactNode` | no | — | |
256
+ | `label` | `ReactNode` | no | — | |
257
+ | `onValueBlur` | `((value: number \| null) => void)` | no | — | |
258
+ | `prefix` | `ReactNode` | no | — | |
259
+ | `required` | `boolean` | no | — | |
260
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
261
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
262
+ | `suffix` | `ReactNode` | no | — | |
263
+ | `tooltip` | `ReactNode` | no | — | |
264
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
265
265
 
266
266
  ### `field.SelectField`
267
267
 
268
268
  Source: `src/blocks/Form/connectors/SelectField.tsx`
269
269
 
270
- | Prop | Type | Required | Default | Description |
271
- | ------------------ | ---------------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
272
- | `items` | `readonly (SelectItem \| SelectItemGroup)[]` | yes | — | |
273
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
274
- | `aria-describedby` | `string` | no | — | |
275
- | `autoComplete` | `string` | no | — | |
276
- | `className` | `string` | no | — | |
277
- | `defaultOpen` | `boolean` | no | — | |
278
- | `dir` | `"rtl" \| "ltr"` | no | — | |
279
- | `disabled` | `boolean` | no | — | |
280
- | `form` | `string` | no | — | |
281
- | `help` | `ReactNode` | no | — | |
282
- | `label` | `ReactNode` | no | — | |
283
- | `onOpenChange` | `((open: boolean) => void)` | no | — | |
284
- | `open` | `boolean` | no | — | |
285
- | `required` | `boolean` | no | — | |
286
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
287
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
288
- | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
289
- | `tooltip` | `ReactNode` | no | — | |
290
- | `triggerClassName` | `string` | no | — | |
291
- | `variant` | `"primary" \| "secondary" \| "inline" \| null` | no | — | |
270
+ | Prop | Type | Required | Default | Description |
271
+ | ------------------ | ---------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
272
+ | `items` | `readonly (SelectItem \| SelectItemGroup)[]` | yes | — | |
273
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
274
+ | `aria-describedby` | `string` | no | — | |
275
+ | `autoComplete` | `string` | no | — | |
276
+ | `className` | `string` | no | — | |
277
+ | `defaultOpen` | `boolean` | no | — | |
278
+ | `dir` | `"rtl" \| "ltr"` | no | — | |
279
+ | `disabled` | `boolean` | no | — | |
280
+ | `form` | `string` | no | — | |
281
+ | `help` | `ReactNode` | no | — | |
282
+ | `label` | `ReactNode` | no | — | |
283
+ | `onOpenChange` | `((open: boolean) => void)` | no | — | |
284
+ | `open` | `boolean` | no | — | |
285
+ | `required` | `boolean` | no | — | |
286
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
287
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
288
+ | `state` | `"warning" \| "error" \| "default" \| null` | no | — | |
289
+ | `tooltip` | `ReactNode` | no | — | |
290
+ | `triggerClassName` | `string` | no | — | |
291
+ | `variant` | `"primary" \| "secondary" \| "inline" \| null` | no | — | |
292
292
 
293
293
  ### `field.TextareaField`
294
294
 
295
295
  Source: `src/blocks/Form/connectors/TextareaField.tsx`
296
296
 
297
- | Prop | Type | Required | Default | Description |
298
- | -------------------- | --------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
299
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
300
- | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
301
- | `className` | `string` | no | — | |
302
- | `containerClassName` | `string` | no | — | |
303
- | `defaultValue` | `string \| null` | no | — | |
304
- | `disableResize` | `boolean` | no | — | |
305
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
306
- | `help` | `ReactNode` | no | — | |
307
- | `label` | `ReactNode` | no | — | |
308
- | `maxRows` | `number \| "unlimited"` | no | — | |
309
- | `onValueBlur` | `(((value: string) => void) & ((value: string) => void))` | no | — | |
310
- | `required` | `boolean` | no | — | |
311
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
312
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
313
- | `tooltip` | `ReactNode` | no | — | |
314
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
297
+ | Prop | Type | Required | Default | Description |
298
+ | -------------------- | --------------------------------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
299
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
300
+ | `aria-describedby` | `string` | no | — | Identifies the element (or elements) that describes the object. @see aria-labelledby |
301
+ | `className` | `string` | no | — | |
302
+ | `containerClassName` | `string` | no | — | |
303
+ | `defaultValue` | `string \| null` | no | — | |
304
+ | `disableResize` | `boolean` | no | — | |
305
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
306
+ | `help` | `ReactNode` | no | — | |
307
+ | `label` | `ReactNode` | no | — | |
308
+ | `maxRows` | `number \| "unlimited"` | no | — | |
309
+ | `onValueBlur` | `(((value: string) => void) & ((value: string) => void))` | no | — | |
310
+ | `required` | `boolean` | no | — | |
311
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
312
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
313
+ | `tooltip` | `ReactNode` | no | — | |
314
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
315
+
316
+ ### `ComboboxField`
317
+
318
+ Source: `src/blocks/Form/connectors/ComboboxField.tsx`
319
+
320
+ > One value from a searchable list — state is `string`, `''` for no selection, never an object. Project labels with `itemToStringLabel`, which names the input and the rows; `allowClear` defaults to `!required`. Imported by name from `@keboola/design`, composed inside `form.AppField` — NOT reachable as `field.ComboboxField`.
321
+
322
+ | Prop | Type | Required | Default | Description |
323
+ | --------------------- | ------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
324
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
325
+ | `allowClear` | `boolean` | no | — | `false` where clearing must be unreachable, e.g. a required field. |
326
+ | `allowCreate` | `boolean` | no | — | |
327
+ | `aria-describedby` | `string` | no | — | |
328
+ | `canCreate` | `((query: string) => boolean)` | no | — | Gate on the typed query for `allowCreate`; `false` hides the create row. - Called only for a non-empty query that matches no existing item. |
329
+ | `className` | `string` | no | — | |
330
+ | `collapsibleGroups` | `boolean` | no | — | Each group gets a toggle row; with `groupToValue`, only the chevron and ←/→ keys toggle it. - A query shows all matches regardless of collapse and hides groups without one. |
331
+ | `empty` | `ReactNode` | no | — | |
332
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
333
+ | `groupToLabel` | `((group: Group<string>) => ReactNode)` | no | — | Defaults to the group's `label`, as `Select` shows it. |
334
+ | `groupToValue` | `((group: Group<string>) => string)` | no | — | Makes each group's row selectable as the returned value. - `itemToStringLabel`, `itemToSelectedLabel` and `itemToDisabled` then receive it too. |
335
+ | `help` | `ReactNode` | no | — | |
336
+ | `indicator` | `Indicator` | no | — | |
337
+ | `inputClassName` | `string` | no | — | |
338
+ | `inputValueSanitizer` | `((input: string) => string)` | no | — | Rewrites typed text (not the selected label); filter and `allowCreate` see the result. - Rewrite, don't drop: it sees the whole text per keystroke, so `trim()` eats word spaces. |
339
+ | `isItemEqualToValue` | `((itemValue: string, value: string) => boolean)` | no | — | Custom comparison logic used to determine if a combobox item value matches the current selected value. Useful when item values are objects without matching referentially. Defaults to `Object.is` comparison. |
340
+ | `isLoading` | `boolean` | no | — | The options are still arriving — a request for `items` is in flight. - Does not disable the control; pass `disabled` too where the user has to wait. |
341
+ | `items` | `readonly (string \| Group<string>)[]` | no | — | Read as immutable: pass a new array to change it; one mutated in place is not re-filtered. |
342
+ | `itemToDisabled` | `((item: string) => boolean)` | no | — | |
343
+ | `itemToIcon` | `((item: string) => ReactNode)` | no | — | |
344
+ | `itemToLabel` | `((item: string, query: string) => ReactNode)` | no | — | Row content, `itemToStringLabel` by default; pass `query` to `MarkedText` to mark a match. |
345
+ | `itemToSelectedLabel` | `((item: string) => ReactNode)` | no | — | Selection node drawn over the transparent input while closed; typing dissolves it. Clipped. - Decoration: the input keeps `itemToStringLabel` text for screen readers, unlike `prefix`. |
346
+ | `itemToStringLabel` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for display in the input. If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop. |
347
+ | `itemToStringValue` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for form submission. If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop. |
348
+ | `label` | `ReactNode` | no | — | |
349
+ | `onQueryChange` | `((query: string) => void)` | no | — | Reports the sanitized query, also on mount; empty while the input shows the selection. - Notification only: the control owns the input text; there is no controlled `inputValue`. |
350
+ | `prefix` | `ReactNode` | no | — | |
351
+ | `queryToCreateLabel` | `((query: string) => ReactNode)` | no | — | |
352
+ | `queryToCreateValue` | `((query: string) => string)` | no | — | |
353
+ | `required` | `boolean` | no | — | |
354
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
355
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
356
+ | `tooltip` | `ReactNode` | no | — | |
357
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
358
+ | `virtualized` | `boolean \| "auto"` | no | — | Puts only the rows in view into the DOM: `'auto'` past 30 options, grouped or not; `true` always. |
315
359
 
316
360
  ### `MultiComboboxField`
317
361
 
@@ -319,44 +363,48 @@ Source: `src/blocks/Form/connectors/MultiComboboxField.tsx`
319
363
 
320
364
  > Several values from a searchable list — state is `string[]`, never objects, so the form value stays what gets submitted. Project labels with `itemToLabel`; add `allowCreate` for an enum the user may extend. Imported by name from `@keboola/design`, composed inside `form.AppField` — NOT reachable as `field.MultiComboboxField`.
321
365
 
322
- | Prop | Type | Required | Default | Description |
323
- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
324
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
325
- | `allowClear` | `boolean` | no | — | Offer a clear-all button once something is selected. Defaults to **`true`**. - `BaseCombobox.Clear` only mounts while chips exist, so an empty control renders identically either way. Individual chips stay removable regardless. - Pass `false` where emptying the whole selection must not be one click away. |
326
- | `allowCreate` | `boolean` | no | — | |
327
- | `allowSelectAll` | `boolean` | no | — | Adds a "Select All" row that selects the whole item set. - The row is hidden while a query narrows the list — it never means "everything matching". - Selecting it while everything is already selected clears the selection. |
328
- | `aria-describedby` | `string` | no | — | |
329
- | `canCreate` | `((query: string) => boolean)` | no | — | Gate on each value the entry stands for, for `allowCreate`. - Returning `false` drops that value, so an entry left with none hides the create row and the empty state shows instead. - Only called for a value that matches no item and nothing already selected — one naming an item is selected rather than minted, so its format is not this gate's business. - Reach for it when a free-form value has a format (a column name, an email address). |
330
- | `className` | `string` | no | — | |
331
- | `createSeparator` | `string \| RegExp \| null` | no | — | Separator that makes one creatable entry stand for several values. Defaults to **`','`**, so pasting `id1, id2, id3` adds three chips. - Pass a string or a non-capturing `RegExp` for another convention: `';'` for an Outlook address list, `/[\s,]+/` where a value can never contain a space. A capture group would be handed back as a value of its own — that is `String.prototype.split`'s own behaviour. - Pass `null` where a value legitimately contains the separator — a free-text label, a sentence — and one entry must stay one chip. - Whitespace is deliberately not part of the default: tags and column names contain spaces, and each part is trimmed anyway, so `id1, id2` needs nothing more than the comma. |
332
- | `empty` | `ReactNode` | no | — | |
333
- | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
334
- | `groupToLabel` | `((group: Group<string>) => ReactNode)` | no | — | |
335
- | `help` | `ReactNode` | no | — | |
336
- | `indicator` | `Indicator` | no | — | |
337
- | `inputClassName` | `string` | no | — | |
338
- | `inputValueSanitizer` | `((input: string) => string)` | no | — | Rewrites what the user types before the control adopts it. - The query the list filters by is the rewritten text, and so is every value a created entry is split into — a character the user cannot type is one they cannot create. - Reach for it where a created value has a character set: a column name, a scope, an identifier. `canCreate` is the gate for a format the user must get right themselves. - It has to rewrite rather than drop: it sees the whole text on every keystroke, so one calling `trim()` swallows the space before the next word. |
339
- | `isItemEqualToValue` | `((itemValue: string, value: string) => boolean)` | no | — | Custom comparison logic used to determine if a combobox item value matches the current selected value. Useful when item values are objects without matching referentially. Defaults to `Object.is` comparison. |
340
- | `items` | `readonly (string \| Group<string>)[]` | no | — | |
341
- | `itemToChipColor` | `((item: string) => "gray" \| "gray-darker" \| "gray-inverse" \| "green" \| "green-darker" \| "green-inverse" \| "blue" \| "blue-inverse" \| "red" \| "orange" \| "orange-inverse" \| "amber" \| ... 9 more ...)` | no | — | |
342
- | `itemToChipLabel` | `((item: string) => ReactNode)` | no | — | |
343
- | `itemToDisabled` | `((item: string) => boolean)` | no | — | |
344
- | `itemToIcon` | `((item: string) => ReactNode)` | no | — | |
345
- | `itemToLabel` | `((item: string) => ReactNode)` | no | — | The item's row in the list, and its chip unless `itemToChipLabel` overrides it. - Defaults to `itemToStringLabel`, so a control that projects its items — ids carrying the selection, the label looked up beside them — states the projection once. - Pass it separately only where the row is richer than the input's own text. |
346
- | `itemToStringLabel` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for display in the input. If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop. |
347
- | `itemToStringValue` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for form submission. If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop. |
348
- | `label` | `ReactNode` | no | — | |
349
- | `maxVisible` | `number` | no | — | |
350
- | `onQueryChange` | `((query: string) => void)` | no | — | Reports the query the list filters by, `inputValueSanitizer` already applied. - For an owner that needs the query for itself: a server-side search, an option order, the text a synthetic row is offered for. The mount render reports too, so a search driven by this needs no first fetch of its own. - Notification only, and deliberately not Base UI's own `onInputValueChange`: the control keeps ownership of the text — a pick clears it — so there is no controlled `inputValue` to hold in sync. |
351
- | `pinnedChipLabels` | `ReactNode[]` | no | — | Labels for chips the control shows but the user does not own — a pinned set the caller keeps. - Each label gets a chip of its own, ahead of the values and outside the `maxVisible` slice. - No remove button, and no entry in `value` — there is nothing for a removal to report. |
352
- | `queryToCreateLabel` | `((query: string) => ReactNode)` | no | — | Words the create row. Receives the values committing the row will add — an entry standing for several values arrives trimmed and re-joined with its own separator, not as typed. |
353
- | `queryToCreateValue` | `((query: string) => string)` | no | — | Projects one entered string into an item. Called once per value, so a split entry calls it several times, each with an already-trimmed part. |
354
- | `renderChips` | `((values: string[]) => ReactNode)` | no | — | Renders the chip area from the selected values, in place of the default chips. - For the case no per-value accessor can express: one node standing for the whole selection ("3 tables selected"), or a chip count that is not the value count. - A chip that merely holds richer content — a link, an action of its own — needs no slot: `itemToChipLabel` returns a `ReactNode` and the chip lets it take the keyboard. - The chip props above go unused while this is set, `maxVisible` and its `+N` chip included. - `Combobox.Chip` builds a removable chip. |
355
- | `required` | `boolean` | no | — | |
356
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
357
- | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
358
- | `tooltip` | `ReactNode` | no | — | |
359
- | `variant` | `"primary" \| "secondary" \| null` | no | — | |
366
+ | Prop | Type | Required | Default | Description |
367
+ | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
368
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
369
+ | `allowClear` | `boolean` | no | — | Clear-all button, shown only while chips exist. Chips stay removable either way. |
370
+ | `allowCreate` | `boolean` | no | — | |
371
+ | `allowSelectAll` | `boolean` | no | — | "Select All" row for the whole set; hidden while a query is active, clears when all are selected. |
372
+ | `aria-describedby` | `string` | no | — | |
373
+ | `canCreate` | `((query: string) => boolean)` | no | — | Rejects a value `allowCreate` would mint; values naming an item or already selected skip it. |
374
+ | `className` | `string` | no | — | |
375
+ | `collapsibleGroups` | `boolean` | no | — | A row per group that folds it. A query shows every match regardless; state is keyed by position. |
376
+ | `createSeparator` | `string \| RegExp \| null` | no | — | Splits one entry into several values (default `','`). A `RegExp` must not capture; `null` never splits. |
377
+ | `empty` | `ReactNode` | no | — | |
378
+ | `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
379
+ | `groupToLabel` | `((group: Group<string>) => ReactNode)` | no | — | Defaults to the group's `label`, as `Select` shows it. |
380
+ | `help` | `ReactNode` | no | — | |
381
+ | `indicator` | `Indicator` | no | — | |
382
+ | `inputClassName` | `string` | no | — | |
383
+ | `inputValueSanitizer` | `((input: string) => string)` | no | — | Rewrites typed text before filtering and creating. Sees the whole text per keystroke — don't `trim()`. |
384
+ | `isItemEqualToValue` | `((itemValue: string, value: string) => boolean)` | no | — | Custom comparison logic used to determine if a combobox item value matches the current selected value. Useful when item values are objects without matching referentially. Defaults to `Object.is` comparison. |
385
+ | `isLoading` | `boolean` | no | — | Options still arriving; doesn't disable — pass `disabled` where the user must wait. |
386
+ | `items` | `readonly (string \| Group<string>)[]` | no | — | Read as immutable: pass a new array to change it; one mutated in place is not re-filtered. |
387
+ | `itemToChipColor` | `((item: string) => "gray" \| "gray-darker" \| "gray-inverse" \| "green" \| "green-darker" \| "green-inverse" \| "blue" \| "blue-inverse" \| "red" \| "orange" \| "orange-inverse" \| "amber" \| ... 9 more ...)` | no | — | |
388
+ | `itemToChipLabel` | `((item: string) => ReactNode)` | no | — | |
389
+ | `itemToDisabled` | `((item: string) => boolean)` | no | — | |
390
+ | `itemToIcon` | `((item: string) => ReactNode)` | no | — | |
391
+ | `itemToLabel` | `((item: string, query: string) => ReactNode)` | no | — | Row and chip content (unless `itemToChipLabel`), `itemToStringLabel` by default. - `query` is the search text, for `MarkedText`; a chip gets `''`. |
392
+ | `itemToStringLabel` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for display in the input. If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop. |
393
+ | `itemToStringValue` | `((itemValue: string) => string)` | no | — | When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for form submission. If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop. |
394
+ | `label` | `ReactNode` | no | — | |
395
+ | `maxVisible` | `number` | no | — | |
396
+ | `onQueryChange` | `((query: string) => void)` | no | — | Reports the sanitized query, on mount too. Notification only — the control owns the text. |
397
+ | `pinnedChipLabels` | `ReactNode[]` | no | — | Non-removable chips ahead of the values, outside `maxVisible` and absent from `value`. |
398
+ | `queryToCreateLabel` | `((query: string) => ReactNode)` | no | — | Words the create row. Receives the values it adds, trimmed and re-joined — not the entry as typed. |
399
+ | `queryToCreateValue` | `((query: string) => string)` | no | — | Projects one entered value into an item. Called once per trimmed part of a split entry. |
400
+ | `renderChips` | `((values: string[]) => ReactNode)` | no | — | Replaces the default chips; the chip props, `maxVisible` included, are then ignored. |
401
+ | `required` | `boolean` | no | — | |
402
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
403
+ | `selectableGroups` | `boolean` | no | — | A group's row selects its matching enabled items. The row itself never enters `value`. |
404
+ | `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
405
+ | `tooltip` | `ReactNode` | no | — | |
406
+ | `variant` | `"primary" \| "secondary" \| null` | no | — | |
407
+ | `virtualized` | `boolean \| "auto"` | no | — | Puts only the rows in view into the DOM: `'auto'` past 30 options, grouped or not; `true` always. |
360
408
 
361
409
  ### `field.CheckboxField`
362
410
 
@@ -390,26 +438,26 @@ Source: `src/blocks/Form/connectors/OtpInputField.tsx`
390
438
 
391
439
  > Fixed-length code; string value. Pass `maxLength` — slots are rendered for you.
392
440
 
393
- | Prop | Type | Required | Default | Description |
394
- | ----------------------------- | ------------------------------- | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
395
- | `maxLength` | `number` | yes | — | |
396
- | `action` | `ReactNode` | no | — | Optional node rendered at the trailing edge of the label row (opposite the label) — e.g. a "Forgot password?" link beside a Password label. Presentational placement only; it is a sibling of the `<Label>`, not part of the field's accessible name. Provide an interactive element (`ButtonInline` / `Link`). |
397
- | `aria-describedby` | `string` | no | — | |
398
- | `className` | `string` | no | — | |
399
- | `containerClassName` | `string` | no | — | |
400
- | `help` | `ReactNode` | no | — | |
401
- | `label` | `ReactNode` | no | — | |
402
- | `nonce` | `string` | no | — | |
403
- | `noScriptCSSFallback` | `string \| null` | no | — | |
404
- | `onComplete` | `((...args: any[]) => unknown)` | no | — | |
405
- | `pasteTransformer` | `((pasted: string) => string)` | no | — | |
406
- | `pushPasswordManagerStrategy` | `"none" \| "increase-width"` | no | — | |
407
- | `render` | `undefined` | no | — | |
408
- | `required` | `boolean` | no | — | |
409
- | `requiredMark` | `RequiredMark` | no | — | Which marker to show beside the label — gated by `required` so it never lies: `'required'` renders `*` only when the field is `required`; `'optional'` renders `(optional)` only when it is not; `'hidden'` renders neither. Defaults to `'required'`. |
410
- | `sizing` | `OtpInputSizing` | no | — | |
411
- | `textAlign` | `"center" \| "right" \| "left"` | no | — | |
412
- | `tooltip` | `ReactNode` | no | — | |
441
+ | Prop | Type | Required | Default | Description |
442
+ | ----------------------------- | ------------------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
443
+ | `maxLength` | `number` | yes | — | |
444
+ | `action` | `ReactNode` | no | — | Trailing node on the label row (e.g. a `Link`); not part of the accessible name. |
445
+ | `aria-describedby` | `string` | no | — | |
446
+ | `className` | `string` | no | — | |
447
+ | `containerClassName` | `string` | no | — | |
448
+ | `help` | `ReactNode` | no | — | |
449
+ | `label` | `ReactNode` | no | — | |
450
+ | `nonce` | `string` | no | — | |
451
+ | `noScriptCSSFallback` | `string \| null` | no | — | |
452
+ | `onComplete` | `((...args: any[]) => unknown)` | no | — | |
453
+ | `pasteTransformer` | `((pasted: string) => string)` | no | — | |
454
+ | `pushPasswordManagerStrategy` | `"none" \| "increase-width"` | no | — | |
455
+ | `render` | `undefined` | no | — | |
456
+ | `required` | `boolean` | no | — | |
457
+ | `requiredMark` | `RequiredMark` | no | — | Gated by `required`: `'required'` shows `*` only if required, `'optional'` shows `(optional)` only if not, `'hidden'` neither. Defaults to `'required'`. |
458
+ | `sizing` | `OtpInputSizing` | no | — | |
459
+ | `textAlign` | `"center" \| "right" \| "left"` | no | — | |
460
+ | `tooltip` | `ReactNode` | no | — | |
413
461
 
414
462
  ## Data display — Card (compound)
415
463
 
@@ -430,10 +478,10 @@ Source: `src/components/Card/CardHeader.tsx`
430
478
 
431
479
  > Own props below, plus native `<div>` attributes.
432
480
 
433
- | Prop | Type | Required | Default | Description |
434
- | --------- | ------------------------------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
435
- | `divider` | `boolean` | no | `false` | Adds a bottom rule, the header's own padding, and a 64px height floor so the band stays the same height with or without an action button. The rule spans the full card width — pair with `Card padding="none"`; on a padded root it is inset. |
436
- | `layout` | `"inline" \| "row" \| "stack"` | no | `row` | How the header distributes its children. `row` (default) pushes them apart — title left, actions right. `inline` keeps them together on one line, for a title with an adornment such as an icon or badge. `stack` puts a description under the title. |
481
+ | Prop | Type | Required | Default | Description |
482
+ | --------- | ------------------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------- |
483
+ | `divider` | `boolean` | no | `false` | Bottom rule plus own padding and a 64px min height. Full-bleed only with `Card padding="none"`. |
484
+ | `layout` | `"inline" \| "row" \| "stack"` | no | `row` | `row`: title left, actions right. `inline`: together, e.g. title + badge. `stack`: description under the title. |
437
485
 
438
486
  ### `Card.Title`
439
487
 
@@ -463,15 +511,15 @@ Source: `src/components/ThemeProvider/ThemeProvider.tsx`
463
511
 
464
512
  > Wrap the app root once. Resolves the active brand from `brands` by `brandId` (or `defaultBrandId` when uncontrolled); with neither set it falls back to the design-system defaults (no brand tokens injected). `scheme` sets light/dark/system (default `light`). Pair with `useTheme()` to read/flip the brand or scheme at runtime. Mounts a `TooltipProvider` around its subtree, so a `Tooltip` works without a separately-mounted provider.
465
513
 
466
- | Prop | Type | Required | Default | Description |
467
- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
468
- | `brandId` | `string` | no | — | Controlled active brand id. When set, the parent owns the value and `setBrand` only notifies via `onBrandIdChange` (it does not mutate internal state). |
469
- | `brands` | `readonly { id: string; name: string; theme: { colors?: { foreground?: string; background?: string; muted?: string \| undefined; mutedForeground?: string \| undefined; border?: string \| undefined; ... 23 more ...; sidebar?: { ...; } \| undefined; } \| undefined; ... 6 more ...; gradient?: { ...; }...` | no | `[]` | Brands this provider knows about; the active brand id resolves against these. |
470
- | `defaultBrandId` | `string` | no | — | Initial active brand id for uncontrolled use. Defaults to the design-system sentinel (`DEFAULT_BRAND_ID`) — no brand tokens injected, so the stylesheet defaults apply. |
471
- | `defaultScheme` | `ColorScheme` | no | — | Initial colour scheme for uncontrolled use. Defaults to `light` (`DEFAULT_COLOR_SCHEME`). |
472
- | `onBrandIdChange` | `((brandId: string) => void)` | no | — | Called with the next id whenever `setBrand` runs — required to persist the choice in controlled mode. |
473
- | `onSchemeChange` | `((theme: ColorScheme) => void)` | no | — | Called with the next scheme whenever `setScheme` runs — required to persist the choice in controlled mode. |
474
- | `scheme` | `ColorScheme` | no | — | Controlled colour scheme (`light` / `dark` / `system`). When set, the parent owns the value and `setScheme` only notifies via `onSchemeChange`. `system` follows `prefers-color-scheme` and resolves reactively. |
514
+ | Prop | Type | Required | Default | Description |
515
+ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
516
+ | `brandId` | `string` | no | — | Controlled active brand id. When set, the parent owns the value and `setBrand` only notifies via `onBrandIdChange` (it does not mutate internal state). |
517
+ | `brands` | `readonly { id: string; name: string; theme: { colors?: { foreground?: string; background?: string; muted?: string \| undefined; mutedForeground?: string \| undefined; border?: string \| undefined; ... 23 more ...; sidebar?: { ...; } \| undefined; } \| undefined; ... 6 more ...; gradient?: { ...; }...` | no | `[]` | Brands this provider knows about; the active brand id resolves against these. |
518
+ | `defaultBrandId` | `string` | no | — | Initial active brand id for uncontrolled use. Defaults to the design-system sentinel (`DEFAULT_BRAND_ID`) — no brand tokens injected, so the stylesheet defaults apply. |
519
+ | `defaultScheme` | `ColorScheme` | no | — | Initial scheme when uncontrolled; defaults to `light`. |
520
+ | `onBrandIdChange` | `((brandId: string) => void)` | no | — | Called with the next id whenever `setBrand` runs — required to persist the choice in controlled mode. |
521
+ | `onSchemeChange` | `((theme: ColorScheme) => void)` | no | — | Required to persist the choice in controlled mode. |
522
+ | `scheme` | `ColorScheme` | no | — | Controlled scheme; `setScheme` then only calls `onSchemeChange`. `system` follows `prefers-color-scheme` live. |
475
523
 
476
524
  ### `BrandLogo`
477
525
 
@@ -479,11 +527,11 @@ Source: `src/components/BrandLogo/BrandLogo.tsx`
479
527
 
480
528
  > Renders the active brand's logo from the nearest `<ThemeProvider>`. `variant` is `wordmark` (default) | `mark`; each falls back to the other and light↔dark. Inline SVG (a `currentColor` mark inherits text colour) or `<img>` per source. Size via `className` height. `Sidebar.Header` / `Navbar.Header` render it by default when given no children.
481
529
 
482
- | Prop | Type | Required | Default | Description |
483
- | ----------- | ---------------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
484
- | `className` | `string` | no | — | Sets the logo height; aspect ratio is preserved (e.g. `tw:h-7`). |
485
- | `label` | `string` | no | — | The logo's accessible name. - Defaults to the brand's `name`, which is registry metadata: it labels the brand's row in a picker, so it carries whatever disambiguates it there (`Keboola (V2)`). - Pass the product's own name wherever the logo is what names something to a screen reader — a link around it most of all, which otherwise announces that suffix. |
486
- | `variant` | `"mark" \| "wordmark"` | no | `wordmark` | `wordmark` (default, full logo) or `mark` (square icon); each falls back to the other. |
530
+ | Prop | Type | Required | Default | Description |
531
+ | ----------- | ---------------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
532
+ | `className` | `string` | no | — | Sets the logo height; aspect ratio is preserved (e.g. `tw:h-7`). |
533
+ | `label` | `string` | no | — | Accessible name; defaults to the brand's picker `name`, suffixes included (`Keboola (V2)`). Pass the product name where the logo names something, e.g. a link. |
534
+ | `variant` | `"mark" \| "wordmark"` | no | `wordmark` | `wordmark` (default, full logo) or `mark` (square icon); each falls back to the other. |
487
535
 
488
536
  ## Layout & shell
489
537
 
@@ -493,9 +541,9 @@ Source: `src/blocks/AppShell/AppShell.tsx`
493
541
 
494
542
  > Compound app-root shell that follows the active brand (sidebar vs top-nav). Subcomponents: `AppShell.Sidebar`, `AppShell.Header`, `AppShell.Aside`, `AppShell.Main`. `AppShell.Main` owns the default page gutter (`tw:p-6`) on a wrapper inside its scroll container — override with `contentClassName="tw:p-0"`, never a `p-*` in `className` (that sits on the scrollport and breaks every sticky header below it, `Table.Header` included). `Main` is also the scrollport by default and its content wrapper grows with the content; pass `clampContent` when the page runs its own `overflow-auto` scroller, so a `flex-1` descendant clamps to the shell instead of resolving against the content. `AppShell.Header` and `AppShell.Aside` take `flush` — pass it when the slot hosts a chrome component that paints itself (`Navbar`, `Sidebar side="right"`), so the slot drops its own padding, background and border instead of insetting the child. Native `<div>` attributes.
495
543
 
496
- | Prop | Type | Required | Default | Description |
497
- | ------------ | -------------------- | -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
498
- | `headerSpan` | `AppShellHeaderSpan` | no | `content` | How far the header row stretches. `content` (default) gives it the middle column only, with both rails beside it; `full` spans all three columns and drops the rails below it, so the brand mark aligns to the viewport edge. No-op under the top-nav geometry, whose header is already full width. Reach for `full` when the header carries app-wide identity (brand mark, project switcher, account menu) rather than page-level navigation. |
544
+ | Prop | Type | Required | Default | Description |
545
+ | ------------ | -------------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------- |
546
+ | `headerSpan` | `AppShellHeaderSpan` | no | `content` | `content`: middle column only; `full`: spans above both rails, for app-wide identity. No-op under the top-nav geometry. |
499
547
 
500
548
  ### `PageLayout`
501
549
 
@@ -513,12 +561,12 @@ Source: `src/blocks/AuthLayout/AuthLayout.tsx`
513
561
 
514
562
  > Compound signed-out page frame — sign-in, sign-up, password reset, MFA, project picker. Subcomponents: `AuthLayout.Header` (a `header`; pairs the active brand mark with the `productName` it is given unless children replace the lockup, and takes `actions` for theme / strategy controls), `AuthLayout.Content` (the `main` form column), `AuthLayout.Footer` (a `footer`). `width` is `form` (28rem) | `wide` (34rem). Pass `aside` (plus `asideSide`) for the split geometry: the form column becomes `bg-background` and the panel `bg-muted`; without one the page is `bg-muted` and the call site supplies the `Card`. Below `lg` the split collapses to one column and the panel is dropped — `asideCollapse='stack'` stacks it above or below the form instead, for a page whose pitch has to survive a phone. Deliberately does **not** own the card — two of the pages it frames have none. Native `<div>` attributes.
515
563
 
516
- | Prop | Type | Required | Default | Description |
517
- | --------------- | ------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
518
- | `aside` | `ReactNode` | no | — | Marketing / illustration panel. Its presence switches the page to the split geometry. |
519
- | `asideCollapse` | `"hide" \| "stack"` | no | `hide` | What the `aside` does below `lg`, where the split collapses to one column. - `hide` (default) — the panel is dropped. Right for a page a signed-out _user_ asked for: they came to sign in, and the pitch is not why they are here. - `stack` — the panel keeps its `asideSide` order relative to the form and renders above or below it. Right for a page that has to sell: an acquisition funnel loses its social proof otherwise, on the devices most of it arrives on. |
520
- | `asideSide` | `"start" \| "end"` | no | `end` | Which side the `aside` takes on wide screens. |
521
- | `width` | `Width` | no | `form` | |
564
+ | Prop | Type | Required | Default | Description |
565
+ | --------------- | ------------------- | -------- | ------- | -------------------------------------------------------------------------------------------- |
566
+ | `aside` | `ReactNode` | no | — | Marketing / illustration panel. Its presence switches the page to the split geometry. |
567
+ | `asideCollapse` | `"hide" \| "stack"` | no | `hide` | The `aside` below `lg`: `hide` it (sign-in) or `stack` it by the form (acquisition funnels). |
568
+ | `asideSide` | `"start" \| "end"` | no | `end` | Which side the `aside` takes on wide screens. |
569
+ | `width` | `Width` | no | `form` | |
522
570
 
523
571
  ### `PageHeader.Index`
524
572
 
@@ -526,15 +574,15 @@ Source: `src/blocks/PageHeader/PageHeaderIndex.tsx`
526
574
 
527
575
  > Index-page header. Pass `Tabs` via `headerNav`.
528
576
 
529
- | Prop | Type | Required | Default | Description |
530
- | ---------------------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
531
- | `title` | `ReactNode` | yes | — | |
532
- | `action` | `ReactNode` | no | — | Primary "create / add new X" `Button`. |
533
- | `description` | `ReactNode` | no | — | Prose description shown below the title. Mutually exclusive with `metadata` in the pattern; `metadata` wins when both are passed. |
534
- | `documentation` | `ReactNode` | no | — | Icon-only docs button (`Button variant="invisible" icon={<BookOpen />}`). Sits next to `action`. |
535
- | `fullWidthDescription` | `boolean` | no | `false` | Opt into the responsive layout: the description spans its own full-width row below the title, and the action group wraps beneath the title (right-aligned) on narrow widths instead of shrinking. Defaults to `false` (the description shares the title column and actions stay `shrink-0`). Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical. |
536
- | `headerNav` | `ReactNode` | no | — | Optional `Tabs` row rendered below the title block. Use only when >1 dataset / section is worth navigating to. |
537
- | `metadata` | `ReactNode` | no | — | Count / system summary shown below the title (e.g. "3 buckets and 39 tables"). Wins over `description`. |
577
+ | Prop | Type | Required | Default | Description |
578
+ | ---------------------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------------- |
579
+ | `title` | `ReactNode` | yes | — | |
580
+ | `action` | `ReactNode` | no | — | The one primary "create X" `Button`. |
581
+ | `description` | `ReactNode` | no | — | Prose below the title; `metadata` wins when both are set. |
582
+ | `documentation` | `ReactNode` | no | — | Icon-only docs button (`Button variant="invisible" icon={<BookOpen />}`). |
583
+ | `fullWidthDescription` | `boolean` | no | `false` | Description on its own full-width row; actions wrap below the title on narrow widths. |
584
+ | `headerNav` | `ReactNode` | no | — | `Tabs` row below the title block. |
585
+ | `metadata` | `ReactNode` | no | — | Count summary ("3 buckets and 39 tables"). Wins over `description`. |
538
586
 
539
587
  ### `PageHeader.Detail`
540
588
 
@@ -542,19 +590,19 @@ Source: `src/blocks/PageHeader/PageHeaderDetail.tsx`
542
590
 
543
591
  > Detail-page header (back link, title, actions).
544
592
 
545
- | Prop | Type | Required | Default | Description |
546
- | ---------------------- | ----------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
547
- | `breadcrumbs` | `ReactNode` | yes | — | `Breadcrumb` chain to the entity's parent list / hierarchy. Required. Never repeat the entity's own name as a final, non-link item — it's already the `title` below. |
548
- | `title` | `ReactNode` | yes | — | |
549
- | `badges` | `ReactNode` | no | — | Inline `Badge`s rendered next to the title (status, environment, version). Always rendered as pills. |
550
- | `compact` | `boolean` | no | `false` | Compact title mode: renders a smaller title for information-dense pages. Default `false`. |
551
- | `description` | `ReactNode` | no | — | |
552
- | `fullWidthDescription` | `boolean` | no | `false` | Opt into the responsive layout: the description spans its own full-width row below the title/actions row instead of sharing the title column. Defaults to `false` (description sits inside the title column). Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical. |
553
- | `headerNav` | `ReactNode` | no | — | Optional `Tabs` row below the title block. |
554
- | `overflowActions` | `ReactNode` | no | — | `DropdownMenu` for tertiary actions. Sits on the breadcrumbs row, not the title row. |
555
- | `primaryAction` | `ReactNode` | no | — | Primary action (`Button`). Use the verb appropriate to the entity (Deploy / Run / Save). |
556
- | `secondaryAction` | `ReactNode` | no | — | Optional second action (`Button variant="secondary"`). Everything beyond goes in `overflowActions`. |
557
- | `titleIcon` | `ReactNode` | no | — | Optional icon rendered immediately left of the title (entity / component / type icon). |
593
+ | Prop | Type | Required | Default | Description |
594
+ | ---------------------- | ----------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
595
+ | `breadcrumbs` | `ReactNode` | yes | — | Chain to the entity's parent. Don't end with the entity's own name — that's the `title`. |
596
+ | `title` | `ReactNode` | yes | — | |
597
+ | `badges` | `ReactNode` | no | — | `Badge`s beside the title (status, environment, version). |
598
+ | `compact` | `boolean` | no | `false` | Smaller title for information-dense pages. |
599
+ | `description` | `ReactNode` | no | — | |
600
+ | `fullWidthDescription` | `boolean` | no | `false` | Description on its own full-width row below title and actions, not in the title column. |
601
+ | `headerNav` | `ReactNode` | no | — | `Tabs` row below the title block. |
602
+ | `overflowActions` | `ReactNode` | no | — | `DropdownMenu` for all other actions, on the breadcrumbs row. |
603
+ | `primaryAction` | `ReactNode` | no | — | `Button` with the verb appropriate to the entity (Deploy / Run / Save). |
604
+ | `secondaryAction` | `ReactNode` | no | — | `Button variant="secondary"`. Further actions go in `overflowActions`. |
605
+ | `titleIcon` | `ReactNode` | no | — | Entity / type icon left of the title. |
558
606
 
559
607
  ## Navigation shell
560
608
 
@@ -564,16 +612,17 @@ Source: `src/components/Sidebar/Sidebar.tsx`
564
612
 
565
613
  > App-shell left navigation rail (host inside `AppShell.Sidebar`). Compound: `Sidebar.Header`, `Sidebar.Content`, `Sidebar.Footer`, `Sidebar.Menu`, `Sidebar.Group`, `Sidebar.SearchInput` (concrete `<input>`, no `asChild`).
566
614
 
567
- | Prop | Type | Required | Default | Description |
568
- | ----------------- | --------------- | -------- | ------- | --------------------------------------------------------------- |
569
- | `className` | `string` | no | — | |
570
- | `container` | `boolean` | no | `false` | |
571
- | `id` | `string` | no | — | |
572
- | `keepMounted` | `boolean` | no | — | |
573
- | `mountAfterEnter` | `boolean` | no | — | Hold the panel's content back until it has finished sliding in. |
574
- | `resizable` | `boolean` | no | `false` | |
575
- | `side` | `SidebarSide` | no | `left` | |
576
- | `style` | `CSSProperties` | no | — | |
615
+ | Prop | Type | Required | Default | Description |
616
+ | ----------------- | --------------- | -------- | ------- | ------------------------------------------------------------------------------------------ |
617
+ | `className` | `string` | no | — | |
618
+ | `container` | `boolean` | no | `false` | |
619
+ | `id` | `string` | no | — | |
620
+ | `keepMounted` | `boolean` | no | — | |
621
+ | `mobileTitle` | `string` | no | — | Visually hidden name of the mobile sheet; defaults to `Navigation` / `Side panel` by side. |
622
+ | `mountAfterEnter` | `boolean` | no | — | Hold the panel's content back until it has finished sliding in. |
623
+ | `resizable` | `boolean` | no | `false` | |
624
+ | `side` | `SidebarSide` | no | `left` | |
625
+ | `style` | `CSSProperties` | no | — | |
577
626
 
578
627
  ### `SectionNav`
579
628
 
@@ -581,14 +630,14 @@ Source: `src/blocks/SectionNav/SectionNav.tsx`
581
630
 
582
631
  > In-page navigation for one page's grouped sections — a tree above the container breakpoint, a dropdown below it. **Not** `Sidebar`: page-scoped, hosted in `PageLayout.Content nav`, no global state. Router-agnostic — `renderItem` returns your router's link and receives `{ targetId, isActive, children, itemProps }`; spread `itemProps` whole. Visibility / permission filtering and the group model stay in the app (see RECIPES.md#section-nav).
583
632
 
584
- | Prop | Type | Required | Default | Description |
585
- | ------------------ | ------------------------------------------------- | -------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
586
- | `groups` | `SectionNavGroup[]` | yes | — | The sections to show, already filtered. Visibility, permissions and feature flags stay in the app — this block renders exactly what it is handed, in order. |
587
- | `renderItem` | `(props: SectionNavItemRenderProps) => ReactNode` | yes | — | Renders the clickable element for one row, so routing never enters the design system. Return a `NavLink` / TanStack `Link` / `<a>` pointing at `targetId` and spread `itemProps` onto it. |
588
- | `activeId` | `string` | no | — | `id` of the current section: a child's, or a childless group's. |
589
- | `className` | `string` | no | — | Applied to the tree's `<nav>`. The column's own geometry belongs to `PageLayout.Content nav`. |
590
- | `label` | `string` | no | `Sections` | Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. |
591
- | `showDescriptions` | `boolean` | no | `false` | Print each section's `description` under its title. Off — the tree stays scannable without it. |
633
+ | Prop | Type | Required | Default | Description |
634
+ | ------------------ | ------------------------------------------------- | -------- | ---------- | --------------------------------------------------------------------------------------- |
635
+ | `groups` | `SectionNavGroup[]` | yes | — | Already filtered: visibility, permissions and flags stay in the app; rendered as given. |
636
+ | `renderItem` | `(props: SectionNavItemRenderProps) => ReactNode` | yes | — | Return a router link / `<a>` to `targetId` with `itemProps` spread on it. |
637
+ | `activeId` | `string` | no | — | `id` of the current section: a child's, or a childless group's. |
638
+ | `className` | `string` | no | — | Applied to the tree's `<nav>`; the column geometry belongs to `PageLayout.Content nav`. |
639
+ | `label` | `string` | no | `Sections` | Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. |
640
+ | `showDescriptions` | `boolean` | no | `false` | Show each section's `description` under its title. |
592
641
 
593
642
  ### `Navbar`
594
643
 
@@ -649,13 +698,13 @@ Source: `src/components/SpotlightBackdrop/SpotlightBackdrop.tsx`
649
698
 
650
699
  > Dimmed full-viewport layer with an SVG-mask cut-out around a target rect (spotlight). Presentational — pass a `rect` from the `useTargetRect(target, enabled)` hook and compose with `Popover` for an anchored callout. Tour / coachmark orchestration (steps, next/prev, "seen") is app-owned; see the "Guided tour (recipe)" story.
651
700
 
652
- | Prop | Type | Required | Default | Description |
653
- | ----------- | ----------------------------------- | -------- | ------- | -------------------------------------------------------------------------------- |
654
- | `rect` | `TargetRect \| null` | yes | — | Target box to cut out of the dim layer, or `null` for a full dim (no highlight). |
655
- | `className` | `string` | no | — | |
656
- | `onClick` | `MouseEventHandler<HTMLDivElement>` | no | — | Fired when the dim layer is clicked (e.g. to dismiss). Receives the click event. |
657
- | `padding` | `number` | no | `8` | Padding around the target inside the cut-out, in px. |
658
- | `radius` | `number` | no | `8` | Corner radius of the cut-out, in px. |
701
+ | Prop | Type | Required | Default | Description |
702
+ | ----------- | ----------------------------------- | -------- | ------- | ----------------------------------------------------------------------------- |
703
+ | `rect` | `TargetRect \| null` | yes | — | Box to cut out, or `null` to dim everything. |
704
+ | `className` | `string` | no | — | |
705
+ | `onClick` | `MouseEventHandler<HTMLDivElement>` | no | — | Fires for clicks on the dim only — a click in the cut-out reaches the target. |
706
+ | `padding` | `number` | no | `8` | In px. |
707
+ | `radius` | `number` | no | `8` | In px. |
659
708
 
660
709
  ## Data display — layout
661
710