@nadicodeai/ui 12.1.171 → 12.1.173

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/AGENTS.md +7 -5
  2. package/README.md +1 -2
  3. package/dist/components/chart-card.js +1 -1
  4. package/dist/components/checkbox.js +1 -1
  5. package/dist/components/dialog.js +1 -1
  6. package/dist/components/kpi-card.d.ts.map +1 -1
  7. package/dist/components/kpi-card.js +3 -3
  8. package/dist/components/multi-select.js +1 -1
  9. package/dist/components/object-page.d.ts +6 -6
  10. package/dist/components/object-page.d.ts.map +1 -1
  11. package/dist/components/object-page.js +4 -5
  12. package/dist/components/object-workspace.d.ts +17 -9
  13. package/dist/components/object-workspace.d.ts.map +1 -1
  14. package/dist/components/object-workspace.js +7 -6
  15. package/dist/components/overview-page.d.ts +7 -2
  16. package/dist/components/overview-page.d.ts.map +1 -1
  17. package/dist/components/overview-page.js +4 -4
  18. package/dist/components/page-actions.d.ts +22 -0
  19. package/dist/components/page-actions.d.ts.map +1 -1
  20. package/dist/components/page-actions.js +16 -0
  21. package/dist/components/radio-group.js +1 -1
  22. package/dist/components/record-list.d.ts +4 -2
  23. package/dist/components/record-list.d.ts.map +1 -1
  24. package/dist/components/record-list.js +1 -1
  25. package/dist/components/settings-facts.d.ts +5 -4
  26. package/dist/components/settings-facts.d.ts.map +1 -1
  27. package/dist/components/settings-facts.js +5 -4
  28. package/dist/components/settings-section.d.ts +19 -8
  29. package/dist/components/settings-section.d.ts.map +1 -1
  30. package/dist/components/settings-section.js +4 -3
  31. package/dist/components/table-card.d.ts +9 -4
  32. package/dist/components/table-card.d.ts.map +1 -1
  33. package/dist/components/table-card.js +7 -5
  34. package/dist/components/text-link.d.ts +6 -6
  35. package/dist/components/text-link.js +6 -6
  36. package/dist/showcase/specimens/actions.d.ts +1 -0
  37. package/dist/showcase/specimens/actions.d.ts.map +1 -1
  38. package/dist/showcase/specimens/actions.js +5 -1
  39. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  40. package/dist/showcase/specimens/compositions.js +1 -1
  41. package/dist/showcase/specimens/data.js +1 -1
  42. package/dist/showcase/specimens/index.d.ts +1 -0
  43. package/dist/showcase/specimens/index.d.ts.map +1 -1
  44. package/dist/showcase/usage.generated.d.ts +1 -1
  45. package/dist/showcase/usage.generated.d.ts.map +1 -1
  46. package/dist/showcase/usage.generated.js +22 -11
  47. package/dist/styles/components.css +9 -0
  48. package/package.json +2 -2
package/AGENTS.md CHANGED
@@ -4,11 +4,13 @@ Shared React components, primitives, the Agent conversation interface, and
4
4
  product compositions. Source lives in `src/`; consumers receive `dist/` through
5
5
  `package.json` exports.
6
6
 
7
- The rules every component shares are in `../design-system/DESIGN.md`: tokens,
8
- roles, materials, glass, motion, status, activity, Agent orbs and marks. A
9
- component's own contract (its sizes, variants, behaviour, words and access) is
10
- the usage page in the TSDoc of its main export, which `generate:usage` compiles
11
- and `check:usage` checks. A component change a person can see goes through
7
+ How components look comes from `../design-system/DESIGN.md`, the visual
8
+ identity: tokens, roles, materials, glass and motion. What a component does,
9
+ takes or holds (its sizes, variants, slots, behaviour, words and access) is the
10
+ usage page in the TSDoc of its main export, which `generate:usage` compiles and
11
+ `check:usage` checks; a rule several components share goes in the component
12
+ that draws it for all of them, never in `DESIGN.md`
13
+ ([what goes in it](../design-system/AGENTS.md#what-goes-in-designmd)). A component change a person can see goes through
12
14
  `product-design` first. This file holds only how the package is kept.
13
15
 
14
16
  - **Styling.** A component uses the semantic roles and the generated tokens, and
package/README.md CHANGED
@@ -3,8 +3,7 @@
3
3
  nadicode's React components, published as a built package: shadcn components on
4
4
  Base UI, the chart kit, the Agent conversation interface, and the product
5
5
  compositions the website, the Portal, Nadia and Alveare share. They build on
6
- `@nadicodeai/design-system`, whose `DESIGN.md` is the design system and its design
7
- authority for tokens, visual direction and the rules components share; a
6
+ `@nadicodeai/design-system`, whose `DESIGN.md` is the visual identity; a
8
7
  component's own contract is the usage page in its source.
9
8
 
10
9
  ## Install
@@ -71,7 +71,7 @@ function ChartCard({ variant = "default", title, period, controls, link, summary
71
71
  return (_jsxs(Card, { "data-slot": "chart-card", className: cn("@container/chart-card", className), children: [_jsxs(CardHeader, { narrowAction: variant === "summary" || controls ? "own" : undefined, className: cn(variant === "summary"
72
72
  ? "flex flex-wrap items-center gap-3"
73
73
  : controls && CONTROLS_UNDER_TITLE_WHEN_NARROW), children: [_jsx(CardTitle, { id: titleId, role: "heading", "aria-level": headingLevel, className: variant === "summary" ? "text-heading-xs" : undefined, children: title }), variant === "summary" ? controls : null, period && variant !== "summary" ? _jsx(CardDescription, { children: period }) : null, (variant === "summary" ? link : controls || link) ? (_jsxs(CardAction, { className: cn("flex flex-wrap items-center gap-2", variant === "summary" && "ml-auto"), children: [variant === "summary" ? null : controls, link ? (_jsx(ButtonLink, { variant: "ghost", size: "sm", suffix: _jsx(ChevronRight, { "aria-hidden": "true" }), "aria-label": link.accessibleName, render: link.link, children: link.label })) : null] })) : null] }), summary && variant !== "summary" ? (_jsx("div", { "data-slot": "chart-card-summary", className: "px-(--card-spacing)", children: summary })) : null, _jsxs(CardContent, { className: cn(aside &&
74
- "grid min-w-0 gap-(--card-spacing) @3xl/chart-card:grid-cols-[minmax(0,2fr)_minmax(16rem,1fr)]"), children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-4", children: [variant === "summary" && (summary || period) ? (_jsxs("div", { "data-slot": "chart-card-summary", className: "flex flex-wrap items-start justify-between gap-3", children: [summary, period ? _jsx(CardDescription, { children: period }) : null] })) : null, children(titleId)] }), aside ? (_jsx("aside", { "data-slot": "chart-card-aside", className: "min-w-0 border-t border-border pt-(--card-spacing) @3xl/chart-card:border-t-0 @3xl/chart-card:border-l @3xl/chart-card:pt-0 @3xl/chart-card:pl-(--card-spacing)", children: aside })) : null] }), footer ? (_jsx(FooterStrip, { hint: footer.reading, hintSlot: "chart-card-reading", children: footer.link ? _jsx(PageCommandButton, { command: footer.link, variant: "ghost" }) : null })) : null] }));
74
+ "grid min-w-0 gap-(--card-spacing) @3xl/chart-card:grid-cols-[minmax(0,2fr)_minmax(16rem,1fr)]"), children: [_jsxs("div", { className: "flex min-w-0 flex-col gap-4", children: [variant === "summary" && (summary || period) ? (_jsxs("div", { "data-slot": "chart-card-summary", className: "flex flex-wrap items-start justify-between gap-3", children: [summary, period ? _jsx(CardDescription, { children: period }) : null] })) : null, children(titleId)] }), aside ? (_jsx("aside", { "data-slot": "chart-card-aside", className: "min-w-0 border-t border-border pt-(--card-spacing) @3xl/chart-card:border-t-0 @3xl/chart-card:border-l @3xl/chart-card:pt-0 @3xl/chart-card:pl-(--card-spacing)", children: aside })) : null] }), footer ? (_jsx(FooterStrip, { hint: footer.reading, hintSlot: "chart-card-reading", children: footer.link ? _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) : null })) : null] }));
75
75
  }
76
76
  function ChartSummary({ variant = "default", label, value, valueTitle, valueSize = "default", trend, status, }) {
77
77
  return (_jsxs("div", { "data-slot": "chart-summary", className: "flex flex-col items-start gap-2", children: [_jsx("div", { className: cn(variant === "summary" ? "sr-only" : "text-muted-foreground text-sm"), children: label }), _jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-3", children: [_jsx("div", { "data-slot": "chart-summary-value", className: cn("truncate tabular-nums", variant === "summary"
@@ -48,6 +48,6 @@ import { CheckIcon, MinusIcon } from "lucide-react";
48
48
  * `FieldSet` with its legend.
49
49
  */
50
50
  function Checkbox({ className, nativeButton, ...props }) {
51
- return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", "data-nc-ui": "", className: cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-xs-plus border border-input nc-transition-paint after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-1/2 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground data-disabled:cursor-not-allowed data-disabled:not-data-checked:border-border data-disabled:not-data-checked:bg-muted data-disabled:data-checked:border-transparent data-disabled:data-checked:bg-input/50 data-indeterminate:text-input data-unchecked:not-data-disabled:hover:bg-accent data-indeterminate:not-data-disabled:hover:bg-accent aria-invalid:border-destructive aria-invalid:aria-checked:border-primary [@media(hover:hover)_and_(pointer:fine)]:after:hidden", className), ...props, nativeButton: nativeButton, render: nativeButton ? _jsx("button", { type: "button" }) : undefined, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", "data-nc-ui": "", className: "grid place-content-center text-current transition-none [&>svg]:size-3.5", render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: state.indeterminate ? _jsx(MinusIcon, {}) : _jsx(CheckIcon, {}) })) }) }));
51
+ return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", "data-nc-ui": "", className: cn("peer relative flex size-4 shrink-0 items-center justify-center rounded-xs-plus border border-input nc-transition-paint after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-1/2 data-checked:border-foreground data-checked:bg-foreground data-checked:text-background data-disabled:cursor-not-allowed data-disabled:not-data-checked:border-border data-disabled:not-data-checked:bg-muted data-disabled:data-checked:border-transparent data-disabled:data-checked:bg-input/50 data-indeterminate:text-input data-unchecked:not-data-disabled:hover:bg-accent data-indeterminate:not-data-disabled:hover:bg-accent aria-invalid:border-destructive aria-invalid:aria-checked:border-foreground [@media(hover:hover)_and_(pointer:fine)]:after:hidden", className), ...props, nativeButton: nativeButton, render: nativeButton ? _jsx("button", { type: "button" }) : undefined, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", "data-nc-ui": "", className: "grid place-content-center text-current transition-none [&>svg]:size-3.5", render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: state.indeterminate ? _jsx(MinusIcon, {}) : _jsx(CheckIcon, {}) })) }) }));
52
52
  }
