@keboola/design 9.1.0 → 11.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.
- package/AGENTS.md +119 -40
- package/COMPONENT-API.md +31 -9
- package/README.md +3 -3
- package/dist/MermaidDiagram-ZU5KAVRT.js +18 -0
- package/dist/MermaidDiagram-ZU5KAVRT.js.map +1 -0
- package/dist/charts.d.ts +37 -2
- package/dist/charts.js +11 -9
- package/dist/charts.js.map +1 -1
- package/dist/chunk-2YYJDKSP.js +51 -0
- package/dist/chunk-2YYJDKSP.js.map +1 -0
- package/dist/chunk-3P5UUCFI.js +385 -0
- package/dist/chunk-3P5UUCFI.js.map +1 -0
- package/dist/chunk-3QDFDDWZ.js +99 -0
- package/dist/chunk-3QDFDDWZ.js.map +1 -0
- package/dist/chunk-3W27OLK5.js +15 -0
- package/dist/chunk-3W27OLK5.js.map +1 -0
- package/dist/chunk-4FIZZONW.js +40 -0
- package/dist/chunk-4FIZZONW.js.map +1 -0
- package/dist/chunk-4GIAXOJG.js +133 -0
- package/dist/chunk-4GIAXOJG.js.map +1 -0
- package/dist/chunk-52NDNMK7.js +99 -0
- package/dist/chunk-52NDNMK7.js.map +1 -0
- package/dist/chunk-576G5OES.js +201 -0
- package/dist/chunk-576G5OES.js.map +1 -0
- package/dist/chunk-5AIE6SET.js +659 -0
- package/dist/chunk-5AIE6SET.js.map +1 -0
- package/dist/chunk-5FTNAZRW.js +327 -0
- package/dist/chunk-5FTNAZRW.js.map +1 -0
- package/dist/chunk-5IG2S7ZY.js +70 -0
- package/dist/chunk-5IG2S7ZY.js.map +1 -0
- package/dist/chunk-5QCXHNCW.js +404 -0
- package/dist/chunk-5QCXHNCW.js.map +1 -0
- package/dist/chunk-6DUMGC7Y.js +105 -0
- package/dist/chunk-6DUMGC7Y.js.map +1 -0
- package/dist/chunk-6J25CVST.js +174 -0
- package/dist/chunk-6J25CVST.js.map +1 -0
- package/dist/chunk-6NN35XOP.js +120 -0
- package/dist/chunk-6NN35XOP.js.map +1 -0
- package/dist/chunk-6NZBVA4T.js +24 -0
- package/dist/chunk-6NZBVA4T.js.map +1 -0
- package/dist/chunk-6W5BHRCL.js +295 -0
- package/dist/chunk-6W5BHRCL.js.map +1 -0
- package/dist/chunk-72BKRCEG.js +409 -0
- package/dist/chunk-72BKRCEG.js.map +1 -0
- package/dist/chunk-7GTI3PPI.js +95 -0
- package/dist/chunk-7GTI3PPI.js.map +1 -0
- package/dist/chunk-7P6PLZ4B.js +74 -0
- package/dist/chunk-7P6PLZ4B.js.map +1 -0
- package/dist/chunk-7WZWY5IA.js +46 -0
- package/dist/chunk-7WZWY5IA.js.map +1 -0
- package/dist/chunk-AIYO2632.js +489 -0
- package/dist/chunk-AIYO2632.js.map +1 -0
- package/dist/chunk-ANFZWPNE.js +112 -0
- package/dist/chunk-ANFZWPNE.js.map +1 -0
- package/dist/chunk-ANZTVAJU.js +73 -0
- package/dist/chunk-ANZTVAJU.js.map +1 -0
- package/dist/chunk-BD5BTJKX.js +166 -0
- package/dist/chunk-BD5BTJKX.js.map +1 -0
- package/dist/chunk-BHGIDSRJ.js +140 -0
- package/dist/chunk-BHGIDSRJ.js.map +1 -0
- package/dist/chunk-BSQWZITZ.js +507 -0
- package/dist/chunk-BSQWZITZ.js.map +1 -0
- package/dist/chunk-D3LAIK62.js +23 -0
- package/dist/chunk-D3LAIK62.js.map +1 -0
- package/dist/chunk-DODCR43C.js +155 -0
- package/dist/chunk-DODCR43C.js.map +1 -0
- package/dist/chunk-EEK5NGZF.js +40 -0
- package/dist/chunk-EEK5NGZF.js.map +1 -0
- package/dist/chunk-ENRG7TXA.js +11 -0
- package/dist/chunk-ENRG7TXA.js.map +1 -0
- package/dist/chunk-EQRMGIGY.js +239 -0
- package/dist/chunk-EQRMGIGY.js.map +1 -0
- package/dist/chunk-ERAHK5YQ.js +495 -0
- package/dist/chunk-ERAHK5YQ.js.map +1 -0
- package/dist/chunk-F3FOFY2P.js +124 -0
- package/dist/chunk-F3FOFY2P.js.map +1 -0
- package/dist/chunk-F6BTWFOC.js +507 -0
- package/dist/chunk-F6BTWFOC.js.map +1 -0
- package/dist/chunk-F6J6NNAL.js +34 -0
- package/dist/chunk-F6J6NNAL.js.map +1 -0
- package/dist/chunk-FCHJ7D5O.js +59 -0
- package/dist/chunk-FCHJ7D5O.js.map +1 -0
- package/dist/chunk-FFJTEQCC.js +80 -0
- package/dist/chunk-FFJTEQCC.js.map +1 -0
- package/dist/chunk-FUFMVW7O.js +64 -0
- package/dist/chunk-FUFMVW7O.js.map +1 -0
- package/dist/chunk-FVPGQ6UE.js +25 -0
- package/dist/chunk-FVPGQ6UE.js.map +1 -0
- package/dist/chunk-G3PMV62Z.js +33 -0
- package/dist/chunk-G3PMV62Z.js.map +1 -0
- package/dist/chunk-GACFOW3E.js +51 -0
- package/dist/chunk-GACFOW3E.js.map +1 -0
- package/dist/chunk-GDT6HQMK.js +42 -0
- package/dist/chunk-GDT6HQMK.js.map +1 -0
- package/dist/chunk-HLGU22C6.js +2589 -0
- package/dist/chunk-HLGU22C6.js.map +1 -0
- package/dist/chunk-HPMYYGP7.js +134 -0
- package/dist/chunk-HPMYYGP7.js.map +1 -0
- package/dist/chunk-I2UCOD45.js +197 -0
- package/dist/chunk-I2UCOD45.js.map +1 -0
- package/dist/chunk-IEGDZUVM.js +75 -0
- package/dist/chunk-IEGDZUVM.js.map +1 -0
- package/dist/chunk-IIS7INHF.js +47 -0
- package/dist/chunk-IIS7INHF.js.map +1 -0
- package/dist/chunk-ITELSEFU.js +256 -0
- package/dist/chunk-ITELSEFU.js.map +1 -0
- package/dist/chunk-IXAYNBOY.js +407 -0
- package/dist/chunk-IXAYNBOY.js.map +1 -0
- package/dist/chunk-JUW2ETEI.js +191 -0
- package/dist/chunk-JUW2ETEI.js.map +1 -0
- package/dist/chunk-K65C7CVE.js +127 -0
- package/dist/chunk-K65C7CVE.js.map +1 -0
- package/dist/chunk-KDI64MCY.js +189 -0
- package/dist/chunk-KDI64MCY.js.map +1 -0
- package/dist/chunk-KN4ASMH5.js +160 -0
- package/dist/chunk-KN4ASMH5.js.map +1 -0
- package/dist/chunk-KQW7QNTU.js +1549 -0
- package/dist/chunk-KQW7QNTU.js.map +1 -0
- package/dist/chunk-KR7NXXHC.js +66 -0
- package/dist/chunk-KR7NXXHC.js.map +1 -0
- package/dist/chunk-KRZKIVMA.js +142 -0
- package/dist/chunk-KRZKIVMA.js.map +1 -0
- package/dist/chunk-KTTLLKGQ.js +185 -0
- package/dist/chunk-KTTLLKGQ.js.map +1 -0
- package/dist/chunk-KWKSHPDP.js +234 -0
- package/dist/chunk-KWKSHPDP.js.map +1 -0
- package/dist/chunk-KZVC7OYG.js +57 -0
- package/dist/chunk-KZVC7OYG.js.map +1 -0
- package/dist/chunk-L5DHUN2V.js +204 -0
- package/dist/chunk-L5DHUN2V.js.map +1 -0
- package/dist/chunk-LCTGEH57.js +1376 -0
- package/dist/chunk-LCTGEH57.js.map +1 -0
- package/dist/chunk-LXLIQ2D6.js +12 -0
- package/dist/chunk-LXLIQ2D6.js.map +1 -0
- package/dist/chunk-M4CTURKX.js +84 -0
- package/dist/chunk-M4CTURKX.js.map +1 -0
- package/dist/chunk-M6LTUPVP.js +301 -0
- package/dist/chunk-M6LTUPVP.js.map +1 -0
- package/dist/chunk-MA6RRHDT.js +291 -0
- package/dist/chunk-MA6RRHDT.js.map +1 -0
- package/dist/chunk-MODE4QIA.js +6 -0
- package/dist/chunk-MODE4QIA.js.map +1 -0
- package/dist/chunk-MVILMVGG.js +118 -0
- package/dist/chunk-MVILMVGG.js.map +1 -0
- package/dist/chunk-MWS4VCLV.js +17 -0
- package/dist/chunk-MWS4VCLV.js.map +1 -0
- package/dist/chunk-NEUX74SO.js +315 -0
- package/dist/chunk-NEUX74SO.js.map +1 -0
- package/dist/chunk-NFHKYBRD.js +156 -0
- package/dist/chunk-NFHKYBRD.js.map +1 -0
- package/dist/chunk-NHJNNXD3.js +89 -0
- package/dist/chunk-NHJNNXD3.js.map +1 -0
- package/dist/chunk-O2BF3HZL.js +33 -0
- package/dist/chunk-O2BF3HZL.js.map +1 -0
- package/dist/chunk-OANXCZYD.js +212 -0
- package/dist/chunk-OANXCZYD.js.map +1 -0
- package/dist/chunk-ODJF7YIP.js +230 -0
- package/dist/chunk-ODJF7YIP.js.map +1 -0
- package/dist/chunk-ON4BJTHI.js +101 -0
- package/dist/chunk-ON4BJTHI.js.map +1 -0
- package/dist/chunk-OTL5WXIJ.js +16 -0
- package/dist/chunk-OTL5WXIJ.js.map +1 -0
- package/dist/chunk-PACNBKJV.js +47 -0
- package/dist/chunk-PACNBKJV.js.map +1 -0
- package/dist/chunk-PROCA7K7.js +23 -0
- package/dist/chunk-PROCA7K7.js.map +1 -0
- package/dist/chunk-QGMIPA67.js +85 -0
- package/dist/chunk-QGMIPA67.js.map +1 -0
- package/dist/chunk-QQA37LFB.js +190 -0
- package/dist/chunk-QQA37LFB.js.map +1 -0
- package/dist/chunk-QZAWRSEB.js +61 -0
- package/dist/chunk-QZAWRSEB.js.map +1 -0
- package/dist/chunk-R74KGWNS.js +699 -0
- package/dist/chunk-R74KGWNS.js.map +1 -0
- package/dist/chunk-RFDLHMKL.js +110 -0
- package/dist/chunk-RFDLHMKL.js.map +1 -0
- package/dist/chunk-RL64HN7S.js +40 -0
- package/dist/chunk-RL64HN7S.js.map +1 -0
- package/dist/chunk-RMRQKPL7.js +115 -0
- package/dist/chunk-RMRQKPL7.js.map +1 -0
- package/dist/chunk-RQVK4IYC.js +606 -0
- package/dist/chunk-RQVK4IYC.js.map +1 -0
- package/dist/chunk-RTW56PWZ.js +59 -0
- package/dist/chunk-RTW56PWZ.js.map +1 -0
- package/dist/chunk-RUTPQNLR.js +266 -0
- package/dist/chunk-RUTPQNLR.js.map +1 -0
- package/dist/chunk-S6TAF63G.js +25 -0
- package/dist/chunk-S6TAF63G.js.map +1 -0
- package/dist/chunk-SBGAUGXY.js +224 -0
- package/dist/chunk-SBGAUGXY.js.map +1 -0
- package/dist/chunk-SC275NHZ.js +407 -0
- package/dist/chunk-SC275NHZ.js.map +1 -0
- package/dist/chunk-SCQPU4UE.js +97 -0
- package/dist/chunk-SCQPU4UE.js.map +1 -0
- package/dist/chunk-SFFF2WQP.js +8 -0
- package/dist/chunk-SFFF2WQP.js.map +1 -0
- package/dist/chunk-SJYMHZKA.js +36 -0
- package/dist/chunk-SJYMHZKA.js.map +1 -0
- package/dist/chunk-SLCCUJVN.js +125 -0
- package/dist/chunk-SLCCUJVN.js.map +1 -0
- package/dist/chunk-SVBSNSD4.js +259 -0
- package/dist/chunk-SVBSNSD4.js.map +1 -0
- package/dist/chunk-SVPLTL35.js +62 -0
- package/dist/chunk-SVPLTL35.js.map +1 -0
- package/dist/chunk-SWQFYNYG.js +338 -0
- package/dist/chunk-SWQFYNYG.js.map +1 -0
- package/dist/chunk-THHB4EWS.js +72 -0
- package/dist/chunk-THHB4EWS.js.map +1 -0
- package/dist/chunk-TUCDD33E.js +246 -0
- package/dist/chunk-TUCDD33E.js.map +1 -0
- package/dist/chunk-TV4WAP2R.js +14 -0
- package/dist/chunk-TV4WAP2R.js.map +1 -0
- package/dist/chunk-U3A6YBTZ.js +134 -0
- package/dist/chunk-U3A6YBTZ.js.map +1 -0
- package/dist/chunk-UGT6DKWM.js +95 -0
- package/dist/chunk-UGT6DKWM.js.map +1 -0
- package/dist/chunk-VSERHUWD.js +212 -0
- package/dist/chunk-VSERHUWD.js.map +1 -0
- package/dist/chunk-VYG7BDXC.js +49 -0
- package/dist/chunk-VYG7BDXC.js.map +1 -0
- package/dist/chunk-WETKNYZX.js +52 -0
- package/dist/chunk-WETKNYZX.js.map +1 -0
- package/dist/chunk-WGG4AML3.js +216 -0
- package/dist/chunk-WGG4AML3.js.map +1 -0
- package/dist/chunk-WKAUEL6I.js +30 -0
- package/dist/chunk-WKAUEL6I.js.map +1 -0
- package/dist/chunk-WPOLA5CG.js +81 -0
- package/dist/chunk-WPOLA5CG.js.map +1 -0
- package/dist/chunk-WPVETCGJ.js +254 -0
- package/dist/chunk-WPVETCGJ.js.map +1 -0
- package/dist/chunk-WTSM3A7E.js +13 -0
- package/dist/chunk-WTSM3A7E.js.map +1 -0
- package/dist/chunk-WU3F2K3T.js +148 -0
- package/dist/chunk-WU3F2K3T.js.map +1 -0
- package/dist/chunk-WZZK2DTZ.js +39 -0
- package/dist/chunk-WZZK2DTZ.js.map +1 -0
- package/dist/chunk-X4IHLKRD.js +42 -0
- package/dist/chunk-X4IHLKRD.js.map +1 -0
- package/dist/chunk-XAHEXZJC.js +80 -0
- package/dist/chunk-XAHEXZJC.js.map +1 -0
- package/dist/chunk-XCYGJDUX.js +31 -0
- package/dist/chunk-XCYGJDUX.js.map +1 -0
- package/dist/chunk-Y4W3JORC.js +104 -0
- package/dist/chunk-Y4W3JORC.js.map +1 -0
- package/dist/chunk-YFZJ3ZLG.js +1297 -0
- package/dist/chunk-YFZJ3ZLG.js.map +1 -0
- package/dist/chunk-YI3WLXEN.js +4387 -0
- package/dist/chunk-YI3WLXEN.js.map +1 -0
- package/dist/chunk-ZBKFSPD3.js +29 -0
- package/dist/chunk-ZBKFSPD3.js.map +1 -0
- package/dist/chunk-ZOERRQ6A.js +79 -0
- package/dist/chunk-ZOERRQ6A.js.map +1 -0
- package/dist/chunk-ZSTGUKHU.js +10 -0
- package/dist/chunk-ZSTGUKHU.js.map +1 -0
- package/dist/chunk-ZUEHDL27.js +65 -0
- package/dist/chunk-ZUEHDL27.js.map +1 -0
- package/dist/editors.d.ts +27 -3
- package/dist/editors.js +93 -2081
- package/dist/editors.js.map +1 -1
- package/dist/icons.d.ts +29 -8
- package/dist/icons.js +7 -361
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +715 -441
- package/dist/index.js +121 -24643
- package/dist/index.js.map +1 -1
- package/dist/internal/blocks/AIKit.js +30 -0
- package/dist/internal/blocks/AIKit.js.map +1 -0
- package/dist/internal/blocks/AppShell.js +11 -0
- package/dist/internal/blocks/AppShell.js.map +1 -0
- package/dist/internal/blocks/AutoSaveTextarea.js +14 -0
- package/dist/internal/blocks/AutoSaveTextarea.js.map +1 -0
- package/dist/internal/blocks/BrandEditor.js +23 -0
- package/dist/internal/blocks/BrandEditor.js.map +1 -0
- package/dist/internal/blocks/ChartPanel.js +10 -0
- package/dist/internal/blocks/ChartPanel.js.map +1 -0
- package/dist/internal/blocks/ClipboardButton.js +12 -0
- package/dist/internal/blocks/ClipboardButton.js.map +1 -0
- package/dist/internal/blocks/ColorInput.js +13 -0
- package/dist/internal/blocks/ColorInput.js.map +1 -0
- package/dist/internal/blocks/ColorModeSwitch.js +13 -0
- package/dist/internal/blocks/ColorModeSwitch.js.map +1 -0
- package/dist/internal/blocks/Command.js +15 -0
- package/dist/internal/blocks/Command.js.map +1 -0
- package/dist/internal/blocks/CopyField.js +11 -0
- package/dist/internal/blocks/CopyField.js.map +1 -0
- package/dist/internal/blocks/DashboardHero.js +9 -0
- package/dist/internal/blocks/DashboardHero.js.map +1 -0
- package/dist/internal/blocks/DateInput.js +16 -0
- package/dist/internal/blocks/DateInput.js.map +1 -0
- package/dist/internal/blocks/DateRangeInput.js +16 -0
- package/dist/internal/blocks/DateRangeInput.js.map +1 -0
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +10 -0
- package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -0
- package/dist/internal/blocks/EmptyState.js +4 -0
- package/dist/internal/blocks/EmptyState.js.map +1 -0
- package/dist/internal/blocks/ErrorState.js +5 -0
- package/dist/internal/blocks/ErrorState.js.map +1 -0
- package/dist/internal/blocks/ExportMenu.js +13 -0
- package/dist/internal/blocks/ExportMenu.js.map +1 -0
- package/dist/internal/blocks/Form.js +29 -0
- package/dist/internal/blocks/Form.js.map +1 -0
- package/dist/internal/blocks/FormGroup.js +18 -0
- package/dist/internal/blocks/FormGroup.js.map +1 -0
- package/dist/internal/blocks/GoogleButton.js +10 -0
- package/dist/internal/blocks/GoogleButton.js.map +1 -0
- package/dist/internal/blocks/MicrosoftButton.js +10 -0
- package/dist/internal/blocks/MicrosoftButton.js.map +1 -0
- package/dist/internal/blocks/MultiActionButtonGroup.js +12 -0
- package/dist/internal/blocks/MultiActionButtonGroup.js.map +1 -0
- package/dist/internal/blocks/MultiCombobox.js +14 -0
- package/dist/internal/blocks/MultiCombobox.js.map +1 -0
- package/dist/internal/blocks/NumberInput.js +12 -0
- package/dist/internal/blocks/NumberInput.js.map +1 -0
- package/dist/internal/blocks/OtpInput.js +10 -0
- package/dist/internal/blocks/OtpInput.js.map +1 -0
- package/dist/internal/blocks/PageHeader.js +9 -0
- package/dist/internal/blocks/PageHeader.js.map +1 -0
- package/dist/internal/blocks/PageLayout.js +9 -0
- package/dist/internal/blocks/PageLayout.js.map +1 -0
- package/dist/internal/blocks/PageToolbar.js +13 -0
- package/dist/internal/blocks/PageToolbar.js.map +1 -0
- package/dist/internal/blocks/PasswordInput.js +13 -0
- package/dist/internal/blocks/PasswordInput.js.map +1 -0
- package/dist/internal/blocks/SearchInput.js +12 -0
- package/dist/internal/blocks/SearchInput.js.map +1 -0
- package/dist/internal/blocks/SearchInputWithNavigation.js +16 -0
- package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -0
- package/dist/internal/blocks/SectionNav.js +15 -0
- package/dist/internal/blocks/SectionNav.js.map +1 -0
- package/dist/internal/blocks/SplitButton.js +14 -0
- package/dist/internal/blocks/SplitButton.js.map +1 -0
- package/dist/internal/blocks/StatCard.js +10 -0
- package/dist/internal/blocks/StatCard.js.map +1 -0
- package/dist/internal/blocks/TextInput.js +13 -0
- package/dist/internal/blocks/TextInput.js.map +1 -0
- package/dist/internal/blocks/Textarea.js +13 -0
- package/dist/internal/blocks/Textarea.js.map +1 -0
- package/dist/internal/blocks/TimeInput.js +17 -0
- package/dist/internal/blocks/TimeInput.js.map +1 -0
- package/dist/internal/components/Alert.js +11 -0
- package/dist/internal/components/Alert.js.map +1 -0
- package/dist/internal/components/AlertModal.js +11 -0
- package/dist/internal/components/AlertModal.js.map +1 -0
- package/dist/internal/components/Avatar.js +9 -0
- package/dist/internal/components/Avatar.js.map +1 -0
- package/dist/internal/components/Badge.js +9 -0
- package/dist/internal/components/Badge.js.map +1 -0
- package/dist/internal/components/BrandLogo.js +11 -0
- package/dist/internal/components/BrandLogo.js.map +1 -0
- package/dist/internal/components/Breadcrumb.js +14 -0
- package/dist/internal/components/Breadcrumb.js.map +1 -0
- package/dist/internal/components/Button.js +10 -0
- package/dist/internal/components/Button.js.map +1 -0
- package/dist/internal/components/ButtonGroup.js +9 -0
- package/dist/internal/components/ButtonGroup.js.map +1 -0
- package/dist/internal/components/Calendar.js +9 -0
- package/dist/internal/components/Calendar.js.map +1 -0
- package/dist/internal/components/Card.js +9 -0
- package/dist/internal/components/Card.js.map +1 -0
- package/dist/internal/components/Checkbox.js +11 -0
- package/dist/internal/components/Checkbox.js.map +1 -0
- package/dist/internal/components/Clipboard.js +9 -0
- package/dist/internal/components/Clipboard.js.map +1 -0
- package/dist/internal/components/Collapsible.js +9 -0
- package/dist/internal/components/Collapsible.js.map +1 -0
- package/dist/internal/components/CollapsiblePanel.js +11 -0
- package/dist/internal/components/CollapsiblePanel.js.map +1 -0
- package/dist/internal/components/Combobox.js +13 -0
- package/dist/internal/components/Combobox.js.map +1 -0
- package/dist/internal/components/DatePicker.js +11 -0
- package/dist/internal/components/DatePicker.js.map +1 -0
- package/dist/internal/components/DateRangePicker.js +17 -0
- package/dist/internal/components/DateRangePicker.js.map +1 -0
- package/dist/internal/components/DiffView.js +9 -0
- package/dist/internal/components/DiffView.js.map +1 -0
- package/dist/internal/components/DotsLoader.js +5 -0
- package/dist/internal/components/DotsLoader.js.map +1 -0
- package/dist/internal/components/DropdownMenu.js +11 -0
- package/dist/internal/components/DropdownMenu.js.map +1 -0
- package/dist/internal/components/EmptySearchContent.js +4 -0
- package/dist/internal/components/EmptySearchContent.js.map +1 -0
- package/dist/internal/components/FileUpload.js +11 -0
- package/dist/internal/components/FileUpload.js.map +1 -0
- package/dist/internal/components/FullScreenModal.js +12 -0
- package/dist/internal/components/FullScreenModal.js.map +1 -0
- package/dist/internal/components/HelpBlock.js +4 -0
- package/dist/internal/components/HelpBlock.js.map +1 -0
- package/dist/internal/components/HoverCard.js +9 -0
- package/dist/internal/components/HoverCard.js.map +1 -0
- package/dist/internal/components/InputGroup.js +11 -0
- package/dist/internal/components/InputGroup.js.map +1 -0
- package/dist/internal/components/Kbd.js +9 -0
- package/dist/internal/components/Kbd.js.map +1 -0
- package/dist/internal/components/Label.js +9 -0
- package/dist/internal/components/Label.js.map +1 -0
- package/dist/internal/components/Link.js +9 -0
- package/dist/internal/components/Link.js.map +1 -0
- package/dist/internal/components/MarkedText.js +5 -0
- package/dist/internal/components/MarkedText.js.map +1 -0
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +10 -0
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -0
- package/dist/internal/components/MergeEditor/PaneHeader.js +4 -0
- package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -0
- package/dist/internal/components/MergeEditor/constants.js +4 -0
- package/dist/internal/components/MergeEditor/constants.js.map +1 -0
- package/dist/internal/components/MergeEditor/useMergeDiff.js +5 -0
- package/dist/internal/components/MergeEditor/useMergeDiff.js.map +1 -0
- package/dist/internal/components/Modal.js +13 -0
- package/dist/internal/components/Modal.js.map +1 -0
- package/dist/internal/components/Navbar.js +14 -0
- package/dist/internal/components/Navbar.js.map +1 -0
- package/dist/internal/components/Pagination.js +11 -0
- package/dist/internal/components/Pagination.js.map +1 -0
- package/dist/internal/components/PanelWithDetails.js +11 -0
- package/dist/internal/components/PanelWithDetails.js.map +1 -0
- package/dist/internal/components/Popconfirm.js +12 -0
- package/dist/internal/components/Popconfirm.js.map +1 -0
- package/dist/internal/components/Popover.js +9 -0
- package/dist/internal/components/Popover.js.map +1 -0
- package/dist/internal/components/Progress.js +9 -0
- package/dist/internal/components/Progress.js.map +1 -0
- package/dist/internal/components/RadioGroup.js +12 -0
- package/dist/internal/components/RadioGroup.js.map +1 -0
- package/dist/internal/components/Resizable.js +9 -0
- package/dist/internal/components/Resizable.js.map +1 -0
- package/dist/internal/components/ScrollArea.js +9 -0
- package/dist/internal/components/ScrollArea.js.map +1 -0
- package/dist/internal/components/Search.js +10 -0
- package/dist/internal/components/Search.js.map +1 -0
- package/dist/internal/components/Select.js +12 -0
- package/dist/internal/components/Select.js.map +1 -0
- package/dist/internal/components/Separator.js +9 -0
- package/dist/internal/components/Separator.js.map +1 -0
- package/dist/internal/components/Sheet.js +12 -0
- package/dist/internal/components/Sheet.js.map +1 -0
- package/dist/internal/components/Sidebar.js +20 -0
- package/dist/internal/components/Sidebar.js.map +1 -0
- package/dist/internal/components/Skeleton/Skeleton.js +9 -0
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/internal/components/Skeleton/SkeletonList.js +10 -0
- package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -0
- package/dist/internal/components/Slider.js +11 -0
- package/dist/internal/components/Slider.js.map +1 -0
- package/dist/internal/components/SpotlightBackdrop.js +9 -0
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -0
- package/dist/internal/components/Stepper.js +10 -0
- package/dist/internal/components/Stepper.js.map +1 -0
- package/dist/internal/components/Switch.js +10 -0
- package/dist/internal/components/Switch.js.map +1 -0
- package/dist/internal/components/Table.js +10 -0
- package/dist/internal/components/Table.js.map +1 -0
- package/dist/internal/components/Tabs.js +12 -0
- package/dist/internal/components/Tabs.js.map +1 -0
- package/dist/internal/components/ThemeProvider.js +10 -0
- package/dist/internal/components/ThemeProvider.js.map +1 -0
- package/dist/internal/components/TimePicker.js +12 -0
- package/dist/internal/components/TimePicker.js.map +1 -0
- package/dist/internal/components/Timeline.js +10 -0
- package/dist/internal/components/Timeline.js.map +1 -0
- package/dist/internal/components/Toast.js +11 -0
- package/dist/internal/components/Toast.js.map +1 -0
- package/dist/internal/components/Toggle.js +9 -0
- package/dist/internal/components/Toggle.js.map +1 -0
- package/dist/internal/components/ToggleGroup.js +9 -0
- package/dist/internal/components/ToggleGroup.js.map +1 -0
- package/dist/internal/components/Tooltip.js +8 -0
- package/dist/internal/components/Tooltip.js.map +1 -0
- package/dist/internal/components/Truncated.js +9 -0
- package/dist/internal/components/Truncated.js.map +1 -0
- package/dist/internal/components/Workbench.js +11 -0
- package/dist/internal/components/Workbench.js.map +1 -0
- package/dist/internal/components/ZoomableSvg.js +13 -0
- package/dist/internal/components/ZoomableSvg.js.map +1 -0
- package/dist/internal/hooks/useAutosizeInput.js +4 -0
- package/dist/internal/hooks/useAutosizeInput.js.map +1 -0
- package/dist/internal/hooks/useScrollbarPosition.js +5 -0
- package/dist/internal/hooks/useScrollbarPosition.js.map +1 -0
- package/dist/internal/hooks/useStableCallback.js +4 -0
- package/dist/internal/hooks/useStableCallback.js.map +1 -0
- package/dist/internal/utils/mergeRefs.js +4 -0
- package/dist/internal/utils/mergeRefs.js.map +1 -0
- package/dist/internal/utils.js +8 -0
- package/dist/internal/utils.js.map +1 -0
- package/dist/markdown-editor.js +55 -3426
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.js +16 -1129
- package/dist/mermaid.js.map +1 -1
- package/dist/rjsf.js +252 -9380
- package/dist/rjsf.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/testing.js +10 -357
- package/dist/testing.js.map +1 -1
- package/package.json +31 -75
- package/src/styles.css +95 -10
- package/src/theme.css +65 -0
- package/dist/charts.cjs +0 -268
- package/dist/charts.cjs.map +0 -1
- package/dist/charts.d.cts +0 -181
- package/dist/constants-D3gaMY-W.d.cts +0 -39
- package/dist/editors.cjs +0 -2440
- package/dist/editors.cjs.map +0 -1
- package/dist/editors.d.cts +0 -165
- package/dist/icons.cjs +0 -23888
- package/dist/icons.cjs.map +0 -1
- package/dist/icons.d.cts +0 -20
- package/dist/index.cjs +0 -24894
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -10438
- package/dist/markdown-editor.cjs +0 -4636
- package/dist/markdown-editor.cjs.map +0 -1
- package/dist/markdown-editor.d.cts +0 -75
- package/dist/mermaid.cjs +0 -1138
- package/dist/mermaid.cjs.map +0 -1
- package/dist/mermaid.d.cts +0 -15
- package/dist/rjsf.cjs +0 -10893
- package/dist/rjsf.cjs.map +0 -1
- package/dist/rjsf.d.cts +0 -55
- package/dist/testing.cjs +0 -373
- package/dist/testing.cjs.map +0 -1
- package/dist/testing.d.cts +0 -25
package/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @keboola/design
|
|
2
2
|
|
|
3
|
-
Consumer usage contract for the Keboola design system — shadcn-aligned React primitives (Radix
|
|
3
|
+
Consumer usage contract for the Keboola design system — shadcn-aligned React primitives (Radix under most, Base UI for newer ones such as `Combobox`), Keboola-branded blocks, Lucide icons, and TanStack-Form bindings.
|
|
4
4
|
|
|
5
5
|
This file ships **inside the npm tarball** and is version-pinned to the package you installed — it is the source of truth for **which** component to use and how to wire theming. For the exact **prop signature** of the most-used components, see the generated [`COMPONENT-API.md`](./COMPONENT-API.md) (also shipped in the tarball).
|
|
6
6
|
|
|
@@ -8,6 +8,7 @@ Working **on** the package (commands, layer boundary, token surface, the FA→Lu
|
|
|
8
8
|
|
|
9
9
|
## Import surface
|
|
10
10
|
|
|
11
|
+
- **ESM only.** The package ships no CommonJS build — no `*.cjs` and no `require` condition in the `exports` map. Consume it from an ESM-capable bundler (Vite, webpack, Rollup, esbuild) or `import` it from Node. A `require()` resolves to the ESM entry, so it works only where the runtime can require ESM (Node ≥ 22.12) and throws `ERR_REQUIRE_ESM` on older ones.
|
|
11
12
|
- **Always** import from the package root: `import { Button } from '@keboola/design'`.
|
|
12
13
|
- App entry points **must** import styles. Two paths, pick by build setup:
|
|
13
14
|
- `import '@keboola/design/styles'` — Tailwind-extending consumers. Your PostCSS+Tailwind processes `@tailwind` directives plus design's `dist/` in your content scan. Avoids duplicate preflights/utilities. **Default for any Keboola app.**
|
|
@@ -43,7 +44,7 @@ The API is "shadcn-shaped" enough to invite copy-paste but different enough to b
|
|
|
43
44
|
| `Select` | composed children `<Select><SelectTrigger/><SelectContent><SelectItem/></SelectContent></Select>` | data-driven — `Select` takes **`items`**, and the form connector `SelectField` delegates to it, so both take the same `items`: flat `{ value, label, icon?, disabled? }` or groups of them (`{ label?, items }`) |
|
|
44
45
|
| `Sidebar.SearchInput` | `asChild`-wrappable trigger | concrete `<input>` (`ComponentProps<'input'>`), **no `asChild`** — put a custom search affordance in a plain element inside `Sidebar.Header` |
|
|
45
46
|
|
|
46
|
-
Other compound (not named-export) components in the barrel: `Modal.*`, `Sheet.*`, `Card.*`, `Sidebar.*`, `PageHeader.Index` / `.Detail`, `EmptyState.*`, `Pagination.*`, `Popover.*` — reach for the dotted sub-parts, not flat `XContent` / `XTrigger` named imports. (The root `SearchInput` block is distinct from `Sidebar.SearchInput` and is fully composable.)
|
|
47
|
+
Other compound (not named-export) components in the barrel: `Modal.*`, `Sheet.*`, `Card.*`, `Sidebar.*`, `PageHeader.Index` / `.Detail`, `EmptyState.*`, `Pagination.*`, `Popover.*`, `Workbench.*` — reach for the dotted sub-parts, not flat `XContent` / `XTrigger` named imports. (The root `SearchInput` block is distinct from `Sidebar.SearchInput` and is fully composable.)
|
|
47
48
|
|
|
48
49
|
## Decision tree
|
|
49
50
|
|
|
@@ -85,10 +86,13 @@ This file answers **which** component to use; [`COMPONENT-API.md`](./COMPONENT-A
|
|
|
85
86
|
| `useAppForm` | Full form layouts with validation (see Forms below) |
|
|
86
87
|
| `useAppForm` connectors | Picking between `TextField` / `NumberField` / `SelectField` / … |
|
|
87
88
|
| `OtpInput` | Fixed-length verification code (MFA, email confirm, sudo step-up) |
|
|
88
|
-
| `FileUpload` |
|
|
89
|
+
| `FileUpload` | Drag-and-drop file picker box; caller owns the file array |
|
|
90
|
+
| `useFileDropTarget` | Make an existing subtree a drop target, styled by you |
|
|
89
91
|
|
|
90
92
|
**Never** build custom label + input combinations — compose `Label` + `FormGroup.TextInput` + `FormGroup.Help` inside `FormGroup`.
|
|
91
93
|
|
|
94
|
+
`FileUpload` composes `FileUpload.DropZone` (the dashed box, owning the drag / error visuals) with `FileUpload.FileList` (selected files; `invalid` tints the rows). It deliberately ships **no** rejection copy — the wording is product copy, so read the current rejections with `useFileUploadRejections()` inside `FileUpload` and write the sentence yourself. Reach for `useFileDropTarget` only when there is no box to render: it returns `getRootProps()` / `isDragActive` for an affordance you style, and `noClick` / `noKeyboard` keep an already-interactive subtree (a composer, a form) from opening the file dialog on every click.
|
|
95
|
+
|
|
92
96
|
### Status surfaces
|
|
93
97
|
|
|
94
98
|
| Use | When |
|
|
@@ -143,23 +147,36 @@ Charts ship from the **`@keboola/design/charts`** subpath (recharts under the ho
|
|
|
143
147
|
|
|
144
148
|
`data: {…}[]` rows; `xKey` + `series: [{ dataKey, name?, color? }]` (cartesian) or `nameKey` + `dataKey` (pie). Each chart is self-contained (mounts its own responsive container) — give it a `height` (default 300). Pin a series to a palette slot with `color: 1..5`; otherwise it follows series order.
|
|
145
149
|
|
|
150
|
+
**Y-axis baseline — `yDomain`, on `LineChart` only.** Every chart starts the value axis at zero by default. `LineChart` takes `yDomain={[min, max]}` to move it: explicit numbers, `'auto'`, or padded data extremes — `['dataMin - 500', 'dataMax + 500']` (recharts pads the low end DOWN and the high end UP, so `'dataMax - 500'` is not a thing and won't type-check). It works with `showYAxis={false}` too.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
// Credits used vs budgeted — both ~8,000, so a 0–10,000 axis hides the crossover.
|
|
154
|
+
<LineChart data={data} xKey="month" series={series} yDomain={['dataMin - 500', 'dataMax + 500']} />
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Reach for it when **two or more series of similar magnitude sit far from zero** and their difference is the story — actual vs target, used vs quota. Don't reach for it for a **single series whose magnitude the reader is meant to judge**: zooming the axis turns ordinary noise into a dramatic trend. And it is deliberately absent from `BarChart` / `AreaChart` — a line encodes value by position, so the baseline is just a viewport, but a bar's length and an area's fill are measured _from_ the baseline, and truncating those makes the geometry misstate the ratios. If an area chart needs a non-zero baseline, it is a line chart. (`ChartContainer` + a raw recharts chart remains the escape hatch for anything the wrappers don't model.)
|
|
158
|
+
|
|
146
159
|
### Layout
|
|
147
160
|
|
|
148
161
|
**No** `Stack` / `Flex` / `Box` component exists, by design — shadcn doesn't ship them, and adding wrappers creates a third way to do layout. Use Tailwind utility classes directly.
|
|
149
162
|
|
|
150
163
|
| Use | When |
|
|
151
164
|
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
-
| Tailwind classes | All ad-hoc layout: `tw
|
|
165
|
+
| Tailwind classes | All ad-hoc layout: `tw:flex tw:flex-col tw:gap-4`, `tw:grid …`, `tw:p-6` |
|
|
153
166
|
| `AppShell` | App-root shell that follows the active brand (sidebar vs top-nav) |
|
|
154
167
|
| `PageLayout` | Top-level page shape: header, tabs, toolbar, content, footer |
|
|
155
168
|
| `PageToolbar` | Index-page toolbar: search + filters / sort / actions / view + chips row |
|
|
156
|
-
| `Card` | Semantic content surface with
|
|
169
|
+
| `Card` | Semantic content surface with `Card.Header` / `Card.Title` / `Card.Content` slots |
|
|
157
170
|
| `Sidebar` | App-shell left navigation rail (host inside `AppShell.Sidebar`) |
|
|
171
|
+
| `SectionNav` | In-page navigation for **one page's** grouped sections (host in `PageLayout.Content nav`) — tree, dropdown when narrow |
|
|
158
172
|
| `Navbar` | Top navigation bar (host inside `AppShell.Header`) — brand mark, primary nav, search / account. Pairs with the top-nav shell |
|
|
173
|
+
| `Workbench` | Bottom status rail plus a panel that expands over the page — VS Code's bottom dock, for tooling that outlives one page |
|
|
159
174
|
|
|
160
|
-
Vertical rhythm: prefer `tw
|
|
175
|
+
Vertical rhythm: prefer `tw:gap-*` on a flex column parent over `tw:mt-*` on children — avoids margin-collapse. Page-level max width: use `PageLayout`'s `maxWidth` prop (`narrow` / `default` / `wide` / `full`), not `tw:max-w-[…]` literals.
|
|
161
176
|
|
|
162
|
-
|
|
177
|
+
**`Card` padding: the root owns it, or the slots do — never both.** `Card padding` (default `small`) pads the root and gaps its slots, which is right for a plain content card. Set `padding="none"` when a slot must bleed to the card edge — a table, an `EmptyState`, or a header with a rule under it — and the root also drops its gap so the bands sit flush. In that mode the slots pad themselves: `Card.Header divider` becomes its own padded band with a full-bleed bottom rule, and `Card.Content padded` takes the standard body padding. `Card.Header` distributes its children by `layout`: **`row`** (default) pushes them apart, title left and actions right; **`inline`** keeps them together for a title with an icon or badge; **`stack`** puts a description under the title. Don't hand-roll these with `className` — `cva` here concatenates rather than tailwind-merges, so a `tw:justify-start` in `className` will not reliably beat the `row` default. Use the prop.
|
|
178
|
+
|
|
179
|
+
**Page gutter: `AppShell.Main` owns it, with an opinionated default.** `AppShell.Main` applies a default page gutter (`tw:p-6`) so content looks right out of the box. Because `cn` is tailwind-merge, override it from the call site when the app owns its own gutter — e.g. `className="tw:p-0"` (kbc-ui does this; it centralizes the gutter on its own shell wrapper). `PageLayout` still adds **no** gutter of its own, so header and content align inside whatever gutter `AppShell.Main` provides.
|
|
163
180
|
|
|
164
181
|
```tsx
|
|
165
182
|
// Default gutter — nothing to add:
|
|
@@ -168,11 +185,21 @@ Vertical rhythm: prefer `tw-gap-*` on a flex column parent over `tw-mt-*` on chi
|
|
|
168
185
|
</AppShell.Main>
|
|
169
186
|
|
|
170
187
|
// Own your gutter — opt out and add your own:
|
|
171
|
-
<AppShell.Main className="tw
|
|
172
|
-
<div className="tw
|
|
188
|
+
<AppShell.Main className="tw:p-0">
|
|
189
|
+
<div className="tw:px-8 tw:py-6">{/* custom gutter */}</div>
|
|
173
190
|
</AppShell.Main>
|
|
174
191
|
```
|
|
175
192
|
|
|
193
|
+
**Header width: `headerSpan` picks the row template — don't hand-roll `gridTemplateAreas`.** By default the sidebar geometry gives the header the middle column only (`"sidebar header aside"`), so both rails sit beside it and run the full height. Pass `headerSpan="full"` for a full-bleed header row above both rails (`"header header header" / "sidebar main aside"`), so the brand mark aligns to the viewport's left edge. Reach for it when the header carries app-wide identity — brand mark, project switcher, account menu — rather than page-level navigation. It is a no-op under the top-nav geometry, whose header already spans the width.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
<AppShell headerSpan="full">
|
|
197
|
+
<AppShell.Header flush>{/* Navbar: brand mark, project switcher, account */}</AppShell.Header>
|
|
198
|
+
<AppShell.Sidebar>{/* left rail, below the header */}</AppShell.Sidebar>
|
|
199
|
+
<AppShell.Main>{/* … */}</AppShell.Main>
|
|
200
|
+
</AppShell>
|
|
201
|
+
```
|
|
202
|
+
|
|
176
203
|
### Navigation / flow
|
|
177
204
|
|
|
178
205
|
| Use | When |
|
|
@@ -184,6 +211,8 @@ Vertical rhythm: prefer `tw-gap-*` on a flex column parent over `tw-mt-*` on chi
|
|
|
184
211
|
|
|
185
212
|
**Never** use `Stepper` for branching navigation (use `Tabs`) or an unordered status list (use `Timeline`).
|
|
186
213
|
|
|
214
|
+
**`SectionNav` is not `Sidebar`.** `Sidebar` is the app's left rail — global, one per shell, outside `PageLayout`, with `SidebarProvider` state and icon-collapse. `SectionNav` is scoped to a single page's sections, lives in `PageLayout.Content nav`, and holds nothing but an open/closed flag per group. Reach for `SectionNav` when a page has more sections than a tab row can hold, or sections that group; `Tabs` when they don't.
|
|
215
|
+
|
|
187
216
|
### Separators
|
|
188
217
|
|
|
189
218
|
| Use | When |
|
|
@@ -260,7 +289,7 @@ const form = useAppForm({
|
|
|
260
289
|
<AlertModal onConfirm={() => deleteBucket(bucketId)}>
|
|
261
290
|
<AlertModal.Trigger asChild>
|
|
262
291
|
<Button variant="danger">
|
|
263
|
-
<Trash2 className="tw
|
|
292
|
+
<Trash2 className="tw:size-4" /> Delete bucket
|
|
264
293
|
</Button>
|
|
265
294
|
</AlertModal.Trigger>
|
|
266
295
|
<AlertModal.Content variant="danger" title="Delete bucket?" confirmLabel="Delete bucket">
|
|
@@ -271,17 +300,19 @@ const form = useAppForm({
|
|
|
271
300
|
|
|
272
301
|
Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` to `AlertModal` (it honors `defaultOpen` too).
|
|
273
302
|
|
|
303
|
+
A host that tracks the request itself rather than returning a promise passes `isLoading` to `AlertModal` for the same locked, spinning state; `AlertModal.Content` takes `confirmDisabled` to block the confirm action alone while a precondition is unmet. The children stay the description — reach for `Modal` when the dialog needs a form, a table, or anything else that isn't phrasing content.
|
|
304
|
+
|
|
274
305
|
**Card with empty state** — branch on the collection length inside `Card.Content`:
|
|
275
306
|
|
|
276
307
|
```tsx
|
|
277
308
|
<Card bordered padding="none">
|
|
278
|
-
<Card.Header
|
|
309
|
+
<Card.Header divider>
|
|
279
310
|
<Card.Title>Tokens</Card.Title>
|
|
280
311
|
<Button size="small">
|
|
281
|
-
<Plus className="tw
|
|
312
|
+
<Plus className="tw:size-4" /> New token
|
|
282
313
|
</Button>
|
|
283
314
|
</Card.Header>
|
|
284
|
-
<Card.Content
|
|
315
|
+
<Card.Content>
|
|
285
316
|
{tokens.length === 0 ? (
|
|
286
317
|
<EmptyState variant="compact">
|
|
287
318
|
<EmptyState.Title>No tokens yet</EmptyState.Title>
|
|
@@ -299,13 +330,13 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
299
330
|
**Entity list** — `SearchInput` + `Table` + `Pagination` + `EmptyState`. Keep query/page in local state, filter then slice:
|
|
300
331
|
|
|
301
332
|
```tsx
|
|
302
|
-
<div className="tw
|
|
333
|
+
<div className="tw:flex tw:flex-col tw:gap-4">
|
|
303
334
|
<SearchInput
|
|
304
335
|
allowClear
|
|
305
336
|
placeholder="Search…"
|
|
306
337
|
value={query}
|
|
307
338
|
onValueChange={setQuery}
|
|
308
|
-
className="tw
|
|
339
|
+
className="tw:w-72"
|
|
309
340
|
/>
|
|
310
341
|
{filtered.length === 0 ? (
|
|
311
342
|
<EmptyState>
|
|
@@ -330,7 +361,7 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
330
361
|
```tsx
|
|
331
362
|
<Card bordered>
|
|
332
363
|
<Card.Header>
|
|
333
|
-
<Card.Title>{isLoading ? <Skeleton height="md" className="tw
|
|
364
|
+
<Card.Title>{isLoading ? <Skeleton height="md" className="tw:w-32" /> : 'Storage'}</Card.Title>
|
|
334
365
|
</Card.Header>
|
|
335
366
|
<Card.Content>{isLoading ? <SkeletonList groups={2} rowHeight="sm" /> : <Stats />}</Card.Content>
|
|
336
367
|
</Card>
|
|
@@ -356,8 +387,8 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
356
387
|
|
|
357
388
|
```tsx
|
|
358
389
|
<Tooltip tooltip={canSave ? null : reason} placement="top" triggerAsChild>
|
|
359
|
-
<span className={canSave ? undefined : 'tw
|
|
360
|
-
<Button disabled={!canSave} className={canSave ? undefined : 'tw
|
|
390
|
+
<span className={canSave ? undefined : 'tw:inline-block tw:cursor-not-allowed'}>
|
|
391
|
+
<Button disabled={!canSave} className={canSave ? undefined : 'tw:pointer-events-none'}>
|
|
361
392
|
Save
|
|
362
393
|
</Button>
|
|
363
394
|
</span>
|
|
@@ -367,16 +398,16 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
367
398
|
**Info tooltip** — an icon-only `Button variant="inline"` next to a `Label`, with the hint on a `Tooltip`:
|
|
368
399
|
|
|
369
400
|
```tsx
|
|
370
|
-
<div className="tw
|
|
401
|
+
<div className="tw:flex tw:items-center tw:gap-1">
|
|
371
402
|
<Label htmlFor={id}>{label}</Label>
|
|
372
403
|
<Tooltip tooltip={hint} placement="right" triggerAsChild>
|
|
373
404
|
<Button
|
|
374
405
|
variant="inline"
|
|
375
406
|
size="icon-3xs"
|
|
376
407
|
aria-label={`More info about ${label}`}
|
|
377
|
-
className="tw
|
|
408
|
+
className="tw:text-muted-foreground"
|
|
378
409
|
>
|
|
379
|
-
<Info className="tw
|
|
410
|
+
<Info className="tw:size-3" />
|
|
380
411
|
</Button>
|
|
381
412
|
</Tooltip>
|
|
382
413
|
</div>
|
|
@@ -400,6 +431,33 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
400
431
|
</PageLayout>
|
|
401
432
|
```
|
|
402
433
|
|
|
434
|
+
**Page with a section nav** — `PageLayout.Header sticky` + `PageLayout.Content nav={<SectionNav …/>}`. The block and the slot are shipped; the **group model**, **visibility / permission filtering** and **all routing** are the composition and stay in your app. Build the model once and feed both the nav and any flat tab row from it, so the two can never disagree about what exists. `renderItem` is the router seam — return your router's link and spread `itemProps`:
|
|
435
|
+
|
|
436
|
+
```tsx
|
|
437
|
+
<PageLayout>
|
|
438
|
+
<PageLayout.Header sticky>
|
|
439
|
+
<PageHeader.Index title="Settings" />
|
|
440
|
+
</PageLayout.Header>
|
|
441
|
+
<PageLayout.Content
|
|
442
|
+
nav={
|
|
443
|
+
<SectionNav
|
|
444
|
+
groups={groups} // already filtered for this user
|
|
445
|
+
activeId={pathname}
|
|
446
|
+
renderItem={({ targetId, children, itemProps }) => (
|
|
447
|
+
<Link to={targetId} {...itemProps}>
|
|
448
|
+
{children}
|
|
449
|
+
</Link>
|
|
450
|
+
)}
|
|
451
|
+
/>
|
|
452
|
+
}
|
|
453
|
+
>
|
|
454
|
+
{page}
|
|
455
|
+
</PageLayout.Content>
|
|
456
|
+
</PageLayout>
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
Both router wirings (TanStack Router, and a custom named router) are in [`RECIPES.md`](./RECIPES.md#section-nav).
|
|
460
|
+
|
|
403
461
|
**Creatable combobox** — `Combobox` with `allowCreate` accepts values not in `items`:
|
|
404
462
|
|
|
405
463
|
```tsx
|
|
@@ -413,13 +471,13 @@ Controlled (opened from elsewhere, no `Trigger`): pass `open` + `onOpenChange` t
|
|
|
413
471
|
/>
|
|
414
472
|
```
|
|
415
473
|
|
|
416
|
-
**Sheet** — use `Sheet.Header title="…" description="…"` for a styled title + close icon; do **not** hand-roll with the raw `Sheet.Title`, which renders an unstyled `<h2>`. `Sheet.Body` provides horizontal padding only (`tw
|
|
474
|
+
**Sheet** — use `Sheet.Header title="…" description="…"` for a styled title + close icon; do **not** hand-roll with the raw `Sheet.Title`, which renders an unstyled `<h2>`. `Sheet.Body` provides horizontal padding only (`tw:px-4`) — add your own vertical rhythm/gap:
|
|
417
475
|
|
|
418
476
|
```tsx
|
|
419
477
|
<Sheet open={open} onOpenChange={setOpen}>
|
|
420
478
|
<Sheet.Content>
|
|
421
479
|
<Sheet.Header title="Edit table" description="Adjust the table metadata." />
|
|
422
|
-
<Sheet.Body className="tw
|
|
480
|
+
<Sheet.Body className="tw:flex tw:flex-col tw:gap-4 tw:py-4">{/* fields */}</Sheet.Body>
|
|
423
481
|
</Sheet.Content>
|
|
424
482
|
</Sheet>
|
|
425
483
|
```
|
|
@@ -431,14 +489,15 @@ Canonical icon surface is `@keboola/design/icons` — a re-export of every [luci
|
|
|
431
489
|
```tsx
|
|
432
490
|
import { ChevronDown, Keboola, Loader2 } from '@keboola/design/icons';
|
|
433
491
|
|
|
434
|
-
<button>Toggle <ChevronDown className="tw
|
|
435
|
-
<Loader2 className="tw
|
|
436
|
-
<Keboola className="tw
|
|
492
|
+
<button>Toggle <ChevronDown className="tw:size-4" /></button>
|
|
493
|
+
<Loader2 className="tw:size-4 tw:animate-spin" />
|
|
494
|
+
<Keboola className="tw:size-6" />
|
|
437
495
|
```
|
|
438
496
|
|
|
439
497
|
- **One import surface**: Lucide icons and Keboola-custom icons (e.g. `Keboola`) both export from `@keboola/design/icons` and share the `LucideIcon` type, so they're interchangeable in any API typed `icon: LucideIcon` (Button, etc.).
|
|
440
|
-
- **
|
|
441
|
-
- **
|
|
498
|
+
- **Vendor marks** also ship from `@keboola/design/icons` — `Aws`, `Azure`, `ChatGpt`, `Claude`, `Cursor`, `Devin`, `Gcp`, `Google`, `Keboola`, `Make`, `Microsoft` — in their own brand colours by default; pass **`mono`** to render one in `currentColor` instead. The `Eu` / `Us` flags are colour-only.
|
|
499
|
+
- **Sizing**: prefixed Tailwind `tw:size-*` utility — `tw:size-4` = 16px (default for inline icons), `tw:size-5` = 20px, `tw:size-6` = 24px.
|
|
500
|
+
- **Spinner animation**: explicit via `tw:animate-spin`.
|
|
442
501
|
|
|
443
502
|
**FontAwesome is fully removed.** Every `icon` prop takes a Lucide `ReactNode`. (Maintainers: the canonical FA→Lucide mapping table lives in `MAINTAINING.md`.)
|
|
444
503
|
|
|
@@ -446,9 +505,11 @@ import { ChevronDown, Keboola, Loader2 } from '@keboola/design/icons';
|
|
|
446
505
|
|
|
447
506
|
Layer-0 colour usage splits into three buckets.
|
|
448
507
|
|
|
449
|
-
**Chrome — follows the brand.** Surface, structure, navigation: Card body, Modal frame, Input border, Button outline, focus rings, Sidebar, generic text. Re-skins when a customer brand is applied. **Rule:** use semantic tokens (`tw
|
|
508
|
+
**Chrome — follows the brand.** Surface, structure, navigation: Card body, Modal frame, Input border, Button outline, focus rings, Sidebar, generic text. Re-skins when a customer brand is applied. **Rule:** use semantic tokens (`tw:bg-background`, `tw:text-foreground`, `tw:border-border`, `tw:bg-muted`, `tw:text-muted-foreground`, `tw:bg-accent`, `tw:bg-destructive`, …). Customers override these via `@keboola/brand-registry`.
|
|
509
|
+
|
|
510
|
+
A border **width** utility carries no colour of its own — a lone `tw:border` / `tw:border-t` / `tw:border-2` paints the element's _text_ colour, a near-black frame where a light-grey rule belongs. Pair every width with a colour: `tw:border tw:border-border` for chrome, `tw:border-input` on form controls. `pnpm test:stories` fails on any story that ships a width without one.
|
|
450
511
|
|
|
451
|
-
**Status — themeable under argo, with AA-legible defaults.** The four semantic states — `success`, `warning`, `info`, and `destructive` (used for "error") — are brand-overridable tokens, not fixed scales. Alert `variant`, `HelpBlock` / field-error state, `ErrorState`, and `Stepper` status read them, so a brand recolours every status surface at once. **Rule:** consume the token as **tint + text/icon** — `tw
|
|
512
|
+
**Status — themeable under argo, with AA-legible defaults.** The four semantic states — `success`, `warning`, `info`, and `destructive` (used for "error") — are brand-overridable tokens, not fixed scales. Alert `variant`, `HelpBlock` / field-error state, `ErrorState`, and `Stepper` status read them, so a brand recolours every status surface at once. **Rule:** consume the token as **tint + text/icon** — `tw:bg-<role>/10` for the surface, `tw:text-<role>` / `tw:border-<role>/25` for the mark. The default token values ship dark enough to be AA (≥4.5:1) as text/icon on their own tint, in light **and** dark mode — a brand overriding them should preserve that. Avoid solid fills with a white foreground (`tw:bg-<role>` + white): the token flips light in dark mode, so white-on-token fails there. A brand _can_ recolour "error" away from red — that is now allowed; the accessible-on-tint contract is what must hold, not the hue. **Legacy exception:** the themeable treatment is gated to argo (`data-[argo=true]:` / `group-data-[argo=true]/…:`). Under legacy chrome (`useArgoDesign()` → `false`) Alert and `ErrorState` keep their original fixed status scales (`blue-*`/`green-*`/`warning-*`/`error-*`), and the legacy brand retains its original status token hues — so legacy status colour is unchanged.
|
|
452
513
|
|
|
453
514
|
**Decorative — stays fixed across brands.** The non-semantic palette that encodes category rather than state: `Badge` decorative colours (`purple`, `cyan`, `teal`, `blue`, …), chart colours, decorative tag palette. **Rule:** keep using primitive scales (`purple-500`, `cyan-500`, …). These are an identity/category contract with the consumer and do not re-skin.
|
|
454
515
|
|
|
@@ -466,22 +527,38 @@ import { useAppForm, withForm, setServerFieldErrors } from '@keboola/design';
|
|
|
466
527
|
|
|
467
528
|
## Theming (brand + colorScheme)
|
|
468
529
|
|
|
469
|
-
Wrap your app once in `<ThemeProvider>` from `@keboola/design`.
|
|
530
|
+
Wrap your app once in `<ThemeProvider>` from `@keboola/design`. You give it the set of `Brand`s it may activate and the id of the active one; it sets `data-brand` and `data-theme` on `<html>` and injects the matching `--color-*` / `--radius-*` CSS variables.
|
|
470
531
|
|
|
471
532
|
```tsx
|
|
472
533
|
import { ThemeProvider } from '@keboola/design';
|
|
534
|
+
import { keboola } from '@keboola/brand-registry';
|
|
473
535
|
|
|
474
|
-
<ThemeProvider
|
|
536
|
+
<ThemeProvider brands={[keboola]} defaultBrandId={keboola.id} defaultScheme="system">
|
|
475
537
|
<App />
|
|
476
538
|
</ThemeProvider>;
|
|
477
539
|
```
|
|
478
540
|
|
|
479
|
-
- **`
|
|
480
|
-
- **`
|
|
541
|
+
- **`brands`** — the brands this provider knows about; the active id resolves against them. Defaults to an empty list, in which case the active brand falls back to a `design-system` sentinel whose empty theme injects nothing, so the stylesheet's own `:root` defaults provide every token.
|
|
542
|
+
- **`brandId` / `defaultBrandId` / `onBrandIdChange`** — the active brand, controlled or uncontrolled. An unknown id (including the sentinel) falls back to that same empty theme rather than throwing.
|
|
543
|
+
- **`scheme` / `defaultScheme` / `onSchemeChange`** — `"light"` (default) / `"dark"` / `"system"`, controlled or uncontrolled. Dark mode is set **here, on the root provider** — not per component. `"system"` follows `prefers-color-scheme` and resolves reactively. Render the user-facing control with the **`ColorModeSwitch`** block (`<ColorModeSwitch value={scheme} onValueChange={setScheme} />`) and feed the same state back in.
|
|
481
544
|
|
|
482
|
-
|
|
545
|
+
Read the resolved values with `useTheme()` (`brandId`, `currentTheme`, `themes`, `scheme`, `resolvedScheme`, and the setters). With no provider above it, it answers the defaults rather than throwing.
|
|
483
546
|
|
|
484
|
-
|
|
547
|
+
### The argo/legacy switch is separate from the brand
|
|
548
|
+
|
|
549
|
+
`ThemeProvider` does **not** decide whether a subtree renders the argo design language — that is a kbc-ui migration concern, so it rides its own context:
|
|
550
|
+
|
|
551
|
+
```tsx
|
|
552
|
+
import { ArgoDesignContext, useArgoDesign } from '@keboola/design';
|
|
553
|
+
|
|
554
|
+
<ArgoDesignContext value={false}>{/* legacy chrome for this subtree */}</ArgoDesignContext>;
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
`ArgoDesignContext` defaults to `true` (argo — the modern default; legacy chrome is the exception), so an app that never provides it gets argo everywhere. kbc-ui provides `false` for its legacy brands and overrides per subtree as pages are migrated; components read it with `useArgoDesign()`. It is **temporary** and will be deleted once every kbc-ui surface is migrated — don't build on it in a new app.
|
|
558
|
+
|
|
559
|
+
Because the value is read from the nearest provider, a nested override scopes to that subtree. The build ships a single instance of both contexts across every subpath entry, so a provider mounted from the root barrel is visible to components that ship in `@keboola/design/rjsf`, `/markdown-editor`, `/mermaid` and `/editors` too.
|
|
560
|
+
|
|
561
|
+
Define a custom brand with `@keboola/brand-registry`'s `brandSchema` (Zod) and pass it in `brands`; or override the `--color-*` / `--radius-*` CSS variables directly on `:root`.
|
|
485
562
|
|
|
486
563
|
## Testing (Vitest)
|
|
487
564
|
|
|
@@ -514,8 +591,10 @@ pnpm exec ui-gen-bench eval --serve dist --route /tokens --brief "Tokens list wi
|
|
|
514
591
|
## Common Tailwind patterns
|
|
515
592
|
|
|
516
593
|
```
|
|
517
|
-
not-disabled:hover:
|
|
518
|
-
disabled:
|
|
519
|
-
focus-visible:
|
|
520
|
-
[&_svg]:
|
|
594
|
+
tw:not-disabled:hover:bg-accent
|
|
595
|
+
tw:disabled:opacity-40 tw:cursor-not-allowed
|
|
596
|
+
tw:focus-visible:ring-2 tw:ring-primary
|
|
597
|
+
tw:[&_svg]:text-muted-foreground
|
|
521
598
|
```
|
|
599
|
+
|
|
600
|
+
The `tw:` prefix always comes **first**, ahead of every variant — `tw:not-disabled:hover:bg-accent`, never `not-disabled:hover:tw-bg-accent`. Tailwind v4 makes the prefix a variant of its own, so it leads the chain and the utility keeps its bare name.
|
package/COMPONENT-API.md
CHANGED
|
@@ -382,9 +382,12 @@ Source: `src/components/Card/Card.tsx`
|
|
|
382
382
|
|
|
383
383
|
Source: `src/components/Card/CardHeader.tsx`
|
|
384
384
|
|
|
385
|
-
>
|
|
385
|
+
> Own props below, plus native `<div>` attributes.
|
|
386
386
|
|
|
387
|
-
|
|
387
|
+
| Prop | Type | Required | Default | Description |
|
|
388
|
+
| --------- | ------------------------------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
389
|
+
| `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. |
|
|
390
|
+
| `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. |
|
|
388
391
|
|
|
389
392
|
### `Card.Title`
|
|
390
393
|
|
|
@@ -400,9 +403,11 @@ Source: `src/components/Card/CardTitle.tsx`
|
|
|
400
403
|
|
|
401
404
|
Source: `src/components/Card/CardContent.tsx`
|
|
402
405
|
|
|
403
|
-
>
|
|
406
|
+
> Own props below, plus native `<div>` attributes.
|
|
404
407
|
|
|
405
|
-
|
|
408
|
+
| Prop | Type | Required | Default | Description |
|
|
409
|
+
| -------- | --------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
410
|
+
| `padded` | `boolean` | no | `false` | Applies the standard body padding. Use with `Card padding="none"`, where the root adds none — otherwise the padding is doubled. |
|
|
406
411
|
|
|
407
412
|
## Theming
|
|
408
413
|
|
|
@@ -415,7 +420,7 @@ Source: `src/components/ThemeProvider/ThemeProvider.tsx`
|
|
|
415
420
|
| Prop | Type | Required | Default | Description |
|
|
416
421
|
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
417
422
|
| `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). |
|
|
418
|
-
| `brands` | `readonly { id: string; name: string; theme: { colors?: { foreground?: string; background?: string; muted?: string \| undefined; mutedForeground?: string \| undefined; border?: string \| undefined; ...
|
|
423
|
+
| `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. |
|
|
419
424
|
| `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. |
|
|
420
425
|
| `defaultScheme` | `ColorScheme` | no | — | Initial colour scheme for uncontrolled use. Defaults to `light` (`DEFAULT_COLOR_SCHEME`). |
|
|
421
426
|
| `onBrandIdChange` | `((brandId: string) => void)` | no | — | Called with the next id whenever `setBrand` runs — required to persist the choice in controlled mode. |
|
|
@@ -439,19 +444,21 @@ Source: `src/components/BrandLogo/BrandLogo.tsx`
|
|
|
439
444
|
|
|
440
445
|
Source: `src/blocks/AppShell/AppShell.tsx`
|
|
441
446
|
|
|
442
|
-
> Compound app-root shell that follows the active brand (sidebar vs top-nav). Subcomponents: `AppShell.Sidebar`, `AppShell.Header`, `AppShell.Main`. `AppShell.Main` owns the default page gutter (`tw
|
|
447
|
+
> 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`) — override with `className="tw:p-0"`. `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.
|
|
443
448
|
|
|
444
|
-
|
|
449
|
+
| Prop | Type | Required | Default | Description |
|
|
450
|
+
| ------------ | -------------------- | -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
451
|
+
| `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. |
|
|
445
452
|
|
|
446
453
|
### `PageLayout`
|
|
447
454
|
|
|
448
455
|
Source: `src/blocks/PageLayout/PageLayout.tsx`
|
|
449
456
|
|
|
450
|
-
> Compound page shape: header, tabs, toolbar, content, footer. Subcomponents: `PageLayout.Header`, `PageLayout.Content`, `PageLayout.Footer`. `maxWidth` is `narrow` | `default` | `wide` | `full`. Adds no gutter of its own. Native `<div>` attributes.
|
|
457
|
+
> Compound page shape: header, tabs, toolbar, content, footer. Subcomponents: `PageLayout.Header`, `PageLayout.Content`, `PageLayout.Footer`. `maxWidth` is `narrow` | `default` | `wide` | `full`. Adds no gutter of its own. `PageLayout.Header` takes `sticky` (pins + paints the header, and publishes its measured height as `--page-header-height` on the root); `PageLayout.Content` takes `nav` (a `SectionNav`) for the two-column in-page-navigation layout, and behaves exactly as before without it. Native `<div>` attributes.
|
|
451
458
|
|
|
452
459
|
| Prop | Type | Required | Default | Description |
|
|
453
460
|
| ---------- | ------------------------------------------- | -------- | ------- | ----------- |
|
|
454
|
-
| `maxWidth` | `"default" \| "
|
|
461
|
+
| `maxWidth` | `"default" \| "full" \| "narrow" \| "wide"` | no | `full` | |
|
|
455
462
|
|
|
456
463
|
### `PageHeader.Index`
|
|
457
464
|
|
|
@@ -507,6 +514,21 @@ Source: `src/components/Sidebar/Sidebar.tsx`
|
|
|
507
514
|
| `side` | `SidebarSide` | no | `left` | |
|
|
508
515
|
| `style` | `CSSProperties` | no | — | |
|
|
509
516
|
|
|
517
|
+
### `SectionNav`
|
|
518
|
+
|
|
519
|
+
Source: `src/blocks/SectionNav/SectionNav.tsx`
|
|
520
|
+
|
|
521
|
+
> 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).
|
|
522
|
+
|
|
523
|
+
| Prop | Type | Required | Default | Description |
|
|
524
|
+
| ------------------ | ------------------------------------------------- | -------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
525
|
+
| `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. |
|
|
526
|
+
| `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. |
|
|
527
|
+
| `activeId` | `string` | no | — | `id` of the current section: a child's, or a childless group's. |
|
|
528
|
+
| `className` | `string` | no | — | Applied to the tree's `<nav>`. The column's own geometry belongs to `PageLayout.Content nav`. |
|
|
529
|
+
| `label` | `string` | no | `Sections` | Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. |
|
|
530
|
+
| `showDescriptions` | `boolean` | no | `false` | Print each section's `description` under its title. Off — the tree stays scannable without it. |
|
|
531
|
+
|
|
510
532
|
### `Navbar`
|
|
511
533
|
|
|
512
534
|
Source: `src/components/Navbar/Navbar.tsx`
|
package/README.md
CHANGED
|
@@ -130,13 +130,13 @@ Coverage is **measured, not gated** — it gives a baseline for the story suite.
|
|
|
130
130
|
pnpm --filter @keboola/design test:stories:coverage
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
Same prerequisites as `test:stories` (build workspace deps, install Chromium). Reports land in `packages/design/coverage/` (gitignored): a `text` summary in the console and a browsable `html` report at `coverage/index.html`.
|
|
133
|
+
Same prerequisites as `test:stories` (build workspace deps, install Chromium). Reports land in `packages/design/coverage/stories/` (gitignored): a `text` summary in the console and a browsable `html` report at `coverage/stories/index.html`. The jsdom unit lane reports separately into `coverage/unit/` — it uses the shared v8 preset (`@keboola/vitest-config`), so the two providers don't overwrite each other.
|
|
134
134
|
|
|
135
135
|
**Why istanbul, not v8:** this is a browser-mode Vitest project. v8 coverage relies on Node's inspector, which isn't available in a Playwright-driven browser, so the [istanbul provider](https://vitest.dev/guide/coverage#coverage-providers) (`@vitest/coverage-istanbul`, pinned to the Vitest version) instruments the source at transform time and works in both Node and the browser.
|
|
136
136
|
|
|
137
|
-
**What's covered:** `src/**` component source, excluding stories (`*.stories.tsx`), unit tests (`*.test.{ts,tsx}`),
|
|
137
|
+
**What's covered:** `src/**` component source, excluding stories (`*.stories.tsx`), unit tests (`*.test.{ts,tsx}`), type decls, `src/docs/**`, and `src/icons/**` (curated lucide re-exports plus custom SVG marks like `Keboola` — trivial visual surface, no logic to gate).
|
|
138
138
|
|
|
139
|
-
**What the numbers reflect:** only some story files carry a `play()` interaction test; the rest contribute just their render/smoke path, so branch coverage trails statement coverage. The lowest-covered areas are the interaction-heavy blocks that still lack a `play()`. Run `test:stories:coverage` and open `coverage/index.html` for the current per-file numbers — they're not pinned here because they drift with every story and `play()` added.
|
|
139
|
+
**What the numbers reflect:** only some story files carry a `play()` interaction test; the rest contribute just their render/smoke path, so branch coverage trails statement coverage. The lowest-covered areas are the interaction-heavy blocks that still lack a `play()`. Run `test:stories:coverage` and open `coverage/stories/index.html` for the current per-file numbers — they're not pinned here because they drift with every story and `play()` added.
|
|
140
140
|
|
|
141
141
|
### Icons
|
|
142
142
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { MermaidDiagram } from './chunk-MA6RRHDT.js';
|
|
2
|
+
import './chunk-SVBSNSD4.js';
|
|
3
|
+
import './chunk-SFFF2WQP.js';
|
|
4
|
+
import './chunk-PACNBKJV.js';
|
|
5
|
+
import './chunk-IIS7INHF.js';
|
|
6
|
+
import './chunk-FUFMVW7O.js';
|
|
7
|
+
import './chunk-7P6PLZ4B.js';
|
|
8
|
+
import './chunk-IXAYNBOY.js';
|
|
9
|
+
import './chunk-RQVK4IYC.js';
|
|
10
|
+
import './chunk-KR7NXXHC.js';
|
|
11
|
+
import './chunk-SWQFYNYG.js';
|
|
12
|
+
import './chunk-3W27OLK5.js';
|
|
13
|
+
import './chunk-MODE4QIA.js';
|
|
14
|
+
import './chunk-WETKNYZX.js';
|
|
15
|
+
import './chunk-LXLIQ2D6.js';
|
|
16
|
+
import './chunk-G3PMV62Z.js';
|
|
17
|
+
//# sourceMappingURL=MermaidDiagram-ZU5KAVRT.js.map
|
|
18
|
+
//# sourceMappingURL=MermaidDiagram-ZU5KAVRT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"MermaidDiagram-ZU5KAVRT.js"}
|
package/dist/charts.d.ts
CHANGED
|
@@ -75,6 +75,23 @@ type ChartSeries = {
|
|
|
75
75
|
/** Pin to a specific palette token (1–5). Defaults to the series position. */
|
|
76
76
|
color?: ChartColorToken;
|
|
77
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* The lower end of a value-axis domain: an explicit number, `'auto'` (let the
|
|
80
|
+
* axis pick), or the data minimum with optional padding below it.
|
|
81
|
+
*
|
|
82
|
+
* Split from the upper bound rather than sharing one union, so a tuple can't be
|
|
83
|
+
* written back to front. The offset forms mirror what recharts actually parses —
|
|
84
|
+
* it pads the low end DOWN only (`'dataMin - 500'`), and `'dataMax'` as a lower
|
|
85
|
+
* bound is nonsense, so neither is typed here.
|
|
86
|
+
*/
|
|
87
|
+
type ChartAxisLowerBound = number | 'auto' | 'dataMin' | `dataMin - ${number}`;
|
|
88
|
+
/**
|
|
89
|
+
* The upper end of a value-axis domain. Mirror of {@link ChartAxisLowerBound}:
|
|
90
|
+
* recharts pads the high end UP only (`'dataMax + 500'`).
|
|
91
|
+
*/
|
|
92
|
+
type ChartAxisUpperBound = number | 'auto' | 'dataMax' | `dataMax + ${number}`;
|
|
93
|
+
/** `[min, max]` bounds for a value axis. */
|
|
94
|
+
type ChartAxisDomain = readonly [ChartAxisLowerBound, ChartAxisUpperBound];
|
|
78
95
|
/** Props shared by the cartesian charts (line / bar / area). */
|
|
79
96
|
type CartesianChartProps = {
|
|
80
97
|
/** The rows to plot. */
|
|
@@ -100,6 +117,21 @@ type CartesianChartProps = {
|
|
|
100
117
|
className?: string;
|
|
101
118
|
};
|
|
102
119
|
|
|
120
|
+
type LineChartProps = CartesianChartProps & {
|
|
121
|
+
/**
|
|
122
|
+
* `[min, max]` bounds for the value (y) axis — numbers, `'auto'`, or padded
|
|
123
|
+
* data extremes (`['dataMin - 500', 'dataMax + 500']`). Defaults to a zero
|
|
124
|
+
* baseline.
|
|
125
|
+
*
|
|
126
|
+
* Only the line chart takes this. A line encodes value by POSITION, so moving
|
|
127
|
+
* the baseline rescales it without misstating it; bars and areas encode by
|
|
128
|
+
* length and filled area from the baseline, and truncating those makes the
|
|
129
|
+
* geometry lie about the ratios. Use it to compare two series of similar
|
|
130
|
+
* magnitude far from zero — not for a single series whose magnitude the
|
|
131
|
+
* reader is meant to judge.
|
|
132
|
+
*/
|
|
133
|
+
yDomain?: ChartAxisDomain;
|
|
134
|
+
};
|
|
103
135
|
/**
|
|
104
136
|
* A themed multi-series line chart. Each series' color comes from the semantic
|
|
105
137
|
* `--chart-*` palette (by order, or pinned via `series[].color`), which
|
|
@@ -112,8 +144,11 @@ type CartesianChartProps = {
|
|
|
112
144
|
* xKey="month"
|
|
113
145
|
* series={[{ dataKey: 'revenue', name: 'Revenue' }, { dataKey: 'cost' }]}
|
|
114
146
|
* />
|
|
147
|
+
*
|
|
148
|
+
* @example Two close-but-high series, on a baseline that shows the gap
|
|
149
|
+
* <LineChart data={data} xKey="month" series={series} yDomain={[7000, 9000]} />
|
|
115
150
|
*/
|
|
116
|
-
declare const LineChart: ({ data, xKey, series, height, width, className, ...chrome }:
|
|
151
|
+
declare const LineChart: ({ data, xKey, series, height, width, className, ...chrome }: LineChartProps) => react_jsx_runtime.JSX.Element;
|
|
117
152
|
|
|
118
153
|
type BarChartProps = CartesianChartProps & {
|
|
119
154
|
/** Stack the series into a single bar per category. Defaults to grouped. */
|
|
@@ -178,4 +213,4 @@ type PieChartProps = {
|
|
|
178
213
|
*/
|
|
179
214
|
declare const PieChart: ({ data, nameKey, dataKey, innerRadius, height, width, className, showLegend, showTooltip, valueFormatter, }: PieChartProps) => react_jsx_runtime.JSX.Element;
|
|
180
215
|
|
|
181
|
-
export { AreaChart, type AreaChartProps, BarChart, type BarChartProps, type CartesianChartProps, type ChartColorToken, ChartContainer, type ChartContainerProps, type ChartDatum, type ChartDimension, type ChartSeries, ChartTooltip, ChartTooltipContent, type ChartTooltipProps, LineChart, PieChart, type PieChartProps, chartTokenColor };
|
|
216
|
+
export { AreaChart, type AreaChartProps, BarChart, type BarChartProps, type CartesianChartProps, type ChartAxisDomain, type ChartAxisLowerBound, type ChartAxisUpperBound, type ChartColorToken, ChartContainer, type ChartContainerProps, type ChartDatum, type ChartDimension, type ChartSeries, ChartTooltip, ChartTooltipContent, type ChartTooltipProps, LineChart, type LineChartProps, PieChart, type PieChartProps, chartTokenColor };
|
package/dist/charts.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
import './chunk-SWQFYNYG.js';
|
|
2
|
+
import './chunk-3W27OLK5.js';
|
|
3
|
+
import './chunk-MODE4QIA.js';
|
|
4
|
+
import './chunk-WETKNYZX.js';
|
|
5
|
+
import { cn } from './chunk-LXLIQ2D6.js';
|
|
6
|
+
import './chunk-G3PMV62Z.js';
|
|
1
7
|
import { ResponsiveContainer, Tooltip, LineChart as LineChart$1, Line, BarChart as BarChart$1, Bar, AreaChart as AreaChart$1, Area, PieChart as PieChart$1, Legend, Pie, Cell, CartesianGrid, XAxis, YAxis } from 'recharts';
|
|
2
|
-
import { clsx } from 'clsx';
|
|
3
|
-
import { extendTailwindMerge } from 'tailwind-merge';
|
|
4
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
9
|
|
|
6
|
-
// src/blocks/Charts/ChartContainer.tsx
|
|
7
|
-
var twMerge = extendTailwindMerge({
|
|
8
|
-
prefix: "tw"
|
|
9
|
-
});
|
|
10
|
-
var cn = (...classes) => twMerge(clsx(...classes));
|
|
11
10
|
var ChartContainer = ({
|
|
12
11
|
height = 300,
|
|
13
12
|
width = "100%",
|
|
@@ -111,13 +110,16 @@ var cartesianChrome = ({
|
|
|
111
110
|
showYAxis = true,
|
|
112
111
|
showLegend = false,
|
|
113
112
|
showTooltip = true,
|
|
114
|
-
valueFormatter
|
|
113
|
+
valueFormatter,
|
|
114
|
+
yDomain
|
|
115
115
|
}) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
116
116
|
showGrid && /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }),
|
|
117
117
|
/* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...AXIS_PROPS }),
|
|
118
|
-
showYAxis && /* @__PURE__ */ jsx(
|
|
118
|
+
(showYAxis || yDomain !== void 0) && /* @__PURE__ */ jsx(
|
|
119
119
|
YAxis,
|
|
120
120
|
{
|
|
121
|
+
hide: !showYAxis,
|
|
122
|
+
domain: yDomain,
|
|
121
123
|
width: 48,
|
|
122
124
|
...AXIS_PROPS,
|
|
123
125
|
tickFormatter: valueFormatter ? (value) => formatValue(value, valueFormatter) : void 0
|