@keboola/design 4.2.1 → 4.3.1

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 CHANGED
@@ -465,7 +465,7 @@ import { ThemeProvider } from '@keboola/design';
465
465
  ```
466
466
 
467
467
  - **`brand`** — the active brand decides the chrome. **argo styling is brand-driven**: any non-`keboola-legacy` brand renders argo chrome automatically (`renderArgo = !isLegacy`), so a default `keboola` / `example-customer` brand needs no per-component flags. The `keboola-legacy` brand renders the pre-modernization chrome. With no `brand` prop, `ThemeProvider` defaults to the canonical `keboola` brand.
468
- - **`colorScheme`** — `"light"` (default) / `"dark"` / `"system"`. Dark mode is set **here, on the root provider** — not per component. `"system"` follows the OS preference.
468
+ - **`colorScheme`** — `"light"` (default) / `"dark"` / `"system"`. Dark mode is set **here, on the root provider** — not per component. `"system"` follows the OS preference. Render the user-facing light/dark/system control with the **`ColorModeSwitch`** block (`<ColorModeSwitch value={scheme} onValueChange={setScheme} />`) — a controlled icon-button + dropdown; feed the same state to `ThemeProvider`'s `colorScheme`.
469
469
 
470
470
  Chrome is driven **entirely** by the active brand — there is no per-call-site `argo` prop or `variant="argo"` escape hatch. To render a subtree under a different brand (e.g. an argo section inside a `keboola-legacy` app), wrap it in a nested `<ThemeProvider brand={…}>`; `useIsLegacyBrand()` reads the nearest provider, so the override is scoped to that subtree.
471
471
 
package/COMPONENT-API.md CHANGED
@@ -364,10 +364,175 @@ _No own props — see note above for passthrough attributes._
364
364
 
365
365
  Source: `src/components/ThemeProvider/ThemeProvider.tsx`
366
366
 
367
- > Wrap the app root. `brand` defaults to the canonical `keboola` brand. Pair with `useTheme()` to read/flip the brand at runtime.
367
+ > Wrap the app root. `brand` defaults to the canonical `keboola` brand. Pair with `useTheme()` to read/flip the brand at runtime. Mounts a `TooltipProvider` around its subtree, so a `Tooltip` works without a separately-mounted provider.
368
368
 
369
369
  | Prop | Type | Required | Default | Description |
370
370
  | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
371
371
  | `brand` | `{ id: string; name: string; colors: { foreground: string; background: string; muted: string; mutedForeground: string; border: string; primary: string; primaryForeground: string; destructive: string; destructiveForeground: string; accent?: string; accentForeground?: string; }; ... 6 more ...; ...` | no | — | Brand whose tokens drive the chrome (`@keboola/design`'s semantic CSS variables) inside this provider's subtree. Defaults to the canonical `keboola` brand so existing apps that mount `<ThemeProvider>` without a `brand` prop continue to render as today. |
372
372
  | `colorScheme` | `ColorScheme` | no | `light` | Light/dark mode. `'system'` follows `prefers-color-scheme` and updates reactively. Defaults to `'light'` so existing mounts don't drift. Only the ROOT provider applies this (sets `data-theme`, owns the media listener); a nested provider inherits the root's resolved mode. |
373
373
  | `setBrand` | `((brand: { id: string; name: string; colors: { foreground: string; background: string; muted: string; mutedForeground: string; border: string; primary: string; primaryForeground: string; destructive: string; destructiveForeground: string; accent?: string; accentForeground?: string; }; ... 6 m...` | no | — | Optional setter exposed through `useTheme()` so consumers can flip brands at runtime (Storybook toolbar, a customer-impersonation switch). |
374
+
375
+ ## Layout & shell
376
+
377
+ ### `AppShell`
378
+
379
+ Source: `src/blocks/AppShell/AppShell.tsx`
380
+
381
+ > 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-p-6`) — override with `className="tw-p-0"`. Native `<div>` attributes.
382
+
383
+ _No own props — see note above for passthrough attributes._
384
+
385
+ ### `PageLayout`
386
+
387
+ Source: `src/blocks/PageLayout/PageLayout.tsx`
388
+
389
+ > 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.
390
+
391
+ | Prop | Type | Required | Default | Description |
392
+ | ---------- | ------------------------------------------- | -------- | ------- | ----------- |
393
+ | `maxWidth` | `"default" \| "narrow" \| "wide" \| "full"` | no | `full` | |
394
+
395
+ ### `PageHeader.Index`
396
+
397
+ Source: `src/blocks/PageHeader/PageHeaderIndex.tsx`
398
+
399
+ > Index-page header. Pass `Tabs` via `headerNav`.
400
+
401
+ | Prop | Type | Required | Default | Description |
402
+ | ---------------------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
403
+ | `title` | `ReactNode` | yes | — | |
404
+ | `action` | `ReactNode` | no | — | Primary "create / add new X" `Button`. |
405
+ | `description` | `ReactNode` | no | — | Prose description shown below the title. Mutually exclusive with `metadata` in the pattern; `metadata` wins when both are passed. |
406
+ | `documentation` | `ReactNode` | no | — | Icon-only docs button (`Button variant="invisible" icon={<BookOpen />}`). Sits next to `action`. |
407
+ | `fullWidthDescription` | `boolean` | no | `false` | Opt into the responsive layout: the description spans its own full-width row below the title, and the action group wraps beneath the title (right-aligned) on narrow widths instead of shrinking. Defaults to `false` (the description shares the title column and actions stay `shrink-0`). Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical. |
408
+ | `headerNav` | `ReactNode` | no | — | Optional `Tabs` row rendered below the title block. Use only when >1 dataset / section is worth navigating to. |
409
+ | `metadata` | `ReactNode` | no | — | Count / system summary shown below the title (e.g. "3 buckets and 39 tables"). Wins over `description`. |
410
+
411
+ ### `PageHeader.Detail`
412
+
413
+ Source: `src/blocks/PageHeader/PageHeaderDetail.tsx`
414
+
415
+ > Detail-page header (back link, title, actions).
416
+
417
+ | Prop | Type | Required | Default | Description |
418
+ | ---------------------- | ----------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
419
+ | `breadcrumbs` | `ReactNode` | yes | — | `Breadcrumb` chain ending in the entity name (last item is not a link). Required. |
420
+ | `title` | `ReactNode` | yes | — | |
421
+ | `badges` | `ReactNode` | no | — | Inline `Badge`s rendered next to the title (status, environment, version). Always rendered as pills. |
422
+ | `compact` | `boolean` | no | `false` | Compact title mode: renders a smaller title since the breadcrumb already shows the entity name. Default `false`. |
423
+ | `description` | `ReactNode` | no | — | |
424
+ | `fullWidthDescription` | `boolean` | no | `false` | Opt into the responsive layout: the description spans its own full-width row below the title/actions row instead of sharing the title column. Defaults to `false` (description sits inside the title column). Enabled per the `sidebar-navigation` feature in kbc-ui; leaving it off keeps existing consumers byte-identical. |
425
+ | `headerNav` | `ReactNode` | no | — | Optional `Tabs` row below the title block. |
426
+ | `overflowActions` | `ReactNode` | no | — | `DropdownMenu` for tertiary actions. Sits on the breadcrumbs row, not the title row. |
427
+ | `primaryAction` | `ReactNode` | no | — | Primary action (`Button`). Use the verb appropriate to the entity (Deploy / Run / Save). |
428
+ | `secondaryAction` | `ReactNode` | no | — | Optional second action (`Button variant="secondary"`). Everything beyond goes in `overflowActions`. |
429
+ | `titleIcon` | `ReactNode` | no | — | Optional icon rendered immediately left of the title (entity / component / type icon). |
430
+
431
+ ## Navigation shell
432
+
433
+ ### `Sidebar`
434
+
435
+ Source: `src/components/Sidebar/Sidebar.tsx`
436
+
437
+ > App-shell left navigation rail (host inside `AppShell.Sidebar`). Compound: `Sidebar.Header`, `Sidebar.Content`, `Sidebar.Footer`, `Sidebar.Menu`, `Sidebar.Group`, `Sidebar.SearchInput` (concrete `<input>`, no `asChild`).
438
+
439
+ | Prop | Type | Required | Default | Description |
440
+ | ------------- | --------------- | -------- | ------- | ----------- |
441
+ | `className` | `string` | no | — | |
442
+ | `container` | `boolean` | no | `false` | |
443
+ | `id` | `string` | no | — | |
444
+ | `keepMounted` | `boolean` | no | — | |
445
+ | `resizable` | `boolean` | no | `false` | |
446
+ | `side` | `SidebarSide` | no | `left` | |
447
+ | `style` | `CSSProperties` | no | — | |
448
+
449
+ ### `Navbar`
450
+
451
+ Source: `src/components/Navbar/Navbar.tsx`
452
+
453
+ > Top navigation bar (host inside `AppShell.Header`). Compound: `Navbar.Header`, `Navbar.Content`, `Navbar.Footer`, `Navbar.Menu`. Native `<nav>` attributes.
454
+
455
+ | Prop | Type | Required | Default | Description |
456
+ | ---------- | ------------------------------------------- | -------- | ------- | ----------- |
457
+ | `accent` | `"blue" \| "purple" \| "green" \| "orange"` | no | `blue` | |
458
+ | `bordered` | `boolean \| null` | no | `false` | |
459
+
460
+ ## Navigation / flow
461
+
462
+ ### `Tabs`
463
+
464
+ Source: `src/components/Tabs/Tabs.tsx`
465
+
466
+ > Data-driven — pass `triggers` (accepts a `readonly` array, so `[...] as const` works) plus `TabsContent` children. No `TabsList` / `TabsTrigger` export.
467
+
468
+ | Prop | Type | Required | Default | Description |
469
+ | ----------------------- | ----------------------- | -------- | ------- | ---------------------------------------------------------- |
470
+ | `triggers` | `readonly Trigger<T>[]` | yes | — | |
471
+ | `asChild` | `boolean` | no | — | |
472
+ | `compact` | `boolean` | no | `false` | |
473
+ | `defaultValue` | `string` | no | — | The value of the tab to select by default, if uncontrolled |
474
+ | `listClassName` | `string` | no | — | |
475
+ | `onValueChange` | `((value: T) => void)` | no | — | |
476
+ | `rootClassName` | `string` | no | — | |
477
+ | `triggerClassName` | `string` | no | — | |
478
+ | `triggerGroupClassName` | `string` | no | — | |
479
+
480
+ ### `Timeline`
481
+
482
+ Source: `src/components/Timeline/Timeline.tsx`
483
+
484
+ > Unordered chronological log. Compound: `Timeline.Item`, `Timeline.Content`, `Timeline.Connector`. Native `<ol>` attributes.
485
+
486
+ | Prop | Type | Required | Default | Description |
487
+ | --------- | --------------------- | -------- | -------- | ----------- |
488
+ | `variant` | `"solid" \| "dashed"` | no | `dashed` | |
489
+
490
+ ### `Progress`
491
+
492
+ Source: `src/components/Progress/Progress.tsx`
493
+
494
+ > Single-value determinate progress bar.
495
+
496
+ | Prop | Type | Required | Default | Description |
497
+ | --------- | -------------------------------- | -------- | ------- | ----------- |
498
+ | `asChild` | `boolean` | no | — | |
499
+ | `size` | `"sm" \| "lg" \| null` | no | — | |
500
+ | `variant` | `"success" \| "default" \| null` | no | — | |
501
+
502
+ ## Data display — layout
503
+
504
+ ### `Table`
505
+
506
+ Source: `src/components/Table/Table.tsx`
507
+
508
+ > Presentational table (no inline edit / selection / virtualization). Compound: `Table.Header`, `Table.Body`, `Table.Footer`, `Table.Row`, `Table.Head`, `Table.Cell`. For an editable grid, drive TanStack Table through `Table` (see the DataGrid recipe). Native `<table>` attributes.
509
+
510
+ | Prop | Type | Required | Default | Description |
511
+ | -------------------- | --------- | -------- | ------- | ----------- |
512
+ | `borderCollapsed` | `boolean` | no | `true` | |
513
+ | `bordered` | `boolean` | no | `false` | |
514
+ | `containerClassName` | `string` | no | — | |
515
+
516
+ ### `EmptyState`
517
+
518
+ Source: `src/blocks/EmptyState/EmptyState.tsx`
519
+
520
+ > Compound: `EmptyState.Icon`, `EmptyState.Title`, `EmptyState.Actions`. `variant` is `default` | `compact`. Native `<div>` attributes.
521
+
522
+ | Prop | Type | Required | Default | Description |
523
+ | --------- | -------------------------------- | -------- | --------- | ----------- |
524
+ | `variant` | `"default" \| "compact" \| null` | no | `default` | |
525
+
526
+ ### `Popconfirm`
527
+
528
+ Source: `src/components/Popconfirm/Popconfirm.tsx`
529
+
530
+ > Lightweight inline confirmation anchored to its trigger. Compound: `Popconfirm.Trigger`, `Popconfirm.Content`, `Popconfirm.Body`, `Popconfirm.Footer`, `Popconfirm.Confirm`, `Popconfirm.Cancel`.
531
+
532
+ | Prop | Type | Required | Default | Description |
533
+ | --------------- | ------------------------------------------------------------------------------- | -------- | -------------- | ----------- |
534
+ | `enabled` | `boolean` | no | `true` | |
535
+ | `onCancel` | `((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void)` | no | `() => void 0` | |
536
+ | `onConfirm` | `((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void \| Promise<void>)` | no | `() => void 0` | |
537
+ | `skipAsyncWait` | `boolean` | no | `false` | |
538
+ | `variant` | `"danger" \| "confirm"` | no | `confirm` | |
package/dist/editors.cjs CHANGED
@@ -569,6 +569,9 @@ var argoVariants = classVarianceAuthority.cva(
569
569
  outline: [
570
570
  "!tw-border-input",
571
571
  "tw-bg-background",
572
+ // Semantic base text color so the label/icon flips in dark mode
573
+ // (matches `invisible`); previously unset → inherited a fixed dark color.
574
+ "tw-text-foreground",
572
575
  "hover:not-disabled:tw-bg-accent",
573
576
  "hover:not-disabled:tw-text-accent-foreground",
574
577
  "hover:active:tw-bg-background",