53
53
  export { Checkbox };
@@ -80,7 +80,7 @@ function DialogBody({ className, ...props }) {
80
80
  return (_jsx("div", { "data-slot": "dialog-body", className: cn("-mx-(--dialog-padding) flex min-h-0 flex-1 flex-col gap-nadicode-sm overflow-y-auto px-(--dialog-padding) group-data-[sticky=false]/dialog-content:shrink-0 group-data-[sticky=false]/dialog-content:overflow-y-visible group-data-[sticky=true]/dialog-content:-my-(--dialog-gap) group-data-[sticky=true]/dialog-content:py-(--dialog-padding)", className), ...props }));
81
81
  }
82
82
  function DialogFooter({ className, showCloseButton, closeLabel, children, ...props }) {
83
- return (_jsxs("div", { "data-slot": "dialog-footer", "data-nc-ui": "", className: cn("-mx-(--dialog-padding) -mb-(--dialog-padding) flex shrink-0 flex-row justify-between gap-nadicode-md rounded-b-lg border-t border-border bg-recessed p-nadicode-sm group-data-[phone-layout=sheet]/dialog-content:max-sm:rounded-b-none group-data-[sticky=false]/dialog-content:sticky group-data-[sticky=false]/dialog-content:-bottom-(--dialog-padding) group-data-[sticky=false]/dialog-content:z-10 *:only:w-full **:data-[slot=button]:h-nadicode-control-height-sm **:data-[slot=button]:min-h-nadicode-control-height-sm **:data-[slot=button]:px-button-padding-inline-sm", className), ...props, children: [showCloseButton ? (_jsx(DialogPrimitive.Close, { render: _jsx(Button, { variant: "outline" }), children: closeLabel })) : null, children] }));
83
+ return (_jsxs("div", { "data-slot": "dialog-footer", "data-nc-ui": "", className: cn("-mx-(--dialog-padding) -mb-(--dialog-padding) flex shrink-0 flex-row justify-between gap-nadicode-md rounded-b-lg border-t border-border bg-recessed p-nadicode-sm group-data-[phone-layout=sheet]/dialog-content:max-sm:rounded-b-none group-data-[sticky=false]/dialog-content:sticky group-data-[sticky=false]/dialog-content:-bottom-(--dialog-padding) group-data-[sticky=false]/dialog-content:z-10 *:only:w-full **:data-[slot=button]:h-nadicode-control-height-sm **:data-[slot=button]:min-h-nadicode-control-height-sm **:data-[slot=button]:px-button-padding-inline-sm **:data-[slot=dialog-close]:h-nadicode-control-height-sm **:data-[slot=dialog-close]:min-h-nadicode-control-height-sm **:data-[slot=dialog-close]:px-button-padding-inline-sm", className), ...props, children: [showCloseButton ? (_jsx(DialogPrimitive.Close, { render: _jsx(Button, { variant: "outline" }), children: closeLabel })) : null, children] }));
84
84
  }
85
85
  function DialogTitle({ className, ...props }) {
86
86
  return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", "data-nc-ui": "", className: cn("text-heading-sm group-data-[sticky=true]/dialog-content:leading-6", className), ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"kpi-card.d.ts","sourceRoot":"","sources":["../../src/components/kpi-card.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAY3D,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEtF,KAAK,gBAAgB,GAAG,cAAc,CAAC;AACvC,KAAK,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtD,KAAK,YAAY,GAAG;IAClB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;IACnD,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAQF;;;;;;;;;;;;GAYG;AACH,iBAAS,OAAO,CAAC,EACf,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAgB,EAChB,MAAM,EACN,YAAqB,EACrB,SAAS,GACV,EAAE,YAAY,qBAmHd;AAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"kpi-card.d.ts","sourceRoot":"","sources":["../../src/components/kpi-card.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAY3D,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAEtF,KAAK,gBAAgB,GAAG,cAAc,CAAC;AACvC,KAAK,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtD,KAAK,YAAY,GAAG;IAClB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sGAAsG;IACtG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;IACnD,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAQF;;;;;;;;;;;;GAYG;AACH,iBAAS,OAAO,CAAC,EACf,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAgB,EAChB,MAAM,EACN,YAAqB,EACrB,SAAS,GACV,EAAE,YAAY,qBAwHd;AAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -27,13 +27,13 @@ const VALUE_TONE_CLASS = {
27
27
  */
28
28
  function KpiCard({ label, value, delta, note, tone = "default", render, presentation = "card", sparkline, }) {
29
29
  if (presentation === "inline") {
30
- return (_jsxs("div", { className: "grid min-w-0 content-start gap-2", "data-slot": "metric-summary", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: label }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { className: cn("text-2xl font-semibold tabular-nums", VALUE_TONE_CLASS[tone]), children: value }), delta ? (_jsx(TrendBadge, { value: delta.value, direction: delta.direction, tone: trendTone(delta.direction, delta.upIsGood, delta.neutral), directionLabel: delta.directionLabel })) : null] }), delta ? _jsx("p", { className: "text-xs text-muted-foreground", children: delta.comparison }) : null, note ? _jsx("p", { className: "text-xs text-muted-foreground", children: note }) : null] }));
30
+ return (_jsxs("div", { className: "grid min-w-0 content-start gap-2", "data-slot": "metric-summary", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: label }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("p", { className: cn("text-2xl font-semibold tabular-nums", VALUE_TONE_CLASS[tone]), "data-kpi-value": "", children: value }), delta ? (_jsx(TrendBadge, { value: delta.value, direction: delta.direction, tone: trendTone(delta.direction, delta.upIsGood, delta.neutral), directionLabel: delta.directionLabel })) : null] }), delta ? _jsx("p", { className: "text-xs text-muted-foreground", children: delta.comparison }) : null, note ? _jsx("p", { className: "text-xs text-muted-foreground", children: note }) : null] }));
31
31
  }
