@nadicodeai/ui 12.1.145 → 12.1.147

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 (35) hide show
  1. package/AGENTS.md +3 -1
  2. package/dist/components/chart-bar-horizontal.d.ts +1 -1
  3. package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
  4. package/dist/components/chart-bar-horizontal.js +8 -6
  5. package/dist/components/collection-filters.d.ts +1 -1
  6. package/dist/components/collection-filters.d.ts.map +1 -1
  7. package/dist/components/collection-filters.js +2 -2
  8. package/dist/components/record-list.d.ts +13 -18
  9. package/dist/components/record-list.d.ts.map +1 -1
  10. package/dist/components/record-list.js +54 -39
  11. package/dist/components/scroll-area.d.ts +1 -1
  12. package/dist/components/scroll-area.js +1 -1
  13. package/dist/components/sidebar-sections.js +2 -2
  14. package/dist/components/sidebar.d.ts.map +1 -1
  15. package/dist/components/sidebar.js +2 -1
  16. package/dist/index.d.ts +0 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +0 -1
  19. package/dist/internal/settings-save.d.ts +2 -2
  20. package/dist/internal/settings-save.d.ts.map +1 -1
  21. package/dist/internal/settings-save.js +30 -8
  22. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  23. package/dist/showcase/specimens/compositions.js +6 -1
  24. package/dist/showcase/specimens/index.d.ts +0 -1
  25. package/dist/showcase/specimens/index.d.ts.map +1 -1
  26. package/dist/showcase/specimens/other.d.ts +0 -1
  27. package/dist/showcase/specimens/other.d.ts.map +1 -1
  28. package/dist/showcase/specimens/other.js +0 -2
  29. package/dist/showcase/usage.generated.d.ts +1 -1
  30. package/dist/showcase/usage.generated.d.ts.map +1 -1
  31. package/dist/showcase/usage.generated.js +5 -16
  32. package/package.json +5 -3
  33. package/dist/components/carousel.d.ts +0 -46
  34. package/dist/components/carousel.d.ts.map +0 -1
  35. package/dist/components/carousel.js +0 -109
package/AGENTS.md CHANGED
@@ -45,7 +45,9 @@ and `lint` checks. A component change a person can see goes through
45
45
  an operating system, a messaging channel or a sign-in provider is its icon in
46
46
  Iconify's `logos` set (`platform-mark.tsx`).
47
47
  - **Charts** are stock shadcn registry items; the deliberate deviations are held
48
- by `tests/guards/chart-kit.test.ts`. A chart the kit lacks is pulled from
48
+ by `tests/guards/chart-kit.test.ts`, and what only a browser lays out, such as
49
+ a category axis's labels, by the browser suite in `tests/visual/`, which
50
+ post-merge's `test (website, packages)` job runs. A chart the kit lacks is pulled from
49
51
  `https://ui.shadcn.com/r/styles/new-york-v4/<name>.json`.
50
52
  - **Releases.** No change names a version; the publish picks it after merge:
51
53
  `../../docs/agents/publish.md`.
