@actioneer/ads 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DESIGN.md CHANGED
@@ -179,7 +179,7 @@ components:
179
179
 
180
180
  TASTE.md puts it in one line: On a quiet, neutral ground, colour and motion are spent like money — rarely, deliberately, and only where the eye should go.
181
181
 
182
- ADS 1.0.5 is a library first and a look second. 323 components across 10 families (Primitives / utilities, Foundations, Form controls, Overlays, Data display, Feedback, Navigation, Layout, AI Elements, Chat) ship from one barrel, and every product that consumes them inherits the judgment encoded in 56 semantic tokens and 11 principles rather than re-deciding it per screen.
182
+ ADS 1.0.7 is a library first and a look second. 323 components across 10 families (Primitives / utilities, Foundations, Form controls, Overlays, Data display, Feedback, Navigation, Layout, AI Elements, Chat) ship from one barrel, and every product that consumes them inherits the judgment encoded in 56 semantic tokens and 11 principles rather than re-deciding it per screen.
183
183
 
184
184
  The ground is warm grey and the ink is warm near-black. One hue is spent by default, the Studio teal CTA family, and four more carry semantic status. Everything else stays neutral. A consumer product may narrow that further, and one already does: Baby Sentinel drops the teal and runs every action on ink.
185
185
 
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # @actioneer/ads
2
+
3
+ The **Actioneer Design System**: React 19 components, Tailwind CSS v4 tokens,
4
+ bundled Aribau Grotesk fonts, and accessible interactions with built-in motion.
5
+
6
+ [Browse components in Storybook](https://actioneer-ads-storybook.himanshu-563.workers.dev).
7
+
8
+ > **The one rule:** build UI **only** from the exact named exports of
9
+ > `@actioneer/ads`, and reference tokens — never raw color/dimension literals.
10
+ > Never fork, alias, deep-import, or hand-roll a copy of a component.
11
+ > `@actioneer/ads-lint` enforces this.
12
+
13
+ ---
14
+
15
+ ## 1. Install
16
+
17
+ ```bash
18
+ npm install @actioneer/ads motion
19
+ ```
20
+
21
+ Use an existing **React 19 + Tailwind CSS v4** application with an ESM-capable
22
+ bundler. `react` and `react-dom` are peer dependencies; the application owns the
23
+ React instance. The setup below uses Next.js App Router paths.
24
+
25
+ The bootstrap configures styles and providers and creates the lint config:
26
+
27
+ ```bash
28
+ npx @actioneer/ads init
29
+ ```
30
+
31
+ `init` adds the CSS import, creates `ads-providers.tsx` (or `.jsx`), and writes a
32
+ consumer `ads-lint.config.mjs`. It wraps detected Next.js layouts and reports any
33
+ manual setup still needed. Run it from your application directory after setting
34
+ up Tailwind v4. The manual setup follows.
35
+
36
+ ## 2. Tailwind v4 + `styles.css` (import order matters)
37
+
38
+ In your global stylesheet, import ADS's stylesheet **immediately after**
39
+ Tailwind:
40
+
41
+ ```css
42
+ /* app/globals.css */
43
+ @import "tailwindcss";
44
+ @import "@actioneer/ads/styles.css";
45
+ ```
46
+
47
+ `styles.css` carries three things that must live in the **same CSS graph** as
48
+ `tailwindcss`:
49
+
50
+ - the `@theme` **design tokens** (colors, typography, spacing, and radii),
51
+ - the **Aribau Grotesk** `@font-face` rules (served package-relative — no
52
+ `/public` copy needed), and
53
+ - a baked `@source "./**/*.{js,mjs}"` so Tailwind scans ADS's own class usage and
54
+ generates its utilities in your build.
55
+
56
+ > ⚠️ Import order is load-bearing. If you `@import "@actioneer/ads/styles.css"`
57
+ > **before** `@import "tailwindcss"` — or import it into a stylesheet that isn't
58
+ > part of the Tailwind graph — its `@theme` is an unknown at-rule and **no tokens
59
+ > emit** (you'll get an unstyled, "blank" render).
60
+
61
+ Granular entries are also exported if you need them: `@actioneer/ads/theme.css`
62
+ (tokens only) and `@actioneer/ads/fonts.css` (`@font-face` only).
63
+
64
+ ## 3. Required providers
65
+
66
+ Wrap your app root **once** with all three providers. `npx @actioneer/ads init`
67
+ generates this as `app/ads-providers.tsx` (beside the layout when using `src/app`):
68
+
69
+ ```tsx
70
+ // app/ads-providers.tsx
71
+ "use client";
72
+
73
+ import type { ReactNode } from "react";
74
+ import { TooltipProvider, ToastProvider } from "@actioneer/ads";
75
+ import { MotionConfig } from "motion/react";
76
+
77
+ export function Providers({ children }: { children: ReactNode }) {
78
+ return (
79
+ <MotionConfig reducedMotion="user">
80
+ <ToastProvider>
81
+ <TooltipProvider>{children}</TooltipProvider>
82
+ </ToastProvider>
83
+ </MotionConfig>
84
+ );
85
+ }
86
+ ```
87
+
88
+ ```tsx
89
+ // app/layout.tsx
90
+ import type { ReactNode } from "react";
91
+ import { Providers } from "./ads-providers";
92
+ import "./globals.css";
93
+
94
+ export default function RootLayout({ children }: { children: ReactNode }) {
95
+ return (
96
+ <html lang="en">
97
+ <body><Providers>{children}</Providers></body>
98
+ </html>
99
+ );
100
+ }
101
+ ```
102
+
103
+ - **`TooltipProvider`** — required. The vendored tooltip/attachment chips crash
104
+ the tree without an ancestor provider.
105
+ - **`ToastProvider`** — required to render toasts.
106
+ - **`<MotionConfig reducedMotion="user">`** — honors the OS reduced-motion
107
+ setting across every ADS animation.
108
+
109
+ For other React frameworks, import the global stylesheet and wrap the application
110
+ root with `Providers` in the framework's entry point.
111
+
112
+ ## 4. Usage
113
+
114
+ Import the **exact named export** from the package barrel:
115
+
116
+ ```tsx
117
+ // app/page.tsx
118
+ "use client";
119
+
120
+ import { Button, InputField } from "@actioneer/ads";
121
+
122
+ export default function Example() {
123
+ return (
124
+ <main className="mx-auto flex max-w-sm flex-col gap-4 p-6">
125
+ <InputField label="Workspace name" defaultValue="Actioneer" />
126
+ <div className="flex gap-2">
127
+ <Button variant="solid" size="md">Save</Button>
128
+ <Button variant="secondary">Cancel</Button>
129
+ </div>
130
+ </main>
131
+ );
132
+ }
133
+ ```
134
+
135
+ Do **not**:
136
+
137
+ | ❌ Anti-pattern | ✅ Instead |
138
+ |----------------|-----------|
139
+ | `import { Button } from "@actioneer/ads/button"` (deep import) | `import { Button } from "@actioneer/ads"` |
140
+ | `import { Card as Panel } from "@actioneer/ads"` (alias) | use the export's real name, `Card` |
141
+ | `import Button from "@actioneer/ads"` (default) / `import * as ADS` (namespace) | named imports only |
142
+ | copy a component's source into your repo and edit it (fork) | import it; request an ADS change upstream |
143
+ | `class="bg-[#0a0a0b]"` / `"#0a0a0b"` (literal) | a semantic token, e.g. `bg-brand` |
144
+ | `import { Dialog } from "@radix-ui/react-dialog"` (external UI) | the ADS primitive (`Modal`, `Popover`, …) |
145
+
146
+ **Why:** ADS is a single source of truth. A token or motion fix ships to the
147
+ whole fleet with one version bump — but only if every consumer imports the
148
+ canonical export instead of a divergent fork.
149
+
150
+ **Discover exact names:** the machine-readable catalog ships in the package —
151
+ `@actioneer/ads/manifest.json` (every export → name, family, kind, variants,
152
+ props, showcase URL) and `@actioneer/ads/llms.txt` (the LLM-facing index). Point
153
+ your coding agent at those, or use the ADS MCP server.
154
+
155
+ Reference the semantic tokens (e.g. `bg-brand`, `text-muted-foreground`,
156
+ `border-input`, `ring-ring`) rather than raw values; the full token list is in
157
+ `manifest.json` under `tokens`.
158
+
159
+ Shared motion presets are named exports from `@actioneer/ads`. Components already
160
+ include their own interaction motion; use the exported presets for additional
161
+ application state changes.
162
+
163
+ ## 5. Wire up `ads-lint`
164
+
165
+ `@actioneer/ads-lint` enforces the contract above on your changed files.
166
+
167
+ ```bash
168
+ npm install -D @actioneer/ads-lint typescript
169
+ ```
170
+
171
+ Drop a **consumer-mode** config at your repo root (`init` writes this for you):
172
+
173
+ ```js
174
+ // ads-lint.config.mjs
175
+ export default {
176
+ imports: {
177
+ libraryPackage: "@actioneer/ads",
178
+ libraryRoot: null, // consumer mode: every file is a consumer
179
+ },
180
+ };
181
+ ```
182
+
183
+ Run it:
184
+
185
+ ```bash
186
+ # lint everything
187
+ npx ads-lint --all
188
+ # or just what changed (pre-commit / CI)
189
+ npx ads-lint --staged
190
+ npx ads-lint --diff origin/main
191
+ ```
192
+
193
+ It flags deep imports, aliased/default/namespace barrel imports, external-UI
194
+ imports, hardcoded color/dimension literals, and banned/weak motion — the same
195
+ rules ADS holds itself to. A CI job that runs `npx ads-lint --diff <base>` keeps
196
+ every consuming repo honest.
197
+
198
+ ## Documentation and license
199
+
200
+ - [Storybook: components and recipes](https://actioneer-ads-storybook.himanshu-563.workers.dev)
201
+ - [ADS MCP: component discovery for coding agents](https://www.npmjs.com/package/@actioneer/ads-mcp)
202
+ - Bundled references: `@actioneer/ads/manifest.json`, `@actioneer/ads/llms.txt`,
203
+ and `@actioneer/ads/DESIGN.md`.
204
+
205
+ MIT licensed.
@@ -1,10 +1,10 @@
1
1
  import { VariantProps } from 'class-variance-authority';
2
2
  import * as React from "react";
3
3
  /**
4
- * Alert — inline status messaging on a raised white surface. Status color is
5
- * confined to the indicator, title, and optional timeout progress bar; the
6
- * description stays muted. Timed alerts enter from the right and leave to the
7
- * left once their progress completes.
4
+ * Alert — inline status messaging in an outlined white container. A softly tinted
5
+ * indicator carries status while the title and description stay neutral.
6
+ * Buttons are 24px tall and actions sit 16px below the message. Timed alerts
7
+ * retain their countdown and dismiss after it completes.
8
8
  */
9
9
  declare const alertVariants: (props?: ({
10
10
  variant?: "success" | "warning" | "danger" | "info" | "default" | null | undefined;
@@ -1,90 +1,105 @@
1
1
  "use client";
2
- import { jsx as e, jsxs as k } from "react/jsx-runtime";
3
- import * as t from "react";
4
- import { cva as A } from "class-variance-authority";
5
- import { MotionConfig as E, motion as g } from "motion/react";
6
- import { Info as p, WarningCircle as C, Warning as I, CheckCircle as R, Close as j } from "../lib/icons.js";
7
- import { cn as d } from "../lib/cn.js";
8
- import { springOverlay as z } from "../lib/motion.js";
9
- const D = A(
10
- "relative flex w-full items-start gap-4 overflow-hidden rounded-2xl border border-border bg-card p-4 shadow-[var(--shadow-200)]",
2
+ import { jsx as t, jsxs as I } from "react/jsx-runtime";
3
+ import * as e from "react";
4
+ import { cva as R } from "class-variance-authority";
5
+ import { MotionConfig as j, motion as y } from "motion/react";
6
+ import { Info as h, WarningCircle as V, Warning as M, CheckCircle as S, Close as W } from "../lib/icons.js";
7
+ import { cn as m } from "../lib/cn.js";
8
+ import { fadeTransition as X, springOverlay as H } from "../lib/motion.js";
9
+ const O = R(
10
+ "relative grid w-full min-w-0 grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-4 overflow-hidden rounded-lg border border-border bg-card p-4 text-on-white-primary [&_button]:h-6",
11
11
  {
12
12
  variants: {
13
13
  variant: {
14
- default: "[--alert-accent:var(--foreground)]",
15
- success: "[--alert-accent:var(--color-success-700)]",
16
- warning: "[--alert-accent:var(--color-warning-700)]",
17
- danger: "[--alert-accent:var(--color-danger-700)]",
18
- info: "[--alert-accent:var(--color-info-700)]"
14
+ default: "[--alert-accent:var(--foreground)] [--alert-soft:var(--fill)]",
15
+ success: "[--alert-accent:var(--color-success-700)] [--alert-soft:var(--color-success-50)]",
16
+ warning: "[--alert-accent:var(--color-warning-700)] [--alert-soft:var(--color-warning-50)]",
17
+ danger: "[--alert-accent:var(--color-danger-700)] [--alert-soft:var(--color-danger-50)]",
18
+ info: "[--alert-accent:var(--color-info-700)] [--alert-soft:var(--color-info-50)]"
19
19
  }
20
20
  },
21
21
  defaultVariants: { variant: "default" }
22
22
  }
23
- ), T = {
24
- default: p,
25
- success: R,
26
- warning: I,
27
- danger: C,
28
- info: p
29
- }, M = t.forwardRef(
30
- ({ className: n, variant: r = "default", icon: s, duration: a = 0, onClose: l, children: x, ...v }, h) => {
31
- const b = T[r ?? "default"], [i, w] = t.useState(!1), [o, N] = t.useState(!1), c = t.useRef(l), m = t.useRef(!1);
32
- t.useEffect(() => {
33
- c.current = l;
23
+ ), q = {
24
+ default: h,
25
+ success: S,
26
+ warning: M,
27
+ danger: V,
28
+ info: h
29
+ }, B = e.forwardRef(
30
+ ({ className: o, variant: a = "default", icon: s, duration: i = 0, onClose: l, children: g, ...A }, E) => {
31
+ const T = q[a ?? "default"], [n, k] = e.useState(!1), [c, C] = e.useState(!1), d = e.useRef(l), w = e.useRef(!1), u = e.Children.toArray(g);
32
+ let f = -1;
33
+ u.forEach((r, D) => {
34
+ if (!e.isValidElement(r)) return;
35
+ const v = typeof r.type == "string" ? void 0 : r.type.displayName;
36
+ (r.type === b || r.type === N || v === "AlertTitle" || v === "AlertDescription") && (f = D);
37
+ });
38
+ const _ = f < 0 ? g : u.slice(0, f + 1), x = f < 0 ? [] : u.slice(f + 1);
39
+ e.useEffect(() => {
40
+ d.current = l;
34
41
  }, [l]);
35
- const u = t.useCallback(() => {
36
- o || w(!0);
37
- }, [o]);
38
- t.useEffect(() => {
39
- if (a <= 0 || i || o) return;
40
- const f = window.setTimeout(u, a);
41
- return () => window.clearTimeout(f);
42
- }, [u, a, o, i]);
43
- const y = t.useCallback(() => {
44
- var f;
45
- !i || m.current || (m.current = !0, N(!0), (f = c.current) == null || f.call(c));
46
- }, [i]);
47
- return o ? null : /* @__PURE__ */ e(E, { reducedMotion: "user", children: /* @__PURE__ */ e(
48
- g.div,
42
+ const p = e.useCallback(() => {
43
+ c || k(!0);
44
+ }, [c]);
45
+ e.useEffect(() => {
46
+ if (i <= 0 || n || c) return;
47
+ const r = window.setTimeout(p, i);
48
+ return () => window.clearTimeout(r);
49
+ }, [p, i, c, n]);
50
+ const z = e.useCallback(() => {
51
+ var r;
52
+ !n || w.current || (w.current = !0, C(!0), (r = d.current) == null || r.call(d));
53
+ }, [n]);
54
+ return c ? null : /* @__PURE__ */ t(j, { reducedMotion: "user", children: /* @__PURE__ */ t(
55
+ y.div,
49
56
  {
57
+ className: "w-full min-w-0",
50
58
  initial: { opacity: 1, x: 32 },
51
- animate: i ? { opacity: 0, x: -32 } : { opacity: 1, x: 0 },
52
- transition: i ? { duration: 0.18, ease: "easeIn" } : z,
53
- onAnimationComplete: y,
54
- children: /* @__PURE__ */ k(
59
+ animate: n ? { opacity: 0, x: -32 } : { opacity: 1, x: 0 },
60
+ transition: n ? X : H,
61
+ onAnimationComplete: z,
62
+ children: /* @__PURE__ */ I(
55
63
  "div",
56
64
  {
57
- ref: h,
65
+ ref: E,
66
+ "data-slot": "alert",
58
67
  role: "alert",
59
- className: d(D({ variant: r }), n),
60
- ...v,
68
+ className: m(
69
+ O({ variant: a }),
70
+ l && "grid-cols-[auto_minmax(0,1fr)_auto]",
71
+ o
72
+ ),
73
+ ...A,
61
74
  children: [
62
- /* @__PURE__ */ e("span", { className: "flex shrink-0 select-none items-center justify-center py-1 text-(--alert-accent) [&_svg]:size-4", children: s ?? /* @__PURE__ */ e(b, { "aria-hidden": !0 }) }),
63
- /* @__PURE__ */ e("div", { className: "flex min-w-0 grow flex-col items-start", children: x }),
64
- l && /* @__PURE__ */ e(
75
+ /* @__PURE__ */ t("span", { "data-slot": "alert-icon", className: "col-start-1 row-start-1 flex size-8 self-center select-none items-center justify-center rounded-md bg-(--alert-soft) text-(--alert-accent) [&_svg]:size-4", children: s ?? /* @__PURE__ */ t(T, { "aria-hidden": !0 }) }),
76
+ /* @__PURE__ */ t("div", { "data-slot": "alert-content", className: "col-start-2 row-start-1 flex min-w-0 flex-col items-start gap-0.5 self-center [overflow-wrap:anywhere]", children: _ }),
77
+ l && /* @__PURE__ */ t(
65
78
  "button",
66
79
  {
67
80
  type: "button",
68
81
  "aria-label": "Dismiss",
69
- onClick: u,
70
- className: d(
71
- "inline-flex size-6 shrink-0 items-center justify-center rounded-sm text-muted-foreground",
72
- "transition-colors hover:bg-fill hover:text-foreground",
82
+ onClick: p,
83
+ className: m(
84
+ "col-start-3 row-start-1 inline-flex size-6 cursor-pointer items-center justify-center self-start rounded-sm text-on-white-tertiary",
85
+ "transition-[background-color,color,transform] duration-150 ease-out hover:bg-fill hover:text-on-white-primary",
86
+ "active:scale-[0.97] motion-reduce:active:scale-100 motion-reduce:transition-none",
73
87
  "outline-none focus-visible:ring-3 focus-visible:ring-ring",
74
88
  "[&_svg]:size-4"
75
89
  ),
76
- children: /* @__PURE__ */ e(j, { "aria-hidden": !0 })
90
+ children: /* @__PURE__ */ t(W, { "aria-hidden": !0 })
77
91
  }
78
92
  ),
79
- a > 0 && /* @__PURE__ */ e("span", { "aria-hidden": !0, className: "absolute inset-x-0 bottom-0 h-0.5 bg-wg3", children: /* @__PURE__ */ e(
80
- g.span,
93
+ x.length > 0 && /* @__PURE__ */ t("div", { "data-slot": "alert-actions", className: "col-start-2 row-start-2 flex min-w-0 flex-wrap items-center gap-2 [&>*]:max-w-full", children: x }),
94
+ i > 0 && /* @__PURE__ */ t("span", { "aria-hidden": !0, className: "absolute inset-x-0 bottom-0 h-0.5 bg-wg3", children: /* @__PURE__ */ t(
95
+ y.span,
81
96
  {
82
97
  className: "block size-full origin-left bg-(--alert-accent)",
83
98
  initial: { scaleX: 1 },
84
99
  animate: { scaleX: 0 },
85
- transition: { duration: a / 1e3, ease: "linear" }
100
+ transition: { duration: i / 1e3, ease: "linear" }
86
101
  },
87
- a
102
+ i
88
103
  ) })
89
104
  ]
90
105
  }
@@ -93,32 +108,29 @@ const D = A(
93
108
  ) });
94
109
  }
95
110
  );
96
- M.displayName = "Alert";
97
- const S = t.forwardRef(({ className: n, ...r }, s) => /* @__PURE__ */ e(
111
+ B.displayName = "Alert";
112
+ const b = e.forwardRef(({ className: o, ...a }, s) => /* @__PURE__ */ t(
98
113
  "p",
99
114
  {
100
115
  ref: s,
101
- className: d("text-s font-normal leading-6 text-(--alert-accent)", n),
102
- ...r
116
+ "data-slot": "alert-title",
117
+ className: m("text-m font-medium leading-6 text-on-white-primary", o),
118
+ ...a
103
119
  }
104
120
  ));
105
- S.displayName = "AlertTitle";
106
- const V = t.forwardRef(({ className: n, ...r }, s) => (
107
- // leading-normal (150%) — the description is the only part of an alert that
108
- // regularly wraps, and the text-xs default (138%) sets multi-line copy too
109
- // tight to scan.
110
- /* @__PURE__ */ e(
111
- "p",
112
- {
113
- ref: s,
114
- className: d("text-xs leading-normal text-muted-foreground", n),
115
- ...r
116
- }
117
- )
121
+ b.displayName = "AlertTitle";
122
+ const N = e.forwardRef(({ className: o, ...a }, s) => /* @__PURE__ */ t(
123
+ "p",
124
+ {
125
+ ref: s,
126
+ "data-slot": "alert-description",
127
+ className: m("text-m leading-relaxed text-on-white-secondary [overflow-wrap:anywhere]", o),
128
+ ...a
129
+ }
118
130
  ));
119
- V.displayName = "AlertDescription";
131
+ N.displayName = "AlertDescription";
120
132
  export {
121
- M as Alert,
122
- V as AlertDescription,
123
- S as AlertTitle
133
+ B as Alert,
134
+ N as AlertDescription,
135
+ b as AlertTitle
124
136
  };
@@ -10,7 +10,7 @@ export interface RadioGroupProps extends Omit<React.HTMLAttributes<HTMLDivElemen
10
10
  disabled?: boolean;
11
11
  }
12
12
  export declare const RadioGroup: React.ForwardRefExoticComponent<RadioGroupProps & React.RefAttributes<HTMLDivElement>>;
13
- export interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size" | "value" | "onChange"> {
13
+ export interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size" | "value"> {
14
14
  value: string;
15
15
  }
16
16
  export declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLInputElement>>;
@@ -1,111 +1,111 @@
1
1
  "use client";
2
- import { jsx as r, jsxs as R } from "react/jsx-runtime";
2
+ import { jsx as r, jsxs as y } from "react/jsx-runtime";
3
3
  import * as i from "react";
4
- import { MotionConfig as v, motion as y } from "motion/react";
5
- import { cn as b } from "../lib/cn.js";
6
- import { Field as N } from "./field.js";
7
- import { springRadio as w } from "../lib/motion.js";
8
- const x = i.createContext(null), k = i.forwardRef(
4
+ import { MotionConfig as N, motion as w } from "motion/react";
5
+ import { cn as g } from "../lib/cn.js";
6
+ import { Field as k } from "./field.js";
7
+ import { springRadio as C } from "../lib/motion.js";
8
+ const R = i.createContext(null), j = i.forwardRef(
9
9
  ({
10
- className: d,
11
- name: n,
10
+ className: u,
11
+ name: t,
12
12
  value: o,
13
- onChange: t,
14
- label: a,
15
- description: c,
16
- error: u,
17
- orientation: p = "vertical",
18
- disabled: e,
19
- children: s,
20
- ...l
21
- }, f) => {
13
+ onChange: a,
14
+ label: s,
15
+ description: p,
16
+ error: n,
17
+ orientation: f = "vertical",
18
+ disabled: l,
19
+ children: e,
20
+ ...d
21
+ }, c) => {
22
22
  const m = i.useMemo(
23
- () => ({ name: n, value: o, onValueChange: t, disabled: e }),
24
- [n, o, t, e]
23
+ () => ({ name: t, value: o, onValueChange: a, disabled: l }),
24
+ [t, o, a, l]
25
25
  );
26
26
  return /* @__PURE__ */ r(
27
- N,
27
+ k,
28
28
  {
29
- ref: f,
30
- label: a,
31
- description: c,
32
- error: u,
29
+ ref: c,
30
+ label: s,
31
+ description: p,
32
+ error: n,
33
33
  role: "radiogroup",
34
- className: d,
35
- ...l,
36
- children: /* @__PURE__ */ r(x.Provider, { value: m, children: /* @__PURE__ */ r(
34
+ className: u,
35
+ ...d,
36
+ children: /* @__PURE__ */ r(R.Provider, { value: m, children: /* @__PURE__ */ r(
37
37
  "div",
38
38
  {
39
- className: b(
39
+ className: g(
40
40
  "flex gap-3",
41
- p === "vertical" ? "flex-col" : "flex-row flex-wrap"
41
+ f === "vertical" ? "flex-col" : "flex-row flex-wrap"
42
42
  ),
43
- children: s
43
+ children: e
44
44
  }
45
45
  ) })
46
46
  }
47
47
  );
48
48
  }
49
49
  );
50
- k.displayName = "RadioGroup";
51
- const j = i.forwardRef(
52
- ({ className: d, children: n, value: o, disabled: t, checked: a, defaultChecked: c, ...u }, p) => {
53
- const e = i.useContext(x), s = t || (e == null ? void 0 : e.disabled), l = a !== void 0, [f, m] = i.useState(!!c), g = e ? e.value === o : l ? a : f;
54
- return /* @__PURE__ */ R(
50
+ j.displayName = "RadioGroup";
51
+ const G = i.forwardRef(
52
+ ({ className: u, children: t, value: o, disabled: a, checked: s, defaultChecked: p, onChange: n, ...f }, l) => {
53
+ const e = i.useContext(R), d = a || (e == null ? void 0 : e.disabled), c = s !== void 0, [m, v] = i.useState(!!p), b = e ? e.value === o : c ? s : m;
54
+ return /* @__PURE__ */ y(
55
55
  "label",
56
56
  {
57
- className: b(
57
+ className: g(
58
58
  "group inline-flex items-center gap-2 text-m text-foreground select-none",
59
- s ? "cursor-not-allowed opacity-50" : "cursor-pointer",
60
- d
59
+ d ? "cursor-not-allowed opacity-50" : "cursor-pointer",
60
+ u
61
61
  ),
62
62
  children: [
63
63
  /* @__PURE__ */ r(
64
64
  "input",
65
65
  {
66
- ref: p,
66
+ ref: l,
67
67
  type: "radio",
68
68
  name: e == null ? void 0 : e.name,
69
69
  value: o,
70
- checked: g,
71
- disabled: s,
72
- onChange: (C) => {
70
+ checked: b,
71
+ disabled: d,
72
+ onChange: (x) => {
73
73
  var h;
74
- C.target.checked && (e ? (h = e.onValueChange) == null || h.call(e, o) : l || m(!0));
74
+ x.target.checked && (e ? (h = e.onValueChange) == null || h.call(e, o) : c || v(!0), n == null || n(x));
75
75
  },
76
76
  className: "peer sr-only",
77
- ...u
77
+ ...f
78
78
  }
79
79
  ),
80
80
  /* @__PURE__ */ r(
81
81
  "span",
82
82
  {
83
83
  "aria-hidden": !0,
84
- className: b(
84
+ className: g(
85
85
  "flex size-4.5 shrink-0 items-center justify-center rounded-full border border-input bg-elevated",
86
86
  "transition-[border-color,box-shadow] duration-150 ease-out",
87
87
  "peer-checked:border-brand",
88
88
  "peer-focus-visible:ring-3 peer-focus-visible:ring-ring"
89
89
  ),
90
- children: /* @__PURE__ */ r(v, { reducedMotion: "user", children: /* @__PURE__ */ r(
91
- y.span,
90
+ children: /* @__PURE__ */ r(N, { reducedMotion: "user", children: /* @__PURE__ */ r(
91
+ w.span,
92
92
  {
93
93
  className: "size-2 rounded-full bg-brand",
94
94
  initial: !1,
95
- animate: { opacity: g ? 1 : 0, scale: g ? 1 : 0.9 },
96
- transition: w
95
+ animate: { opacity: b ? 1 : 0, scale: b ? 1 : 0.9 },
96
+ transition: C
97
97
  }
98
98
  ) })
99
99
  }
100
100
  ),
101
- n && /* @__PURE__ */ r("span", { children: n })
101
+ t && /* @__PURE__ */ r("span", { children: t })
102
102
  ]
103
103
  }
104
104
  );
105
105
  }
106
106
  );
107
- j.displayName = "Radio";
107
+ G.displayName = "Radio";
108
108
  export {
109
- j as Radio,
110
- k as RadioGroup
109
+ G as Radio,
110
+ j as RadioGroup
111
111
  };