32
32
  const footerLine = [delta?.comparison, note].filter(Boolean).join(" · ");
33
33
  const badge = delta ? (_jsx(TrendBadge, { value: delta.value, direction: delta.direction, tone: trendTone(delta.direction, delta.upIsGood, delta.neutral), directionLabel: delta.directionLabel })) : null;
34
34
  if (sparkline) {
35
- return (_jsx(Card, { size: "sm", "data-slot": "kpi-card", "data-tone": tone, render: render, variant: render ? "link" : "default", children: _jsxs(CardHeader, { className: "gap-y-1", children: [_jsxs(CardDescription, { className: "col-span-2 flex min-w-0 items-center gap-0.5", children: [_jsx("span", { className: "truncate", title: label, children: label }), render ? _jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 shrink-0" }) : null] }), delta ? (_jsx(CardAction, { "data-kpi-delta": delta.direction, className: "row-span-1 row-start-2 self-center", children: badge })) : null, _jsx(CardTitle, { className: cn("col-start-1 row-start-2 min-w-0 truncate text-heading-md tabular-nums group-data-[size=sm]/card:text-heading-md", VALUE_TONE_CLASS[tone]), children: value }), _jsx("div", { "data-slot": "kpi-card-sparkline", className: "col-span-2 mt-1 h-8 min-w-0", children: sparkline.length > 1 ? (_jsx(ChartSparkline, { data: sparkline, className: "h-8 w-full" })) : null }), _jsx("p", { "data-slot": "kpi-card-change", className: "col-span-2 mt-1 line-clamp-2 min-h-10 min-w-0 text-sm text-muted-foreground", title: footerLine || undefined, children: footerLine })] }) }));
35
+ return (_jsx(Card, { size: "sm", "data-slot": "kpi-card", "data-tone": tone, render: render, variant: render ? "link" : "default", children: _jsxs(CardHeader, { className: "gap-y-1", children: [_jsxs(CardDescription, { className: "col-span-2 flex min-w-0 items-center gap-0.5", children: [_jsx("span", { className: "truncate", title: label, children: label }), render ? _jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 shrink-0" }) : null] }), delta ? (_jsx(CardAction, { "data-kpi-delta": delta.direction, className: "row-span-1 row-start-2 self-center", children: badge })) : null, _jsx(CardTitle, { className: cn("col-start-1 row-start-2 min-w-0 truncate text-heading-md tabular-nums group-data-[size=sm]/card:text-heading-md", VALUE_TONE_CLASS[tone]), "data-kpi-value": "", children: value }), _jsx("div", { "data-slot": "kpi-card-sparkline", className: "col-span-2 mt-1 h-8 min-w-0", children: sparkline.length > 1 ? (_jsx(ChartSparkline, { data: sparkline, className: "h-8 w-full" })) : null }), _jsx("p", { "data-slot": "kpi-card-change", className: "col-span-2 mt-1 line-clamp-2 min-h-10 min-w-0 text-sm text-muted-foreground", title: footerLine || undefined, children: footerLine })] }) }));
36
36
  }
37
- return (_jsxs(Card, { size: "sm", "data-slot": "kpi-card", "data-tone": tone, render: render, variant: render ? "link" : "default", children: [_jsxs(CardHeader, { children: [_jsxs(CardDescription, { className: "flex min-h-10 items-start gap-0.5", children: [_jsx("span", { className: "line-clamp-2", children: label }), render ? _jsx(ChevronRight, { "aria-hidden": "true", className: "mt-0.5 size-4 shrink-0" }) : null] }), _jsx(CardTitle, { className: cn("text-heading-md tabular-nums group-data-[size=sm]/card:text-heading-md", VALUE_TONE_CLASS[tone]), children: value }), delta ? _jsx(CardAction, { "data-kpi-delta": delta.direction, children: badge }) : null] }), delta || note ? (_jsx(CardFooter, { className: "flex-nowrap", children: _jsx("span", { className: "min-w-0 truncate", title: footerLine, children: footerLine }) })) : null] }));
37
+ return (_jsxs(Card, { size: "sm", "data-slot": "kpi-card", "data-tone": tone, render: render, variant: render ? "link" : "default", children: [_jsxs(CardHeader, { children: [_jsxs(CardDescription, { className: "flex min-h-10 items-start gap-0.5", children: [_jsx("span", { className: "line-clamp-2", children: label }), render ? _jsx(ChevronRight, { "aria-hidden": "true", className: "mt-0.5 size-4 shrink-0" }) : null] }), _jsx(CardTitle, { className: cn("text-heading-md tabular-nums group-data-[size=sm]/card:text-heading-md", VALUE_TONE_CLASS[tone]), "data-kpi-value": "", children: value }), delta ? _jsx(CardAction, { "data-kpi-delta": delta.direction, children: badge }) : null] }), delta || note ? (_jsx(CardFooter, { className: "flex-nowrap", children: _jsx("span", { className: "min-w-0 truncate", title: footerLine, children: footerLine }) })) : null] }));
38
38
  }
39
39
  export { KpiCard };
@@ -87,7 +87,7 @@ function MultiSelect({ selectedCount, totalCount, onSelectAll, selectOnlyLabel,
87
87
  }
88
88
  function MultiSelectTrigger({ className, children, size = "default", label, error, ...props }) {
89
89
  const summaryId = React.useId();
90
- return (_jsx(FieldFrame, { label: label, error: error, size: size, control: props, children: (aria) => (_jsxs(PopoverTrigger, { "data-slot": "multi-select-trigger", "data-size": size, "data-field-frame": "", className: cn(selectTriggerVariants({ size }), fieldTriggerStates, "group/multi-select-trigger pr-3.25 pl-2.5", size !== "lg" && "leading-5.25", className), ...props, ...aria, "aria-describedby": [aria["aria-describedby"], summaryId].filter(Boolean).join(" "), children: [_jsx("span", { id: summaryId, className: "flex-1 truncate px-1.5 text-left", children: children }), _jsx(ChevronDownIcon, { "aria-hidden": "true", className: "size-3.5 text-muted-foreground group-data-popup-open/multi-select-trigger:hidden" }), _jsx(ChevronUpIcon, { "aria-hidden": "true", className: "hidden size-3.5 text-muted-foreground group-data-popup-open/multi-select-trigger:block" })] })) }));
90
+ return (_jsx(FieldFrame, { label: label, error: error, size: size, control: props, children: (aria) => (_jsxs(PopoverTrigger, { "data-slot": "multi-select-trigger", "data-size": size, "data-field-frame": "", className: cn(selectTriggerVariants({ size }), fieldTriggerStates, "group/multi-select-trigger", size !== "lg" && "leading-5.25", className), ...props, ...aria, "aria-describedby": [aria["aria-describedby"], summaryId].filter(Boolean).join(" "), children: [_jsx("span", { id: summaryId, className: "flex-1 truncate text-left", children: children }), _jsx(ChevronDownIcon, { "aria-hidden": "true", className: "size-3.5 text-muted-foreground group-data-popup-open/multi-select-trigger:hidden" }), _jsx(ChevronUpIcon, { "aria-hidden": "true", className: "hidden size-3.5 text-muted-foreground group-data-popup-open/multi-select-trigger:block" })] })) }));
91
91
  }
92
92
  const ROW = "[data-slot=multi-select-row]";
93
93
  function moveFocus(event) {
@@ -1,6 +1,6 @@
1
1
  import type { ComponentProps, ReactElement, ReactNode } from "react";
2
2
  import { type IdentityMarkProps } from "./identity-mark.js";
3
- import { type PageActionsProps } from "./page-actions.js";
3
+ import { type CardActions } from "./page-actions.js";
4
4
  type ObjectPageFact = {
5
5
  label: string;
6
6
  value: ReactNode;
@@ -35,10 +35,10 @@ export type ObjectPageProps = {
35
35
  headingProps?: Omit<ComponentProps<"h1">, "children">;
36
36
  /** One line saying what it is: "Customer of Partner Alpha · since 3 August 2026". */
37
37
  description?: ReactNode;
38
- /** Key facts as labelled values in one row; an object always has at least one. */
39
- facts: readonly [ObjectPageFact, ...ObjectPageFact[]];
38
+ /** Key facts as labelled values in one row. Left out only while the object does not exist yet, such as an account with no plan. */
39
+ facts?: readonly [ObjectPageFact, ...ObjectPageFact[]];
40
40
  /** The object's commands on its header bar: a secondary, the primary, then the three dots. */
41
- actions?: Omit<PageActionsProps, "period">;
41
+ actions?: CardActions;
42
42
  /** Rows that open under the facts, each one part of the object: settings, logs, checks. */
43
43
  entries?: readonly ObjectPageEntry[];
44
44
  /** The footer: a hint and one link elsewhere. Left out when the object has no such line. */
@@ -53,9 +53,9 @@ export type ObjectPageProps = {
53
53
  * @family Compositions
54
54
  * @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
55
55
  * @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent's Edit page in Nadia's window opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
56
- * @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts in four columns once they have 36rem and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
56
+ * @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), the mark at 64 stands beside the name and optional line in the header, for every kind of object, with no preview box, since a product object has no picture of itself as a deployment has its screenshot; full-width facts follow in four columns once they have 36rem and two below (an object that exists always has one; an object not made yet, such as an account's plan before it chooses one, has none, and its card is the header alone, its name saying so and, for a viewer who may, its primary making it), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
57
57
  * @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
58
- * @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is an h2 heading holding a button with `aria-expanded` that controls its panel.
58
+ * @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the name. Each entry is an h2 heading holding a button with `aria-expanded` that controls its panel.
59
59
  */
60
60
  export declare function ObjectPage({ mark, name, headingProps, description, facts, actions, entries, footer, children, }: ObjectPageProps): ReactElement;
61
61
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAqC,MAAM,gBAAgB,CAAC;AAE1F,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;IACtD,qFAAqF;IACrF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACtD,8FAA8F;IAC9F,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC3C,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+HAA+H;IAC/H,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,CAwGhC"}
1
+ {"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,WAAW,EAAqC,MAAM,gBAAgB,CAAC;AAErF,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;IACtD,qFAAqF;IACrF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,mIAAmI;IACnI,KAAK,CAAC,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACvD,8FAA8F;IAC9F,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+HAA+H;IAC/H,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,CA0FhC"}
@@ -4,7 +4,7 @@ import { cn } from "../lib/utils.js";
4
4
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion.js";
5
5
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./card.js";
6
6
  import { IdentityMark } from "./identity-mark.js";
7
- import { PageActionsRow, PageCommandButton } from "./page-actions.js";
7
+ import { CardActionsRow, PageCommandButton } from "./page-actions.js";
8
8
  /**
9
9
  * One object's page: the object card with its name, commands, facts, rows that open and one link
10
10
  * elsewhere, then its sections as cards.
@@ -12,14 +12,13 @@ import { PageActionsRow, PageCommandButton } from "./page-actions.js";
12
12
  * @family Compositions
13
13
  * @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
14
14
  * @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent's Edit page in Nadia's window opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
15
- * @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts in four columns once they have 36rem and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
15
+ * @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), the mark at 64 stands beside the name and optional line in the header, for every kind of object, with no preview box, since a product object has no picture of itself as a deployment has its screenshot; full-width facts follow in four columns once they have 36rem and two below (an object that exists always has one; an object not made yet, such as an account's plan before it chooses one, has none, and its card is the header alone, its name saying so and, for a viewer who may, its primary making it), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
16
16
  * @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
17
- * @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is an h2 heading holding a button with `aria-expanded` that controls its panel.
17
+ * @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the name. Each entry is an h2 heading holding a button with `aria-expanded` that controls its panel.
18
18
  */
19
19
  export function ObjectPage({ mark, name, headingProps, description, facts, actions, entries, footer, children, }) {
20
- const company = mark.kind === "company";
21
20
  const title = headingProps ? (_jsx("h1", { ...headingProps, className: cn("outline-none", headingProps.className), children: name })) : (name);
22
- return (_jsxs("div", { className: "grid min-w-0 gap-6", "data-slot": "object-page", children: [_jsxs("div", { className: "grid min-w-0 gap-3", children: [_jsxs(Card, { className: "min-w-0", render: _jsx("div", { "data-slot": "object-card" }), size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b", children: [company ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 items-center gap-4", actions?.menu && !actions.secondary && !actions.primary ? "basis-0" : "basis-64"), children: [_jsx(IdentityMark, { ...mark, size: 64 }), _jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx(CardTitle, { className: "min-w-0 wrap-break-word group-data-[size=sm]/card:text-heading-sm", children: title }), description ? _jsx(CardDescription, { children: description }) : null] })] })) : (_jsx(CardTitle, { className: "min-w-0 flex-1 basis-32 wrap-break-word", children: title })), actions ? _jsx(PageActionsRow, { ...actions }) : null] }), _jsxs(CardContent, { className: cn("grid min-w-0 gap-x-6 gap-y-5", !company && "md:grid-cols-[minmax(0,18.75rem)_minmax(0,1fr)]"), children: [!company ? (_jsx("div", { className: "flex h-32 min-w-0 items-center md:h-auto md:aspect-16/10 justify-center rounded-sm border border-border bg-muted", "data-slot": "object-page-tile", children: _jsx(IdentityMark, { ...mark, size: 64 }) })) : null, _jsxs("div", { className: "@container/object-page-facts grid min-w-0 content-start gap-4", children: [!company && description ? (_jsx("div", { className: "min-w-0 text-body-sm text-muted-foreground", children: description })) : null, _jsx("dl", { className: "grid min-w-0 grid-cols-2 gap-x-6 gap-y-4 @xl/object-page-facts:grid-cols-4", "data-slot": "object-page-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 content-start gap-1", children: [_jsx("dt", { className: "text-label-sm text-muted-foreground", children: fact.label }), _jsx("dd", { className: "min-w-0 text-body-sm wrap-break-word text-foreground", children: fact.value })] }, fact.label))) })] })] }), footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-page-hint", children: _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) })) : null] }), entries && entries.length > 0 ? (_jsx(Card, { className: "min-w-0 py-0", render: _jsx("div", { "data-slot": "object-page-entries" }), size: "sm", children: _jsx(Accordion, { className: "*:last:border-b-0", defaultValue: entries
21
+ return (_jsxs("div", { className: "grid min-w-0 gap-6", "data-slot": "object-page", children: [_jsxs("div", { className: "grid min-w-0 gap-3", children: [_jsxs(Card, { className: "min-w-0", render: _jsx("div", { "data-slot": "object-card" }), size: "sm", children: [_jsxs(CardHeader, { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-3", facts && "border-b"), children: [_jsxs("div", { className: cn("flex min-w-0 flex-1 items-center gap-4", actions?.menu && !actions.secondary && !actions.primary ? "basis-0" : "basis-64"), children: [_jsx(IdentityMark, { ...mark, size: 64 }), _jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx(CardTitle, { className: "min-w-0 wrap-break-word group-data-[size=sm]/card:text-heading-sm", children: title }), description ? _jsx(CardDescription, { children: description }) : null] })] }), actions ? _jsx(CardActionsRow, { ...actions }) : null] }), facts ? (_jsx(CardContent, { className: "grid min-w-0 gap-x-6 gap-y-5", children: _jsx("div", { className: "@container/object-page-facts grid min-w-0 content-start gap-4", children: _jsx("dl", { className: "grid min-w-0 grid-cols-2 gap-x-6 gap-y-4 @xl/object-page-facts:grid-cols-4", "data-slot": "object-page-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 content-start gap-1", children: [_jsx("dt", { className: "text-label-sm text-muted-foreground", children: fact.label }), _jsx("dd", { className: "min-w-0 text-body-sm wrap-break-word text-foreground", children: fact.value })] }, fact.label))) }) }) })) : null, footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-page-hint", children: _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) })) : null] }), entries && entries.length > 0 ? (_jsx(Card, { className: "min-w-0 py-0", render: _jsx("div", { "data-slot": "object-page-entries" }), size: "sm", children: _jsx(Accordion, { className: "*:last:border-b-0", defaultValue: entries
23
22
  .filter((entry) => entry.defaultOpen)
24
23
  .map((entry) => entry.title), multiple: true, size: "small", children: entries.map((entry) => (_jsxs(AccordionItem, { value: entry.title, children: [_jsxs(AccordionTrigger, { className: "justify-start gap-3 px-(--card-spacing) group-data-[size=small]/accordion:text-body-sm focus-visible:-outline-offset-2 *:data-[slot=accordion-trigger-icon]:order-first *:data-[slot=accordion-trigger-icon]:text-muted-foreground", level: 2, children: [_jsx("span", { className: "min-w-0 flex-1", children: entry.title }), entry.summary] }), _jsx(AccordionContent, { className: "ps-[calc(var(--card-spacing)+1.75rem)] pe-(--card-spacing)", children: entry.children })] }, entry.title))) }) })) : null] }), children] }));
25
24
  }
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
- import { type PageCommand } from "./page-actions.js";
2
+ import { type CardActions, type PageCommand } from "./page-actions.js";
3
3
  type ObjectFactShape = {
4
4
  label: string;
5
5
  value: ReactNode;
@@ -20,24 +20,32 @@ export type ObjectFact = ObjectFactShape & ({
20
20
  /** A value that ends in an ellipsis on one line instead of wrapping; a string value is also whole in its title. Not available on a `block` fact. */
21
21
  ellipsis?: boolean;
22
22
  });
23
+ /** A card's footer: one muted sentence at its start and the card's one command at its end. */
24
+ export type CardFooterLine = {
25
+ hint: string;
26
+ command?: PageCommand;
27
+ } | {
28
+ hint?: string;
29
+ command: PageCommand;
30
+ };
23
31
  /**
24
32
  * A section of an object's page: a card that owns one decision about the object.
25
33
  *
26
34
  * @family Compositions
27
- * @when A part of an ObjectPage a person reads or changes on its own: a customer's Company details, an Agent's Instructions, a Library entry's source.
35
+ * @when A part of an ObjectPage a person reads or changes on its own: a customer's Company details, an Agent's Instructions, a Library entry's source, a Partner's services in Billing.
28
36
  * @instead Values a person edits and saves together are a SettingsSection; a list of the object's records is a RecordList with its heading; a passing condition is a MessageNotice.
29
- * @behaviour A resting card: its title and the one-sentence description directly under it, both always given, at the trailing edge `meta` (muted) then `action` as an outline button, then its body. No icon in the header. Neutral throughout. A section that edits in place swaps to the same section as a `SettingsSection`, with Cancel (`save.cancel`) before Save.
30
- * @words The title names what the section holds ("Company", "Instructions"); the description says in one sentence what it holds or lets a person change; the action is a verb on it ("Edit"); `meta` is a short count or time ("2 of 5 Agents").
37
+ * @behaviour As Vercel's Spend Management, Payment Method and AI Gateway Credit cards on its Billing page: a resting card, its title and the one-sentence description directly under it, both always given; at the header's trailing edge `actions`, drawn as every card's header draws them (`CardActions`: the muted `meta`, then up to two secondaries as outline buttons, the primary as the filled one, then the three dots), so a way to another page is a secondary with its `link`, an outline button named for the page, never a text link; then its body; then the optional `footer`, a strip under a divider with its sentence at the start and its one command at the end as an outline button. No icon in the header. Neutral throughout. A section that edits in place swaps to the same section as a `SettingsSection`, with Cancel (`save.cancel`) before Save.
38
+ * @words The title names what the section holds ("Company", "Instructions"); the description says in one sentence what it holds or lets a person change; a command is a verb on it ("Edit"), and a way to another page is that page's name ("Statements"); `meta` is a short count or time ("2 of 5 Agents"); the footer's sentence is a limit or where the section's object changes ("At most three cards.").
31
39
  * @access The title is a heading one level under the page (h2), deeper only under another heading through `headingLevel`.
32
40
  */
33
- export declare function ObjectSection({ title, description, action, meta, children, headingLevel, }: {
41
+ export declare function ObjectSection({ title, description, actions, footer, children, headingLevel, }: {
34
42
  title: string;
35
43
  /** The one sentence under the title that says what the section holds or changes. */
36
44
  description: NonNullable<ReactNode>;
37
- /** The section's one command, an outline button in its header. */
38
- action?: PageCommand;
39
- /** A muted note at the header's trailing edge, before the action: "2 of 5 Agents". */
40
- meta?: ReactNode;
45
+ /** The section's commands at its header's trailing edge, a way to another page among them. */
46
+ actions?: CardActions;
47
+ /** The strip under the body: a limit or where the object changes, and the one command after it. */
48
+ footer?: CardFooterLine;
41
49
  children: ReactNode;
42
50
  /** A card titles a section of its page; nest it deeper only under another heading. */
43
51
  headingLevel?: 2 | 3 | 4;
@@ -1 +1 @@
1
- {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAI9C,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AAGrE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,eAAe,GACtC,CACI;IACE;;;OAGG;IACH,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,GACD;IACE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oJAAoJ;IACpJ,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CACJ,CAAC;AAEJ;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,YAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,kEAAkE;IAClE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,sFAAsF;IACtF,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1B,+BAsBA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BAuDA"}
1
+ {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAK9C,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AAGxB,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,eAAe,GACtC,CACI;IACE;;;OAGG;IACH,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,KAAK,CAAC;CAClB,GACD;IACE,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oJAAoJ;IACpJ,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CACJ,CAAC;AAEJ,8FAA8F;AAC9F,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAE,GACvC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5C;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,QAAQ,EACR,YAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,8FAA8F;IAC9F,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,mGAAmG;IACnG,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1B,+BAsBA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BAuDA"}
@@ -2,21 +2,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Info } from "lucide-react";
3
3
  import { useId } from "react";
4
4
  import { cn } from "../lib/utils.js";
5
+ import { FooterStrip } from "../internal/footer-strip.js";
5
6
  import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "./card.js";
6
- import { PageCommandButton } from "./page-actions.js";
7
+ import { CardActionsRow, PageCommandButton, } from "./page-actions.js";
7
8
  import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
8
9
  /**
9
10
  * A section of an object's page: a card that owns one decision about the object.
10
11
  *
11
12
  * @family Compositions
12
- * @when A part of an ObjectPage a person reads or changes on its own: a customer's Company details, an Agent's Instructions, a Library entry's source.
13
+ * @when A part of an ObjectPage a person reads or changes on its own: a customer's Company details, an Agent's Instructions, a Library entry's source, a Partner's services in Billing.
13
14
  * @instead Values a person edits and saves together are a SettingsSection; a list of the object's records is a RecordList with its heading; a passing condition is a MessageNotice.
14
- * @behaviour A resting card: its title and the one-sentence description directly under it, both always given, at the trailing edge `meta` (muted) then `action` as an outline button, then its body. No icon in the header. Neutral throughout. A section that edits in place swaps to the same section as a `SettingsSection`, with Cancel (`save.cancel`) before Save.
15
- * @words The title names what the section holds ("Company", "Instructions"); the description says in one sentence what it holds or lets a person change; the action is a verb on it ("Edit"); `meta` is a short count or time ("2 of 5 Agents").
15
+ * @behaviour As Vercel's Spend Management, Payment Method and AI Gateway Credit cards on its Billing page: a resting card, its title and the one-sentence description directly under it, both always given; at the header's trailing edge `actions`, drawn as every card's header draws them (`CardActions`: the muted `meta`, then up to two secondaries as outline buttons, the primary as the filled one, then the three dots), so a way to another page is a secondary with its `link`, an outline button named for the page, never a text link; then its body; then the optional `footer`, a strip under a divider with its sentence at the start and its one command at the end as an outline button. No icon in the header. Neutral throughout. A section that edits in place swaps to the same section as a `SettingsSection`, with Cancel (`save.cancel`) before Save.
16
+ * @words The title names what the section holds ("Company", "Instructions"); the description says in one sentence what it holds or lets a person change; a command is a verb on it ("Edit"), and a way to another page is that page's name ("Statements"); `meta` is a short count or time ("2 of 5 Agents"); the footer's sentence is a limit or where the section's object changes ("At most three cards.").
16
17
  * @access The title is a heading one level under the page (h2), deeper only under another heading through `headingLevel`.
17
18
  */
18
- export function ObjectSection({ title, description, action, meta, children, headingLevel = 2, }) {
19
- return (_jsxs(Card, { "data-slot": "object-section", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { role: "heading", "aria-level": headingLevel, children: title }), _jsx(CardDescription, { children: description }), action || meta ? (_jsxs(CardAction, { className: "flex items-center gap-3", children: [meta ? (_jsx("span", { className: "text-label-sm text-muted-foreground", "data-slot": "object-section-meta", children: meta })) : null, action ? _jsx(PageCommandButton, { command: action, variant: "outline" }) : null] })) : null] }), _jsx(CardContent, { children: children })] }));
19
+ export function ObjectSection({ title, description, actions, footer, children, headingLevel = 2, }) {
20
+ return (_jsxs(Card, { "data-slot": "object-section", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { role: "heading", "aria-level": headingLevel, children: title }), _jsx(CardDescription, { children: description }), actions ? (_jsx(CardAction, { children: _jsx(CardActionsRow, { ...actions }) })) : null] }), _jsx(CardContent, { children: children }), footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-section-hint", children: footer.command ? _jsx(PageCommandButton, { command: footer.command, variant: "outline" }) : null })) : null] }));
20
21
  }
21
22
  /**
22
23
  * An object's facts as labelled values in a grid, inside one of its sections.
@@ -5,6 +5,11 @@ export type OverviewPageProps = {
5
5
  period?: ReactElement;
6
6
  /** The figures, one row of equal cards, one column below md. */
7
7
  figures?: readonly Omit<KpiCardProps, "presentation">[];
8
+ /**
9
+ * When nothing has happened yet: one line drawn in place of the figures and charts, such as "No
10
+ * commission yet this month." Given only when every figure would read zero.
11
+ */
12
+ nothingYet?: string;
8
13
  /** The chart cards, each with its one header, in reading order. */
9
14
  charts?: ReactNode;
10
15
  /** The exceptions that need a person, each opening its owner: a RecordList with its heading. */
@@ -16,9 +21,9 @@ export type OverviewPageProps = {
16
21
  * @family Compositions
17
22
  * @when "For in-product cards and dashboard tiles, use `Card`; Book is too decorative for repeated UI rows." (https://vercel.com/geist/book) Ours: the landing page of an area a person checks: the Portal's Dashboard, Analytics, Statements, System health, an Agent's Usage.
18
23
  * @instead A list of records a person finds one of is a `CollectionPage`; one record is an `ObjectPage`. Never a stack of previews of every section: each exception links to its owner instead.
19
- * @behaviour "Show a Skeleton when async data fills a known layout: table rows, card grids, profile blocks, sidebars." (https://vercel.com/geist/skeleton) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the reading period on the title row, then the figures in one row of equal `KpiCard`s (as many columns as figures up to five, five reading two by two from md, three over two from lg and one row from xl at 1280 px; six as three over three, more in rows of four; one column below md), then the chart cards, then the exceptions. Cards stand 24 px apart with no heading between them (the figures 16 px apart in their row), and the title row has no title: the path names the page. Its cards are dashboard cards: a figure or a chart that reads, drills into its owner and holds no setting; neither an object card nor a setting card appears here. Colour sits in a figure's change and tone, never in the page. It has no states of its own: each card and the exceptions' `RecordList` draw theirs.
24
+ * @behaviour "Show a Skeleton when async data fills a known layout: table rows, card grids, profile blocks, sidebars." (https://vercel.com/geist/skeleton) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the reading period on the title row, then the figures in one row of equal `KpiCard`s (as many columns as figures up to five, five reading two by two from md, three over two from lg and one row from xl at 1280 px; six as three over three, more in rows of four; one column below md), then the chart cards, then the exceptions. Cards stand 24 px apart with no heading between them (the figures 16 px apart in their row), and the title row has no title: the path names the page. Its cards are dashboard cards: a figure or a chart that reads, drills into its owner and holds no setting; neither an object card nor a setting card appears here. Colour sits in a figure's change and tone, never in the page. It has no states of its own but one: when nothing has happened yet, `nothingYet` is one muted line in place of the figures and charts, never a row of figures that all read zero; each card and the exceptions' `RecordList` draw theirs.
20
25
  * @words The product words every figure, chart and exception. A figure's label names its measure ("Active Agents", "Spend"), the chart's title names its reading ("Usage"), and the exceptions' heading says what they are ("Needs attention").
21
26
  * @access Each chart card is a named section at the page's heading level, and the exceptions carry their own heading; figures are text, never colour alone.
22
27
  */
23
- export declare function OverviewPage({ period, figures, charts, exceptions, }: OverviewPageProps): import("react").JSX.Element;
28
+ export declare function OverviewPage({ period, figures, nothingYet, charts, exceptions, }: OverviewPageProps): import("react").JSX.Element;
24
29
  //# sourceMappingURL=overview-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overview-page.d.ts","sourceRoot":"","sources":["../../src/components/overview-page.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrD,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGnE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,gEAAgE;IAChE,OAAO,CAAC,EAAE,SAAS,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,CAAC;IACxD,mEAAmE;IACnE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,gGAAgG;IAChG,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB,CAAC;AAWF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAoB,EACpB,MAAM,EACN,UAAU,GACX,EAAE,iBAAiB,+BAenB"}
1
+ {"version":3,"file":"overview-page.d.ts","sourceRoot":"","sources":["../../src/components/overview-page.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrD,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGnE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,gEAAgE;IAChE,OAAO,CAAC,EAAE,SAAS,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,CAAC;IACxD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,gGAAgG;IAChG,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB,CAAC;AAWF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAoB,EACpB,UAAU,EACV,MAAM,EACN,UAAU,GACX,EAAE,iBAAiB,+BAuBnB"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { CardRow } from "./card-row.js";
4
4
  import { KpiCard } from "./kpi-card.js";
5
5
  import { PageActions } from "./page-actions.js";
@@ -19,10 +19,10 @@ const NO_FIGURES = [];
19
19
  * @family Compositions
20
20
  * @when "For in-product cards and dashboard tiles, use `Card`; Book is too decorative for repeated UI rows." (https://vercel.com/geist/book) Ours: the landing page of an area a person checks: the Portal's Dashboard, Analytics, Statements, System health, an Agent's Usage.
21
21
  * @instead A list of records a person finds one of is a `CollectionPage`; one record is an `ObjectPage`. Never a stack of previews of every section: each exception links to its owner instead.
22
- * @behaviour "Show a Skeleton when async data fills a known layout: table rows, card grids, profile blocks, sidebars." (https://vercel.com/geist/skeleton) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the reading period on the title row, then the figures in one row of equal `KpiCard`s (as many columns as figures up to five, five reading two by two from md, three over two from lg and one row from xl at 1280 px; six as three over three, more in rows of four; one column below md), then the chart cards, then the exceptions. Cards stand 24 px apart with no heading between them (the figures 16 px apart in their row), and the title row has no title: the path names the page. Its cards are dashboard cards: a figure or a chart that reads, drills into its owner and holds no setting; neither an object card nor a setting card appears here. Colour sits in a figure's change and tone, never in the page. It has no states of its own: each card and the exceptions' `RecordList` draw theirs.
22
+ * @behaviour "Show a Skeleton when async data fills a known layout: table rows, card grids, profile blocks, sidebars." (https://vercel.com/geist/skeleton) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the reading period on the title row, then the figures in one row of equal `KpiCard`s (as many columns as figures up to five, five reading two by two from md, three over two from lg and one row from xl at 1280 px; six as three over three, more in rows of four; one column below md), then the chart cards, then the exceptions. Cards stand 24 px apart with no heading between them (the figures 16 px apart in their row), and the title row has no title: the path names the page. Its cards are dashboard cards: a figure or a chart that reads, drills into its owner and holds no setting; neither an object card nor a setting card appears here. Colour sits in a figure's change and tone, never in the page. It has no states of its own but one: when nothing has happened yet, `nothingYet` is one muted line in place of the figures and charts, never a row of figures that all read zero; each card and the exceptions' `RecordList` draw theirs.
23
23
  * @words The product words every figure, chart and exception. A figure's label names its measure ("Active Agents", "Spend"), the chart's title names its reading ("Usage"), and the exceptions' heading says what they are ("Needs attention").
24
24
  * @access Each chart card is a named section at the page's heading level, and the exceptions carry their own heading; figures are text, never colour alone.
25
25
  */
26
- export function OverviewPage({ period, figures = NO_FIGURES, charts, exceptions, }) {
27
- return (_jsxs("div", { "data-slot": "overview-page", className: "grid min-w-0 gap-6", children: [_jsx(PageActions, { period: period }), figures.length > 0 ? (_jsx(CardRow, { columns: figureColumns(figures.length), from: "md", children: figures.map((figure) => (_jsx(KpiCard, { ...figure }, figure.label))) })) : null, charts, exceptions] }));
26
+ export function OverviewPage({ period, figures = NO_FIGURES, nothingYet, charts, exceptions, }) {
27
+ return (_jsxs("div", { "data-slot": "overview-page", className: "grid min-w-0 gap-6", children: [_jsx(PageActions, { period: period }), nothingYet ? (_jsx("p", { className: "text-muted-foreground nc-type-body-sm", "data-slot": "overview-nothing-yet", children: nothingYet })) : (_jsxs(_Fragment, { children: [figures.length > 0 ? (_jsx(CardRow, { columns: figureColumns(figures.length), from: "md", children: figures.map((figure) => (_jsx(KpiCard, { ...figure }, figure.label))) })) : null, charts] })), exceptions] }));
28
28
  }
@@ -67,6 +67,28 @@ export type PageActionsProps = {
67
67
  primary?: PagePrimaryCommand | undefined;
68
68
  menu?: PageMenu | undefined;
69
69
  };
70
+ /**
71
+ * The trailing edge of every card's header: a short muted text, then the card's reading period and
72
+ * commands in `PageActions`' order, with up to two secondaries, as Vercel's deployment card draws
73
+ * "Share" and "Logs" before "Visit". A way to another page is a secondary with its `link`, drawn as
74
+ * a button like the others, as Vercel's plan card draws "Invoices" and "Usage".
75
+ */
76
+ export type CardActions = Omit<PageActionsProps, "secondary"> & {
77
+ /** A period or a count before the commands: "26 Oct – 26 Nov", "2 of 5 Agents". */
78
+ meta?: string | undefined;
79
+ secondary?: PageCommand | readonly [PageCommand, PageCommand] | undefined;
80
+ };
81
+ /**
82
+ * The end of a card's header: what the card's reader can do from it, and where it leads.
83
+ *
84
+ * @family Actions
85
+ * @when The header of every card composition draws it from the card's `actions`: ObjectPage, ObjectSection, SettingsSection, SettingsFactsSection and TableCard. A page gives the card its `actions` and never renders this row.
86
+ * @instead A page's own commands are `PageActions` on the title's row. A row's commands are its one or two buttons and its `ActionMenu`. A setting card whose value stands at its header's end, such as an avatar upload, gives `SettingsSection` its `control`. A link inside the card's description or footer line is a `TextLink` in that sentence.
87
+ * @behaviour As Vercel's card headers draw it (the plan card's "Invoices" and "Usage", a deployment's "Share" and "Logs" before "Visit", the overview's Usage card's "Billing"): the muted `meta` (a period or a count), the reading `period`, up to two secondaries as outline buttons, the primary as the filled button, and the three dots last. A way to another page is a secondary with its `link`, drawn as a button like the others and named for the page; it is never a text link in the header's corner. A page has one filled button, so a card on a page whose primary stands elsewhere takes outline buttons only. It wraps under the title when the header is narrow, as the card's header places it.
88
+ * @words A command is a verb on the card's object ("Add card", "Buy Extra usage for Customers"); a way to another page is that page's name as its navigation writes it ("Statements"); `meta` is a short count or period ("2 of 5 Agents").
89
+ * @access DOM order is visual order. A command whose label does not name its target carries `accessibleName`. A way to another page is a real link.
90
+ */
91
+ export declare function CardActionsRow({ meta, period, secondary, primary, menu }: CardActions): import("react").JSX.Element | null;
70
92
  type CommandVariant = "default" | "outline" | "ghost" | "link";
71
93
  export declare function PageCommandButton({ command, shape, size, variant, }: {
72
94
  command: PagePrimaryCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"page-actions.d.ts","sourceRoot":"","sources":["../../src/components/page-actions.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-actions.d.ts","sourceRoot":"","sources":["../../src/components/page-actions.tsx"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAMf,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAGpE,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE;AACrF;;;GAGG;GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE;AACzD;;;GAGG;GACD;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE5D,uGAAuG;AACvG,MAAM,MAAM,WAAW,GACnB;IACE,kGAAkG;IAClG,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB,GACD;IAAE,OAAO,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEvE,KAAK,eAAe,GAAG,WAAW,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAChC,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,4GAA4G;AAC5G,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAE9D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG;IACjD,OAAO,EAAE,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;IAC/D,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,kBAAkB,CAAC;AAElE,uEAAuE;AACvE,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG;IACpD,QAAQ,EAAE,SAAS,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC;CACjE,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qGAAqG;IACrG,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,GAAG;IAC9D,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC;CAC3E,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,WAAW,sCAkBrF;AAED,KAAK,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/D,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EACL,IAAI,EACJ,OAAO,GACR,EAAE;IACD,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,cAAc,CAAC;CACzB,+BA8CA;AAED,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,gBAAgB,sCAUpF;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAG5E;AAED,yFAAyF;AACzF,wBAAgB,eAAe,gCAS9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,sCA6BlD"}
@@ -8,6 +8,22 @@ import { MenuCommandRow } from "../internal/record-menu-items.js";
8
8
  import { ActionMenu } from "./action-menu.js";
9
9
  import { Button, ButtonLink } from "./button.js";
10
10
  import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "./dropdown-menu.js";
11
+ /**
12
+ * The end of a card's header: what the card's reader can do from it, and where it leads.
13
+ *
14
+ * @family Actions
15
+ * @when The header of every card composition draws it from the card's `actions`: ObjectPage, ObjectSection, SettingsSection, SettingsFactsSection and TableCard. A page gives the card its `actions` and never renders this row.
16
+ * @instead A page's own commands are `PageActions` on the title's row. A row's commands are its one or two buttons and its `ActionMenu`. A setting card whose value stands at its header's end, such as an avatar upload, gives `SettingsSection` its `control`. A link inside the card's description or footer line is a `TextLink` in that sentence.
17
+ * @behaviour As Vercel's card headers draw it (the plan card's "Invoices" and "Usage", a deployment's "Share" and "Logs" before "Visit", the overview's Usage card's "Billing"): the muted `meta` (a period or a count), the reading `period`, up to two secondaries as outline buttons, the primary as the filled button, and the three dots last. A way to another page is a secondary with its `link`, drawn as a button like the others and named for the page; it is never a text link in the header's corner. A page has one filled button, so a card on a page whose primary stands elsewhere takes outline buttons only. It wraps under the title when the header is narrow, as the card's header places it.
18
+ * @words A command is a verb on the card's object ("Add card", "Buy Extra usage for Customers"); a way to another page is that page's name as its navigation writes it ("Statements"); `meta` is a short count or period ("2 of 5 Agents").
19
+ * @access DOM order is visual order. A command whose label does not name its target carries `accessibleName`. A way to another page is a real link.
20
+ */
21
+ export function CardActionsRow({ meta, period, secondary, primary, menu }) {
22
+ const secondaries = secondary === undefined ? [] : "label" in secondary ? [secondary] : secondary;
23
+ if (!meta && !period && secondaries.length === 0 && !primary && !menu)
24
+ return null;
25
+ return (_jsxs("div", { "data-slot": "card-actions", className: "flex max-w-full min-w-0 flex-wrap items-center gap-2", children: [meta ? (_jsx("span", { className: "mr-1 text-label-sm text-muted-foreground", "data-slot": "card-actions-meta", children: meta })) : null, period, secondaries.map((command) => (_jsx(PageCommandButton, { command: command, variant: "outline" }, command.label))), primary ? _jsx(PageCommandButton, { command: primary, variant: "default" }) : null, menu ? _jsx(ActionMenu, { ...menu }) : null] }));
26
+ }
11
27
  export function PageCommandButton({ command, shape, size, variant, }) {
12
28
  const look = {
13
29
  "aria-label": command.accessibleName,
@@ -54,6 +54,6 @@ function RadioGroup({ className, ...props }) {
54
54
  return (_jsx(RadioGroupPrimitive, { "data-slot": "radio-group", className: cn("grid w-full gap-6", className), ...props }));
55
55
  }
56
56
  function RadioGroupItem({ children, className, ...props }) {
57
- return (_jsx(RadioPrimitive.Root, { "data-slot": "radio-group-item", className: cn("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input nc-transition-paint after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-1/2 data-checked:border-primary data-checked:text-primary data-disabled:cursor-not-allowed data-disabled:opacity-50 data-unchecked:not-data-disabled:hover:border-muted-foreground data-unchecked:not-data-disabled:hover:bg-accent aria-invalid:border-destructive aria-invalid:aria-checked:border-primary [@media(hover:hover)_and_(pointer:fine)]:after:hidden", className), ...props, children: children ?? (_jsx(RadioPrimitive.Indicator, { "data-slot": "radio-group-indicator", keepMounted: true, className: "absolute top-1/2 left-1/2 size-2 -translate-1/2 scale-0 rounded-full bg-current nc-transition-transform data-checked:scale-100" })) }));
57
+ return (_jsx(RadioPrimitive.Root, { "data-slot": "radio-group-item", className: cn("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input nc-transition-paint after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-1/2 data-checked:border-foreground data-checked:text-foreground data-disabled:cursor-not-allowed data-disabled:opacity-50 data-unchecked:not-data-disabled:hover:border-muted-foreground data-unchecked:not-data-disabled:hover:bg-accent aria-invalid:border-destructive aria-invalid:aria-checked:border-foreground [@media(hover:hover)_and_(pointer:fine)]:after:hidden", className), ...props, children: children ?? (_jsx(RadioPrimitive.Indicator, { "data-slot": "radio-group-indicator", keepMounted: true, className: "absolute top-1/2 left-1/2 size-2 -translate-1/2 scale-0 rounded-full bg-current nc-transition-transform data-checked:scale-100" })) }));
58
58
  }
59
59
  export { RadioGroup, RadioGroupItem };
@@ -1,5 +1,5 @@
1
1
  import type { RowData } from "@tanstack/react-table";
2
- import { type ReactNode } from "react";
2
+ import { type ReactElement, type ReactNode } from "react";
3
3
  import { type MenuCommand } from "./action-menu.js";
4
4
  import { type DataTableRowLinkProps } from "./data-table.js";
5
5
  import { type EmptyStateKind } from "./empty-state.js";
@@ -153,8 +153,10 @@ export type RecordListProps<TRecord extends RowData> = {
153
153
  */
154
154
  heading?: {
155
155
  title: string;
156
+ /** The list's state right after the title: a `CheckCounts`. */
157
+ status?: ReactElement;
156
158
  description?: ReactNode;
157
- meta?: ReactNode;
159
+ meta?: string;
158
160
  };
159
161
  footer?: RecordListFooter;
160
162
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"record-list.d.ts","sourceRoot":"","sources":["../../src/components/record-list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAiB,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAEzE,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAExE,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAIjG,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAI9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,KAAK,UAAU,EAAqC,MAAM,wBAAwB,CAAC;AAG5F,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,MAAM,MAAM,UAAU,GAAG;IACvB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,0GAA0G;IAC1G,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACnC,+FAA+F;IAC/F,IAAI,EAAE,MAAM,CAAC;IACb,gHAAgH;IAChH,KAAK,CAAC,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,kGAAkG;AAClG,MAAM,MAAM,WAAW,CAAC,OAAO,IAC3B,SAAS,EAAE,GACX,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAC9B,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GACnD,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7E,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC;AAgFpE,MAAM,MAAM,gBAAgB,CAAC,OAAO,IAAI;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnE,6EAA6E;IAC7E,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IAClD,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,OAAO,IAAI;IACrC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IACtC,eAAe,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iBAAiB;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,SAAS,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;QACtC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC/B,CAAC;IACF,2IAA2I;IAC3I,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,OAAO,IAAI;IACrD,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,CAAC;IACxC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;IACnC,gHAAgH;IAChH,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,CAAC;IACtC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7B,yDAAyD;IACzD,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,YAAY,GAAG,IAAI,CAAC;QAC7C,gGAAgG;QAChG,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,IAAI,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE;QACV,0DAA0D;QAC1D,KAAK,EAAE,MAAM,CAAC;QACd,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,sBAAsB,GAAG,IAAI,CAAC;KACxD,CAAC;IACF,mEAAmE;IACnE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACvF;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAC;QACzC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;QACnC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,SAAS,CAAC;KAC1D,CAAC;IACF;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,CAAA;KAAE,CAAC;IAChE,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC;;;OAGG;IACH,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;IACxE,kDAAkD;IAClD,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;IACvE,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,WAAW,GAAG,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC;IACxF,iFAAiF;IACjF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,GAAG,IAAI,CAAC;IAC/C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,OAAO,EAAE,GAAG,SAAS,WAAW,IAAI,IAAI,CACpF,eAAe,CAAC,OAAO,CAAC,EACxB,GAAG,CACJ,CAAC;AA4VF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,UAAU,CAAC,OAAO,SAAS,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,sCAwClF"}
1
+ {"version":3,"file":"record-list.d.ts","sourceRoot":"","sources":["../../src/components/record-list.tsx"],"names":[],"mappings":"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"}
@@ -325,5 +325,5 @@ export function RecordList(props) {
325
325
  else {
326
326
  body = _jsx(RecordRows, { ...props, records: records });
327
327
  }
328
- return (_jsx(TableCard, { actions: heading?.meta ? (_jsx("span", { className: "text-body-sm text-muted-foreground", children: heading.meta })) : undefined, footer: footer?.pages && (footer.pages.onPrevious || footer.pages.onNext) ? (_jsx(Pages, { pages: footer.pages })) : undefined, footerHint: footer?.count, note: footer?.note, description: heading?.description, title: heading?.title, children: _jsx(ShownList.Provider, { value: props, children: _jsx(SkeletonRegion, { busy: loading, children: body }) }) }));
328
+ return (_jsx(TableCard, { actions: heading?.meta ? { meta: heading.meta } : undefined, footer: footer?.pages && (footer.pages.onPrevious || footer.pages.onNext) ? (_jsx(Pages, { pages: footer.pages })) : undefined, footerHint: footer?.count, note: footer?.note, description: heading?.description, status: heading?.status, title: heading?.title, children: _jsx(ShownList.Provider, { value: props, children: _jsx(SkeletonRegion, { busy: loading, children: body }) }) }));
329
329
  }