@@ -11,7 +11,7 @@ declare function signedAxis(data: readonly Record<string, number | string>[], va
11
11
  * @instead Never encode a loss as a share. An unsigned ranking is the compact `Progress` ranking or a `DataTable`.
12
12
  * @behaviour Horizontal bars from a 1.5 px zero line: favourable values to the right in success with right corners rounded, unfavourable to the left in destructive with left corners rounded.
13
13
  * @words The money unit in the period or the axis. Losses stay negative, written with a true minus: −€360.
14
- * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line and only past that is cut with an ellipsis, whole in the tooltip.
14
+ * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line where its row holds two lines and is cut with an ellipsis past what its lines hold, whole in the tooltip, so no label runs into its neighbour.
15
15
  */
16
16
  declare function ChartBarHorizontal({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter, axisFormatter, emptyState, size, className, }: Omit<ChartCardProps, "series" | "entityColorMap" | "otherLabel"> & {
17
17
  valueKey: string;
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bar-horizontal.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-horizontal.tsx"],"names":[],"mappings":"AAaA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAoCjC,iBAAS,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM;;;EAqCrF;AAED;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,YAAY,CAAC,GAAG;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,+BA+GA;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-bar-horizontal.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-horizontal.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAoCjC,iBAAS,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM;;;EAqCrF;AAED;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,YAAY,CAAC,GAAG;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,+BA+GA;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  // Pulled from the shadcn registry item `chart-bar-horizontal`.
2
2
  "use client";
3
3
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
- import { Bar, BarChart, CartesianGrid, ReferenceLine, Text, XAxis, YAxis } from "recharts";
4
+ import { Bar, BarChart, CartesianGrid, ReferenceLine, Text, XAxis, YAxis, } from "recharts";
5
5
  import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from "./chart.js";
6
6
  import { niceAxisMax, niceAxisTicks, niceStep } from "./chart-axis.js";
7
7
  import { CHART_LEGEND_CLASS, ChartCard, chartPlotClassName, defaultValueFormatter, } from "./chart-card.js";
@@ -9,18 +9,20 @@ const POSITIVE_KEY = "__positive";
9
9
  const NEGATIVE_KEY = "__negative";
10
10
  const POSITIVE_BAR_COLOR = "var(--success)";
11
11
  const NEGATIVE_BAR_COLOR = "var(--destructive)";
12
+ const TWO_LINE_ROW_HEIGHT = 28;
12
13
  /**
13
14
  * Recharts keeps only SVG attributes from a `tick` object, so `maxLines` reaches
14
- * its `Text` only through a tick it renders: up to two lines, then an ellipsis.
15
+ * its `Text` only through a tick it renders.
15
16
  */
16
17
  function CategoryTick({ payload, ...props }) {
17
- return (_jsx(Text, { ...props, maxLines: 2, children: payload.value }));
18
+ const rowHeight = Number(props.height) / props.visibleTicksCount;
19
+ return (_jsx(Text, { ...props, maxLines: rowHeight >= TWO_LINE_ROW_HEIGHT ? 2 : 1, children: payload.value }));
18
20
  }
19
- /** About one 12 px character, and the bounds that keep a name whole on two lines without starving the bars. */
21
+ /** About one 12 px character, and the bounds that keep a long name readable without starving the bars. */
20
22
  const CATEGORY_CHAR_WIDTH = 6.6;
21
23
  const CATEGORY_AXIS_MIN = 64;
22
24
  const CATEGORY_AXIS_MAX = 128;
23
- /** The category axis as wide as its longest name up to the bound; a longer name wraps to a second line. */
25
+ /** The category axis as wide as its longest name up to the bound; a longer name wraps or is cut, as `CategoryTick` decides. */
24
26
  function categoryAxisWidth(data, xKey) {
25
27
  const longest = data.reduce((most, datum) => Math.max(most, String(datum[xKey] ?? "").length), 0);
26
28
  return Math.min(CATEGORY_AXIS_MAX, Math.max(CATEGORY_AXIS_MIN, Math.ceil(longest * CATEGORY_CHAR_WIDTH) + 16));
@@ -62,7 +64,7 @@ function signedAxis(data, valueKey) {
62
64
  * @instead Never encode a loss as a share. An unsigned ranking is the compact `Progress` ranking or a `DataTable`.
63
65
  * @behaviour Horizontal bars from a 1.5 px zero line: favourable values to the right in success with right corners rounded, unfavourable to the left in destructive with left corners rounded.
64
66
  * @words The money unit in the period or the axis. Losses stay negative, written with a true minus: −€360.
65
- * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line and only past that is cut with an ellipsis, whole in the tooltip.
67
+ * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line where its row holds two lines and is cut with an ellipsis past what its lines hold, whole in the tooltip, so no label runs into its neighbour.
66
68
  */
67
69
  function ChartBarHorizontal({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter = defaultValueFormatter, axisFormatter, emptyState, size = "default", className, }) {
68
70
  const axis = signedAxis(data, valueKey);
@@ -40,7 +40,7 @@ export type CollectionFiltersProps = {
40
40
  * @family Compositions
41
41
  * @when A collection or a feed a person narrows by a property its records share (its query facets): a status, an owner, a kind. It stands in the toolbar after the search and before the sort.
42
42
  * @instead Finding one record by its name is the search. Changing the order is the sort. Switching between sibling collections is the page's tabs.
43
- * @behaviour Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.
43
+ * @behaviour Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. The picker stays inside the window: where its values are taller than the room beside its trigger, it takes that room, Back and the search stay in view, and the values scroll under them. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.
44
44
  * @words Every string is the product's: `copy` names Add filter, the two searches, the empty result, Back and Remove; each facet names itself, its values and its "All" choice.
45
45
  * @access Each chip is a group named by its facet; its remove button reads Remove with the facet's name. The pickers are searchable lists named by what they search.
46
46
  */
@@ -1 +1 @@
1
- {"version":3,"file":"collection-filters.d.ts","sourceRoot":"","sources":["../../src/components/collection-filters.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAyHF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpC,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,sBAAsB,4BAmFzE"}
1
+ {"version":3,"file":"collection-filters.d.ts","sourceRoot":"","sources":["../../src/components/collection-filters.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6HF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpC,IAAI,EAAE,oBAAoB,CAAC;CAC5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,sBAAsB,4BAmFzE"}
@@ -31,7 +31,7 @@ function FilterPicker({ facets, copy, initialField, returnFocus, children, }) {
31
31
  setOpen(next);
32
32
  if (next)
33
33
  changeField(initialField);
34
- }, children: [_jsx(PopoverTrigger, { render: children }), _jsxs(PopoverContent, { align: "start", initialFocus: input, children: [_jsx(PopoverTitle, { className: "sr-only", children: facet?.label ?? copy.add }), facet ? (_jsx(Button, { variant: "ghost", className: "justify-start", prefix: _jsx(ArrowLeft, {}), onClick: () => changeField(undefined), children: copy.back })) : null, _jsxs(Command, { label: facet ? `${copy.searchValues}: ${facet.label}` : copy.searchFields, resultCount: copy.results, onKeyDown: (event) => {
34
+ }, children: [_jsx(PopoverTrigger, { render: children }), _jsxs(PopoverContent, { align: "start", className: "max-h-(--available-height) overflow-y-auto", initialFocus: input, children: [_jsx(PopoverTitle, { className: "sr-only", children: facet?.label ?? copy.add }), facet ? (_jsx(Button, { variant: "ghost", className: "justify-start", prefix: _jsx(ArrowLeft, {}), onClick: () => changeField(undefined), children: copy.back })) : null, _jsxs(Command, { label: facet ? `${copy.searchValues}: ${facet.label}` : copy.searchFields, resultCount: copy.results, onKeyDown: (event) => {
35
35
  if (event.key === "Backspace" && !search && facet) {
36
36
  event.preventDefault();
37
37
  changeField(undefined);
@@ -46,7 +46,7 @@ function FilterPicker({ facets, copy, initialField, returnFocus, children, }) {
46
46
  * @family Compositions
47
47
  * @when A collection or a feed a person narrows by a property its records share (its query facets): a status, an owner, a kind. It stands in the toolbar after the search and before the sort.
48
48
  * @instead Finding one record by its name is the search. Changing the order is the sort. Switching between sibling collections is the page's tabs.
49
- * @behaviour Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.
49
+ * @behaviour Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. The picker stays inside the window: where its values are taller than the room beside its trigger, it takes that room, Back and the search stay in view, and the values scroll under them. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.
50
50
  * @words Every string is the product's: `copy` names Add filter, the two searches, the empty result, Back and Remove; each facet names itself, its values and its "All" choice.
51
51
  * @access Each chip is a group named by its facet; its remove button reads Remove with the facet's name. The pickers are searchable lists named by what they search.
52
52
  */
@@ -74,7 +74,7 @@ export type RecordListFooter = {
74
74
  /** One muted line about the whole list, with Learn more and one secondary action, in a strip of its own under the count and the paging. */
75
75
  note?: CollectionNote;
76
76
  };
77
- type RecordListBase<TRecord extends RowData> = {
77
+ export type RecordListProps<TRecord extends RowData> = {
78
78
  /** Names the list for assistive technology: "Skills". */
79
79
  label: string;
80
80
  /** Already searched, filtered and ordered; undefined while they load. */
@@ -117,7 +117,10 @@ type RecordListBase<TRecord extends RowData> = {
117
117
  label: string;
118
118
  commands: readonly MenuCommand[];
119
119
  } | null;
120
- /** Names the command column for assistive technology: "Actions". */
120
+ /**
121
+ * Names the command column for assistive technology: "Actions". Left out, its heading is empty,
122
+ * since each of its controls names itself, and never the list's name a second time.
123
+ */
121
124
  commandsHeader?: string;
122
125
  /** The record opens its own page: the whole row is one target. */
123
126
  open?: {
@@ -154,12 +157,6 @@ type RecordListBase<TRecord extends RowData> = {
154
157
  meta?: ReactNode;
155
158
  };
156
159
  footer?: RecordListFooter;
157
- };
158
- type RecordListCommands<TRecord extends RowData> = {
159
- command?: never;
160
- state?: never;
161
- commandsSize?: number;
162
- } | {
163
160
  /**
164
161
  * The row's visible commands, one or two outline buttons of 32 px before the three dots:
165
162
  * "Connect account", "Open report". A third goes in the menu.
@@ -168,16 +165,14 @@ type RecordListCommands<TRecord extends RowData> = {
168
165
  /** The record's own action failed or was refused: its message inside its row. */
169
166
  state?: (record: TRecord) => RowMessage | null;
170
167
  /**
171
- * The commands column's width in pixels, for the row command or a failed action's next
172
- * steps beside the three dots; a list with neither, or whose failed action shows on no row,
173
- * keeps the width of the three dots alone, so the name keeps the room.
168
+ * The least width of the commands column in pixels, for a row that draws a button or a failed
169
+ * action's next steps. The column is already as wide as its widest row's buttons, next steps,
170
+ * three dots and chevron need, worked out from their labels, so none is cut: a list gives it
171
+ * only to hold a wider column.
174
172
  */
175
- commandsSize: number;
173
+ commandsSize?: number;
176
174
  };
177
- export type RecordListProps<TRecord extends RowData> = RecordListBase<TRecord> & RecordListCommands<TRecord>;
178
- type WithoutKeys<List, Key extends PropertyKey> = List extends unknown ? Omit<List, Key> : never;
179
- /** The list's props without some keys, keeping a row command and its `commandsSize` together. */
180
- export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey> = WithoutKeys<RecordListProps<TRecord>, Key>;
175
+ export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey> = Omit<RecordListProps<TRecord>, Key>;
181
176
  /**
182
177
  * Entity rows: objects a person opens or acts on, one line each on one resting card: the
183
178
  * identity mark and name over what it is, a few facts, a status only for the exception, when it
@@ -189,7 +184,7 @@ export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey>
189
184
  * @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
190
185
  * “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
191
186
  * Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table, and anything more than a few facts lives on the record's page. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and nothing else draws a record row. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
192
- * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
187
+ * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (as wide as the widest row's buttons, a failed action's next steps and the three dots or the chevron after them need, worked out from their labels, each label at most 8 px a character and a button holding the longer of its label and its pending label, the dots at their 44 px touch target; 64 px for the three dots or the chevron alone; a row that draws a button or next steps is never narrower than a `commandsSize` the caller gives). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does, and the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
193
188
  * “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state)
194
189
  * Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
195
190
  * “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)
@@ -201,7 +196,7 @@ export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey>
201
196
  * “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)
202
197
  * Ours: every string is the product's: `label` names the list, a time's `phrase` writes its sentence ("Updated {when}"), `missing` is what a screen reader hears for a record with no time, the menu's `label` reads "More for {record}". A row command names its result in sentence case ("Edit domain"). A status is the exception's word ("Needs attention"), never "Active" on every row.
203
198
  * @access “Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton)
204
- * Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
199
+ * Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only; the commands column's is `commandsHeader`, and empty without one, since its controls name themselves, never the list's name a second time. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
205
200
  * “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity)
206
201
  * Ours: each box is named by `select.label`, which reads "Select {record}".
207
202
  */
@@ -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;AAK9E,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;AA2CpE,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,KAAK,cAAc,CAAC,OAAO,SAAS,OAAO,IAAI;IAC7C,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,oEAAoE;IACpE,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;CAC3B,CAAC;AAEF,KAAK,kBAAkB,CAAC,OAAO,SAAS,OAAO,IAC3C;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IACE;;;OAGG;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;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEN,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,GAC5E,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE9B,KAAK,WAAW,CAAC,IAAI,EAAE,GAAG,SAAS,WAAW,IAAI,IAAI,SAAS,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AAEjG,iGAAiG;AACjG,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,OAAO,EAAE,GAAG,SAAS,WAAW,IAAI,WAAW,CAC3F,eAAe,CAAC,OAAO,CAAC,EACxB,GAAG,CACJ,CAAC;AAoUF;;;;;;;;;;;;;;;;;;;;;;;;;;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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"}
@@ -17,37 +17,57 @@ import { TableValue } from "./table-value.js";
17
17
  import { soleMenuButton } from "../internal/record-menu-items.js";
18
18
  import { RowMessageActions, RowMessageLine } from "../internal/row-message.js";
19
19
  import { useTableLaidOutCompact } from "../internal/table-compact-line.js";
20
- /** The width of the commands column when it holds only the three dots or the chevron. */
21
- const ICON_COMMANDS_SIZE = 64;
22
- /**
23
- * A 32 px outline button with its icon, as a lone menu command draws it: the cell's 8 px before it
24
- * and 20 px after it at the card's edge, the button's edges and 6 px padding, the 14 px icon and
25
- * its gap, 8 px to spare, and each character of a 14 px medium label at most 8 px wide, so the
26
- * label is never cut.
27
- */
28
- const SOLE_BUTTON_FRAME = 72;
29
- const SOLE_BUTTON_CHARACTER = 8;
30
- /**
31
- * The commands column's width when the caller gives none: the three dots alone, or the widest
32
- * lone menu command any record turns into a button, so a button is never cut to its icon.
33
- */
34
- function defaultCommandsSize(props, records) {
35
- if (props.layout === "line" || !props.menu)
36
- return ICON_COMMANDS_SIZE;
37
- const menu = props.menu;
38
- return records.reduce((widest, record) => {
39
- const sole = soleMenuButton(menu(record)?.commands ?? []);
40
- if (!sole)
41
- return widest;
42
- return Math.max(widest, SOLE_BUTTON_FRAME + sole.label.length * SOLE_BUTTON_CHARACTER);
43
- }, ICON_COMMANDS_SIZE);
20
+ const CELL_START = 8;
21
+ const CELL_END_AT_CARD_EDGE = 20;
22
+ const COMMANDS_GAP = 8;
23
+ const TOUCH_TARGET = 44;
24
+ const DOTS_ALONE_SIZE = CELL_END_AT_CARD_EDGE + TOUCH_TARGET;
25
+ const BUTTON_EDGE = 1;
26
+ const BUTTON_PADDING = { sm: 6, default: 10 };
27
+ const BUTTON_LABEL_INSET = 6;
28
+ const BUTTON_ICON_SLOT = 20;
29
+ const BUTTON_ICON_GAP = 3;
30
+ const EXTERNAL_ARROW = 14;
31
+ const CHEVRON = 16;
32
+ const WIDEST_LABEL_CHARACTER = 8;
33
+ function shownCommands(list, record) {
34
+ const menu = list.menu?.(record);
35
+ const commands = menu?.commands ?? [];
36
+ const own = list.command?.(record);
37
+ const menuButton = own || list.layout === "line" ? undefined : soleMenuButton(commands);
38
+ const buttons = own ? [own].flat() : menuButton ? [menuButton] : [];
39
+ const state = list.state?.(record) ?? null;
40
+ const dots = menu && commands.length > 0 && !menuButton ? menu : undefined;
41
+ const chevron = !dots && !state && Boolean(list.open?.href(record));
42
+ return { buttons, state, dots, chevron };
43
+ }
44
+ function buttonRoom(command, size) {
45
+ const longerLabel = Math.max(command.label.length, command.pendingLabel?.length ?? 0);
46
+ return (2 * (BUTTON_EDGE + BUTTON_PADDING[size] + BUTTON_LABEL_INSET) +
47
+ (command.icon ? BUTTON_ICON_SLOT + BUTTON_ICON_GAP : 0) +
48
+ (command.external ? BUTTON_ICON_GAP + EXTERNAL_ARROW + BUTTON_ICON_GAP : 0) +
49
+ longerLabel * WIDEST_LABEL_CHARACTER);
50
+ }
51
+ function commandsRoom(list, record) {
52
+ const { buttons, state, dots, chevron } = shownCommands(list, record);
53
+ const widths = [
54
+ ...buttons.map((command) => buttonRoom(command, "sm")),
55
+ ...(state?.message.actions ?? []).map((action) => buttonRoom(action, "default")),
56
+ ];
57
+ if (widths.length === 0)
58
+ return DOTS_ALONE_SIZE;
59
+ if (dots)
60
+ widths.push(TOUCH_TARGET);
61
+ if (chevron)
62
+ widths.push(CHEVRON);
63
+ const room = CELL_START +
64
+ widths.reduce((sum, width) => sum + width, 0) +
65
+ COMMANDS_GAP * (widths.length - 1) +
66
+ CELL_END_AT_CARD_EDGE;
67
+ return Math.max(room, list.commandsSize ?? 0);
44
68
  }
45
69
  function commandsColumnSize(props) {
46
- const state = props.state;
47
- const roomUnused = state !== undefined && !props.command && !props.records.some((record) => state(record));
48
- return roomUnused || props.commandsSize === undefined
49
- ? defaultCommandsSize(props, props.records)
50
- : props.commandsSize;
70
+ return props.records.reduce((widest, record) => Math.max(widest, commandsRoom(props, record)), DOTS_ALONE_SIZE);
51
71
  }
52
72
  /** The checklist's ring: one 36 px button and the cell's padding. */
53
73
  const CHECKLIST_SIZE = 52;
@@ -110,15 +130,10 @@ function ChecklistCell({ row }) {
110
130
  function CommandsCell({ row }) {
111
131
  const list = useShownList();
112
132
  const record = row.original;
113
- const state = list.state?.(record);
114
- const menu = list.menu?.(record);
115
- const commands = menu?.commands ?? [];
116
- const own = list.command?.(record);
117
- const menuButton = own || list.layout === "line" ? undefined : soleMenuButton(commands);
133
+ const { buttons, state, dots, chevron } = shownCommands(list, record);
118
134
  // On a card too narrow for the row's columns the next steps stand under the message instead.
119
135
  const laidOutCompact = useTableLaidOutCompact();
120
- const buttons = own ? [own].flat() : menuButton ? [menuButton] : [];
121
- const end = menu && commands.length > 0 && !menuButton ? (_jsx(ActionMenu, { commands: commands, label: menu.label, record: list.name(record).name })) : list.open?.href(record) && !state ? (_jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 text-muted-foreground" })) : null;
136
+ const end = dots ? (_jsx(ActionMenu, { commands: dots.commands, label: dots.label, record: list.name(record).name })) : chevron ? (_jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 text-muted-foreground" })) : null;
122
137
  if (buttons.length === 0 && !state && !end)
123
138
  return null;
124
139
  return (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [buttons.length > 0 ? (_jsx("div", { className: "flex min-w-0 justify-end gap-2 [&>*]:max-w-full [&>*]:min-w-0 [&>*]:shrink [&>*>span:not([data-icon])]:truncate", children: buttons.map((command) => (_jsx(PageCommandButton, { command: command, size: "sm", variant: "outline" }, command.label))) })) : null, state && !laidOutCompact ? _jsx(RowMessageActions, { state: state }) : null, end] }));
@@ -206,7 +221,7 @@ function recordColumns(props) {
206
221
  if (props.open || someRecordHasCommands) {
207
222
  columns.push({
208
223
  id: "commands",
209
- header: props.commandsHeader ?? props.label,
224
+ header: props.commandsHeader ?? "",
210
225
  size: commandsColumnSize(props),
211
226
  cell: CommandsCell,
212
227
  });
@@ -250,7 +265,7 @@ function RecordRows(props) {
250
265
  * @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
251
266
  * “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
252
267
  * Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table, and anything more than a few facts lives on the record's page. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and nothing else draws a record row. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
253
- * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
268
+ * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (as wide as the widest row's buttons, a failed action's next steps and the three dots or the chevron after them need, worked out from their labels, each label at most 8 px a character and a button holding the longer of its label and its pending label, the dots at their 44 px touch target; 64 px for the three dots or the chevron alone; a row that draws a button or next steps is never narrower than a `commandsSize` the caller gives). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does, and the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
254
269
  * “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state)
255
270
  * Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
256
271
  * “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)
@@ -262,7 +277,7 @@ function RecordRows(props) {
262
277
  * “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)
263
278
  * Ours: every string is the product's: `label` names the list, a time's `phrase` writes its sentence ("Updated {when}"), `missing` is what a screen reader hears for a record with no time, the menu's `label` reads "More for {record}". A row command names its result in sentence case ("Edit domain"). A status is the exception's word ("Needs attention"), never "Active" on every row.
264
279
  * @access “Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton)
265
- * Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
280
+ * Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only; the commands column's is `commandsHeader`, and empty without one, since its controls name themselves, never the list's name a second time. The row link carries `open.label`; the three dots carry the menu's `label`, and the menu's first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them.
266
281
  * “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity)
267
282
  * Ours: each box is named by `select.label`, which reads "Select {record}".
268
283
  */
@@ -30,7 +30,7 @@ type ScrollAreaProps = Omit<ScrollAreaPrimitive.Root.Props, "children" | "render
30
30
  * Ours: Geist's `Scroller` is `ScrollArea`, and `vertical`, `horizontal` and `free` are `overflow="y"`,
31
31
  * `"x"` and `"both"`. A bounded area whose content overflows: a side panel's list, a menu's long
32
32
  * body, a rail of chips or logos.
33
- * @instead Ours: a page scrolls as the document. A sequence of slides on the website is `Carousel`.
33
+ * @instead Ours: a page scrolls as the document.
34
34
  * @behaviour “Buttons will automatically scroll to a given **direct** child.” (https://vercel.com/geist/scroller)
35
35
  * “Auto-scroll buttons target direct children only. If items are wrapped in extra layout nodes the buttons won’t find their target.” (https://vercel.com/geist/scroller)
36
36
  * “Show edge fade or shadow affordances on the clipped axis so users see there’s more content past the viewport.” (https://vercel.com/geist/scroller)
@@ -38,7 +38,7 @@ const buttonIcons = {
38
38
  * Ours: Geist's `Scroller` is `ScrollArea`, and `vertical`, `horizontal` and `free` are `overflow="y"`,
39
39
  * `"x"` and `"both"`. A bounded area whose content overflows: a side panel's list, a menu's long
40
40
  * body, a rail of chips or logos.
41
- * @instead Ours: a page scrolls as the document. A sequence of slides on the website is `Carousel`.
41
+ * @instead Ours: a page scrolls as the document.
42
42
  * @behaviour “Buttons will automatically scroll to a given **direct** child.” (https://vercel.com/geist/scroller)
43
43
  * “Auto-scroll buttons target direct children only. If items are wrapped in extra layout nodes the buttons won’t find their target.” (https://vercel.com/geist/scroller)
44
44
  * “Show edge fade or shadow affordances on the clipped axis so users see there’s more content past the viewport.” (https://vercel.com/geist/scroller)
@@ -22,10 +22,10 @@ function actionProps(action, disabled = false) {
22
22
  if (element) {
23
23
  return { render: element, "aria-disabled": disabled || undefined };
24
24
  }
25
- // The row's tooltip trigger takes `disabled` for itself, so the button element carries it.
26
25
  return {
26
+ disabled,
27
27
  onClick: action.onClick,
28
- render: _jsx("button", { disabled: disabled, type: "button" }),
28
+ type: "button",
29
29
  };
30
30
  }
31
31
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../src/components/sidebar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../src/components/sidebar.tsx"],"names":[],"mappings":"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"}
@@ -298,7 +298,8 @@ function SidebarMenuButton({ render, isActive = false, variant = "default", size
298
298
  props: mergeProps({
299
299
  className: cn(sidebarMenuButtonVariants({ variant, size }), className),
300
300
  }, props),
301
- render: !tooltip ? render : _jsx(TooltipTrigger, { render: render }),
301
+ // Base UI's tooltip trigger takes `disabled` for its tooltip, so the button element carries it too.
302
+ render: !tooltip ? (render) : (_jsx(TooltipTrigger, { render: render ?? _jsx("button", { disabled: props.disabled, type: props.type ?? "button" }) })),
302
303
  state: {
303
304
  slot: "sidebar-menu-button",
304
305
  sidebar: "menu-button",
package/dist/index.d.ts CHANGED
@@ -22,7 +22,6 @@ export * from "./components/button-group.js";
22
22
  export * from "./components/calendar.js";
23
23
  export * from "./components/card.js";
24
24
  export * from "./components/card-row.js";
25
- export * from "./components/carousel.js";
26
25
  export * from "./components/catalog-drawer.js";
27
26
  export * from "./components/chart.js";
28
27
  export * from "./components/chart-area-stacked.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -22,7 +22,6 @@ export * from "./components/button-group.js";
22
22
  export * from "./components/calendar.js";
23
23
  export * from "./components/card.js";
24
24
  export * from "./components/card-row.js";
25
- export * from "./components/carousel.js";
26
25
  export * from "./components/catalog-drawer.js";
27
26
  export * from "./components/chart.js";
28
27
  export * from "./components/chart-area-stacked.js";
@@ -17,8 +17,8 @@ export type SettingsSave = {
17
17
  /** "Saving" */
18
18
  pendingLabel: string;
19
19
  /**
20
- * Called once a save resolves null, in the transition that ends the save: the product announces it through its
21
- * own toast, and a state change made here renders with Save ready again.
20
+ * Called once a save resolves null, after the render that ends the save and before it paints: the product
21
+ * announces it through its own toast, which shows with Save ready again, as a state change made here renders.
22
22
  */
23
23
  saved: () => void;
24
24
  /** What is specific to this card, on the footer's left: a limit, what a value is for, a plan it needs, a link. Absent: nothing. */
@@ -1 +1 @@
1
- {"version":3,"file":"settings-save.d.ts","sourceRoot":"","sources":["../../src/internal/settings-save.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AAMf,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAOtF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACpE,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,eAAe;IACf,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mIAAmI;IACnI,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AA4FF,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,OAAO,EACP,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAsFA;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,sCAqC1D"}
1
+ {"version":3,"file":"settings-save.d.ts","sourceRoot":"","sources":["../../src/internal/settings-save.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,SAAS,EAQf,MAAM,OAAO,CAAC;AAMf,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAOtF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACpE,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IACd,eAAe;IACf,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mIAAmI;IACnI,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3F;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAuGF,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,OAAO,EACP,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAwGA;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,sCAqC1D"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createContext, startTransition, use, useCallback, useEffect, useRef, useState, } from "react";
3
+ import { createContext, startTransition, use, useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
4
4
  import { useFormStatus } from "react-dom";
5
5
  import { Button } from "../components/button.js";
6
6
  import { FieldError } from "../components/field.js";
@@ -52,8 +52,12 @@ function editableValues(form) {
52
52
  ? [name, [value.name, value.size, value.type, value.lastModified]]
53
53
  : [name, value]));
54
54
  }
55
- function SaveFooter({ save, changed }) {
55
+ function SaveFooter({ announce, save, changed, }) {
56
56
  const { pending } = useFormStatus();
57
+ useLayoutEffect(() => {
58
+ if (!pending)
59
+ announce();
60
+ }, [announce, pending]);
57
61
  return (_jsxs(FooterStrip, { hint: save.hint, hintSlot: "settings-section-hint", children: [save.cancel ? (_jsx(Button, { disabled: pending, loading: save.cancel.pending ?? false, loadingLabel: save.cancel.pendingLabel ?? save.cancel.label, onClick: save.cancel.onCancel, type: "button", variant: "outline", children: save.cancel.label })) : null, _jsx(FormSubmitButton, { submit: {
58
62
  label: save.label,
59
63
  pendingLabel: save.pendingLabel,
@@ -64,6 +68,8 @@ function SaveFooter({ save, changed }) {
64
68
  export function SettingsSaveForm({ save, titleId, children, }) {
65
69
  const [fieldsChanged, setFieldsChanged] = useState(false);
66
70
  const [failure, setFailure] = useState(null);
71
+ const unannounced = useRef(null);
72
+ const mounted = useRef(false);
67
73
  const [claimedFields, setClaimedFields] = useState(() => new Set());
68
74
  const submittedValues = useRef(null);
69
75
  const keepValuesOnReset = useRef(false);
@@ -94,18 +100,34 @@ export function SettingsSaveForm({ save, titleId, children, }) {
94
100
  element.addEventListener("reset", onReset);
95
101
  return () => element.removeEventListener("reset", onReset);
96
102
  }, [controlled]);
103
+ // A toast's store renders at once, outside the transition that ends the save, so `saved` waits for the commit
104
+ // that ends it, or for the section to close with it.
105
+ const announce = useCallback(() => {
106
+ const saved = unannounced.current;
107
+ unannounced.current = null;
108
+ saved?.();
109
+ }, []);
110
+ useLayoutEffect(() => {
111
+ mounted.current = true;
112
+ return () => {
113
+ mounted.current = false;
114
+ announce();
115
+ };
116
+ }, [announce]);
97
117
  const changed = save.changed ?? fieldsChanged;
98
118
  const sectionFailure = failure && (failure.field === undefined || !claimedFields.has(failure.field)) ? failure : null;
99
119
  return (_jsx(SettingsSaveContext, { value: { failure, claim }, children: _jsxs("form", { ref: form, "aria-labelledby": titleId, className: "contents", "data-slot": "settings-section-form", action: async (formData) => {
100
120
  const result = await save.action(formData);
101
121
  keepValuesOnReset.current = result !== null;
122
+ if (result === null) {
123
+ if (mounted.current)
124
+ unannounced.current = save.saved;
125
+ else
126
+ save.saved();
127
+ }
102
128
  // React leaves an update after an await out of the action, so it would render while Save still says
103
129
  // Saving; inside a transition it renders with the end of the save.
104
- startTransition(() => {
105
- setFailure(result);
106
- if (result === null)
107
- save.saved();
108
- });
130
+ startTransition(() => setFailure(result));
109
131
  }, onChange: (event) => {
110
132
  const edited = event.target;
111
133
  if (edited instanceof Element &&
@@ -117,7 +139,7 @@ export function SettingsSaveForm({ save, titleId, children, }) {
117
139
  setFailure(null);
118
140
  keepValuesOnReset.current = false;
119
141
  submittedValues.current = editableValues(event.currentTarget);
120
- }, children: [_jsx("fieldset", { className: "contents", disabled: !hydrated, children: children }), sectionFailure ? (_jsx(CardContent, { children: _jsx(MessageNotice, { message: sectionFailure.message, placement: "action" }) })) : null, _jsx(SaveFooter, { changed: changed, save: save })] }) }));
142
+ }, children: [_jsx("fieldset", { className: "contents", disabled: !hydrated, children: children }), sectionFailure ? (_jsx(CardContent, { children: _jsx(MessageNotice, { message: sectionFailure.message, placement: "action" }) })) : null, _jsx(SaveFooter, { announce: announce, changed: changed, save: save })] }) }));
121
143
  }
122
144
  export function SettingsFieldFailure({ id }) {
123
145
  const context = use(SettingsSaveContext);
@@ -1 +1 @@
1
- {"version":3,"file":"compositions.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/compositions.tsx"],"names":[],"mappings":"AAoIA,iBAAS,oBAAoB,gCA+B5B;AAED,iBAAS,wBAAwB,gCAahC;AAED,iBAAS,qBAAqB,gCA0B7B;AAED,iBAAS,yBAAyB,gCAGjC;AAED,iBAAS,sBAAsB,gCAyD9B;AAED,iBAAS,yBAAyB,gCAUjC;AAED,iBAAS,qBAAqB,gCAwC7B;AAED,iBAAS,kBAAkB,gCAiB1B;AAED,iBAAS,kBAAkB,gCAuE1B;AAED,iBAAS,kBAAkB,gCAwB1B;AAED,iBAAS,oBAAoB,gCAkD5B;AAED,iBAAS,oBAAoB,gCAqC5B;AAED,iBAAS,mBAAmB,gCA2B3B;AAED,iBAAS,mBAAmB,gCAoB3B;AAwBD,iBAAS,uBAAuB,gCAkD/B;AA0BD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;CAmFE,CAAC"}
1
+ {"version":3,"file":"compositions.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/compositions.tsx"],"names":[],"mappings":"AAoIA,iBAAS,oBAAoB,gCA+B5B;AAED,iBAAS,wBAAwB,gCAahC;AAED,iBAAS,qBAAqB,gCA0B7B;AAED,iBAAS,yBAAyB,gCAGjC;AAED,iBAAS,sBAAsB,gCAyD9B;AAED,iBAAS,yBAAyB,gCAUjC;AAED,iBAAS,qBAAqB,gCAwC7B;AAED,iBAAS,kBAAkB,gCAiB1B;AAED,iBAAS,kBAAkB,gCAuE1B;AAED,iBAAS,kBAAkB,gCAwB1B;AAED,iBAAS,oBAAoB,gCAkD5B;AAED,iBAAS,oBAAoB,gCAqC5B;AAED,iBAAS,mBAAmB,gCA2B3B;AAED,iBAAS,mBAAmB,gCAoB3B;AAwBD,iBAAS,uBAAuB,gCAkD/B;AA0BD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;CA8FE,CAAC"}
@@ -375,7 +375,12 @@ export const COMPOSITIONS = {
375
375
  RecordList: () => (_jsxs("div", { className: "grid gap-6", children: [_jsx(RecordList, { ...MAILBOX_LIST, footer: { count: "3 mailboxes" }, label: "Mailboxes", records: MAILBOXES }), _jsx(RecordList, { ...MAILBOX_LIST, label: "Mailboxes with one command", menu: (mailbox) => ({
376
376
  label: `More for ${mailbox.address}`,
377
377
  commands: [{ label: "Reconnect", icon: _jsx(RefreshCw, {}), onClick: nothing }],
378
- }), records: MAILBOXES }), _jsx(SelectableRecordListSpecimen, {})] })),
378
+ }), records: MAILBOXES }), _jsx(RecordList, { ...MAILBOX_LIST, command: () => ({
379
+ label: "Reconnect",
380
+ pendingLabel: "Reconnecting…",
381
+ icon: _jsx(RefreshCw, {}),
382
+ onClick: nothing,
383
+ }), label: "Mailboxes with a row command", records: MAILBOXES }), _jsx(SelectableRecordListSpecimen, {})] })),
379
384
  RecordSheet: RecordSheetSpecimen,
380
385
  RowEditForm: RowEditFormSpecimen,
381
386
  SettingsPage: () => (_jsx(SettingsPage, { children: _jsx(SenderSection, {}) })),
@@ -2,7 +2,6 @@ export declare const SPECIMENS: {
2
2
  Accordion: () => import("react").JSX.Element;
3
3
  AspectRatio: () => import("react").JSX.Element;
4
4
  BrandField: () => import("react").JSX.Element;
5
- Carousel: () => import("react").JSX.Element;
6
5
  Collapsible: () => import("react").JSX.Element;
7
6
  CompanyCard: () => import("react").JSX.Element;
8
7
  Disclosure: () => import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYiB,CAAC"}
@@ -6,7 +6,6 @@ export declare const OTHER: {
6
6
  Accordion: () => import("react").JSX.Element;
7
7
  AspectRatio: typeof AspectRatioSpecimen;
8
8
  BrandField: () => import("react").JSX.Element;
9
- Carousel: () => import("react").JSX.Element;
10
9
  Collapsible: () => import("react").JSX.Element;
11
10
  CompanyCard: typeof CompanyCardSpecimen;
12
11
  Disclosure: () => import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"other.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/other.tsx"],"names":[],"mappings":"AA8CA,iBAAS,mBAAmB,gCAS3B;AAED,iBAAS,mBAAmB,gCAiB3B;AAED,iBAAS,iBAAiB,gCAczB;AAED,iBAAS,qBAAqB,gCAa7B;AAED,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;CA6LS,CAAC"}
1
+ {"version":3,"file":"other.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/other.tsx"],"names":[],"mappings":"AAuCA,iBAAS,mBAAmB,gCAS3B;AAED,iBAAS,mBAAmB,gCAiB3B;AAED,iBAAS,iBAAiB,gCAczB;AAED,iBAAS,qBAAqB,gCAa7B;AAED,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;CA8KS,CAAC"}
@@ -7,7 +7,6 @@ import { AspectRatio } from "../../components/aspect-ratio.js";
7
7
  import { BrandField } from "../../components/brand-field.js";
8
8
  import { BrandWordmark } from "../../components/brand.js";
9
9
  import { Button } from "../../components/button.js";
10
- import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, } from "../../components/carousel.js";
11
10
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../components/collapsible.js";
12
11
  import { CompanyCard } from "../../components/company-card.js";
13
12
  import { Disclosure } from "../../components/disclosure.js";
@@ -47,7 +46,6 @@ export const OTHER = {
47
46
  Accordion: () => (_jsxs("div", { className: "grid max-w-lg gap-10", children: [["default", "small"].map((size) => (_jsxs(Accordion, { size: size, children: [_jsxs(AccordionItem, { value: "data", children: [_jsx(AccordionTrigger, { children: "Where does my data live?" }), _jsx(AccordionContent, { children: "In the EU, on servers nadicode runs." })] }), _jsxs(AccordionItem, { value: "agents", children: [_jsx(AccordionTrigger, { children: "Can an Agent send email on its own?" }), _jsx(AccordionContent, { children: "Only from a mailbox you connect, and only with approval." })] }), _jsxs(AccordionItem, { value: "export", children: [_jsx(AccordionTrigger, { children: "Can I take my data with me?" }), _jsx(AccordionContent, { hiddenUntilFound: false, children: "Yes. Export every record as a .zip from Settings." })] })] }, size))), _jsxs(Accordion, { multiple: true, children: [_jsxs(AccordionItem, { value: "invoices", children: [_jsx(AccordionTrigger, { children: "Invoices" }), _jsx(AccordionContent, { children: "Issued on the first of each month." })] }), _jsxs(AccordionItem, { value: "payments", children: [_jsx(AccordionTrigger, { children: "Payments" }), _jsx(AccordionContent, { children: "Card and bank transfer, in euro." })] })] })] })),
48
47
  AspectRatio: AspectRatioSpecimen,
49
48
  BrandField: () => (_jsxs(BrandField, { className: "grid gap-2 rounded-md p-8", children: [_jsx(BrandWordmark, {}), _jsx("p", { className: "text-sm text-muted-foreground", children: "White on ink, in either theme." })] })),
50
- Carousel: () => (_jsxs(Carousel, { className: "mx-12 max-w-xs", children: [_jsx(CarouselContent, { children: ["Invoices", "Orders", "Support"].map((name) => (_jsx(CarouselItem, { children: _jsx("div", { className: "grid h-32 place-items-center rounded-md border border-border text-sm", children: name }) }, name))) }), _jsx(CarouselPrevious, {}), _jsx(CarouselNext, {})] })),
51
49
  Collapsible: () => (_jsxs(Collapsible, { className: "max-w-sm", children: [_jsx(CollapsibleTrigger, { render: _jsx(Button, { prefix: _jsx(ChevronDown, { "aria-hidden": "true" }), variant: "ghost" }), children: "src" }), _jsxs(CollapsibleContent, { className: "grid gap-1 pl-8 font-mono text-sm", children: [_jsx("span", { children: "index.ts" }), _jsx("span", { children: "quote.ts" })] })] })),
52
50
  CompanyCard: CompanyCardSpecimen,
53
51
  Disclosure: () => (_jsx(Disclosure, { label: "Other formats", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "Download for Windows, or as a .zip for macOS." }) })),
@@ -1,4 +1,4 @@
1
- export type UsageName = "ActivityFeed" | "AgentProfileCard" | "CatalogDrawer" | "CollectionFilters" | "CollectionPage" | "CollectionToolbar" | "ConfirmDialog" | "EntryScene" | "FormDialog" | "FormDrawer" | "LibraryShelf" | "ObjectPage" | "ObjectSection" | "OverviewPage" | "PageHeader" | "RecordList" | "RecordSheet" | "RowEditForm" | "SettingsPage" | "SettingsSection" | "Button" | "ButtonGroup" | "ButtonLink" | "CopyButton" | "LoadMoreButton" | "PageActions" | "Calendar" | "ClearableInput" | "CollectionSearch" | "Field" | "Input" | "InputGroup" | "InputOTP" | "Label" | "NativeSelect" | "SettingsField" | "SettingsRows" | "Slider" | "Textarea" | "Checkbox" | "ChoiceboxGroup" | "CollectionSort" | "Combobox" | "ModelSelect" | "MultiSelect" | "RadioGroup" | "SegmentedChoice" | "SegmentedControl" | "Select" | "Switch" | "ThemeModeSegments" | "ThemeModeSwitcher" | "Toggle" | "ToggleGroup" | "ActionStatus" | "AgentOrb" | "AppMark" | "ArchIcon" | "Avatar" | "Badge" | "BrandWordmark" | "CheckCounts" | "FileTypeIcon" | "IdentityMark" | "ModelIdentity" | "ModelMark" | "ObjectFactValue" | "PlatformMark" | "ProgressChecklist" | "RecordIdentity" | "StatusBadge" | "Tag" | "AgentListRow" | "Breadcrumb" | "CommandDialog" | "Footer" | "PortalSidebarFrame" | "ScopeSwitcher" | "Sidebar" | "SidebarBrand" | "SidebarFind" | "SidebarFrame" | "SidebarMenuChevron" | "SidebarSections" | "Tabs" | "TabsNav" | "textLinkVariants" | "AgentCard" | "Card" | "CardRow" | "CodeBlock" | "DataTable" | "DiffCount" | "DisclosureRow" | "FileDiff" | "Gauge" | "Item" | "Kbd" | "MiddleTruncate" | "ObjectFacts" | "PairingCode" | "Progress" | "QrCode" | "RecordTime" | "RunTimeline" | "SettingsFactsSection" | "Snippet" | "Table" | "TableCard" | "TableValue" | "TextWithCopyButton" | "UsageMeter" | "Alert" | "EmptyState" | "EntryProgress" | "EntryStageList" | "HoverCard" | "MessageNotice" | "NoticeBanner" | "PendingLabel" | "Skeleton" | "SkeletonRegion" | "Toaster" | "Tooltip" | "UpdateCard" | "WaitingLine" | "AccountMenu" | "ActionContextMenu" | "ActionMenu" | "AlertDialog" | "ContextMenu" | "Dialog" | "Drawer" | "DropdownMenu" | "GlassControl" | "MenuChoiceRow" | "Popover" | "Sheet" | "ThemeModeMenu" | "ActivityCalendar" | "ChartAreaStacked" | "ChartBarHorizontal" | "ChartBarMultiple" | "ChartBarStacked" | "ChartCard" | "ChartContainer" | "ChartRanking" | "ChartSparkline" | "DateRangeControl" | "KpiCard" | "TrendBadge" | "createEntityColorMap" | "Accordion" | "AspectRatio" | "BrandField" | "Carousel" | "Collapsible" | "CompanyCard" | "Disclosure" | "HiveScene" | "NadiaPresence" | "NumberedSteps" | "Prose" | "ReadingColumn" | "ResizablePanelGroup" | "ScrollArea" | "Separator" | "ToolIcon";
1
+ export type UsageName = "ActivityFeed" | "AgentProfileCard" | "CatalogDrawer" | "CollectionFilters" | "CollectionPage" | "CollectionToolbar" | "ConfirmDialog" | "EntryScene" | "FormDialog" | "FormDrawer" | "LibraryShelf" | "ObjectPage" | "ObjectSection" | "OverviewPage" | "PageHeader" | "RecordList" | "RecordSheet" | "RowEditForm" | "SettingsPage" | "SettingsSection" | "Button" | "ButtonGroup" | "ButtonLink" | "CopyButton" | "LoadMoreButton" | "PageActions" | "Calendar" | "ClearableInput" | "CollectionSearch" | "Field" | "Input" | "InputGroup" | "InputOTP" | "Label" | "NativeSelect" | "SettingsField" | "SettingsRows" | "Slider" | "Textarea" | "Checkbox" | "ChoiceboxGroup" | "CollectionSort" | "Combobox" | "ModelSelect" | "MultiSelect" | "RadioGroup" | "SegmentedChoice" | "SegmentedControl" | "Select" | "Switch" | "ThemeModeSegments" | "ThemeModeSwitcher" | "Toggle" | "ToggleGroup" | "ActionStatus" | "AgentOrb" | "AppMark" | "ArchIcon" | "Avatar" | "Badge" | "BrandWordmark" | "CheckCounts" | "FileTypeIcon" | "IdentityMark" | "ModelIdentity" | "ModelMark" | "ObjectFactValue" | "PlatformMark" | "ProgressChecklist" | "RecordIdentity" | "StatusBadge" | "Tag" | "AgentListRow" | "Breadcrumb" | "CommandDialog" | "Footer" | "PortalSidebarFrame" | "ScopeSwitcher" | "Sidebar" | "SidebarBrand" | "SidebarFind" | "SidebarFrame" | "SidebarMenuChevron" | "SidebarSections" | "Tabs" | "TabsNav" | "textLinkVariants" | "AgentCard" | "Card" | "CardRow" | "CodeBlock" | "DataTable" | "DiffCount" | "DisclosureRow" | "FileDiff" | "Gauge" | "Item" | "Kbd" | "MiddleTruncate" | "ObjectFacts" | "PairingCode" | "Progress" | "QrCode" | "RecordTime" | "RunTimeline" | "SettingsFactsSection" | "Snippet" | "Table" | "TableCard" | "TableValue" | "TextWithCopyButton" | "UsageMeter" | "Alert" | "EmptyState" | "EntryProgress" | "EntryStageList" | "HoverCard" | "MessageNotice" | "NoticeBanner" | "PendingLabel" | "Skeleton" | "SkeletonRegion" | "Toaster" | "Tooltip" | "UpdateCard" | "WaitingLine" | "AccountMenu" | "ActionContextMenu" | "ActionMenu" | "AlertDialog" | "ContextMenu" | "Dialog" | "Drawer" | "DropdownMenu" | "GlassControl" | "MenuChoiceRow" | "Popover" | "Sheet" | "ThemeModeMenu" | "ActivityCalendar" | "ChartAreaStacked" | "ChartBarHorizontal" | "ChartBarMultiple" | "ChartBarStacked" | "ChartCard" | "ChartContainer" | "ChartRanking" | "ChartSparkline" | "DateRangeControl" | "KpiCard" | "TrendBadge" | "createEntityColorMap" | "Accordion" | "AspectRatio" | "BrandField" | "Collapsible" | "CompanyCard" | "Disclosure" | "HiveScene" | "NadiaPresence" | "NumberedSteps" | "Prose" | "ReadingColumn" | "ResizablePanelGroup" | "ScrollArea" | "Separator" | "ToolIcon";
2
2
  export type UsageFamily = "Compositions" | "Actions" | "Inputs" | "Choices" | "Status" | "Navigation" | "Data" | "Feedback" | "Menus" | "Charts" | "Other";
3
3
  export type ComponentUsage = {
4
4
  name: UsageName;
@@ -1 +1 @@
1
- {"version":3,"file":"usage.generated.d.ts","sourceRoot":"","sources":["../../src/showcase/usage.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usage.generated.d.ts","sourceRoot":"","sources":["../../src/showcase/usage.generated.ts"],"names":[],"mappings":"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"}
@@ -54,7 +54,7 @@ export const USAGE = [
54
54
  summary: "The filters in a collection's toolbar: one Add filter button, a chip for each facet in force, and the facets most often narrowed to waiting as dashed chips.",
55
55
  when: "A collection or a feed a person narrows by a property its records share (its query facets): a status, an owner, a kind. It stands in the toolbar after the search and before the sort.",
56
56
  instead: "Finding one record by its name is the search. Changing the order is the sort. Switching between sibling collections is the page's tabs.",
57
- behaviour: "Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.",
57
+ behaviour: "Add filter opens a picker of the facets, then of a facet's values, each searchable; Backspace in an empty search goes back to the facets. The picker stays inside the window: where its values are taller than the room beside its trigger, it takes that room, Back and the search stay in view, and the values scroll under them. A facet in force is a chip that reopens its values, with a button that removes it. A suggested value waits as a dashed chip in the muted grey, led by a + and never by the value's own mark, so it never reads as a filter in force, while its facet is unset, and applies in one click. Focus returns to Add filter when a facet is removed. The product keeps each facet's value, in the URL where it has one.",
58
58
  words: 'Every string is the product\'s: `copy` names Add filter, the two searches, the empty result, Back and Remove; each facet names itself, its values and its "All" choice.',
59
59
  access: "Each chip is a group named by its facet; its remove button reads Remove with the facet's name. The pickers are searchable lists named by what they search.",
60
60
  },
@@ -186,9 +186,9 @@ export const USAGE = [
186
186
  summary: "Entity rows: objects a person opens or acts on, one line each on one resting card: the identity mark and name over what it is, a few facts, a status only for the exception, when it happened, at most two row commands, and the three dots last.",
187
187
  when: "“Use `<Entity>` for a row of descriptive content paired with one or two controls (member rows, integration rows, domain rows).” (https://vercel.com/geist/entity) Ours: the records are things a person opens or acts on and that name themselves: projects, deployments, domains, members, integrations, Agents, Skills, mailboxes. A list inside another page: an Overview's exceptions, an object page's \"Needs attention\". A page whose whole job is the list is a `CollectionPage`, which draws this. Values edited in place (a domain, an environment variable) are the same rows with an `editor`: the row expands into its form. Of the three kinds of list, entity rows and rows edited in place are this; records compared across columns are a `DataTable`.",
188
188
  instead: "“For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity) “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity) Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table, and anything more than a few facts lives on the record's page. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and nothing else draws a record row. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.",
189
- behaviour: "One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout=\"line\"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list (\"Deployment retention is enabled. Learn more\", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message. “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state) Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card. “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) Ours: one or two row commands (outline buttons of 32 px) stand before the three dots (36 px), the Dots Menu. “Render the Skeleton variant (`entity-with-skeleton`) during load instead of an empty row, and swap to real content once data resolves.” (https://vercel.com/geist/entity) Ours: three still skeleton rows hold the place, in a region that announces what replaces them; then the first that holds: the failed read, no match, the empty state, the rows.",
189
+ behaviour: "One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (as wide as the widest row's buttons, a failed action's next steps and the three dots or the chevron after them need, worked out from their labels, each label at most 8 px a character and a button holding the longer of its label and its pending label, the dots at their 44 px touch target; 64 px for the three dots or the chevron alone; a row that draws a button or next steps is never narrower than a `commandsSize` the caller gives). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout=\"line\"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, the status keeping its mark whole and breaking between its words only when it alone is wider than the line, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does, and the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list (\"Deployment retention is enabled. Learn more\", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message. “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state) Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card. “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) Ours: one or two row commands (outline buttons of 32 px) stand before the three dots (36 px), the Dots Menu. “Render the Skeleton variant (`entity-with-skeleton`) during load instead of an empty row, and swap to real content once data resolves.” (https://vercel.com/geist/entity) Ours: three still skeleton rows hold the place, in a region that announces what replaces them; then the first that holds: the failed read, no match, the empty state, the rows.",
190
190
  words: '“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) Ours: the name is the record\'s own and the labels around it are sentence case, not Title Case. “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) Ours: every string is the product\'s: `label` names the list, a time\'s `phrase` writes its sentence ("Updated {when}"), `missing` is what a screen reader hears for a record with no time, the menu\'s `label` reads "More for {record}". A row command names its result in sentence case ("Edit domain"). A status is the exception\'s word ("Needs attention"), never "Active" on every row.',
191
- access: '“Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton) Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only. The row link carries `open.label`; the three dots carry the menu\'s `label`, and the menu\'s first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them. “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity) Ours: each box is named by `select.label`, which reads "Select {record}".',
191
+ access: '“Wrap the loading region in `aria-busy="true"` and announce completion with `aria-live="polite"` on the destination container, not the skeleton itself.” (https://vercel.com/geist/skeleton) Ours: the loading rows sit in one `SkeletonRegion` that is busy while they stand and announces what replaces them. A table named by `label`, its column headings read by assistive technology only; the commands column\'s is `commandsHeader`, and empty without one, since its controls name themselves, never the list\'s name a second time. The row link carries `open.label`; the three dots carry the menu\'s `label`, and the menu\'s first line names the record. The loading rows are a status named by `loadingLabel`, inside the one live region that announces what replaces them. “For multi-select rows, the leading `Checkbox` carries `aria-label="Select {entity name}"` so the row is selectable without relying on the visual label.” (https://vercel.com/geist/entity) Ours: each box is named by `select.label`, which reads "Select {record}".',
192
192
  },
193
193
  {
194
194
  name: "RecordSheet",
@@ -1574,7 +1574,7 @@ export const USAGE = [
1574
1574
  instead: "Never encode a loss as a share. An unsigned ranking is the compact `Progress` ranking or a `DataTable`.",
1575
1575
  behaviour: "Horizontal bars from a 1.5 px zero line: favourable values to the right in success with right corners rounded, unfavourable to the left in destructive with left corners rounded.",
1576
1576
  words: "The money unit in the period or the axis. Losses stay negative, written with a true minus: −€360.",
1577
- access: "Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line and only past that is cut with an ellipsis, whole in the tooltip.",
1577
+ access: "Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line where its row holds two lines and is cut with an ellipsis past what its lines hold, whole in the tooltip, so no label runs into its neighbour.",
1578
1578
  },
1579
1579
  {
1580
1580
  name: "ChartBarMultiple",
@@ -1719,17 +1719,6 @@ export const USAGE = [
1719
1719
  words: "None of its own.",
1720
1720
  access: "A plain container.",
1721
1721
  },
1722
- {
1723
- name: "Carousel",
1724
- module: "carousel",
1725
- family: "Other",
1726
- summary: "A rail of slides moved with Previous and Next.",
1727
- when: "A controlled, finite rail of like items whose neighbours have a meaningful sequence: screens, testimonials.",
1728
- instead: "A product's records are a list or a table, never a carousel; a sortable record collection is a table or an entity list. One overflowing row is `ScrollArea`.",
1729
- behaviour: "Slides move by swipe, drag or the Previous and Next buttons; the buttons disable at the ends. Left and Right arrow keys move when the carousel holds focus, in both orientations; Up and Down do nothing. The rail is horizontal; `orientation` also accepts `vertical`, which stacks the buttons above and below. The motion is Embla's, and the component does not read the reduced-motion setting, so a page that must honour it sets Embla's `duration` itself through `opts` (Embla jumps with a duration of 0).",
1730
- words: "The buttons name their move: *Previous slide*, *Next slide*.",
1731
- access: "A `region` described as a carousel; each slide is a `group` described as a slide.",
1732
- },
1733
1722
  {
1734
1723
  name: "Collapsible",
1735
1724
  module: "collapsible",
@@ -1835,7 +1824,7 @@ export const USAGE = [
1835
1824
  family: "Other",
1836
1825
  summary: "An area that scrolls along one axis, with a fade where more is waiting.",
1837
1826
  when: '“Use Scroller for an overflowing list of peer items along a single axis: chip rows, log streams, code snippets, command palettes.” (https://vercel.com/geist/scroller) “Pick `vertical` for stacked feeds, `horizontal` for chip and tile rails, `free` only when content genuinely scrolls in both directions (logs with very long lines).” (https://vercel.com/geist/scroller) “For paginated or virtualized data sets larger than a few hundred items, render with a virtualization library inside the Scroller rather than dumping every node into the DOM.” (https://vercel.com/geist/scroller) Ours: Geist\'s `Scroller` is `ScrollArea`, and `vertical`, `horizontal` and `free` are `overflow="y"`, `"x"` and `"both"`. A bounded area whose content overflows: a side panel\'s list, a menu\'s long body, a rail of chips or logos.',
1838
- instead: "Ours: a page scrolls as the document. A sequence of slides on the website is `Carousel`.",
1827
+ instead: "Ours: a page scrolls as the document.",
1839
1828
  behaviour: '“Buttons will automatically scroll to a given **direct** child.” (https://vercel.com/geist/scroller) “Auto-scroll buttons target direct children only. If items are wrapped in extra layout nodes the buttons won’t find their target.” (https://vercel.com/geist/scroller) “Show edge fade or shadow affordances on the clipped axis so users see there’s more content past the viewport.” (https://vercel.com/geist/scroller) “Keep item widths and gaps consistent in horizontal scrollers; ragged edges break the snap rhythm and make the rail feel broken.” (https://vercel.com/geist/scroller) Ours: `overflow` is required, and `buttonLabels` goes only with `overflow="y"` or `"x"`, never `"both"`. Give the area its height or width with `className`, and a border or radius with `frameClassName`, which draws only the scrolling box and leaves the buttons outside it. The scrollbar is hidden; a 40 px fade of the surface at each clipped edge is the only sign there is more, and it is gone at an edge with nothing beyond it. The viewport scrolls natively, so wheel, touch and keyboard all reach it. `buttonLabels` adds two round 32 px outline buttons, 16 px from the area: above it and centred for `y`, below it and at the start for `x`. Each moves to the nearest direct child that is clipped at that end, not by a fixed amount, and sits disabled at the end with nothing beyond it. Smooth scrolling gives way to an instant jump under reduced motion. Colour is neutral only.',
1840
1829
  words: "“Scroller buttons need `aria-label`s that name the direction and content (`Scroll customer logos left`), not bare `Previous`/`Next`.” (https://vercel.com/geist/scroller) Ours: *Scroll installations left*; both labels are required with the buttons.",
1841
1830
  access: "“Tab order follows DOM order, so place items in reading order regardless of visual scroll direction.” (https://vercel.com/geist/scroller) “Make sure focusing an off-screen item scrolls it into view; the default browser behavior covers this, but custom focus traps can break it.” (https://vercel.com/geist/scroller) Ours: the content keeps its own semantics. The viewport is a tab stop when it scrolls.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "12.1.145",
3
+ "version": "12.1.147",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -74,6 +74,7 @@
74
74
  "check:static": "npm run check",
75
75
  "pretest": "npm run build",
76
76
  "test": "node ../../tools/workspace/heavy-slots.mjs --skip-if-filtered -- vitest run",
77
+ "test:visual": "node ../../tools/workspace/heavy-slots.mjs -- playwright test --config playwright.visual.config.ts",
77
78
  "check:export-targets": "node ../../tools/release/check-export-targets.mjs",
78
79
  "test:distribution": "node ../../tools/release/package-smoke-test.mjs"
79
80
  },
@@ -83,14 +84,13 @@
83
84
  "@base-ui/react": "^1.9.0",
84
85
  "@iconify-icons/logos": "^2.0.3",
85
86
  "@iconify/react": "^6.0.2",
86
- "@nadicodeai/design-system": "12.1.145",
87
+ "@nadicodeai/design-system": "12.1.147",
87
88
  "@tanstack/react-table": "^9.3.1",
88
89
  "@vgpu/wgsl": "0.6.0",
89
90
  "class-variance-authority": "^0.7.1",
90
91
  "clsx": "^2.1.1",
91
92
  "cmdk": "^1.1.1",
92
93
  "date-fns": "^4.4.0",
93
- "embla-carousel-react": "^8.6.0",
94
94
  "input-otp": "^1.5.0",
95
95
  "lucide-react": "1.58.0",
96
96
  "motion": "^14.3.0",
@@ -119,7 +119,9 @@
119
119
  "@nadicodeai/eslint-config": "*",
120
120
  "@nadicodeai/eslint-plugin": "*",
121
121
  "@nadicodeai/oxlint-config": "*",
122
+ "@nadicodeai/static-design-server": "*",
122
123
  "@nadicodeai/test-support": "*",
124
+ "@playwright/test": "^1.64.1",
123
125
  "@stryker-mutator/core": "10.0.0",
124
126
  "@stryker-mutator/vitest-runner": "10.0.0",
125
127
  "@tailwindcss/postcss": "^4.3.3",
@@ -1,46 +0,0 @@
1
- import * as React from "react";
2
- import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
3
- import { type IconButtonPartProps } from "./button.js";
4
- type CarouselApi = UseEmblaCarouselType[1];
5
- type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
6
- type CarouselOptions = UseCarouselParameters[0];
7
- type CarouselPlugin = UseCarouselParameters[1];
8
- type CarouselProps = {
9
- opts?: CarouselOptions;
10
- plugins?: CarouselPlugin;
11
- orientation?: "horizontal" | "vertical";
12
- setApi?: (api: CarouselApi) => void;
13
- };
14
- type CarouselContextProps = {
15
- carouselRef: ReturnType<typeof useEmblaCarousel>[0];
16
- api: ReturnType<typeof useEmblaCarousel>[1];
17
- scrollPrev: () => void;
18
- scrollNext: () => void;
19
- canScrollPrev: boolean;
20
- canScrollNext: boolean;
21
- } & CarouselProps;
22
- declare function useCarousel(): CarouselContextProps;
23
- /**
24
- * A rail of slides moved with Previous and Next.
25
- *
26
- * @family Other
27
- * @when A controlled, finite rail of like items whose neighbours have a meaningful sequence:
28
- * screens, testimonials.
29
- * @instead A product's records are a list or a table, never a carousel; a sortable record
30
- * collection is a table or an entity list. One overflowing row is `ScrollArea`.
31
- * @behaviour Slides move by swipe, drag or the Previous and Next buttons; the buttons disable at
32
- * the ends. Left and Right arrow keys move when the carousel holds focus, in both orientations;
33
- * Up and Down do nothing. The rail is horizontal; `orientation` also accepts `vertical`, which
34
- * stacks the buttons above and below. The motion is Embla's, and the component does not read the
35
- * reduced-motion setting, so a page that must honour it sets Embla's `duration` itself through
36
- * `opts` (Embla jumps with a duration of 0).
37
- * @words The buttons name their move: *Previous slide*, *Next slide*.
38
- * @access A `region` described as a carousel; each slide is a `group` described as a slide.
39
- */
40
- declare function Carousel({ orientation, opts, setApi, plugins, className, children, ...props }: React.ComponentProps<"div"> & CarouselProps): React.JSX.Element;
41
- declare function CarouselContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
42
- declare function CarouselItem({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
43
- declare function CarouselPrevious({ className, variant, size, "aria-label": ariaLabel, ...props }: IconButtonPartProps): React.JSX.Element;
44
- declare function CarouselNext({ className, variant, size, "aria-label": ariaLabel, ...props }: IconButtonPartProps): React.JSX.Element;
45
- export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel, };
46
- //# sourceMappingURL=carousel.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../src/components/carousel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,gBAAgB,EAAE,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGnF,OAAO,EAAU,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGvE,KAAK,WAAW,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC3C,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,KAAK,eAAe,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAChD,KAAK,cAAc,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAE/C,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,WAAW,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,GAAG,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,aAAa,CAAC;AAIlB,iBAAS,WAAW,yBAQnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,QAAQ,CAAC,EAChB,WAA0B,EAC1B,IAAI,EACJ,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,aAAa,qBAgF7C;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW5E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAgBzE;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,YAAY,EAAE,SAA4B,EAC1C,GAAG,KAAK,EACT,EAAE,mBAAmB,qBAuBrB;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,YAAY,EAAE,SAAwB,EACtC,GAAG,KAAK,EACT,EAAE,mBAAmB,qBAuBrB;AAED,OAAO,EACL,KAAK,WAAW,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,CAAC"}
@@ -1,109 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import useEmblaCarousel from "embla-carousel-react";
5
- import { cn } from "../lib/utils.js";
6
- import { Button } from "./button.js";
7
- import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
8
- const CarouselContext = React.createContext(null);
9
- function useCarousel() {
10
- const context = React.useContext(CarouselContext);
11
- if (!context) {
12
- throw new Error("useCarousel must be used within a <Carousel />");
13
- }
14
- return context;
15
- }
16
- /**
17
- * A rail of slides moved with Previous and Next.
18
- *
19
- * @family Other
20
- * @when A controlled, finite rail of like items whose neighbours have a meaningful sequence:
21
- * screens, testimonials.
22
- * @instead A product's records are a list or a table, never a carousel; a sortable record
23
- * collection is a table or an entity list. One overflowing row is `ScrollArea`.
24
- * @behaviour Slides move by swipe, drag or the Previous and Next buttons; the buttons disable at
25
- * the ends. Left and Right arrow keys move when the carousel holds focus, in both orientations;
26
- * Up and Down do nothing. The rail is horizontal; `orientation` also accepts `vertical`, which
27
- * stacks the buttons above and below. The motion is Embla's, and the component does not read the
28
- * reduced-motion setting, so a page that must honour it sets Embla's `duration` itself through
29
- * `opts` (Embla jumps with a duration of 0).
30
- * @words The buttons name their move: *Previous slide*, *Next slide*.
31
- * @access A `region` described as a carousel; each slide is a `group` described as a slide.
32
- */
33
- function Carousel({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }) {
34
- const [carouselRef, api] = useEmblaCarousel({
35
- ...opts,
36
- axis: orientation === "horizontal" ? "x" : "y",
37
- }, plugins);
38
- const [canScrollPrev, setCanScrollPrev] = React.useState(false);
39
- const [canScrollNext, setCanScrollNext] = React.useState(false);
40
- const onSelect = React.useCallback((api) => {
41
- if (!api)
42
- return;
43
- setCanScrollPrev(api.canScrollPrev());
44
- setCanScrollNext(api.canScrollNext());
45
- }, []);
46
- const scrollPrev = React.useCallback(() => {
47
- api?.scrollPrev();
48
- }, [api]);
49
- const scrollNext = React.useCallback(() => {
50
- api?.scrollNext();
51
- }, [api]);
52
- const handleKeyDown = React.useCallback((event) => {
53
- if (event.key === "ArrowLeft") {
54
- event.preventDefault();
55
- scrollPrev();
56
- }
57
- else if (event.key === "ArrowRight") {
58
- event.preventDefault();
59
- scrollNext();
60
- }
61
- }, [scrollPrev, scrollNext]);
62
- React.useEffect(() => {
63
- if (!api || !setApi)
64
- return;
65
- setApi(api);
66
- }, [api, setApi]);
67
- React.useEffect(() => {
68
- if (!api)
69
- return;
70
- onSelect(api);
71
- api.on("reInit", onSelect);
72
- api.on("select", onSelect);
73
- return () => {
74
- api.off("reInit", onSelect);
75
- api.off("select", onSelect);
76
- };
77
- }, [api, onSelect]);
78
- return (_jsx(CarouselContext.Provider, { value: {
79
- carouselRef,
80
- api: api,
81
- opts,
82
- orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
83
- scrollPrev,
84
- scrollNext,
85
- canScrollPrev,
86
- canScrollNext,
87
- }, children: _jsx("div", { onKeyDownCapture: handleKeyDown, className: cn("relative", className), role: "region", "aria-roledescription": "carousel", "data-slot": "carousel", ...props, children: children }) }));
88
- }
89
- function CarouselContent({ className, ...props }) {
90
- const { carouselRef, orientation } = useCarousel();
91
- return (_jsx("div", { ref: carouselRef, className: "overflow-hidden", "data-slot": "carousel-content", children: _jsx("div", { className: cn("flex", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className), ...props }) }));
92
- }
93
- function CarouselItem({ className, ...props }) {
94
- const { orientation } = useCarousel();
95
- return (_jsx("div", { role: "group", "aria-roledescription": "slide", "data-slot": "carousel-item", className: cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className), ...props }));
96
- }
97
- function CarouselPrevious({ className, variant = "outline", size = "icon-sm", "aria-label": ariaLabel = "Previous slide", ...props }) {
98
- const { orientation, scrollPrev, canScrollPrev } = useCarousel();
99
- return (_jsx(Button, { "data-slot": "carousel-previous", "aria-label": ariaLabel, variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
100
- ? "inset-y-0 -left-12 my-auto"
101
- : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollPrev, onClick: scrollPrev, ...props, children: _jsx(ChevronLeftIcon, {}) }));
102
- }
103
- function CarouselNext({ className, variant = "outline", size = "icon-sm", "aria-label": ariaLabel = "Next slide", ...props }) {
104
- const { orientation, scrollNext, canScrollNext } = useCarousel();
105
- return (_jsx(Button, { "data-slot": "carousel-next", "aria-label": ariaLabel, variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
106
- ? "inset-y-0 -right-12 my-auto"
107
- : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollNext, onClick: scrollNext, ...props, children: _jsx(ChevronRightIcon, {}) }));
108
- }
109
- export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel, };