@keboola/design 11.3.0 → 11.4.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 +17 -0
- package/CHANGELOG.md +170 -0
- package/COMPONENT-API.md +32 -31
- package/dist/{AIKit-DaFT7p92.js → AIKit-DDg5DBCG.js} +142 -63
- package/dist/AIKit-DDg5DBCG.js.map +1 -0
- package/dist/{Alert-CseY3yAj.js → Alert-DHJFrWnS.js} +3 -3
- package/dist/{Alert-CseY3yAj.js.map → Alert-DHJFrWnS.js.map} +1 -1
- package/dist/{AlertModal-DQAGpsEy.js → AlertModal-BGJdaRRj.js} +3 -3
- package/dist/{AlertModal-DQAGpsEy.js.map → AlertModal-BGJdaRRj.js.map} +1 -1
- package/dist/{AppShell-BUoxM3fv.js → AppShell-DRgJxpXW.js} +2 -2
- package/dist/{AppShell-BUoxM3fv.js.map → AppShell-DRgJxpXW.js.map} +1 -1
- package/dist/{BrandEditor-BnTLMRMp.js → BrandEditor-Go7w8Zj2.js} +7 -7
- package/dist/{BrandEditor-BnTLMRMp.js.map → BrandEditor-Go7w8Zj2.js.map} +1 -1
- package/dist/{BrandLogo-V2pRUAeO.js → BrandLogo-Dmi7jo21.js} +2 -2
- package/dist/{BrandLogo-V2pRUAeO.js.map → BrandLogo-Dmi7jo21.js.map} +1 -1
- package/dist/{Breadcrumb-CQTPn_KB.js → Breadcrumb-uEkM6adI.js} +3 -3
- package/dist/{Breadcrumb-CQTPn_KB.js.map → Breadcrumb-uEkM6adI.js.map} +1 -1
- package/dist/{Button-CPsEQuTN.js → Button-DsRrU5F1.js} +6 -5
- package/dist/Button-DsRrU5F1.js.map +1 -0
- package/dist/{Card-Cd5HSBmv.js → Card-Dyo7055Q.js} +2 -2
- package/dist/{Card-Cd5HSBmv.js.map → Card-Dyo7055Q.js.map} +1 -1
- package/dist/{Checkbox-5VNCcV7E.js → Checkbox-fC0BuO2B.js} +3 -3
- package/dist/{Checkbox-5VNCcV7E.js.map → Checkbox-fC0BuO2B.js.map} +1 -1
- package/dist/{Clipboard-B7rckqV_.js → Clipboard-ChPdiUy3.js} +2 -2
- package/dist/{Clipboard-B7rckqV_.js.map → Clipboard-ChPdiUy3.js.map} +1 -1
- package/dist/{ClipboardButton-CQ6Aewpg.js → ClipboardButton-D9pDjgkB.js} +3 -3
- package/dist/{ClipboardButton-CQ6Aewpg.js.map → ClipboardButton-D9pDjgkB.js.map} +1 -1
- package/dist/{CodeEditor-CUse8znx.js → CodeEditor-Cxy3HnKH.js} +15 -26
- package/dist/CodeEditor-Cxy3HnKH.js.map +1 -0
- package/dist/{ColorInput-Q1D9Vcc_.js → ColorInput-Bxj-1eLT.js} +3 -3
- package/dist/{ColorInput-Q1D9Vcc_.js.map → ColorInput-Bxj-1eLT.js.map} +1 -1
- package/dist/{ColorModeSwitch-B5PXCVqB.js → ColorModeSwitch-CsWLiTBX.js} +3 -3
- package/dist/{ColorModeSwitch-B5PXCVqB.js.map → ColorModeSwitch-CsWLiTBX.js.map} +1 -1
- package/dist/{Combobox-CyoRA7oY.js → Combobox-Cs_1pj2q.js} +29 -22
- package/dist/Combobox-Cs_1pj2q.js.map +1 -0
- package/dist/{Command-Ds68v2rX.js → Command-B7ML9YMv.js} +6 -6
- package/dist/{Command-Ds68v2rX.js.map → Command-B7ML9YMv.js.map} +1 -1
- package/dist/{CopyField-DI66uY_g.js → CopyField-BO_sh-HO.js} +2 -2
- package/dist/{CopyField-DI66uY_g.js.map → CopyField-BO_sh-HO.js.map} +1 -1
- package/dist/{DateInput-BPj2pzsn.js → DateInput-ZdaMQo5i.js} +4 -4
- package/dist/{DateInput-BPj2pzsn.js.map → DateInput-ZdaMQo5i.js.map} +1 -1
- package/dist/{DatePicker-DyEGuW9m.js → DatePicker-nA8YdE84.js} +2 -2
- package/dist/{DatePicker-DyEGuW9m.js.map → DatePicker-nA8YdE84.js.map} +1 -1
- package/dist/{DateRangeInput-u9DxNbHW.js → DateRangeInput-DkvNh_sT.js} +4 -4
- package/dist/{DateRangeInput-u9DxNbHW.js.map → DateRangeInput-DkvNh_sT.js.map} +1 -1
- package/dist/{DateRangePicker-CYYhX6S7.js → DateRangePicker-DjSUFjh4.js} +5 -5
- package/dist/{DateRangePicker-CYYhX6S7.js.map → DateRangePicker-DjSUFjh4.js.map} +1 -1
- package/dist/{DropdownMenu-DpMEcyCq.js → DropdownMenu-CASr-jgl.js} +2 -2
- package/dist/{DropdownMenu-DpMEcyCq.js.map → DropdownMenu-CASr-jgl.js.map} +1 -1
- package/dist/{FieldItem-qQKGU9lF.js → FieldItem-CCd9-xnp.js} +3 -3
- package/dist/{FieldItem-qQKGU9lF.js.map → FieldItem-CCd9-xnp.js.map} +1 -1
- package/dist/{FileUpload-C336MVnU.js → FileUpload-ABThVZyg.js} +2 -2
- package/dist/{FileUpload-C336MVnU.js.map → FileUpload-ABThVZyg.js.map} +1 -1
- package/dist/{Form-CTygENDc.js → Form-k6PH-em3.js} +8 -8
- package/dist/{Form-CTygENDc.js.map → Form-k6PH-em3.js.map} +1 -1
- package/dist/{FormGroup-BnwP0jNu.js → FormGroup-DbcDtrgU.js} +3 -3
- package/dist/{FormGroup-BnwP0jNu.js.map → FormGroup-DbcDtrgU.js.map} +1 -1
- package/dist/{FullScreenModal-j-M4aPFd.js → FullScreenModal-BvPuYibe.js} +3 -3
- package/dist/{FullScreenModal-j-M4aPFd.js.map → FullScreenModal-BvPuYibe.js.map} +1 -1
- package/dist/{HoverCard-yQq-O49c.js → HoverCard-B9ZMJxjn.js} +2 -2
- package/dist/{HoverCard-yQq-O49c.js.map → HoverCard-B9ZMJxjn.js.map} +1 -1
- package/dist/{InputGroup-D7zlmqPB.js → InputGroup-BnLHY0eq.js} +3 -3
- package/dist/{InputGroup-D7zlmqPB.js.map → InputGroup-BnLHY0eq.js.map} +1 -1
- package/dist/{Kbd-D6LpR7G2.js → Kbd-CvSM3D3-.js} +2 -2
- package/dist/{Kbd-D6LpR7G2.js.map → Kbd-CvSM3D3-.js.map} +1 -1
- package/dist/MarkedText-DNGEUVWc.js +67 -0
- package/dist/MarkedText-DNGEUVWc.js.map +1 -0
- package/dist/{MermaidDiagram-JlvuGcY-.js → MermaidDiagram-WkonYErO.js} +3 -3
- package/dist/{MermaidDiagram-JlvuGcY-.js.map → MermaidDiagram-WkonYErO.js.map} +1 -1
- package/dist/{Modal-o4ATIexE.js → Modal-Coj-H02o.js} +16 -4
- package/dist/Modal-Coj-H02o.js.map +1 -0
- package/dist/{MultiActionButtonGroup-GTeFk-L8.js → MultiActionButtonGroup-CxWH7yWK.js} +3 -3
- package/dist/{MultiActionButtonGroup-GTeFk-L8.js.map → MultiActionButtonGroup-CxWH7yWK.js.map} +1 -1
- package/dist/{Navbar-CAQs4BZz.js → Navbar-B2UsolVU.js} +3 -3
- package/dist/{Navbar-CAQs4BZz.js.map → Navbar-B2UsolVU.js.map} +1 -1
- package/dist/{PageToolbar-bG2YtSa3.js → PageToolbar-DnbFt14Q.js} +3 -3
- package/dist/{PageToolbar-bG2YtSa3.js.map → PageToolbar-DnbFt14Q.js.map} +1 -1
- package/dist/{Pagination-BB3X7ooY.js → Pagination-C_b7Xhey.js} +2 -2
- package/dist/{Pagination-BB3X7ooY.js.map → Pagination-C_b7Xhey.js.map} +1 -1
- package/dist/{Popconfirm-C2Ky5hJO.js → Popconfirm-CILjmzKI.js} +3 -3
- package/dist/{Popconfirm-C2Ky5hJO.js.map → Popconfirm-CILjmzKI.js.map} +1 -1
- package/dist/{Popover-DsbI2HKu.js → Popover-BEbQrC_P.js} +22 -19
- package/dist/Popover-BEbQrC_P.js.map +1 -0
- package/dist/{RadioGroup-BMxuZEbT.js → RadioGroup-XFzFd1ti.js} +3 -3
- package/dist/{RadioGroup-BMxuZEbT.js.map → RadioGroup-XFzFd1ti.js.map} +1 -1
- package/dist/{Search-DFeECt5D.js → Search-4Bxtt8hS.js} +2 -2
- package/dist/{Search-DFeECt5D.js.map → Search-4Bxtt8hS.js.map} +1 -1
- package/dist/{SearchInput-CCpdUego.js → SearchInput-f_oY9T4Z.js} +3 -3
- package/dist/{SearchInput-CCpdUego.js.map → SearchInput-f_oY9T4Z.js.map} +1 -1
- package/dist/{SectionNav-Bw_MVL0_.js → SectionNav-BpJlisbT.js} +4 -4
- package/dist/{SectionNav-Bw_MVL0_.js.map → SectionNav-BpJlisbT.js.map} +1 -1
- package/dist/{Select-D6IZVvwL.js → Select-DpcgKqKB.js} +31 -20
- package/dist/Select-DpcgKqKB.js.map +1 -0
- package/dist/{Sheet-BIzs2K2H.js → Sheet-Chf0kX1E.js} +3 -3
- package/dist/{Sheet-BIzs2K2H.js.map → Sheet-Chf0kX1E.js.map} +1 -1
- package/dist/{Sidebar-r1TW4g_b.js → Sidebar-Cm6I4dE1.js} +9 -7
- package/dist/{Sidebar-r1TW4g_b.js.map → Sidebar-Cm6I4dE1.js.map} +1 -1
- package/dist/{Slider-CjxyfEty.js → Slider-pPC_3gz9.js} +3 -3
- package/dist/{Slider-CjxyfEty.js.map → Slider-pPC_3gz9.js.map} +1 -1
- package/dist/{Switch-BueTV03C.js → Switch-ChfPKcTE.js} +2 -2
- package/dist/{Switch-BueTV03C.js.map → Switch-ChfPKcTE.js.map} +1 -1
- package/dist/{Tabs-l72-WuhK.js → Tabs-eB974xJf.js} +2 -2
- package/dist/{Tabs-l72-WuhK.js.map → Tabs-eB974xJf.js.map} +1 -1
- package/dist/{TextInput-DhdRk8qm.js → TextInput-DHM6dHmn.js} +3 -3
- package/dist/{TextInput-DhdRk8qm.js.map → TextInput-DHM6dHmn.js.map} +1 -1
- package/dist/{ThemeProvider-DZfGdf1v.js → ThemeProvider-DrQJtzpd.js} +90 -15
- package/dist/ThemeProvider-DrQJtzpd.js.map +1 -0
- package/dist/{TimePicker-B6d2rAbX.js → TimePicker-BGeqc-Ed.js} +2 -2
- package/dist/{TimePicker-B6d2rAbX.js.map → TimePicker-BGeqc-Ed.js.map} +1 -1
- package/dist/{Toast-CxXUulYN.js → Toast-Dr6Uw7ao.js} +2 -2
- package/dist/{Toast-CxXUulYN.js.map → Toast-Dr6Uw7ao.js.map} +1 -1
- package/dist/{ZoomableSvg-CNIzRHKH.js → ZoomableSvg-BWnDkR61.js} +4 -4
- package/dist/{ZoomableSvg-CNIzRHKH.js.map → ZoomableSvg-BWnDkR61.js.map} +1 -1
- package/dist/{context-BrNtMc1H.js → context-D7X470dy.js} +4 -3
- package/dist/context-D7X470dy.js.map +1 -0
- package/dist/{defaults-CTfvj2KB.js → defaults-i_xG2F_1.js} +2 -4
- package/dist/defaults-i_xG2F_1.js.map +1 -0
- package/dist/editors.js +4 -4
- package/dist/findLiteralMatches-BGBw8Vbl.js +62 -0
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +1 -0
- package/dist/flint.js +3 -3
- package/dist/index.d.ts +677 -527
- package/dist/index.js +59 -58
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/ErrorState.js +1 -1
- package/dist/internal/blocks/ExportMenu.js +5 -5
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +14 -11
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +2 -2
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +2 -2
- package/dist/internal/blocks/StatCard.js +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +1 -1
- package/dist/internal/blocks/TimeInput.js +3 -3
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/Card.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +1 -1
- package/dist/internal/components/Combobox.js +1 -1
- package/dist/internal/components/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +4 -4
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Toggle.js +3 -3
- package/dist/internal/components/Toggle.js.map +1 -1
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/utils.js +3 -3
- package/dist/markdown-editor.js +7 -7
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.js +11 -11
- package/dist/styles.css +1 -1
- package/dist/testing.js +4 -4
- package/dist/testing.js.map +1 -1
- package/dist/{themeTokens-7T1AFLhq.js → themeTokens-D70HeNVF.js} +3 -3
- package/dist/{themeTokens-7T1AFLhq.js.map → themeTokens-D70HeNVF.js.map} +1 -1
- package/dist/{toast-BweSoKn3.js → toast-DIC0iNRf.js} +2 -2
- package/dist/{toast-BweSoKn3.js.map → toast-DIC0iNRf.js.map} +1 -1
- package/dist/{useColorSchemeState-BJEk6esG.js → useColorSchemeState-klihG9-i.js} +2 -2
- package/dist/{useColorSchemeState-BJEk6esG.js.map → useColorSchemeState-klihG9-i.js.map} +1 -1
- package/dist/{utils-B-g7d_Jb.js → utils-B5Z52hYs.js} +2 -2
- package/dist/{utils-B-g7d_Jb.js.map → utils-B5Z52hYs.js.map} +1 -1
- package/dist/vega.js +2 -2
- package/dist/{vegaTheme-FBXgAdHK.js → vegaTheme-DfoEQhOy.js} +2 -2
- package/dist/{vegaTheme-FBXgAdHK.js.map → vegaTheme-DfoEQhOy.js.map} +1 -1
- package/package.json +5 -5
- package/dist/AIKit-DaFT7p92.js.map +0 -1
- package/dist/Button-CPsEQuTN.js.map +0 -1
- package/dist/CodeEditor-CUse8znx.js.map +0 -1
- package/dist/Combobox-CyoRA7oY.js.map +0 -1
- package/dist/MarkedText-Ckbft5mw.js +0 -44
- package/dist/MarkedText-Ckbft5mw.js.map +0 -1
- package/dist/Modal-o4ATIexE.js.map +0 -1
- package/dist/Popover-DsbI2HKu.js.map +0 -1
- package/dist/Select-D6IZVvwL.js.map +0 -1
- package/dist/ThemeProvider-DZfGdf1v.js.map +0 -1
- package/dist/context-BrNtMc1H.js.map +0 -1
- package/dist/defaults-CTfvj2KB.js.map +0 -1
- package/dist/escapeStringRegexp-8MxP2knR.js +0 -6
- package/dist/escapeStringRegexp-8MxP2knR.js.map +0 -1
package/AGENTS.md
CHANGED
|
@@ -497,6 +497,19 @@ Both router wirings (TanStack Router, and a custom named router) are in [`RECIPE
|
|
|
497
497
|
/>
|
|
498
498
|
```
|
|
499
499
|
|
|
500
|
+
**Pinned chip in a `MultiCombobox`** — a chip the control shows but the user does not own (a set of packages the runtime already ships, a role every member has). `pinnedChipLabels` is a render-only slot, so nothing enters `value`: there is no sentinel to strip on save and the control's own counting never sees a non-item.
|
|
501
|
+
|
|
502
|
+
```tsx
|
|
503
|
+
<MultiCombobox
|
|
504
|
+
allowCreate
|
|
505
|
+
value={packages}
|
|
506
|
+
onValueChange={save}
|
|
507
|
+
pinnedChipLabels={['Default packages']}
|
|
508
|
+
/>
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Don't fake one by prepending a sentinel to `value` — that costs the caller a strip on every change plus a label branch, and leaks the sentinel into the primitive's counting.
|
|
512
|
+
|
|
500
513
|
**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:
|
|
501
514
|
|
|
502
515
|
```tsx
|
|
@@ -535,6 +548,10 @@ Layer-0 colour usage splits into three buckets.
|
|
|
535
548
|
|
|
536
549
|
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.
|
|
537
550
|
|
|
551
|
+
An **opacity modifier composites over `transparent`, not over the element's own rest fill.** On a control that is opaque at rest (`tw:bg-card`, `tw:bg-background`) a `tw:hover:bg-<token>/NN` therefore _replaces_ that fill, and the control shows whatever it overlaps — a flow-canvas edge, an `Alert` tint. Mix the state fill into the control's rest token instead: `tw:hover:bg-[color-mix(in_oklab,rgb(var(--muted-foreground))_15%,rgb(var(--card)))]`. Use the raw `--*` triples — `--color-*` is `@theme inline`, build-time only, and an unresolved one invalidates the declaration into `transparent`. A control that is **transparent at rest** (menu item, ghost button, table row) is the case the modifier is for; leave those alone.
|
|
552
|
+
|
|
553
|
+
A tint also cannot carry a **state change** on a light surface — a brand-primary tint stays within ~1.5:1 of the surface at any opacity that still reads as a tint. Step the border for that, and keep the roles apart: hover steps the chrome border (`border-input` → `border-muted-foreground`), `focus-visible` owns the brand border.
|
|
554
|
+
|
|
538
555
|
**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.
|
|
539
556
|
|
|
540
557
|
**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.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,175 @@
|
|
|
1
1
|
# @keboola/design
|
|
2
2
|
|
|
3
|
+
## 11.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- The AIKit layer for Kai's redesign (DES-20, DES-170).
|
|
8
|
+
- `ThemeScope` (new): a subtree pins its own colour scheme regardless of the app's —
|
|
9
|
+
Kai's panel stays light while its minimized widget is dark. `useThemeScopeContainer`
|
|
10
|
+
hands portalling components the scope element, and `Popover.Content` now takes a
|
|
11
|
+
`container` so a portal stays inside the scope that styles it.
|
|
12
|
+
- `ToolCallStatusHeader` joins AIKit — the tool-call panel header kbc-ui carried,
|
|
13
|
+
promoted with tests and stories.
|
|
14
|
+
- `MessageBubble` drops its avatar; a user turn is a plain bubble. `user` is still accepted
|
|
15
|
+
(deprecated, ignored) so call sites keep compiling.
|
|
16
|
+
- `Command` takes a `variant`, so a command in a small surface (a popover) can opt out
|
|
17
|
+
of the full-screen palette styling the theme would pick.
|
|
18
|
+
- No platform token changes: Kai scopes its own sidebar accent in kbc-ui.
|
|
19
|
+
- The root barrel grows ~1 KB with the new exports; the size budget moves 342→344 KB.
|
|
20
|
+
|
|
21
|
+
- `CodeEditor` search matches literal text instead of a compiled pattern, and `findLiteralMatches` / `hasLiteralMatch` ship as utilities.
|
|
22
|
+
|
|
23
|
+
A search query is data, not a pattern. Compiling one meant escaping it first and living with V8's
|
|
24
|
+
ceiling on how large a pattern may be: a query of a few tens of kilobytes — what pasting a document
|
|
25
|
+
into a find box produces — threw `Regular expression too large` when the pattern was first executed.
|
|
26
|
+
`findMatches` now scans for the query literally, so escaping and that ceiling are both gone, and it
|
|
27
|
+
short-circuits before joining the document's rope when the query cannot fit in it.
|
|
28
|
+
|
|
29
|
+
`findLiteralMatches(text, query)` returns the start offsets of every case-insensitive occurrence and
|
|
30
|
+
`hasLiteralMatch(text, query)` answers whether there is one, stopping at the first. Both fold case
|
|
31
|
+
without changing the length of the string, so the offsets index the caller's own text.
|
|
32
|
+
|
|
33
|
+
Two behaviour notes for anyone matching the editor's counts elsewhere: `İ` (U+0130) now reads as a
|
|
34
|
+
plain `i` rather than matching only itself, and `SearchMatch` no longer carries the matched `text`,
|
|
35
|
+
which nothing read.
|
|
36
|
+
|
|
37
|
+
- `Markdown` accepts `remarkPlugins` and `components`.
|
|
38
|
+
- `remarkPlugins` runs after the built-in GFM one rather than in place of it, so tables, autolinks and task lists keep working whatever a caller adds.
|
|
39
|
+
- `components` is merged over the built-in element renderers by key. An override replaces that element's renderer rather than wrapping it, so a `table` override loses the design `Table` and an `a` override loses the new-tab treatment for absolute links.
|
|
40
|
+
- Together they are the seam an app's own inline syntax arrives through — an annotation an agent writes beside a link, read back by a renderer for that element — which is app product knowledge and does not belong in this package.
|
|
41
|
+
- Both are meant to be held in module constants: `Markdown` re-parses its source on every render, so a caller memoises it, and a prop object built during render defeats that.
|
|
42
|
+
|
|
43
|
+
- `MarkedText` highlights by literal scan instead of a compiled pattern, and `findLiteralMatches` takes an `isCaseSensitive` option.
|
|
44
|
+
|
|
45
|
+
The highlight query was escaped, split on spaces, and joined into one alternation regex — so a
|
|
46
|
+
space-free paste of a few tens of kilobytes (minified SQL, JSON, base64) exceeded V8's pattern
|
|
47
|
+
ceiling and threw `Regular expression too large` from a `useMemo`, taking the page down with it.
|
|
48
|
+
`createMarkedParts` now finds each space-separated term with `findLiteralMatches` and merges the
|
|
49
|
+
offsets, so no pattern is compiled at all.
|
|
50
|
+
|
|
51
|
+
One visible behaviour change: overlapping term matches now merge into one marked run — searching
|
|
52
|
+
`test testing` marks the whole `testing`, where the alternation used to mark only its `test` prefix
|
|
53
|
+
and leave `ing` plain. Adjacent matches merge the same way. Case-insensitive matching also folds
|
|
54
|
+
`İ` (U+0130) to a plain `i`, matching the editor search.
|
|
55
|
+
|
|
56
|
+
`escapeStringRegexp` is gone from the package's internals — nothing compiles user text as a pattern
|
|
57
|
+
anymore.
|
|
58
|
+
|
|
59
|
+
- `MultiCombobox`: a render-only slot for pinned chips, chip callbacks see the real item type, and a created value stops haunting the list.
|
|
60
|
+
|
|
61
|
+
`pinnedChipLabels` renders chips the caller keeps rather than the user — a set of packages the
|
|
62
|
+
runtime already ships, a role every member has. They sit ahead of the values, outside `maxVisible`,
|
|
63
|
+
carry no remove button, and never enter `value`.
|
|
64
|
+
|
|
65
|
+
`itemToChipLabel` and `itemToChipColor` now receive `Value` instead of `unknown`, so a call site
|
|
66
|
+
stops narrowing by hand. Existing call sites keep compiling; their `String(...)` wrappers become
|
|
67
|
+
redundant.
|
|
68
|
+
|
|
69
|
+
Created values were kept in a list that never shrank, so a value the user created and then removed —
|
|
70
|
+
or cleared — stayed in the listbox as an option for the rest of the session, and skewed
|
|
71
|
+
`allowSelectAll`'s "everything is selected" arithmetic. The list now tracks the selection.
|
|
72
|
+
|
|
73
|
+
- Add a `hint` slot to `Select` items, and let the top-level `Select` take `aria-label`.
|
|
74
|
+
|
|
75
|
+
`hint` renders a trailing muted note in the listbox row — "Default" beside the value the
|
|
76
|
+
platform falls back to. It sits outside Radix's `ItemText`, so the trigger keeps showing the
|
|
77
|
+
label alone once the option is picked; because Radix names an option from `ItemText` only
|
|
78
|
+
(`aria-labelledby`), the hint is wired into the item's `aria-describedby` instead, so a screen
|
|
79
|
+
reader still reads it.
|
|
80
|
+
|
|
81
|
+
`aria-label` was the one trigger a11y prop the convenience wrapper did not forward — it already
|
|
82
|
+
curated `aria-describedby`, `aria-invalid` and `aria-required`. Selects that stand without a
|
|
83
|
+
visible `Label` (a filter row, or several selects joined by "OR") need it.
|
|
84
|
+
|
|
85
|
+
- `UsageStats`: the corner alert badge now accepts a severity.
|
|
86
|
+
|
|
87
|
+
`alert` takes `boolean | 'warning' | 'error'` instead of a bare boolean. `'warning'` renders the badge
|
|
88
|
+
amber for an approaching-limit state that isn't at-limit yet; `'error'` (or the existing bare `true`)
|
|
89
|
+
keeps the red at-limit color, so existing call sites keep compiling unchanged.
|
|
90
|
+
|
|
91
|
+
### Patch Changes
|
|
92
|
+
|
|
93
|
+
- `Button variant="outline"`: the hovered button stops dissolving into the surface behind it.
|
|
94
|
+
|
|
95
|
+
Both hover and pressed fills were tints of `transparent` (Tailwind's `bg-<token>/NN`), so hovering
|
|
96
|
+
replaced the variant's opaque rest fill and the button showed whatever it overlapped — an edge on a
|
|
97
|
+
flow canvas, the status tint inside an `Alert`. They now `color-mix` into the variant's own rest
|
|
98
|
+
token (`--card` under legacy chrome, `--background` under argo), which is the same colour on the
|
|
99
|
+
surface the variant assumes and stays opaque off it.
|
|
100
|
+
|
|
101
|
+
Argo compounded that by keeping `border-input` on hover while tinting the fill toward it, so the
|
|
102
|
+
button's edge contrast _dropped_ as the user reached it — measured 1.42:1 → 1.25:1 in light and
|
|
103
|
+
2.28:1 → 1.62:1 in dark, against its own fill on a `--muted` surface. Its hover now steps the
|
|
104
|
+
border to `--muted-foreground` (4.00:1 / 5.24:1), the treatment legacy already shipped. A tint
|
|
105
|
+
cannot carry that signal: brand primary stays within ~1.5:1 of a light surface at any opacity that
|
|
106
|
+
still reads as a tint. `--primary` stays reserved for `focus-visible`, so hover and focus remain
|
|
107
|
+
distinguishable.
|
|
108
|
+
|
|
109
|
+
Consumers overriding the hover fill per call site to work around the leak can drop those
|
|
110
|
+
overrides. `packages/design/AGENTS.md` records the underlying rule in the Layer-0 chrome contract.
|
|
111
|
+
|
|
112
|
+
- Security patches for transitive dependencies: qs 6.16.0 in api-client, mermaid 11.17.2 and dompurify
|
|
113
|
+
3.4.14 in design.
|
|
114
|
+
|
|
115
|
+
No API or behaviour change in either package.
|
|
116
|
+
|
|
117
|
+
- Every theme-aware subpath entry stops carrying `@keboola/brand-registry`.
|
|
118
|
+
|
|
119
|
+
`ThemeProvider/defaults.ts` imported two legacy brands for value, only to build a two-element array
|
|
120
|
+
of their ids — and that array had exactly one consumer, the `renderWithTheme` test helper. Because
|
|
121
|
+
`useThemeAttributes`, `useBrandState` and `useColorSchemeState` each read a constant from
|
|
122
|
+
`defaults.ts`, that one import put the whole registry in the graph of every entry that reads the
|
|
123
|
+
live theme.
|
|
124
|
+
|
|
125
|
+
The ids now live at the helper that uses them, so `defaults.ts` imports `Brand` as a type only. No
|
|
126
|
+
export moved and no behaviour changed — `keboolaLegacySidebar` / `keboolaLegacyTopnav` still resolve
|
|
127
|
+
from the root barrel for the consumers that render them.
|
|
128
|
+
|
|
129
|
+
What a consumer pays for a themed subpath, brotlied:
|
|
130
|
+
|
|
131
|
+
| Entry | Before | After | Δ |
|
|
132
|
+
| --------------------------------- | ---------: | ---------: | ----: |
|
|
133
|
+
| `@keboola/design/vega` | 61.9 kB | 0.9 kB | −98 % |
|
|
134
|
+
| `@keboola/design/editors` | 312.5 kB | 252.0 kB | −19 % |
|
|
135
|
+
| `@keboola/design/flint` | 439.7 kB | 380.2 kB | −14 % |
|
|
136
|
+
| `@keboola/design/rjsf` | 490.2 kB | 430.6 kB | −12 % |
|
|
137
|
+
| `@keboola/design/markdown-editor` | 1 333.9 kB | 1 272.0 kB | −5 % |
|
|
138
|
+
| `@keboola/design/mermaid` | 1 200.4 kB | 1 140.1 kB | −5 % |
|
|
139
|
+
| `{ useAppForm }` from the root | 135.2 kB | 73.9 kB | −45 % |
|
|
140
|
+
|
|
141
|
+
The root barrel is unchanged — it re-exports the brands deliberately, so an app that renders one
|
|
142
|
+
still pays for it once. The per-entry `size-limit` budgets drop to match, so they now measure the
|
|
143
|
+
entry rather than a shared dependency.
|
|
144
|
+
|
|
145
|
+
- `Modal.Footer` now lays its own actions out: right-aligned, 8px apart.
|
|
146
|
+
|
|
147
|
+
The footer owned only horizontal padding, so a bare `<Modal.Footer>` fell back to block flow — its
|
|
148
|
+
buttons sat left-aligned, separated by nothing but collapsed JSX whitespace. Nearly every footer in
|
|
149
|
+
this repo is bare, so that was the default look; a handful re-declared `tw:flex tw:justify-end
|
|
150
|
+
tw:gap-2` at the call site. Consumers can drop those.
|
|
151
|
+
|
|
152
|
+
Overriding the arrangement still works through `className`, but `cn` runs tailwind-merge, which
|
|
153
|
+
displaces only within a conflict group: `tw:justify-between` replaces `justify-end`, while
|
|
154
|
+
`tw:flex-col` leaves `items-center` and the gap in place, so a stacked footer wants
|
|
155
|
+
`tw:items-stretch` alongside it. The footer imposes no width on its children, so one that should
|
|
156
|
+
fill the row carries `tw:w-full` itself (`Button block`, `ButtonGroup variant="block"`).
|
|
157
|
+
|
|
158
|
+
One footer in this repo wanted the stacked arrangement — `wr-google-sheets`' `SheetModal`, which
|
|
159
|
+
puts a saving message above its buttons — and is the only one still passing layout classes.
|
|
160
|
+
|
|
161
|
+
`@keboola/kbc-ui` and `@keboola/control-ui` are private — nothing to release for them; they are
|
|
162
|
+
listed because their call sites changed.
|
|
163
|
+
|
|
164
|
+
- `PromptInput`: `autoFocus` no longer scrolls ancestors to reveal the textarea.
|
|
165
|
+
|
|
166
|
+
The prop was forwarded as the DOM attribute, and the browser's autofocus scrolls every scrollable
|
|
167
|
+
ancestor toward the element. A composer mounting inside a panel that is still sliding in — kbc-ui's
|
|
168
|
+
Kai rail opens this way — sits off-canvas at focus time, so the page scrolled sideways toward it,
|
|
169
|
+
shoving the whole content left until the slide finished and the overflow clamp snapped it back.
|
|
170
|
+
The focus is now applied imperatively on mount with `focus({ preventScroll: true })`: same focus,
|
|
171
|
+
same mount-only semantics, no ancestor scrolling.
|
|
172
|
+
|
|
3
173
|
## 11.3.0
|
|
4
174
|
|
|
5
175
|
### Minor Changes
|
package/COMPONENT-API.md
CHANGED
|
@@ -319,37 +319,38 @@ Source: `src/blocks/Form/connectors/MultiComboboxField.tsx`
|
|
|
319
319
|
|
|
320
320
|
> 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
321
|
|
|
322
|
-
| Prop | Type
|
|
323
|
-
| -------------------- |
|
|
324
|
-
| `action` | `ReactNode`
|
|
325
|
-
| `allowClear` | `boolean`
|
|
326
|
-
| `allowCreate` | `boolean`
|
|
327
|
-
| `allowSelectAll` | `boolean`
|
|
328
|
-
| `aria-describedby` | `string`
|
|
329
|
-
| `className` | `string`
|
|
330
|
-
| `empty` | `ReactNode`
|
|
331
|
-
| `focusVariant` | `"off" \| "on" \| "default" \| null`
|
|
332
|
-
| `groupToLabel` | `((group: Group<string>) => ReactNode)`
|
|
333
|
-
| `help` | `ReactNode`
|
|
334
|
-
| `indicator` | `Indicator`
|
|
335
|
-
| `inputClassName` | `string`
|
|
336
|
-
| `items` | `readonly (string \| Group<string>)[]`
|
|
337
|
-
| `itemToChipColor` | `((item:
|
|
338
|
-
| `itemToChipLabel` | `((item:
|
|
339
|
-
| `itemToDisabled` | `((item: string) => boolean)`
|
|
340
|
-
| `itemToIcon` | `((item: string) => ReactNode)`
|
|
341
|
-
| `itemToLabel` | `((item: string) => ReactNode)`
|
|
342
|
-
| `itemToStringLabel` | `((itemValue: string) => string)`
|
|
343
|
-
| `itemToStringValue` | `((itemValue: string) => string)`
|
|
344
|
-
| `label` | `ReactNode`
|
|
345
|
-
| `maxVisible` | `number`
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
348
|
-
| `
|
|
349
|
-
| `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
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 | — | |
|
|
326
|
+
| `allowCreate` | `boolean` | no | — | |
|
|
327
|
+
| `allowSelectAll` | `boolean` | no | — | |
|
|
328
|
+
| `aria-describedby` | `string` | no | — | |
|
|
329
|
+
| `className` | `string` | no | — | |
|
|
330
|
+
| `empty` | `ReactNode` | no | — | |
|
|
331
|
+
| `focusVariant` | `"off" \| "on" \| "default" \| null` | no | — | |
|
|
332
|
+
| `groupToLabel` | `((group: Group<string>) => ReactNode)` | no | — | |
|
|
333
|
+
| `help` | `ReactNode` | no | — | |
|
|
334
|
+
| `indicator` | `Indicator` | no | — | |
|
|
335
|
+
| `inputClassName` | `string` | no | — | |
|
|
336
|
+
| `items` | `readonly (string \| Group<string>)[]` | no | — | |
|
|
337
|
+
| `itemToChipColor` | `((item: string) => "gray" \| "gray-darker" \| "gray-inverse" \| "green" \| "green-darker" \| "green-inverse" \| "blue" \| "blue-inverse" \| "red" \| "orange" \| "orange-inverse" \| "amber" \| ... 9 more ...)` | no | — | |
|
|
338
|
+
| `itemToChipLabel` | `((item: string) => ReactNode)` | no | — | |
|
|
339
|
+
| `itemToDisabled` | `((item: string) => boolean)` | no | — | |
|
|
340
|
+
| `itemToIcon` | `((item: string) => ReactNode)` | no | — | |
|
|
341
|
+
| `itemToLabel` | `((item: string) => ReactNode)` | no | — | |
|
|
342
|
+
| `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. |
|
|
343
|
+
| `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. |
|
|
344
|
+
| `label` | `ReactNode` | no | — | |
|
|
345
|
+
| `maxVisible` | `number` | no | — | |
|
|
346
|
+
| `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. |
|
|
347
|
+
| `queryToCreateLabel` | `((query: string) => ReactNode)` | no | — | |
|
|
348
|
+
| `queryToCreateValue` | `((query: string) => string)` | no | — | |
|
|
349
|
+
| `required` | `boolean` | no | — | |
|
|
350
|
+
| `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'`. |
|
|
351
|
+
| `sizing` | `"small" \| "medium" \| "default" \| null` | no | — | |
|
|
352
|
+
| `tooltip` | `ReactNode` | no | — | |
|
|
353
|
+
| `variant` | `"primary" \| "secondary" \| null` | no | — | |
|
|
353
354
|
|
|
354
355
|
### `field.CheckboxField`
|
|
355
356
|
|