@nadicodeai/ui 12.1.130 → 12.1.131

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.
@@ -1,6 +1,5 @@
1
1
  import type { CSSProperties } from "react";
2
2
  import { type AgentOrbFigure, type AgentOrbState } from "./agent-orb.js";
3
- import { type StatusBadgeTone } from "./status-badge.js";
4
3
  /**
5
4
  * One Agent in a list of them: the orb, the name, and the line that says what
6
5
  * the Agent is doing now or what it is for.
@@ -8,11 +7,11 @@ import { type StatusBadgeTone } from "./status-badge.js";
8
7
  * @family Navigation
9
8
  * @when Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.
10
9
  * @instead An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.
11
- * @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.
12
- * @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.
13
- * @access The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative shape, so the line carries its meaning.
10
+ * @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. The orb carries the Agent's state, working, waiting on the person or blocked, so the state line is plain muted text and never a badge. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.
11
+ * @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). Nadia's list says "Working", "Idle" or "Needs you".
12
+ * @access The orb is decorative; the name and the state line are the row's text, read by its control.
14
13
  */
15
- export declare function AgentListRow({ className, color, current, form, motionKey, name, narrow, size, state, stateLine, stateTone, ...props }: Omit<React.ComponentProps<"span">, "color"> & {
14
+ export declare function AgentListRow({ className, color, current, form, motionKey, name, narrow, size, state, stateLine, ...props }: Omit<React.ComponentProps<"span">, "color"> & {
16
15
  /** The pigment of the Agent's chosen form; Nadia's striped ribbon keeps her own. */
17
16
  color?: CSSProperties["color"];
18
17
  /** The row the list is on now. */
@@ -26,7 +25,5 @@ export declare function AgentListRow({ className, color, current, form, motionKe
26
25
  state?: AgentOrbState;
27
26
  /** What the Agent is doing, or what it is for. Absent, the name stands alone. */
28
27
  stateLine?: string;
29
- /** How the state line stands: a failure is `danger`. Absent, the line stays plain text. */
30
- stateTone?: StatusBadgeTone;
31
28
  }): import("react").JSX.Element;
32
29
  //# sourceMappingURL=agent-list-row.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-list-row.d.ts","sourceRoot":"","sources":["../../src/components/agent-list-row.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG9E;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,KAAK,EACL,OAAe,EACf,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAc,EACd,IAAS,EACT,KAAc,EACd,SAAS,EACT,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG;IAC/C,oFAAoF;IACpF,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,+BAoCA"}
1
+ {"version":3,"file":"agent-list-row.d.ts","sourceRoot":"","sources":["../../src/components/agent-list-row.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG3F;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,KAAK,EACL,OAAe,EACf,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAc,EACd,IAAS,EACT,KAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG;IAC/C,oFAAoF;IACpF,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAgCA"}
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { AgentOrb } from "./agent-orb.js";
4
- import { StatusBadge } from "./status-badge.js";
5
4
  import { cn } from "../lib/utils.js";
6
5
  /**
7
6
  * One Agent in a list of them: the orb, the name, and the line that says what
@@ -10,10 +9,10 @@ import { cn } from "../lib/utils.js";
10
9
  * @family Navigation
11
10
  * @when Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.
12
11
  * @instead An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.
13
- * @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.
14
- * @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.
15
- * @access The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative shape, so the line carries its meaning.
12
+ * @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. The orb carries the Agent's state, working, waiting on the person or blocked, so the state line is plain muted text and never a badge. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.
13
+ * @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). Nadia's list says "Working", "Idle" or "Needs you".
14
+ * @access The orb is decorative; the name and the state line are the row's text, read by its control.
16
15
  */
17
- export function AgentListRow({ className, color, current = false, form, motionKey, name, narrow = false, size = 40, state = "idle", stateLine, stateTone, ...props }) {
18
- return (_jsxs("span", { className: cn("flex w-full min-w-0 items-center gap-3 text-left text-sm", size === 64 && "gap-1", narrow && "justify-center", className), "data-slot": "agent-list-row", "data-current": current || undefined, ...props, children: [_jsx(AgentOrb, { className: cn(size === 64 && "-my-1.5 -ml-1"), color: color, decorative: true, form: form, motionKey: motionKey, size: size, state: state }), _jsxs("span", { className: cn("grid min-w-0", narrow && "sr-only"), children: [_jsx("span", { className: cn("truncate text-foreground", current && "font-medium"), children: name }), stateLine ? (_jsx("span", { className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground", children: stateTone ? (_jsx(StatusBadge, { label: stateLine, size: "sm", tone: stateTone })) : (_jsx("span", { className: "truncate", children: stateLine })) })) : null] })] }));
16
+ export function AgentListRow({ className, color, current = false, form, motionKey, name, narrow = false, size = 40, state = "idle", stateLine, ...props }) {
17
+ return (_jsxs("span", { className: cn("flex w-full min-w-0 items-center gap-3 text-left text-sm", size === 64 && "gap-1", narrow && "justify-center", className), "data-slot": "agent-list-row", "data-current": current || undefined, ...props, children: [_jsx(AgentOrb, { className: cn(size === 64 && "-my-1.5 -ml-1"), color: color, decorative: true, form: form, motionKey: motionKey, size: size, state: state }), _jsxs("span", { className: cn("grid min-w-0", narrow && "sr-only"), children: [_jsx("span", { className: cn("truncate text-foreground", current && "font-medium"), children: name }), stateLine ? (_jsx("span", { className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground", children: _jsx("span", { className: "truncate", children: stateLine }) })) : null] })] }));
19
18
  }
@@ -29,7 +29,11 @@ import { type FieldSize } from "../internal/input-box.js";
29
29
  * the placeholder, marks and list stay neutral. `label` and `error` go on `ComboboxInput`, and a
30
30
  * string `label` requires `id`; a box with no name does not compile. The list, a solid floating surface, opens 8 px under it
31
31
  * at its width (a narrower `className` width centres under the box), in a 6 px inset, up to five
32
- * and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap.
32
+ * and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap;
33
+ * a `long` list, one people scan by section, shows twelve and a half rows (462 px).
34
+ * A trigger that opens a list with its own search puts `ComboboxInput` first in `ComboboxContent`:
35
+ * there the box draws no ring or halo, spans the list on its surface, and a hairline divides it
36
+ * from the rows, wherever it sits in the content.
33
37
  * A row is one line that ends in an ellipsis, with a 16 px mark 12 px before the name and a 14 px
34
38
  * check at the chosen row's end, after the name. A row that cannot be chosen turns its text muted,
35
39
  * never dimmed. Typing filters the list. "Options can opt out of the fixed row height with `ignoreDefaultHeight`
@@ -98,7 +102,10 @@ declare function ComboboxContent({ className, side, sideOffset, align, alignOffs
98
102
  /** What the list says when nothing matches, quoting the query; `null` while a search runs. */
99
103
  empty: string | null;
100
104
  }): React.JSX.Element;
101
- declare function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props): React.JSX.Element;
105
+ declare function ComboboxList({ className, long, ...props }: ComboboxPrimitive.List.Props & {
106
+ /** A list people scan by section, such as the models of every lab: twelve and a half rows. */
107
+ long?: boolean;
108
+ }): React.JSX.Element;
102
109
  declare function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.Props): React.JSX.Element;
103
110
  declare function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props): React.JSX.Element;
104
111
  declare function ComboboxLabel({ className, ...props }: ComboboxPrimitive.GroupLabel.Props): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/components/combobox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAIxE,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AASpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,QAAA,MAAM,QAAQ,+BAAyB,CAAC;AAExC,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,qBAEjE;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,OAAO,CAAC,KAAK,qBAW1F;AAkBD,KAAK,qBAAqB,GACtB;IAAE,WAAW,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,CAAA;CAAE,GAChD;IAAE,WAAW,CAAC,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,KAAK,mBAAmB,GACpB;IAAE,SAAS,CAAC,EAAE,KAAK,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAA;CAAE,GAC7C;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,QAAgB,EAChB,WAAkB,EAClB,YAAY,EACZ,SAAiB,EACjB,UAAU,EACV,IAAI,EACJ,KAAK,EACL,KAAK,EACL,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,GAAG;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,wFAAwF;IACxF,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SAAS,GACX,qBAAqB,GACrB,mBAAmB,qBA0CpB;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,IAAe,EACf,UAAc,EACd,KAAgB,EAChB,WAAe,EACf,MAAM,EACN,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,GAC9B,IAAI,CACF,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAClC,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,aAAa,GAAG,QAAQ,CAC3D,GAAG;IACF,8FAA8F;IAC9F,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,qBA2BF;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,qBAW1E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,qBAwBpF;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,qBAI5E;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,UAAU,CAAC,KAAK,qBAQjF;AAED,iBAAS,kBAAkB,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,UAAU,CAAC,KAAK,qBAE3E;AAeD,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,MAAM,CAAC,KAAK,qBAQ/E;AAED,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,CAAC,SAAS,CAAC,KAAK,qBAQpF;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,qBAAqB,CAAC,OAAO,iBAAiB,CAAC,KAAK,CAAC,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,qBAa7F;AAED,KAAK,kBAAkB,GACnB;IAAE,UAAU,EAAE,KAAK,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAA;CAAE,GAC9C;IAAE,UAAU,CAAC,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,QAAQ,EACR,UAAiB,EACjB,WAAW,EACX,GAAG,KAAK,EACT,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,GAAG,kBAAkB,qBAsBnD;AAED,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,GAAG,cAAc,qBAShD;AAED,iBAAS,iBAAiB,2CAEzB;AAED,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/components/combobox.tsx"],"names":[],"mappings":"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"}
@@ -34,7 +34,11 @@ import { ChevronDownIcon, XIcon, CheckIcon, SearchIcon } from "lucide-react";
34
34
  * the placeholder, marks and list stay neutral. `label` and `error` go on `ComboboxInput`, and a
35
35
  * string `label` requires `id`; a box with no name does not compile. The list, a solid floating surface, opens 8 px under it
36
36
  * at its width (a narrower `className` width centres under the box), in a 6 px inset, up to five
37
- * and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap.
37
+ * and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap;
38
+ * a `long` list, one people scan by section, shows twelve and a half rows (462 px).
39
+ * A trigger that opens a list with its own search puts `ComboboxInput` first in `ComboboxContent`:
40
+ * there the box draws no ring or halo, spans the list on its surface, and a hairline divides it
41
+ * from the rows, wherever it sits in the content.
38
42
  * A row is one line that ends in an ellipsis, with a 16 px mark 12 px before the name and a 14 px
39
43
  * check at the chosen row's end, after the name. A row that cannot be chosen turns its text muted,
40
44
  * never dimmed. Typing filters the list. "Options can opt out of the fixed row height with `ignoreDefaultHeight`
@@ -84,15 +88,20 @@ function ComboboxTrigger({ className, children, ...props }) {
84
88
  function ComboboxClear({ className, ...props }) {
85
89
  return (_jsx(ComboboxPrimitive.Clear, { "data-slot": "combobox-clear", render: _jsx(InputGroupButton, { variant: "ghost", size: "icon", "aria-label": props["aria-label"] }), className: cn(className), ...props, children: _jsx(XIcon, { className: "pointer-events-none size-3.5" }) }));
86
90
  }
91
+ /** True inside `ComboboxContent`, where `ComboboxInput` is the list's own search. */
92
+ const InComboboxList = React.createContext(false);
87
93
  function ComboboxInput({ className, children, disabled = false, showTrigger = true, triggerLabel, showClear = false, clearLabel, size, label, error, ...props }) {
88
94
  const hasButton = showTrigger || showClear;
89
- return (_jsx(FieldFrame, { label: label, error: error, size: size, control: props, children: (aria) => (_jsxs(InputGroup, { size: size, className: className, children: [_jsx(InputGroupAddon, { children: _jsx(SearchIcon, { "aria-hidden": "true" }) }), _jsx(ComboboxPrimitive.Input, { render: _jsx(InputGroupControl, { disabled: disabled, className: cn("aria-invalid:text-destructive", hasButton && "pr-0") }), ...props, ...aria }), hasButton ? (_jsxs(InputGroupAddon, { align: "inline-end", children: [showTrigger && triggerLabel !== undefined ? (_jsx(InputGroupButton, { size: "icon", variant: "ghost", "aria-label": triggerLabel, render: _jsx(ComboboxTrigger, {}), "data-slot": "input-group-button", className: "group-data-[size=default]/input-group:h-7.5 group-data-[size=default]/input-group:self-center group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent", disabled: disabled })) : null, showClear && clearLabel !== undefined ? (_jsx(ComboboxClear, { "aria-label": clearLabel, disabled: disabled })) : null] })) : null, children] })) }));
95
+ const inList = React.useContext(InComboboxList);
96
+ return (_jsx(FieldFrame, { label: label, error: error, size: size, control: props, children: (aria) => (_jsxs(InputGroup, { size: size, className: cn(inList && "rounded-none border-b border-border bg-transparent shadow-none", className), children: [_jsx(InputGroupAddon, { children: _jsx(SearchIcon, { "aria-hidden": "true" }) }), _jsx(ComboboxPrimitive.Input, { render: _jsx(InputGroupControl, { disabled: disabled, className: cn("aria-invalid:text-destructive", hasButton && "pr-0") }), ...props, ...aria }), hasButton ? (_jsxs(InputGroupAddon, { align: "inline-end", children: [showTrigger && triggerLabel !== undefined ? (_jsx(InputGroupButton, { size: "icon", variant: "ghost", "aria-label": triggerLabel, render: _jsx(ComboboxTrigger, {}), "data-slot": "input-group-button", className: "group-data-[size=default]/input-group:h-7.5 group-data-[size=default]/input-group:self-center group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent", disabled: disabled })) : null, showClear && clearLabel !== undefined ? (_jsx(ComboboxClear, { "aria-label": clearLabel, disabled: disabled })) : null] })) : null, children] })) }));
90
97
  }
91
98
  function ComboboxContent({ className, side = "bottom", sideOffset = 8, align = "center", alignOffset = 0, anchor, empty, children, ...props }) {
92
- return (_jsx(ComboboxPrimitive.Portal, { children: _jsx(ComboboxPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, anchor: anchor, className: "isolate z-50", children: _jsxs(ComboboxPrimitive.Popup, { "data-slot": "combobox-content", className: cn("pointer-events-auto", "group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) overflow-hidden rounded-lg border-0 bg-popover text-popover-foreground nc-elevation-floating *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-control-height *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-[0_0_0_1px_color-mix(in_oklab,var(--input)_30%,transparent)]", anchoredOverlayMotion, className), ...props, children: [empty === null ? null : _jsx(ComboboxEmpty, { children: empty }), children] }) }) }));
99
+ return (_jsx(ComboboxPrimitive.Portal, { children: _jsx(ComboboxPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, anchor: anchor, className: "isolate z-50", children: _jsx(ComboboxPrimitive.Popup, { "data-slot": "combobox-content", className: cn("pointer-events-auto", "group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) overflow-hidden rounded-lg border-0 bg-popover text-popover-foreground nc-elevation-floating", anchoredOverlayMotion, className), ...props, children: _jsxs(InComboboxList.Provider, { value: true, children: [empty === null ? null : _jsx(ComboboxEmpty, { children: empty }), children] }) }) }) }));
93
100
  }
94
- function ComboboxList({ className, ...props }) {
95
- return (_jsx(ComboboxPrimitive.List, { "data-slot": "combobox-list", className: cn("no-scrollbar max-h-[min(--spacing(52.5),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1.5 data-empty:p-0", className), ...props }));
101
+ function ComboboxList({ className, long = false, ...props }) {
102
+ return (_jsx(ComboboxPrimitive.List, { "data-slot": "combobox-list", className: cn("no-scrollbar scroll-py-1 overflow-y-auto overscroll-contain p-1.5 data-empty:p-0", long
103
+ ? "max-h-[min(--spacing(115.5),calc(var(--available-height)---spacing(9)))]"
104
+ : "max-h-[min(--spacing(52.5),calc(var(--available-height)---spacing(9)))]", className), ...props }));
96
105
  }
97
106
  function ComboboxItem({ className, children, ...props }) {
98
107
  return (_jsxs(ComboboxPrimitive.Item, { "data-slot": "combobox-item", className: cn("relative flex min-h-touch-target w-full cursor-default items-center gap-3 rounded-sm px-2 py-2 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:text-muted-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [React.Children.map(children, (child) => React.isValidElement(child) ? (child) : (_jsx("span", { className: "min-w-0 truncate text-left", children: child }))), _jsx(ComboboxPrimitive.ItemIndicator, { render: _jsx("span", { className: "pointer-events-none ml-auto flex shrink-0 items-center" }), children: _jsx(CheckIcon, { className: "pointer-events-none size-3.5" }) })] }));
@@ -26,7 +26,10 @@ import { type FieldSize } from "../internal/input-box.js";
26
26
  * never dimmed. Arrows, typing, Enter, Escape. A placeholder reads in the muted grey and is never
27
27
  * an option. `label` and `error` go on `SelectTrigger`, and a string `label` requires `id`; a
28
28
  * trigger with no name does not compile. "Group options past ~10 items with native `<optgroup>`;
29
- * Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: group the
29
+ * Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: `look="inline"`
30
+ * draws the trigger as a ghost `Button` of its size, for a toolbar such as a chat bar's reasoning
31
+ * level: no box and no field ring, the fill only when hovered or open, the Button's focus outline
32
+ * and its disabled dimming; the list is the same. Group the
30
33
  * options with `SelectGroup`. "Validate on blur and pass a string to `error`; messages name the
31
34
  * field and end in a period (`Select a framework.`)." (https://vercel.com/geist/select) "Don’t wrap
32
35
  * a labelled `<Select>` in a `Tooltip`; put the hint on a sibling icon button so the label stays
@@ -50,10 +53,13 @@ declare function SelectValue({ className, ...props }: SelectPrimitive.Value.Prop
50
53
  * `SelectTrigger`, such as `MultiSelectTrigger`, wears the same box.
51
54
  */
52
55
  declare const selectTriggerVariants: (props?: ({
56
+ look?: "inline" | "field" | null | undefined;
53
57
  size?: "default" | "sm" | "lg" | null | undefined;
54
58
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
55
59
  type SelectTriggerProps = Omit<SelectPrimitive.Trigger.Props, "prefix"> & {
56
60
  size?: FieldSize;
61
+ /** `inline` sits among a toolbar's ghost buttons, such as a chat bar's reasoning level, and is drawn as one. */
62
+ look?: "field" | "inline";
57
63
  /** A mark before the value, such as an icon. */
58
64
  prefix?: React.ReactNode;
59
65
  /** A mark at the end, in place of the chevron. */
@@ -63,7 +69,7 @@ type SelectTriggerProps = Omit<SelectPrimitive.Trigger.Props, "prefix"> & {
63
69
  /** The message under the box, in the product's words; it also marks the box invalid. */
64
70
  error?: string;
65
71
  } & FieldName;
66
- declare function SelectTrigger({ className, size, prefix, suffix, label, description, error, children, ...props }: SelectTriggerProps): React.JSX.Element;
72
+ declare function SelectTrigger({ className, size, look, prefix, suffix, label, description, error, children, ...props }: SelectTriggerProps): React.JSX.Element;
67
73
  declare function SelectContent({ className, children, side, sideOffset, align, alignOffset, alignItemWithTrigger, ...props }: SelectPrimitive.Popup.Props & Pick<SelectPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger">): React.JSX.Element;
68
74
  declare function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props): React.JSX.Element;
69
75
  declare function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKlE,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,QAAA,MAAM,MAAM,6BAAuB,CAAC;AAEpC,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED;;;GAGG;AACH,QAAA,MAAM,qBAAqB;;8EAgB1B,CAAC;AAEF,KAAK,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG;IACxE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kDAAkD;IAClD,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SAAS,CAAC;AAEd,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,IAAgB,EAChB,MAAM,EACN,MAAM,EACN,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,qBAyCpB;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,IAAe,EACf,UAAc,EACd,KAAgB,EAChB,WAAe,EACf,oBAA4B,EAC5B,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,GAC5B,IAAI,CACF,eAAe,CAAC,UAAU,CAAC,KAAK,EAChC,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,sBAAsB,CACzE,qBA6BF;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,UAAU,CAAC,KAAK,qBAQ7E;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAsBhF;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,qBAQhF;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,aAAa,CAAC,qBAa5D;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,eAAe,CAAC,qBAa9D;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,WAAW,GACZ,CAAC"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/components/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMlE,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAG9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,QAAA,MAAM,MAAM,6BAAuB,CAAC;AAEpC,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAQxE;AAED;;;GAGG;AACH,QAAA,MAAM,qBAAqB;;;8EAkB1B,CAAC;AAEF,KAAK,kBAAkB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG;IACxE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,gHAAgH;IAChH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,gDAAgD;IAChD,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kDAAkD;IAClD,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SAAS,CAAC;AAEd,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,IAAgB,EAChB,IAAc,EACd,MAAM,EACN,MAAM,EACN,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,qBA+CpB;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,IAAe,EACf,UAAc,EACd,KAAgB,EAChB,WAAe,EACf,oBAA4B,EAC5B,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,GAC5B,IAAI,CACF,eAAe,CAAC,UAAU,CAAC,KAAK,EAChC,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,sBAAsB,CACzE,qBA6BF;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,UAAU,CAAC,KAAK,qBAQ7E;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAsBhF;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,qBAQhF;AAED,iBAAS,oBAAoB,CAAC,EAC5B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,aAAa,CAAC,qBAa5D;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,eAAe,CAAC,qBAa9D;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,WAAW,GACZ,CAAC"}
@@ -4,6 +4,7 @@ import { Select as SelectPrimitive } from "@base-ui/react/select";
4
4
  import { cva } from "class-variance-authority";
5
5
  import { cn } from "../lib/utils.js";
6
6
  import { anchoredOverlayMotion } from "../lib/motion.js";
7
+ import { buttonVariants } from "./button.js";
7
8
  import { FieldFrame } from "../internal/field-frame.js";
8
9
  import { fieldDisabled, fieldOpen, fieldRing, fieldStates, } from "../internal/input-box.js";
9
10
  import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
@@ -31,7 +32,10 @@ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
31
32
  * never dimmed. Arrows, typing, Enter, Escape. A placeholder reads in the muted grey and is never
32
33
  * an option. `label` and `error` go on `SelectTrigger`, and a string `label` requires `id`; a
33
34
  * trigger with no name does not compile. "Group options past ~10 items with native `<optgroup>`;
34
- * Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: group the
35
+ * Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: `look="inline"`
36
+ * draws the trigger as a ghost `Button` of its size, for a toolbar such as a chat bar's reasoning
37
+ * level: no box and no field ring, the fill only when hovered or open, the Button's focus outline
38
+ * and its disabled dimming; the list is the same. Group the
35
39
  * options with `SelectGroup`. "Validate on blur and pass a string to `error`; messages name the
36
40
  * field and end in a period (`Select a framework.`)." (https://vercel.com/geist/select) "Don’t wrap
37
41
  * a labelled `<Select>` in a `Tooltip`; put the hint on a sibling icon button so the label stays
@@ -59,21 +63,25 @@ function SelectValue({ className, ...props }) {
59
63
  * `SelectTrigger`, such as `MultiSelectTrigger`, wears the same box.
60
64
  */
61
65
  const selectTriggerVariants = cva([
62
- "flex min-h-touch-target w-full items-center justify-between gap-1.5 bg-(--nc-field,var(--background)) py-0 pr-3 pl-control-padding-inline text-sm whitespace-nowrap select-none data-placeholder:text-placeholder [@media(hover:hover)_and_(pointer:fine)]:min-h-0 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
63
- fieldRing,
64
- fieldDisabled,
66
+ "flex min-h-touch-target w-full items-center justify-between gap-1.5 py-0 pr-3 pl-control-padding-inline text-sm whitespace-nowrap select-none data-placeholder:text-placeholder [@media(hover:hover)_and_(pointer:fine)]:min-h-0 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
65
67
  ], {
66
68
  variants: {
69
+ look: {
70
+ field: ["bg-(--nc-field,var(--background))", fieldRing, fieldDisabled],
71
+ inline: "",
72
+ },
67
73
  size: {
68
74
  sm: "h-nadicode-control-height-sm rounded-sm",
69
75
  default: "h-control-height rounded-sm",
70
76
  lg: "h-nadicode-control-height-lg rounded-md text-base",
71
77
  },
72
78
  },
73
- defaultVariants: { size: "default" },
79
+ defaultVariants: { look: "field", size: "default" },
74
80
  });
75
- function SelectTrigger({ className, size = "default", prefix, suffix, label, description, error, children, ...props }) {
76
- return (_jsx(FieldFrame, { label: label, description: description, error: error, size: size, control: props, children: (aria) => (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, "data-field-frame": "", className: cn(selectTriggerVariants({ size }), fieldStates, fieldOpen, className), ...props, ...aria, children: [prefix ? (_jsx("span", { "data-slot": "select-prefix", "aria-hidden": "true", className: "mr-1.5 flex shrink-0 items-center text-muted-foreground", children: prefix })) : null, children, suffix ? (_jsx("span", { "data-slot": "select-suffix", "aria-hidden": "true", className: "flex shrink-0 items-center text-muted-foreground", children: suffix })) : (_jsx(SelectPrimitive.Icon, { render: _jsx(ChevronDownIcon, { className: "pointer-events-none size-3.5 text-muted-foreground" }) }))] })) }));
81
+ function SelectTrigger({ className, size = "default", look = "field", prefix, suffix, label, description, error, children, ...props }) {
82
+ return (_jsx(FieldFrame, { label: label, description: description, error: error, size: size, control: props, children: (aria) => (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, "data-field-frame": look === "field" ? "" : undefined, className: cn(selectTriggerVariants({ look, size }), look === "field"
83
+ ? [fieldStates, fieldOpen]
84
+ : [buttonVariants({ variant: "ghost", size }), "w-fit min-w-0 justify-between"], className), ...props, ...aria, children: [prefix ? (_jsx("span", { "data-slot": "select-prefix", "aria-hidden": "true", className: "mr-1.5 flex shrink-0 items-center text-muted-foreground", children: prefix })) : null, children, suffix ? (_jsx("span", { "data-slot": "select-suffix", "aria-hidden": "true", className: "flex shrink-0 items-center text-muted-foreground", children: suffix })) : (_jsx(SelectPrimitive.Icon, { render: _jsx(ChevronDownIcon, { className: "pointer-events-none size-3.5 text-muted-foreground" }) }))] })) }));
77
85
  }
78
86
  function SelectContent({ className, children, side = "bottom", sideOffset = 8, align = "center", alignOffset = 0, alignItemWithTrigger = false, ...props }) {
79
87
  return (_jsx(SelectPrimitive.Portal, { children: _jsx(SelectPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, alignItemWithTrigger: alignItemWithTrigger, className: "isolate z-50", children: _jsxs(SelectPrimitive.Popup, { "data-slot": "select-content", "data-align-trigger": alignItemWithTrigger, className: cn("pointer-events-auto", "relative isolate z-50 max-h-(--available-height) w-auto max-w-(--available-width) min-w-(--anchor-width) overflow-x-hidden overflow-y-auto rounded-lg border-0 bg-popover text-popover-foreground nc-elevation-floating data-[align-trigger=true]:transition-none", anchoredOverlayMotion, className), ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.List, { className: "p-1.5", children: children }), _jsx(SelectScrollDownButton, {})] }) }) }));
@@ -167,7 +167,7 @@ function isRingOrOutlineMechanic(utility) {
167
167
  * `better-tailwindcss/no-unknown-classes` reports it as one. That is what
168
168
  * retired the hand-written colour-name list this rule used to carry.
169
169
  */
170
- function isAppearanceUtility(utility) {
170
+ export function isAppearanceUtility(utility) {
171
171
  const base = withoutVariants(utility);
172
172
  return (
173
173
  /^appearance-/.test(base) ||
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/navigation.tsx"],"names":[],"mappings":"AAoEA,iBAAS,qBAAqB,gCAoC7B;AAED,iBAAS,qBAAqB,gCAmB7B;AAED,iBAAS,uBAAuB,gCAiE/B;AAED,iBAAS,YAAY,gCAqCpB;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;CAmRI,CAAC"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/navigation.tsx"],"names":[],"mappings":"AAoEA,iBAAS,qBAAqB,gCAoC7B;AAED,iBAAS,qBAAqB,gCAmB7B;AAED,iBAAS,uBAAuB,gCAiE/B;AAED,iBAAS,YAAY,gCAqCpB;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;CAkRI,CAAC"}
@@ -86,7 +86,7 @@ function TabsSpecimen() {
86
86
  return (_jsxs("div", { className: "grid gap-8", children: [_jsxs(Tabs, { onValueChange: setPlain, value: plain, children: [_jsxs(TabsList, { "aria-label": "Rossi Ottica", children: [_jsx(TabsTrigger, { value: "overview", children: "Overview" }), _jsx(TabsTrigger, { value: "installations", children: "Installations" }), _jsx(TabsTrigger, { disabled: true, disabledReason: "Only owners see billing", value: "billing", children: "Billing" })] }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "overview", children: "What the customer runs, at a glance." }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "installations", children: "Every machine Nadia is installed on." })] }), _jsxs(Tabs, { onValueChange: setLined, value: lined, children: [_jsxs(TabsList, { "aria-label": "Rossi Ottica, with a rule", variant: "line", children: [_jsx(TabsTrigger, { value: "overview", children: "Overview" }), _jsx(TabsTrigger, { value: "installations", children: "Installations" }), _jsx(TabsTrigger, { disabled: true, disabledReason: "Only owners see billing", value: "billing", children: "Billing" })] }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "overview", children: "What the customer runs, at a glance." }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "installations", children: "Every machine Nadia is installed on." })] })] }));
87
87
  }
88
88
  export const NAVIGATION = {
89
- AgentListRow: () => (_jsxs("ul", { className: "grid max-w-xs gap-1", children: [_jsx("li", { children: _jsx(AgentListRow, { color: COBALTO, current: true, form: "orbit", name: "Invoices", state: "working", stateLine: "Drafting October's invoices" }) }), _jsx("li", { children: _jsx(AgentListRow, { color: VERDE, form: "lattice", name: "Orders", state: "waiting", stateLine: "Waiting for you", stateTone: "warning" }) })] })),
89
+ AgentListRow: () => (_jsxs("ul", { className: "grid max-w-xs gap-1", children: [_jsx("li", { children: _jsx(AgentListRow, { color: COBALTO, current: true, form: "orbit", name: "Invoices", state: "working", stateLine: "Drafting October's invoices" }) }), _jsx("li", { children: _jsx(AgentListRow, { color: VERDE, form: "lattice", name: "Orders", state: "waiting", stateLine: "Waiting for you" }) })] })),
90
90
  Breadcrumb: () => (_jsxs("div", { className: "grid gap-4", children: [_jsx(Breadcrumb, { "aria-label": "Path", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica" }) })] }) }), _jsx(Breadcrumb, { "aria-label": "Path with a closed ancestor", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { disabled: true, children: "Partners" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica" }) })] }) }), _jsx(Breadcrumb, { "aria-label": "Long path", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbEllipsis, { label: "More" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#installations", children: "Installations" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica, Milano" }) })] }) })] })),
91
91
  CommandDialog: CommandDialogSpecimen,
92
92
  Footer: () => (_jsx(Footer, { children: _jsxs(FooterInner, { children: [_jsx(FooterBrand, { "aria-label": "nadicode", href: "#top", children: _jsx(BrandWordmark, { alt: "" }) }), _jsx(FooterIdentity, { children: "Agents that do the work, for Italian companies." }), _jsxs(FooterNav, { "aria-label": "Company", children: [_jsx("a", { href: "#privacy", children: "Privacy" }), _jsx("a", { href: "#terms", children: "Terms" })] }), _jsx(FooterMeta, { children: "\u00A9 2026 nadicode" })] }) })),
@@ -483,7 +483,7 @@ export const USAGE = [
483
483
  summary: "Type to find one value, or several, in a known set.",
484
484
  when: '"Filters large lists to selectable options based on the matching query." (https://vercel.com/geist/combobox) "Pick `<Combobox>` when users type to filter a known list of values (regions, frameworks, env-var names)." (https://vercel.com/geist/combobox) Ours: assign an Agent, choose a time zone, add several Agents at once with `multiple`.',
485
485
  instead: '"For short, fixed lists where typing adds nothing, switch to `Select`." (https://vercel.com/geist/combobox) "When more than one value can be chosen at once, use `MultiSelect`." (https://vercel.com/geist/combobox) "For free-form filter strings that don’t resolve to a single option, drop in `Input` with the `search` variant." (https://vercel.com/geist/combobox) Ours: several values chosen from a list you scan rather than type into is a `MultiSelect`; `Combobox` takes several with `multiple`. `Input` has no `search` variant, so free text is an `Input` and narrowing a collection is `CollectionFilters`.',
486
- behaviour: 'The parts are `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, `ComboboxGroup` with its `ComboboxLabel`, `ComboboxLoading`, and `ComboboxChips` with its `ComboboxChip` and `ComboboxChipsInput` for `multiple`; the line for no match is the `empty` of `ComboboxContent`. The box fills its container and is `Input`\'s: its three sizes (`size` on `ComboboxInput`), its ring, hover, focus halo and disabled, with the search mark at the start, a `placeholder` that names the scope, and the open-list or clear button flush at the end, in the muted grey until hovered (the open-list button is 30 px high and centred at the default size, full height at `sm` and `lg`). Colour sits in one place: an error turns the ring red, fills the halo and colours the typed text; the placeholder, marks and list stay neutral. `label` and `error` go on `ComboboxInput`, and a string `label` requires `id`; a box with no name does not compile. The list, a solid floating surface, opens 8 px under it at its width (a narrower `className` width centres under the box), in a 6 px inset, up to five and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap. A row is one line that ends in an ellipsis, with a 16 px mark 12 px before the name and a 14 px check at the chosen row\'s end, after the name. A row that cannot be chosen turns its text muted, never dimmed. Typing filters the list. "Options can opt out of the fixed row height with `ignoreDefaultHeight` to render multi-line content (e.g. a shared environment variable name plus its target). The list sizes each row to its content and stays scrollable." (https://vercel.com/geist/combobox) Ours: there is no `ignoreDefaultHeight`; a two-line row is an explicit column child. "Show a loading state for async results; don’t collapse the list while the request is in flight." (https://vercel.com/geist/combobox) Ours: while results load the list stays and `ComboboxLoading` says so, and the chosen value stays; `ComboboxContent` requires `empty`, the sentence for no match, or `null` while a search is still running. "Render a custom empty state of the form `No {items} match "{query}"` rather than a bare `No results`." (https://vercel.com/geist/combobox) "Keep arrow-key navigation through `<Combobox.Option>` items; don’t hijack Enter to submit the surrounding form while the list is open." (https://vercel.com/geist/combobox) "Set `clearable` to show a clear button when a value is selected." (https://vercel.com/geist/combobox) Ours: `showClear` with a `clearLabel` does it; clear empties the box and keeps focus there. With `multiple`, each choice is a chip with its own remove; Backspace in an empty box removes the last. "It is common to use Combobox inside a Modal. On mobile, the Modal automatically renders a Dialog instead." (https://vercel.com/geist/combobox) "Inside a `Modal`, Geist switches to a Dialog on mobile automatically; don’t layer a second portal." (https://vercel.com/geist/combobox) Ours: our overlay is `Dialog`, and `ComboboxContent` is the list\'s one portal.',
486
+ behaviour: 'The parts are `ComboboxInput`, `ComboboxContent`, `ComboboxList`, `ComboboxItem`, `ComboboxGroup` with its `ComboboxLabel`, `ComboboxLoading`, and `ComboboxChips` with its `ComboboxChip` and `ComboboxChipsInput` for `multiple`; the line for no match is the `empty` of `ComboboxContent`. The box fills its container and is `Input`\'s: its three sizes (`size` on `ComboboxInput`), its ring, hover, focus halo and disabled, with the search mark at the start, a `placeholder` that names the scope, and the open-list or clear button flush at the end, in the muted grey until hovered (the open-list button is 30 px high and centred at the default size, full height at `sm` and `lg`). Colour sits in one place: an error turns the ring red, fills the halo and colours the typed text; the placeholder, marks and list stay neutral. `label` and `error` go on `ComboboxInput`, and a string `label` requires `id`; a box with no name does not compile. The list, a solid floating surface, opens 8 px under it at its width (a narrower `className` width centres under the box), in a 6 px inset, up to five and a half rows tall (210 px) so a cut row shows there is more, with rows 36 px tall and no gap; a `long` list, one people scan by section, shows twelve and a half rows (462 px). A trigger that opens a list with its own search puts `ComboboxInput` first in `ComboboxContent`: there the box draws no ring or halo, spans the list on its surface, and a hairline divides it from the rows, wherever it sits in the content. A row is one line that ends in an ellipsis, with a 16 px mark 12 px before the name and a 14 px check at the chosen row\'s end, after the name. A row that cannot be chosen turns its text muted, never dimmed. Typing filters the list. "Options can opt out of the fixed row height with `ignoreDefaultHeight` to render multi-line content (e.g. a shared environment variable name plus its target). The list sizes each row to its content and stays scrollable." (https://vercel.com/geist/combobox) Ours: there is no `ignoreDefaultHeight`; a two-line row is an explicit column child. "Show a loading state for async results; don’t collapse the list while the request is in flight." (https://vercel.com/geist/combobox) Ours: while results load the list stays and `ComboboxLoading` says so, and the chosen value stays; `ComboboxContent` requires `empty`, the sentence for no match, or `null` while a search is still running. "Render a custom empty state of the form `No {items} match "{query}"` rather than a bare `No results`." (https://vercel.com/geist/combobox) "Keep arrow-key navigation through `<Combobox.Option>` items; don’t hijack Enter to submit the surrounding form while the list is open." (https://vercel.com/geist/combobox) "Set `clearable` to show a clear button when a value is selected." (https://vercel.com/geist/combobox) Ours: `showClear` with a `clearLabel` does it; clear empties the box and keeps focus there. With `multiple`, each choice is a chip with its own remove; Backspace in an empty box removes the last. "It is common to use Combobox inside a Modal. On mobile, the Modal automatically renders a Dialog instead." (https://vercel.com/geist/combobox) "Inside a `Modal`, Geist switches to a Dialog on mobile automatically; don’t layer a second portal." (https://vercel.com/geist/combobox) Ours: our overlay is `Dialog`, and `ComboboxContent` is the list\'s one portal.',
487
487
  words: '"Visible label is a short Title Case noun (`Region`, `Environment Variable Name`)." (https://vercel.com/geist/combobox) "Placeholder is the inline hint: `Search regions`, `DATABASE_URL`. Never bare `Search…` and never the label restated." (https://vercel.com/geist/combobox) "Option text is Title Case for short values and matches canonical branding (`Next.js`, not `NextJS`); same register across the list." (https://vercel.com/geist/combobox) "Validation names the field and constraint, sentence case with a period (`Select a region.`)." (https://vercel.com/geist/combobox) Ours: the label and the rows are sentence case. The hint is scoped: *Find an Agent*. No match quotes the query: *No Agent matches “Xy”.* A chip reads as the record\'s name.',
488
488
  access: '"`<Combobox>` has no `label` prop; pair a sibling `<Label htmlFor>` with the root `id`, or set `aria-label` on the root for icon-only triggers." (https://vercel.com/geist/combobox) "The root accepts `aria-label` only; there is no `aria-labelledby` prop, so the sibling-label path is the way to reference visible text." (https://vercel.com/geist/combobox) "Trap focus inside the popover when nested in a `Modal` so Tab cycles options instead of the page behind it." (https://vercel.com/geist/combobox) Ours: `ComboboxInput` takes a visible `label` tied to the box by `id`, or `aria-label` or `aria-labelledby`; combobox and listbox roles; the open-list and clear buttons are named by `triggerLabel` and `clearLabel`; each chip\'s remove is named: *Remove Acme Quotes*. An Agent\'s orb in a row is a decorative mark beside her name.',
489
489
  },
@@ -549,7 +549,7 @@ export const USAGE = [
549
549
  summary: "A short fixed list in our style, opened from a trigger that shows the choice.",
550
550
  when: '"Display a dropdown list of items." (https://vercel.com/geist/select) "Pick `<Select>` for short, fixed lists (under ~10 items) where typing adds nothing; switch to `Combobox` once filtering helps." (https://vercel.com/geist/select) Ours: four or more options, each short enough to need no sentence: how often a task runs. A list of two or three static options is a `RadioGroup`, as Geist says.',
551
551
  instead: '"Use `MultiSelect` when more than one value can be chosen at once; use `Switch` for a 2–3 option segmented choice." (https://vercel.com/geist/select) Ours: two or three options are radios or a segmented control. Inside a native form a long list is `NativeSelect`.',
552
- behaviour: 'The trigger is `Input`\'s box: its sizes, its ring, hover, focus halo and disabled, the label above it and the message under it, in the three sizes `sm`, default and `lg` that `Input` has. Colour sits in one place: an error turns the ring red and fills the halo, and colours the message; the fill, the value, the chevron and the label stay neutral. It shows the chosen value, after an optional `prefix` mark, with the chevron at the end in the muted grey (a `suffix` mark takes the chevron\'s place), and fills its container; it keeps the hover edge while its list is open. The list, a solid floating surface with a 12 px corner, opens under it, 8 px away, never covering the trigger (`alignItemWithTrigger` is off), in a 6 px inset, with a 14 px check at the chosen row\'s end, rows 36 px tall and no gap between them; a row that cannot be chosen turns its text muted, never dimmed. Arrows, typing, Enter, Escape. A placeholder reads in the muted grey and is never an option. `label` and `error` go on `SelectTrigger`, and a string `label` requires `id`; a trigger with no name does not compile. "Group options past ~10 items with native `<optgroup>`; Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: group the options with `SelectGroup`. "Validate on blur and pass a string to `error`; messages name the field and end in a period (`Select a framework.`)." (https://vercel.com/geist/select) "Don’t wrap a labelled `<Select>` in a `Tooltip`; put the hint on a sibling icon button so the label stays announced." (https://vercel.com/geist/select) Other form rules are `Field`\'s.',
552
+ behaviour: 'The trigger is `Input`\'s box: its sizes, its ring, hover, focus halo and disabled, the label above it and the message under it, in the three sizes `sm`, default and `lg` that `Input` has. Colour sits in one place: an error turns the ring red and fills the halo, and colours the message; the fill, the value, the chevron and the label stay neutral. It shows the chosen value, after an optional `prefix` mark, with the chevron at the end in the muted grey (a `suffix` mark takes the chevron\'s place), and fills its container; it keeps the hover edge while its list is open. The list, a solid floating surface with a 12 px corner, opens under it, 8 px away, never covering the trigger (`alignItemWithTrigger` is off), in a 6 px inset, with a 14 px check at the chosen row\'s end, rows 36 px tall and no gap between them; a row that cannot be chosen turns its text muted, never dimmed. Arrows, typing, Enter, Escape. A placeholder reads in the muted grey and is never an option. `label` and `error` go on `SelectTrigger`, and a string `label` requires `id`; a trigger with no name does not compile. "Group options past ~10 items with native `<optgroup>`; Geist `<Select>` has no `.Group` static." (https://vercel.com/geist/select) Ours: `look="inline"` draws the trigger as a ghost `Button` of its size, for a toolbar such as a chat bar\'s reasoning level: no box and no field ring, the fill only when hovered or open, the Button\'s focus outline and its disabled dimming; the list is the same. Group the options with `SelectGroup`. "Validate on blur and pass a string to `error`; messages name the field and end in a period (`Select a framework.`)." (https://vercel.com/geist/select) "Don’t wrap a labelled `<Select>` in a `Tooltip`; put the hint on a sibling icon button so the label stays announced." (https://vercel.com/geist/select) Other form rules are `Field`\'s.',
553
553
  words: '"Options are Title Case when short and match canonical branding (`Next.js`, not `NextJS`); keep the same register across the list." (https://vercel.com/geist/select) "Label is a short Title Case noun (`Framework`, `Region`); accept the prop directly on `<Select>`." (https://vercel.com/geist/select) "Placeholder is action-oriented (`Select a framework`), never `Choose one…`, `Pick`, or the label restated." (https://vercel.com/geist/select) Ours: options are parallel phrases in sentence case (*Every hour*, *Every weekday*), the label is a short noun in sentence case, and the trigger never says *Select…* or *Choose one*.',
554
554
  access: "A visible label tied to the trigger by `id`, or `aria-label` or `aria-labelledby`. Listbox and option roles from Base UI; focus returns to the trigger on close. The prefix and suffix are decorative and not part of the trigger's name.",
555
555
  },
@@ -813,9 +813,9 @@ export const USAGE = [
813
813
  summary: "One Agent in a list of them: the orb, the name, and the line that says what the Agent is doing now or what it is for.",
814
814
  when: "Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.",
815
815
  instead: "An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.",
816
- behaviour: "It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.",
817
- words: 'The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia\'s list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.',
818
- access: "The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative shape, so the line carries its meaning.",
816
+ behaviour: "It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. The orb carries the Agent's state, working, waiting on the person or blocked, so the state line is plain muted text and never a badge. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. The name is 14 px and the state line 12 px at every size. The drawn orb leaves about 10 px of its 64 px box empty, so at 64 px that empty edge overlaps the row's padding (6 px above and below, 4 px at the start) and the words stand 4 px from the box: the row hugs the visible orb and the name sits beside it, as beside a solid picture. In Nadia's list her orb is 64 px in her real state, and 40 px in the narrow column from 640 to 899 px.",
817
+ words: 'The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). Nadia\'s list says "Working", "Idle" or "Needs you".',
818
+ access: "The orb is decorative; the name and the state line are the row's text, read by its control.",
819
819
  },
820
820
  {
821
821
  name: "Breadcrumb",
@@ -94,6 +94,43 @@
94
94
  box-shadow: var(--nc-elevation-modal);
95
95
  }
96
96
 
97
+ /*
98
+ * Small state changes share one cadence instead of component-local defaults
99
+ * (design-system DESIGN.md "Motion"). Declared as utilities, beside the
100
+ * elevation rungs, so a host that takes this file and not the design system's
101
+ * whole stylesheet still runs them, and variant prefixes can gate them.
102
+ */
103
+ @utility nc-transition-paint {
104
+ transition-property: background-color, border-color, color, opacity;
105
+ transition-duration: var(--nc-duration-confirm);
106
+ transition-timing-function: var(--nc-ease-out-strong);
107
+ }
108
+
109
+ @utility nc-transition-opacity {
110
+ transition-property: opacity;
111
+ transition-duration: var(--nc-duration-confirm);
112
+ transition-timing-function: var(--nc-ease-out-strong);
113
+ }
114
+
115
+ @utility nc-transition-transform {
116
+ transition-property: transform, translate, scale;
117
+ transition-duration: var(--nc-duration-confirm);
118
+ transition-timing-function: var(--nc-ease-out-strong);
119
+
120
+ @media (prefers-reduced-motion: reduce) {
121
+ transition: none;
122
+ }
123
+ }
124
+
125
+ /* A list that scrolls under its own fade or edge, such as Command's and Combobox's, draws no scrollbar. */
126
+ @utility no-scrollbar {
127
+ scrollbar-width: none;
128
+
129
+ &::-webkit-scrollbar {
130
+ display: none;
131
+ }
132
+ }
133
+
97
134
  /*
98
135
  * The proxy focus outline: the one restatement of the canonical treatment
99
136
  * above, for an element that carries the indicator on another element's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "12.1.130",
3
+ "version": "12.1.131",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -83,7 +83,7 @@
83
83
  "@base-ui/react": "^1.9.0",
84
84
  "@iconify-icons/logos": "^2.0.3",
85
85
  "@iconify/react": "^6.0.2",
86
- "@nadicodeai/design-system": "12.1.130",
86
+ "@nadicodeai/design-system": "12.1.131",
87
87
  "@tanstack/react-table": "^9.3.1",
88
88
  "@vgpu/wgsl": "0.6.0",
89
89
  "class-variance-authority": "^0.7.1",