@devalok/shilp-sutra 0.55.0 → 0.56.0

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 (74) hide show
  1. package/BREAKING.json +13 -0
  2. package/MIGRATION.md +56 -0
  3. package/README.md +16 -1
  4. package/dist/_chunks/badge-group.js +45 -45
  5. package/dist/_chunks/emoji-suggestion.js +32 -30
  6. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  7. package/dist/_chunks/mention-suggestion.js +35 -34
  8. package/dist/_chunks/mention-suggestion.js.map +1 -1
  9. package/dist/_chunks/primitives-internal.js +437 -537
  10. package/dist/_chunks/primitives-internal.js.map +1 -1
  11. package/dist/composed/content-card.js +18 -18
  12. package/dist/composed/extensions/emoji-node.js +8 -7
  13. package/dist/composed/extensions/emoji-node.js.map +1 -1
  14. package/dist/composed/rich-chat-input.js +535 -526
  15. package/dist/composed/rich-chat-input.js.map +1 -1
  16. package/dist/composed/rich-text-editor.js +201 -193
  17. package/dist/composed/rich-text-editor.js.map +1 -1
  18. package/dist/tokens/primitives.css +6 -1
  19. package/dist/tokens/semantic.css +1 -1
  20. package/dist/ui/alert.js +29 -29
  21. package/dist/ui/avatar.js +42 -42
  22. package/dist/ui/banner.js +25 -25
  23. package/dist/ui/button.js +31 -31
  24. package/dist/ui/button.js.map +1 -1
  25. package/dist/ui/card.js +39 -39
  26. package/dist/ui/checkbox.d.ts.map +1 -1
  27. package/dist/ui/checkbox.js +1 -0
  28. package/dist/ui/checkbox.js.map +1 -1
  29. package/dist/ui/combobox.js +135 -135
  30. package/dist/ui/combobox.js.map +1 -1
  31. package/dist/ui/dot.js +13 -13
  32. package/dist/ui/input.js +25 -25
  33. package/dist/ui/lib/utils.js +2 -1
  34. package/dist/ui/lib/utils.js.map +1 -1
  35. package/dist/ui/number-input.js +36 -36
  36. package/dist/ui/progress.js +55 -55
  37. package/dist/ui/select.js +58 -58
  38. package/dist/ui/sheet.js +46 -46
  39. package/dist/ui/sidebar.js +128 -128
  40. package/dist/ui/sidebar.js.map +1 -1
  41. package/dist/ui/skeleton.js +39 -39
  42. package/dist/ui/slider.d.ts.map +1 -1
  43. package/dist/ui/slider.js +18 -17
  44. package/dist/ui/slider.js.map +1 -1
  45. package/dist/ui/surface.js +9 -9
  46. package/dist/ui/switch.d.ts.map +1 -1
  47. package/dist/ui/switch.js +1 -0
  48. package/dist/ui/switch.js.map +1 -1
  49. package/dist/ui/tabs.js +47 -47
  50. package/dist/ui/text.js +8 -8
  51. package/dist/ui/textarea.js +12 -12
  52. package/dist/ui/toggle.js +12 -12
  53. package/docs/recipes/install-astro.md +2 -2
  54. package/docs/recipes/install-next-app-router.md +2 -2
  55. package/docs/recipes/install-remix.md +2 -2
  56. package/docs/recipes/install-tanstack-start.md +2 -2
  57. package/docs/recipes/install-vite.md +2 -2
  58. package/docs/recipes/troubleshoot.md +26 -5
  59. package/llms.txt +1 -1
  60. package/mcp-manifest.json +24 -3
  61. package/package.json +39 -11
  62. package/skill/SKILL.md +1 -1
  63. package/skill/references/components.md +1 -1
  64. package/skill/references/setup-astro.md +2 -2
  65. package/skill/references/setup-next-app-router.md +2 -2
  66. package/skill/references/setup-remix.md +2 -2
  67. package/skill/references/setup-tanstack-start.md +2 -2
  68. package/skill/references/setup-vite.md +2 -2
  69. package/skill/references/troubleshoot.md +26 -5
  70. package/dist/_chunks/tiptap.js +0 -18809
  71. package/dist/_chunks/tiptap.js.map +0 -1
  72. package/dist/_chunks/vendor-utils.js +0 -1766
  73. package/dist/_chunks/vendor-utils.js.map +0 -1
  74. package/scripts/welcome.mjs +0 -312
package/dist/ui/banner.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { motionProps as e, springs as t } from "./lib/motion.js";
3
- import { cva as n } from "../_chunks/vendor-utils.js";
4
- import { cn as r } from "./lib/utils.js";
5
- import { Icon as i } from "./icon.js";
6
- import * as a from "react";
7
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
- import { IconAlertCircle as c, IconAlertTriangle as l, IconCircleCheck as u, IconInfoCircle as d, IconX as f } from "@tabler/icons-react";
9
- import { AnimatePresence as p, motion as m } from "framer-motion";
3
+ import { cn as n } from "./lib/utils.js";
4
+ import { Icon as r } from "./icon.js";
5
+ import * as i from "react";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
+ import { IconAlertCircle as s, IconAlertTriangle as c, IconCircleCheck as l, IconInfoCircle as u, IconX as d } from "@tabler/icons-react";
8
+ import { AnimatePresence as f, motion as p } from "framer-motion";
9
+ import { cva as m } from "class-variance-authority";
10
10
  //#region src/ui/banner.tsx
11
- var h = n("flex flex-wrap items-center gap-ds-04 px-ds-06 py-ds-04 text-body-md font-medium border-b", {
11
+ var h = m("flex flex-wrap items-center gap-ds-04 px-ds-06 py-ds-04 text-body-md font-medium border-b", {
12
12
  variants: { color: {
13
13
  info: "bg-info-3 border-info-7 text-info-11",
14
14
  success: "bg-success-3 border-success-7 text-success-11",
@@ -18,18 +18,18 @@ var h = n("flex flex-wrap items-center gap-ds-04 px-ds-06 py-ds-04 text-body-md
18
18
  } },
19
19
  defaultVariants: { color: "info" }
20
20
  }), g = {
21
- info: d,
22
- success: u,
23
- warning: l,
24
- error: c,
25
- neutral: d
26
- }, _ = a.forwardRef(({ className: n, color: c = "info", actions: l, onDismiss: u, children: d, ..._ }, v) => {
27
- let y = g[c ?? "info"], [b, x] = a.useState(!0), S = a.useCallback(() => {
21
+ info: u,
22
+ success: l,
23
+ warning: c,
24
+ error: s,
25
+ neutral: u
26
+ }, _ = i.forwardRef(({ className: s, color: c = "info", actions: l, onDismiss: u, children: m, ..._ }, v) => {
27
+ let y = g[c ?? "info"], [b, x] = i.useState(!0), S = i.useCallback(() => {
28
28
  x(!1);
29
29
  }, []);
30
- return /* @__PURE__ */ o(p, {
30
+ return /* @__PURE__ */ a(f, {
31
31
  onExitComplete: u,
32
- children: b && /* @__PURE__ */ s(m.div, {
32
+ children: b && /* @__PURE__ */ o(p.div, {
33
33
  ref: v,
34
34
  initial: {
35
35
  height: "auto",
@@ -40,31 +40,31 @@ var h = n("flex flex-wrap items-center gap-ds-04 px-ds-06 py-ds-04 text-body-md
40
40
  opacity: 0
41
41
  },
42
42
  transition: t.snappy,
43
- className: r(h({ color: c }), "overflow-hidden", n),
43
+ className: n(h({ color: c }), "overflow-hidden", s),
44
44
  role: "alert",
45
45
  ...e(_),
46
46
  children: [
47
- /* @__PURE__ */ o(i, {
47
+ /* @__PURE__ */ a(r, {
48
48
  icon: y,
49
49
  size: "md",
50
50
  className: "shrink-0"
51
51
  }),
52
- /* @__PURE__ */ o("div", {
52
+ /* @__PURE__ */ a("div", {
53
53
  className: "min-w-0 flex-1",
54
- children: d
54
+ children: m
55
55
  }),
56
- l && /* @__PURE__ */ o("div", {
56
+ l && /* @__PURE__ */ a("div", {
57
57
  className: "flex shrink-0 items-center gap-ds-02 [&_button]:transition-colors [&_button]:duration-moderate-01 [&_button]:ease-productive-standard [&_button:hover]:bg-current/10",
58
58
  children: l
59
59
  }),
60
- u && /* @__PURE__ */ o("button", {
60
+ u && /* @__PURE__ */ a("button", {
61
61
  type: "button",
62
62
  onClick: S,
63
63
  className: "shrink-0 min-h-ds-xs min-w-ds-xs flex items-center justify-center rounded-control-inner transition-colors duration-moderate-01 ease-productive-standard hover:bg-current/10 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9",
64
64
  "aria-label": "Dismiss",
65
65
  title: "Dismiss",
66
- children: /* @__PURE__ */ o(i, {
67
- icon: f,
66
+ children: /* @__PURE__ */ a(r, {
67
+ icon: d,
68
68
  size: "sm"
69
69
  })
70
70
  })
package/dist/ui/button.js CHANGED
@@ -1,20 +1,20 @@
1
1
  "use client";
2
2
  import { Slot as e, Slottable as t } from "../_chunks/primitives-internal.js";
3
3
  import { IconProvider as n } from "./icon-context.js";
4
- import { motionProps as ee } from "./lib/motion.js";
5
- import { cva as r } from "../_chunks/vendor-utils.js";
4
+ import { motionProps as r } from "./lib/motion.js";
6
5
  import { cn as i } from "./lib/utils.js";
7
6
  import { Spinner as a } from "./spinner.js";
8
- import { Icon as te } from "./icon.js";
7
+ import { Icon as ee } from "./icon.js";
9
8
  import { normalizeIcon as o } from "../_chunks/normalize-icon.js";
10
- import { getGroupPositionStyle as ne, useButtonGroup as re, useButtonGroupItem as ie } from "./button-group.js";
11
- import { ProcessingOverlay as ae } from "./button-processing.js";
9
+ import { getGroupPositionStyle as te, useButtonGroup as ne, useButtonGroupItem as re } from "./button-group.js";
10
+ import { ProcessingOverlay as ie } from "./button-processing.js";
12
11
  import * as s from "react";
13
- import { Fragment as oe, jsx as c, jsxs as l } from "react/jsx-runtime";
14
- import { IconCheck as se, IconX as ce } from "@tabler/icons-react";
15
- import { motion as le, useReducedMotion as ue } from "framer-motion";
12
+ import { Fragment as ae, jsx as c, jsxs as l } from "react/jsx-runtime";
13
+ import { IconCheck as oe, IconX as se } from "@tabler/icons-react";
14
+ import { motion as ce, useReducedMotion as le } from "framer-motion";
15
+ import { cva as u } from "class-variance-authority";
16
16
  //#region src/ui/button.tsx
17
- var u = r("relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]", {
17
+ var d = u("relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]", {
18
18
  variants: {
19
19
  variant: {
20
20
  solid: "",
@@ -208,7 +208,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
208
208
  weight: "semibold",
209
209
  size: "md"
210
210
  }
211
- }), d = {
211
+ }), f = {
212
212
  xs: "px-ds-04",
213
213
  sm: "px-ds-05",
214
214
  md: "px-ds-06",
@@ -216,7 +216,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
216
216
  "compact-xs": "px-ds-03",
217
217
  "compact-sm": "px-ds-04",
218
218
  "compact-md": "px-ds-05"
219
- }, de = {
219
+ }, ue = {
220
220
  xs: {
221
221
  start: "-ml-0.5",
222
222
  end: "-mr-0.5"
@@ -265,7 +265,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
265
265
  start: "",
266
266
  end: ""
267
267
  }
268
- }, f = {
268
+ }, p = {
269
269
  xs: "sm",
270
270
  sm: "sm",
271
271
  md: "sm",
@@ -278,7 +278,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
278
278
  "icon-sm": "sm",
279
279
  "icon-md": "sm",
280
280
  "icon-lg": "md"
281
- }, fe = {
281
+ }, de = {
282
282
  xs: "xs",
283
283
  sm: "sm",
284
284
  md: "md",
@@ -291,8 +291,8 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
291
291
  "icon-sm": "sm",
292
292
  "icon-md": "md",
293
293
  "icon-lg": "lg"
294
- }, p = s.forwardRef(({ className: r, variant: p, color: m, weight: pe, size: me, asChild: he = !1, shape: ge, startIcon: h, endIcon: g, loading: _e = !1, loadingPosition: _ = "start", fullWidth: v = !1, disabled: ve, onClick: ye, onClickAsync: y, asyncFeedbackDuration: b = 1500, processing: x, processingColor: be, processingDisabled: S = !0, children: C, ...w }, T) => {
295
- let E = re(), D = ie(), O = p ?? E.variant, k = m ?? E.color, A = pe ?? E.weight ?? "semibold", j = ge ?? E.shape ?? "default", M = me ?? E.size ?? "md", N = ve ?? E.disabled, P = D && E.attached !== !1 ? ne(D.position, E.orientation ?? "horizontal") : void 0, F = E._stretch ?? !1, I = ue(), L = s.useRef(null), R = s.useRef(null), z = s.useRef(void 0);
294
+ }, m = s.forwardRef(({ className: u, variant: m, color: fe, weight: pe, size: me, asChild: he = !1, shape: ge, startIcon: h, endIcon: g, loading: _e = !1, loadingPosition: _ = "start", fullWidth: v = !1, disabled: ve, onClick: ye, onClickAsync: y, asyncFeedbackDuration: b = 1500, processing: x, processingColor: be, processingDisabled: S = !0, children: C, ...w }, T) => {
295
+ let E = ne(), D = re(), O = m ?? E.variant, k = fe ?? E.color, A = pe ?? E.weight ?? "semibold", j = ge ?? E.shape ?? "default", M = me ?? E.size ?? "md", N = ve ?? E.disabled, P = D && E.attached !== !1 ? te(D.position, E.orientation ?? "horizontal") : void 0, F = E._stretch ?? !1, I = le(), L = s.useRef(null), R = s.useRef(null), z = s.useRef(void 0);
296
296
  s.useEffect(() => {
297
297
  let e = R.current, t = L.current;
298
298
  if (!(!e || !t || v || F || I)) return z.current = requestAnimationFrame(() => {
@@ -319,25 +319,25 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
319
319
  }));
320
320
  }, W = !!y, G = W ? B === "loading" : _e, K = B === "success" || B === "error", q = K ? void 0 : x === !0 ? "working" : x === !1 || !x ? W && B === "loading" && !x ? "working" : void 0 : x, J = !!q, Se = be ?? k ?? "accent";
321
321
  if (he) return /* @__PURE__ */ c(e, {
322
- className: i(u({
322
+ className: i(d({
323
323
  variant: O,
324
324
  color: k,
325
325
  weight: A,
326
326
  size: M
327
- }), j === "pill" && "rounded-pill", j === "pill" && d[M], (v || F) && "w-full", r),
327
+ }), j === "pill" && "rounded-pill", j === "pill" && f[M], (v || F) && "w-full", u),
328
328
  ref: T,
329
329
  disabled: N || G,
330
330
  "aria-busy": G || void 0,
331
331
  ...w,
332
332
  children: /* @__PURE__ */ c(t, { children: C })
333
333
  });
334
- let Y = de[M] ?? {
334
+ let Y = ue[M] ?? {
335
335
  start: "",
336
336
  end: ""
337
337
  }, X = O === "solid" || O === "soft" || O === "outline", Z = () => G && _ === "start" ? /* @__PURE__ */ c("span", {
338
338
  className: i("inline-flex shrink-0 items-center justify-center", h && Y.start),
339
339
  children: /* @__PURE__ */ c(a, {
340
- size: f[M],
340
+ size: p[M],
341
341
  variant: "bare"
342
342
  })
343
343
  }) : h ? /* @__PURE__ */ c("span", {
@@ -346,7 +346,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
346
346
  }) : null, Ce = () => G && _ === "end" ? /* @__PURE__ */ c("span", {
347
347
  className: i("inline-flex shrink-0 items-center justify-center", g && Y.end),
348
348
  children: /* @__PURE__ */ c(a, {
349
- size: f[M],
349
+ size: p[M],
350
350
  variant: "bare"
351
351
  })
352
352
  }) : g ? /* @__PURE__ */ c("span", {
@@ -364,28 +364,28 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
364
364
  }), /* @__PURE__ */ c("span", {
365
365
  className: "absolute inset-0 flex items-center justify-center",
366
366
  children: /* @__PURE__ */ c(a, {
367
- size: f[M],
367
+ size: p[M],
368
368
  variant: "bare"
369
369
  })
370
370
  })]
371
- }) : Q.length > 0 ? /* @__PURE__ */ c("span", { children: $ }) : /* @__PURE__ */ c(oe, { children: $ }), Ee = K ? B === "success" ? "bg-success-9 text-success-fg border-transparent hover:bg-success-9" : "bg-error-9 text-error-fg border-transparent hover:bg-error-9" : void 0, De = K ? /* @__PURE__ */ c("span", {
371
+ }) : Q.length > 0 ? /* @__PURE__ */ c("span", { children: $ }) : /* @__PURE__ */ c(ae, { children: $ }), Ee = K ? B === "success" ? "bg-success-9 text-success-fg border-transparent hover:bg-success-9" : "bg-error-9 text-error-fg border-transparent hover:bg-error-9" : void 0, De = K ? /* @__PURE__ */ c("span", {
372
372
  className: i("inline-flex shrink-0 items-center justify-center pointer-events-none", h && Y.start),
373
- children: /* @__PURE__ */ c(te, {
374
- icon: B === "success" ? se : ce,
373
+ children: /* @__PURE__ */ c(ee, {
374
+ icon: B === "success" ? oe : se,
375
375
  animate: "draw"
376
376
  })
377
- }) : null, Oe = fe[M] ?? "md", ke = /* @__PURE__ */ l(le.button, {
378
- ...ee(w),
377
+ }) : null, Oe = de[M] ?? "md", ke = /* @__PURE__ */ l(ce.button, {
378
+ ...r(w),
379
379
  style: {
380
380
  ...w.style,
381
381
  ...P
382
382
  },
383
- className: i(u({
383
+ className: i(d({
384
384
  variant: J && !K && O !== "ghost" && O !== "outline" && O !== "link" ? "soft" : O,
385
385
  color: k,
386
386
  weight: A,
387
387
  size: M
388
- }), j === "pill" && "rounded-pill", j === "pill" && d[M], (v || F) && "w-full", !G && !K && "transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit", !G && !K && "hover:duration-fast-02 hover:ease-productive-entrance", !G && !K && "active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]", Ee, K && "transition-colors duration-moderate-01 ease-productive-standard", J && S && "pointer-events-none cursor-default", r),
388
+ }), j === "pill" && "rounded-pill", j === "pill" && f[M], (v || F) && "w-full", !G && !K && "transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit", !G && !K && "hover:duration-fast-02 hover:ease-productive-entrance", !G && !K && "active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]", Ee, K && "transition-colors duration-moderate-01 ease-productive-standard", J && S && "pointer-events-none cursor-default", u),
389
389
  ref: (e) => {
390
390
  R.current = e, typeof T == "function" ? T(e) : T && (T.current = e);
391
391
  },
@@ -409,7 +409,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
409
409
  ...v || F || I ? void 0 : { transition: "width 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)" },
410
410
  ...P
411
411
  },
412
- children: [ke, /* @__PURE__ */ c(ae, {
412
+ children: [ke, /* @__PURE__ */ c(ie, {
413
413
  active: J,
414
414
  speed: q ?? "working",
415
415
  color: Se
@@ -417,6 +417,6 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
417
417
  })
418
418
  });
419
419
  });
420
- p.displayName = "Button";
420
+ m.displayName = "Button";
421
421
  //#endregion
422
- export { p as Button, u as buttonVariants };
422
+ export { m as Button, d as buttonVariants };
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":[],"sources":["../../src/ui/button.tsx"],"sourcesContent":["'use client'\n\nimport { Slot, Slottable } from '@primitives/react-slot'\nimport { IconCheck, IconX } from '@tabler/icons-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { getGroupPositionStyle,useButtonGroup, useButtonGroupItem } from './button-group'\nimport type { ProcessingSpeed } from './button-processing'\nimport { ProcessingOverlay } from './button-processing'\nimport { Icon } from './icon'\nimport type { IconSize } from './icon-context'\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { motionProps,springs, tweens } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\nimport { Spinner } from './spinner'\n\nexport const buttonVariants = cva(\n 'relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]',\n {\n variants: {\n variant: {\n solid: '',\n soft: '',\n outline: 'border',\n ghost: '',\n link: 'underline-offset-4 hover:underline active:opacity-80',\n },\n color: {\n accent: '',\n error: '',\n success: '',\n warning: '',\n info: '',\n neutral: '',\n },\n weight: {\n semibold: 'font-semibold',\n normal: 'font-normal',\n },\n size: {\n xs: 'h-ds-xs-plus rounded-control px-ds-03 text-body-sm gap-ds-02',\n sm: 'h-ds-sm rounded-control px-ds-04 text-body-sm gap-ds-02b',\n md: 'h-ds-md rounded-control px-ds-05 text-body-md gap-ds-03',\n lg: 'h-ds-lg rounded-control px-ds-06 text-body-lg gap-2.5',\n 'compact-xs': 'rounded-control px-ds-02 py-[3px] text-body-sm gap-ds-02',\n 'compact-sm': 'rounded-control px-ds-03 py-[5px] text-body-sm gap-ds-02b',\n 'compact-md': 'rounded-control px-ds-04 py-ds-03 text-body-md gap-ds-03',\n icon: 'h-ds-md w-ds-md rounded-control',\n 'icon-xs': 'h-ds-xs-plus w-ds-xs-plus rounded-control',\n 'icon-sm': 'h-ds-sm w-ds-sm rounded-control',\n 'icon-md': 'h-ds-md w-ds-md rounded-control',\n 'icon-lg': 'h-ds-lg w-ds-lg rounded-control',\n },\n },\n compoundVariants: [\n // ============ SOLID ============ (tonal raised shadow; fill deepens on hover — no coloured bloom)\n { variant: 'solid', color: 'accent', className: 'bg-accent-9 text-accent-fg hover:bg-accent-10 shadow-raised' },\n { variant: 'solid', color: 'error', className: 'bg-error-9 text-error-fg hover:bg-error-10 shadow-raised' },\n { variant: 'solid', color: 'success', className: 'bg-success-9 text-success-fg hover:bg-success-10 shadow-raised' },\n { variant: 'solid', color: 'warning', className: 'bg-warning-9 text-warning-fg hover:bg-warning-10 shadow-raised' },\n { variant: 'solid', color: 'info', className: 'bg-info-9 text-info-fg hover:bg-info-10 shadow-raised' },\n { variant: 'solid', color: 'neutral', className: 'bg-neutral-5 text-surface-fg hover:bg-neutral-7 shadow-raised' },\n\n // ============ SOFT ============\n { variant: 'soft', color: 'accent', className: 'bg-accent-3 text-accent-11 hover:bg-accent-4 active:bg-accent-5' },\n { variant: 'soft', color: 'error', className: 'bg-error-3 text-error-11 hover:bg-error-4 active:bg-error-5' },\n { variant: 'soft', color: 'success', className: 'bg-success-3 text-success-11 hover:bg-success-4 active:bg-success-5' },\n { variant: 'soft', color: 'warning', className: 'bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5' },\n { variant: 'soft', color: 'info', className: 'bg-info-3 text-info-11 hover:bg-info-4 active:bg-info-5' },\n { variant: 'soft', color: 'neutral', className: 'bg-surface-raised-hover text-surface-fg-muted hover:bg-surface-raised-active active:bg-neutral-5' },\n\n // ============ OUTLINE ============\n { variant: 'outline', color: 'accent', className: 'bg-transparent text-accent-11 border-accent-7 hover:bg-accent-3 active:bg-accent-4' },\n { variant: 'outline', color: 'error', className: 'bg-transparent text-error-11 border-error-7 hover:bg-error-3 active:bg-error-4' },\n { variant: 'outline', color: 'success', className: 'bg-transparent text-success-11 border-success-7 hover:bg-success-3 active:bg-success-4' },\n { variant: 'outline', color: 'warning', className: 'bg-transparent text-warning-11 border-warning-7 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'outline', color: 'info', className: 'bg-transparent text-info-11 border-info-7 hover:bg-info-3 active:bg-info-4' },\n { variant: 'outline', color: 'neutral', className: 'bg-transparent text-surface-fg border-surface-border-strong hover:bg-surface-raised-hover active:bg-surface-raised-active' },\n\n // ============ GHOST ============\n // ghost+accent uses neutral look for backward compat (most common ghost is toolbar/icon ghost)\n { variant: 'ghost', color: 'accent', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n { variant: 'ghost', color: 'error', className: 'bg-transparent text-error-11 hover:bg-error-3 active:bg-error-4' },\n { variant: 'ghost', color: 'success', className: 'bg-transparent text-success-11 hover:bg-success-3 active:bg-success-4' },\n { variant: 'ghost', color: 'warning', className: 'bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'ghost', color: 'info', className: 'bg-transparent text-info-11 hover:bg-info-3 active:bg-info-4' },\n { variant: 'ghost', color: 'neutral', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n\n // ============ LINK ============\n { variant: 'link', color: 'accent', className: 'text-accent-11' },\n { variant: 'link', color: 'error', className: 'text-error-11' },\n { variant: 'link', color: 'success', className: 'text-success-11' },\n { variant: 'link', color: 'warning', className: 'text-warning-11' },\n { variant: 'link', color: 'info', className: 'text-info-11' },\n { variant: 'link', color: 'neutral', className: 'text-surface-fg-muted' },\n ],\n defaultVariants: {\n variant: 'solid',\n color: 'accent',\n weight: 'semibold',\n size: 'md',\n },\n },\n)\n\n/** Extra horizontal padding for pill shape — rounded ends eat into visual space */\nconst pillPaddingClass: Record<string, string> = {\n xs: 'px-ds-04',\n sm: 'px-ds-05',\n md: 'px-ds-06',\n lg: 'px-ds-07',\n 'compact-xs': 'px-ds-03',\n 'compact-sm': 'px-ds-04',\n 'compact-md': 'px-ds-05',\n}\n\n/** Negative margin to tighten icon side padding — pulls icon closer to button edge */\nconst iconInsetClass: Record<string, { start: string; end: string }> = {\n xs: { start: '-ml-0.5', end: '-mr-0.5' },\n sm: { start: '-ml-1', end: '-mr-1' },\n md: { start: '-ml-1.5', end: '-mr-1.5' },\n lg: { start: '-ml-2', end: '-mr-2' },\n 'compact-xs': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-sm': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-md': { start: '-ml-1', end: '-mr-1' },\n icon: { start: '', end: '' },\n 'icon-xs': { start: '', end: '' },\n 'icon-sm': { start: '', end: '' },\n 'icon-md': { start: '', end: '' },\n 'icon-lg': { start: '', end: '' },\n}\n\n/** Map button size to spinner size */\nconst BUTTON_TO_SPINNER_SIZE: Record<string, 'sm' | 'md'> = {\n xs: 'sm',\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n 'compact-xs': 'sm',\n 'compact-sm': 'sm',\n 'compact-md': 'sm',\n icon: 'sm',\n 'icon-xs': 'sm',\n 'icon-sm': 'sm',\n 'icon-md': 'sm',\n 'icon-lg': 'md',\n}\n\n/** Map button size to Icon context size */\nconst BUTTON_TO_ICON_SIZE: Record<string, IconSize> = {\n xs: 'xs', sm: 'sm', md: 'md', lg: 'lg',\n 'compact-xs': 'xs', 'compact-sm': 'sm', 'compact-md': 'md',\n icon: 'md', 'icon-xs': 'xs', 'icon-sm': 'sm', 'icon-md': 'md', 'icon-lg': 'lg',\n}\n\n/**\n * Props for Button — the primary action component with a two-axis variant system,\n * multiple size options, icon slots, and a built-in loading state.\n *\n * **Two axes:**\n * - `variant` controls **visual style**: `\"solid\"` (default, filled) | `\"soft\"` (tinted bg) |\n * `\"outline\"` (bordered) | `\"ghost\"` (transparent, for toolbars) | `\"link\"` (underline, inline)\n * - `color` controls **semantic intent**: `\"accent\"` (default, brand) | `\"error\"` (destructive) |\n * `\"success\"` | `\"warning\"` | `\"info\"` | `\"neutral\"` (subdued)\n *\n * **Sizes:** `xs` | `sm` | `md` (default) | `lg` for text buttons;\n * `compact-xs` | `compact-sm` | `compact-md` for height-less inline buttons;\n * `icon` | `icon-xs` | `icon-sm` | `icon-md` | `icon-lg` for square icon-only buttons.\n *\n * **Shape:** `\"default\"` uses the `--radius-control` token; `\"pill\"` applies `rounded-pill` (fully-rounded).\n *\n * **Weight:** `\"semibold\"` (default) | `\"normal\"` for lighter labels.\n *\n * **Note:** `ghost` + `accent` renders with neutral styling for backward compat —\n * most ghost buttons are toolbar/icon actions where neutral is expected.\n *\n * **Loading:** When `loading={true}` the button is disabled and aria-busy is set.\n * Use `loadingPosition` to control where the spinner appears.\n *\n * @example\n * // Primary save action (default variant + color):\n * <Button onClick={handleSave}>Save changes</Button>\n *\n * @example\n * // Soft success feedback:\n * <Button variant=\"soft\" color=\"success\" startIcon={<Icon icon={IconCheck} />}>\n * Approved\n * </Button>\n *\n * @example\n * // Destructive delete with loading state:\n * <Button variant=\"solid\" color=\"error\" startIcon={<Icon icon={IconTrash} />} loading={isDeleting}>\n * Delete project\n * </Button>\n *\n * @example\n * // Compact pill tag:\n * <Button variant=\"soft\" color=\"warning\" size=\"compact-sm\" shape=\"pill\">\n * Overdue\n * </Button>\n *\n * @example\n * // Ghost toolbar action:\n * <Button variant=\"ghost\" size=\"sm\" startIcon={<Icon icon={IconEdit} />}>\n * Edit\n * </Button>\n */\nexport interface ButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color'>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n /** Button shape — 'pill' applies rounded-pill for chip/tag-like buttons */\n shape?: 'default' | 'pill'\n /** Icon element rendered before children — use <Icon icon={...} /> */\n startIcon?: IconInput\n /** Icon element rendered after children — use <Icon icon={...} /> */\n endIcon?: IconInput\n /** Show loading spinner and disable button */\n loading?: boolean\n /** Where to render the spinner: replaces startIcon, endIcon, or centers over children */\n loadingPosition?: 'start' | 'end' | 'center'\n /** Stretch to full width of parent */\n fullWidth?: boolean\n /**\n * Async click handler — auto-manages loading → success/error states.\n * When provided, the button shows a spinner while the promise is pending,\n * then briefly flashes green (success) or red (error) before reverting.\n * Overrides `onClick` and `loading` when active.\n */\n onClickAsync?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>\n /** How long (ms) to show the success/error state before reverting. Default: 1500 */\n asyncFeedbackDuration?: number\n\n /**\n * Show processing animation — animated border/glow while content stays visible.\n * `true` = \"working\" speed. Semantic speeds:\n * - `\"ambient\"` (3s) — background sync, file upload\n * - `\"working\"` (2s) — standard API call, generation\n * - `\"urgent\"` (1s) — retry, nearly done\n */\n processing?: boolean | 'ambient' | 'working' | 'urgent'\n\n /** Override processing animation color. Defaults to button's own color. */\n processingColor?: 'accent' | 'error' | 'success' | 'warning' | 'info' | 'neutral'\n\n /** Disable button during processing. Default: true. Set false for cancel-by-click patterns. */\n processingDisabled?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant,\n color,\n weight,\n size,\n asChild = false,\n shape,\n startIcon,\n endIcon,\n loading: loadingProp = false,\n loadingPosition = 'start',\n fullWidth = false,\n disabled,\n onClick,\n onClickAsync,\n asyncFeedbackDuration = 1500,\n processing: processingProp,\n processingColor,\n processingDisabled = true,\n children,\n ...props\n },\n ref,\n ) => {\n const group = useButtonGroup()\n const groupItem = useButtonGroupItem()\n const resolvedVariant = variant ?? group.variant\n const resolvedColor = color ?? group.color\n const resolvedWeight = weight ?? group.weight ?? 'semibold'\n const resolvedShape = shape ?? group.shape ?? 'default'\n const resolvedSize = size ?? group.size ?? 'md'\n // ButtonGroup can propagate disabled to all children\n const resolvedDisabled = disabled ?? group.disabled\n\n // When inside an attached ButtonGroup, adjust border-radius based on position\n const groupRadiusStyle = groupItem && group.attached !== false\n ? getGroupPositionStyle(groupItem.position, group.orientation ?? 'horizontal')\n : undefined\n // Stretch to fill when inside a vertical or fullWidth ButtonGroup\n const groupStretch = group._stretch ?? false\n\n const prefersReduced = useReducedMotion()\n\n // Refs + effect for smooth width transitions (must be before any early returns)\n const wrapperRef = React.useRef<HTMLSpanElement>(null)\n const btnRef = React.useRef<HTMLButtonElement | null>(null)\n const rafRef = React.useRef<number | undefined>(undefined)\n\n \n React.useEffect(() => {\n const btn = btnRef.current\n const wrapper = wrapperRef.current\n if (!btn || !wrapper || fullWidth || groupStretch || prefersReduced) return\n\n rafRef.current = requestAnimationFrame(() => {\n wrapper.style.width = 'auto'\n const w = btn.offsetWidth\n if (w > 0) {\n wrapper.getBoundingClientRect()\n wrapper.style.width = `${w}px`\n }\n })\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current) }\n }) // run on every render to catch content changes\n\n // Async state machine: idle → loading → success | error → idle\n type AsyncState = 'idle' | 'loading' | 'success' | 'error'\n const [asyncState, setAsyncState] = React.useState<AsyncState>('idle')\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isMountedRef = React.useRef(true)\n\n React.useEffect(() => () => {\n isMountedRef.current = false\n clearTimeout(timeoutRef.current)\n }, [])\n\n const handleAsyncClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClickAsync || asyncState !== 'idle') return\n setAsyncState('loading')\n onClickAsync(e)\n .then(() => { if (isMountedRef.current) setAsyncState('success') })\n .catch(() => { if (isMountedRef.current) setAsyncState('error') })\n .finally(() => {\n if (isMountedRef.current) {\n timeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) setAsyncState('idle')\n }, asyncFeedbackDuration)\n }\n })\n }\n\n const isAsync = !!onClickAsync\n const loading = isAsync ? asyncState === 'loading' : loadingProp\n const isAsyncFeedback = asyncState === 'success' || asyncState === 'error'\n\n // Processing: explicit prop takes priority, otherwise auto-processing during onClickAsync.\n // Processing is always OFF during async feedback (success/error) so the feedback colors show.\n const autoProcessing = isAsync && asyncState === 'loading' && !processingProp\n const processingSpeed: ProcessingSpeed | undefined = isAsyncFeedback ? undefined\n : processingProp === true ? 'working'\n : processingProp === false || !processingProp\n ? (autoProcessing ? 'working' : undefined)\n : processingProp\n const isProcessing = !!processingSpeed\n const resolvedProcessingColor = processingColor ?? resolvedColor ?? 'accent'\n\n if (asChild) {\n // Slot merges all props into the child element via cloneElement at runtime.\n // We cast here because SlotProps only types React.HTMLAttributes<HTMLElement>,\n // which excludes button-specific attrs like `disabled`.\n const slotProps = {\n className: cn(\n buttonVariants({ variant: resolvedVariant, color: resolvedColor, weight: resolvedWeight, size: resolvedSize }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n className,\n ),\n ref,\n disabled: resolvedDisabled || loading,\n 'aria-busy': loading || undefined,\n ...props,\n } as React.ComponentPropsWithRef<typeof Slot>\n return (\n <Slot {...slotProps}>\n <Slottable>{children}</Slottable>\n </Slot>\n )\n }\n\n const inset = iconInsetClass[resolvedSize] ?? { start: '', end: '' }\n // Dim icons on filled variants (Radix pattern — icon is decorative, text is primary)\n const dimIcon = resolvedVariant === 'solid' || resolvedVariant === 'soft' || resolvedVariant === 'outline'\n\n const renderStartSlot = () => {\n if (loading && loadingPosition === 'start') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', startIcon && inset.start)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (startIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.start, dimIcon && 'opacity-90')}>\n {normalizeIcon(startIcon)}\n </span>\n )\n }\n return null\n }\n\n const renderEndSlot = () => {\n if (loading && loadingPosition === 'end') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', endIcon && inset.end)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (endIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.end, dimIcon && 'opacity-90')}>\n {normalizeIcon(endIcon)}\n </span>\n )\n }\n return null\n }\n\n // Separate DevalokGrain elements (need to be direct button children for absolute positioning)\n // from text/other content (needs z-elevation above grain)\n const childArray = React.Children.toArray(children)\n const grainElements: React.ReactNode[] = []\n const contentElements: React.ReactNode[] = []\n childArray.forEach((child) => {\n if (React.isValidElement(child) && (child.type as { displayName?: string })?.displayName === 'DevalokGrain') {\n grainElements.push(child)\n } else {\n contentElements.push(child)\n }\n })\n\n const renderChildren = () => {\n if (loading && loadingPosition === 'center') {\n return (\n <span className=\"relative inline-flex items-center justify-center\">\n <span className=\"invisible\">{contentElements}</span>\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n </span>\n )\n }\n // Only wrap in z-elevated span when grain is present (to sit above grain layers).\n // Without grain, render children directly to preserve flex layout.\n if (grainElements.length > 0) {\n return <span>{contentElements}</span>\n }\n return <>{contentElements}</>\n }\n\n // Async feedback: override color to show green/red\n const feedbackColorClass = isAsyncFeedback\n ? asyncState === 'success'\n ? 'bg-success-9 text-success-fg border-transparent hover:bg-success-9'\n : 'bg-error-9 text-error-fg border-transparent hover:bg-error-9'\n : undefined\n\n // Async feedback icon — uses Icon's draw animation for pen-stroke effect\n const asyncFeedbackIcon = isAsyncFeedback ? (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', startIcon && inset.start)}>\n <Icon icon={asyncState === 'success' ? IconCheck : IconX} animate=\"draw\" />\n </span>\n ) : null\n\n const iconSize = BUTTON_TO_ICON_SIZE[resolvedSize] ?? 'md'\n\n const buttonEl = (\n <motion.button\n {...motionProps(props)}\n style={{ ...props.style, ...groupRadiusStyle }}\n className={cn(\n buttonVariants({\n // When processing (and not showing async feedback), force soft variant so ants pop\n variant: isProcessing && !isAsyncFeedback && resolvedVariant !== 'ghost' && resolvedVariant !== 'outline' && resolvedVariant !== 'link' ? 'soft' : resolvedVariant,\n color: resolvedColor,\n weight: resolvedWeight,\n size: resolvedSize,\n }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n // Asymmetric timing: hover-out is slow+relaxed, hover-in is fast+snappy (applied via hover: override)\n !loading && !isAsyncFeedback && 'transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit',\n !loading && !isAsyncFeedback && 'hover:duration-fast-02 hover:ease-productive-entrance',\n !loading && !isAsyncFeedback && 'active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]',\n feedbackColorClass,\n isAsyncFeedback && 'transition-colors duration-moderate-01 ease-productive-standard',\n isProcessing && processingDisabled && 'pointer-events-none cursor-default',\n className,\n )}\n ref={(el: HTMLButtonElement | null) => {\n btnRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = el\n }}\n disabled={resolvedDisabled || (loading && !isProcessing)}\n aria-busy={loading || isProcessing || undefined}\n aria-disabled={isProcessing && processingDisabled || undefined}\n onClick={isAsync ? handleAsyncClick : (isProcessing && processingDisabled ? undefined : onClick)}\n >\n {/* Grain layers render as direct children (need absolute positioning) */}\n {grainElements}\n {/* Content renders above grain via z-[2] span wrapper */}\n {isAsyncFeedback ? asyncFeedbackIcon : renderStartSlot()}\n {isAsyncFeedback ? contentElements : renderChildren()}\n {isAsyncFeedback ? null : renderEndSlot()}\n </motion.button>\n )\n\n // Always wrap in a positioned container so the overlay can render\n // as a sibling OUTSIDE the button (not affected by disabled opacity).\n // Keeping the wrapper always-on prevents React unmount/remount on\n // processing toggle, enabling smooth CSS transitions between states.\n return (\n <IconProvider size={iconSize}>\n <span\n ref={wrapperRef}\n className={cn('relative inline-flex', fullWidth && 'w-full')}\n style={{\n ...(fullWidth || groupStretch || prefersReduced ? undefined : { transition: 'width 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)' }),\n ...groupRadiusStyle,\n }}\n >\n {buttonEl}\n <ProcessingOverlay\n active={isProcessing}\n speed={processingSpeed ?? 'working'}\n color={resolvedProcessingColor}\n />\n </span>\n </IconProvider>\n )\n },\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"],"mappings":"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"}
1
+ {"version":3,"file":"button.js","names":[],"sources":["../../src/ui/button.tsx"],"sourcesContent":["'use client'\n\nimport { Slot, Slottable } from '@primitives/react-slot'\nimport { IconCheck, IconX } from '@tabler/icons-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { getGroupPositionStyle,useButtonGroup, useButtonGroupItem } from './button-group'\nimport type { ProcessingSpeed } from './button-processing'\nimport { ProcessingOverlay } from './button-processing'\nimport { Icon } from './icon'\nimport type { IconSize } from './icon-context'\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { motionProps,springs, tweens } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\nimport { Spinner } from './spinner'\n\nexport const buttonVariants = cva(\n 'relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]',\n {\n variants: {\n variant: {\n solid: '',\n soft: '',\n outline: 'border',\n ghost: '',\n link: 'underline-offset-4 hover:underline active:opacity-80',\n },\n color: {\n accent: '',\n error: '',\n success: '',\n warning: '',\n info: '',\n neutral: '',\n },\n weight: {\n semibold: 'font-semibold',\n normal: 'font-normal',\n },\n size: {\n xs: 'h-ds-xs-plus rounded-control px-ds-03 text-body-sm gap-ds-02',\n sm: 'h-ds-sm rounded-control px-ds-04 text-body-sm gap-ds-02b',\n md: 'h-ds-md rounded-control px-ds-05 text-body-md gap-ds-03',\n lg: 'h-ds-lg rounded-control px-ds-06 text-body-lg gap-2.5',\n 'compact-xs': 'rounded-control px-ds-02 py-[3px] text-body-sm gap-ds-02',\n 'compact-sm': 'rounded-control px-ds-03 py-[5px] text-body-sm gap-ds-02b',\n 'compact-md': 'rounded-control px-ds-04 py-ds-03 text-body-md gap-ds-03',\n icon: 'h-ds-md w-ds-md rounded-control',\n 'icon-xs': 'h-ds-xs-plus w-ds-xs-plus rounded-control',\n 'icon-sm': 'h-ds-sm w-ds-sm rounded-control',\n 'icon-md': 'h-ds-md w-ds-md rounded-control',\n 'icon-lg': 'h-ds-lg w-ds-lg rounded-control',\n },\n },\n compoundVariants: [\n // ============ SOLID ============ (tonal raised shadow; fill deepens on hover — no coloured bloom)\n { variant: 'solid', color: 'accent', className: 'bg-accent-9 text-accent-fg hover:bg-accent-10 shadow-raised' },\n { variant: 'solid', color: 'error', className: 'bg-error-9 text-error-fg hover:bg-error-10 shadow-raised' },\n { variant: 'solid', color: 'success', className: 'bg-success-9 text-success-fg hover:bg-success-10 shadow-raised' },\n { variant: 'solid', color: 'warning', className: 'bg-warning-9 text-warning-fg hover:bg-warning-10 shadow-raised' },\n { variant: 'solid', color: 'info', className: 'bg-info-9 text-info-fg hover:bg-info-10 shadow-raised' },\n { variant: 'solid', color: 'neutral', className: 'bg-neutral-5 text-surface-fg hover:bg-neutral-7 shadow-raised' },\n\n // ============ SOFT ============\n { variant: 'soft', color: 'accent', className: 'bg-accent-3 text-accent-11 hover:bg-accent-4 active:bg-accent-5' },\n { variant: 'soft', color: 'error', className: 'bg-error-3 text-error-11 hover:bg-error-4 active:bg-error-5' },\n { variant: 'soft', color: 'success', className: 'bg-success-3 text-success-11 hover:bg-success-4 active:bg-success-5' },\n { variant: 'soft', color: 'warning', className: 'bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5' },\n { variant: 'soft', color: 'info', className: 'bg-info-3 text-info-11 hover:bg-info-4 active:bg-info-5' },\n { variant: 'soft', color: 'neutral', className: 'bg-surface-raised-hover text-surface-fg-muted hover:bg-surface-raised-active active:bg-neutral-5' },\n\n // ============ OUTLINE ============\n { variant: 'outline', color: 'accent', className: 'bg-transparent text-accent-11 border-accent-7 hover:bg-accent-3 active:bg-accent-4' },\n { variant: 'outline', color: 'error', className: 'bg-transparent text-error-11 border-error-7 hover:bg-error-3 active:bg-error-4' },\n { variant: 'outline', color: 'success', className: 'bg-transparent text-success-11 border-success-7 hover:bg-success-3 active:bg-success-4' },\n { variant: 'outline', color: 'warning', className: 'bg-transparent text-warning-11 border-warning-7 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'outline', color: 'info', className: 'bg-transparent text-info-11 border-info-7 hover:bg-info-3 active:bg-info-4' },\n { variant: 'outline', color: 'neutral', className: 'bg-transparent text-surface-fg border-surface-border-strong hover:bg-surface-raised-hover active:bg-surface-raised-active' },\n\n // ============ GHOST ============\n // ghost+accent uses neutral look for backward compat (most common ghost is toolbar/icon ghost)\n { variant: 'ghost', color: 'accent', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n { variant: 'ghost', color: 'error', className: 'bg-transparent text-error-11 hover:bg-error-3 active:bg-error-4' },\n { variant: 'ghost', color: 'success', className: 'bg-transparent text-success-11 hover:bg-success-3 active:bg-success-4' },\n { variant: 'ghost', color: 'warning', className: 'bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'ghost', color: 'info', className: 'bg-transparent text-info-11 hover:bg-info-3 active:bg-info-4' },\n { variant: 'ghost', color: 'neutral', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n\n // ============ LINK ============\n { variant: 'link', color: 'accent', className: 'text-accent-11' },\n { variant: 'link', color: 'error', className: 'text-error-11' },\n { variant: 'link', color: 'success', className: 'text-success-11' },\n { variant: 'link', color: 'warning', className: 'text-warning-11' },\n { variant: 'link', color: 'info', className: 'text-info-11' },\n { variant: 'link', color: 'neutral', className: 'text-surface-fg-muted' },\n ],\n defaultVariants: {\n variant: 'solid',\n color: 'accent',\n weight: 'semibold',\n size: 'md',\n },\n },\n)\n\n/** Extra horizontal padding for pill shape — rounded ends eat into visual space */\nconst pillPaddingClass: Record<string, string> = {\n xs: 'px-ds-04',\n sm: 'px-ds-05',\n md: 'px-ds-06',\n lg: 'px-ds-07',\n 'compact-xs': 'px-ds-03',\n 'compact-sm': 'px-ds-04',\n 'compact-md': 'px-ds-05',\n}\n\n/** Negative margin to tighten icon side padding — pulls icon closer to button edge */\nconst iconInsetClass: Record<string, { start: string; end: string }> = {\n xs: { start: '-ml-0.5', end: '-mr-0.5' },\n sm: { start: '-ml-1', end: '-mr-1' },\n md: { start: '-ml-1.5', end: '-mr-1.5' },\n lg: { start: '-ml-2', end: '-mr-2' },\n 'compact-xs': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-sm': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-md': { start: '-ml-1', end: '-mr-1' },\n icon: { start: '', end: '' },\n 'icon-xs': { start: '', end: '' },\n 'icon-sm': { start: '', end: '' },\n 'icon-md': { start: '', end: '' },\n 'icon-lg': { start: '', end: '' },\n}\n\n/** Map button size to spinner size */\nconst BUTTON_TO_SPINNER_SIZE: Record<string, 'sm' | 'md'> = {\n xs: 'sm',\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n 'compact-xs': 'sm',\n 'compact-sm': 'sm',\n 'compact-md': 'sm',\n icon: 'sm',\n 'icon-xs': 'sm',\n 'icon-sm': 'sm',\n 'icon-md': 'sm',\n 'icon-lg': 'md',\n}\n\n/** Map button size to Icon context size */\nconst BUTTON_TO_ICON_SIZE: Record<string, IconSize> = {\n xs: 'xs', sm: 'sm', md: 'md', lg: 'lg',\n 'compact-xs': 'xs', 'compact-sm': 'sm', 'compact-md': 'md',\n icon: 'md', 'icon-xs': 'xs', 'icon-sm': 'sm', 'icon-md': 'md', 'icon-lg': 'lg',\n}\n\n/**\n * Props for Button — the primary action component with a two-axis variant system,\n * multiple size options, icon slots, and a built-in loading state.\n *\n * **Two axes:**\n * - `variant` controls **visual style**: `\"solid\"` (default, filled) | `\"soft\"` (tinted bg) |\n * `\"outline\"` (bordered) | `\"ghost\"` (transparent, for toolbars) | `\"link\"` (underline, inline)\n * - `color` controls **semantic intent**: `\"accent\"` (default, brand) | `\"error\"` (destructive) |\n * `\"success\"` | `\"warning\"` | `\"info\"` | `\"neutral\"` (subdued)\n *\n * **Sizes:** `xs` | `sm` | `md` (default) | `lg` for text buttons;\n * `compact-xs` | `compact-sm` | `compact-md` for height-less inline buttons;\n * `icon` | `icon-xs` | `icon-sm` | `icon-md` | `icon-lg` for square icon-only buttons.\n *\n * **Shape:** `\"default\"` uses the `--radius-control` token; `\"pill\"` applies `rounded-pill` (fully-rounded).\n *\n * **Weight:** `\"semibold\"` (default) | `\"normal\"` for lighter labels.\n *\n * **Note:** `ghost` + `accent` renders with neutral styling for backward compat —\n * most ghost buttons are toolbar/icon actions where neutral is expected.\n *\n * **Loading:** When `loading={true}` the button is disabled and aria-busy is set.\n * Use `loadingPosition` to control where the spinner appears.\n *\n * @example\n * // Primary save action (default variant + color):\n * <Button onClick={handleSave}>Save changes</Button>\n *\n * @example\n * // Soft success feedback:\n * <Button variant=\"soft\" color=\"success\" startIcon={<Icon icon={IconCheck} />}>\n * Approved\n * </Button>\n *\n * @example\n * // Destructive delete with loading state:\n * <Button variant=\"solid\" color=\"error\" startIcon={<Icon icon={IconTrash} />} loading={isDeleting}>\n * Delete project\n * </Button>\n *\n * @example\n * // Compact pill tag:\n * <Button variant=\"soft\" color=\"warning\" size=\"compact-sm\" shape=\"pill\">\n * Overdue\n * </Button>\n *\n * @example\n * // Ghost toolbar action:\n * <Button variant=\"ghost\" size=\"sm\" startIcon={<Icon icon={IconEdit} />}>\n * Edit\n * </Button>\n */\nexport interface ButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color'>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n /** Button shape — 'pill' applies rounded-pill for chip/tag-like buttons */\n shape?: 'default' | 'pill'\n /** Icon element rendered before children — use <Icon icon={...} /> */\n startIcon?: IconInput\n /** Icon element rendered after children — use <Icon icon={...} /> */\n endIcon?: IconInput\n /** Show loading spinner and disable button */\n loading?: boolean\n /** Where to render the spinner: replaces startIcon, endIcon, or centers over children */\n loadingPosition?: 'start' | 'end' | 'center'\n /** Stretch to full width of parent */\n fullWidth?: boolean\n /**\n * Async click handler — auto-manages loading → success/error states.\n * When provided, the button shows a spinner while the promise is pending,\n * then briefly flashes green (success) or red (error) before reverting.\n * Overrides `onClick` and `loading` when active.\n */\n onClickAsync?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>\n /** How long (ms) to show the success/error state before reverting. Default: 1500 */\n asyncFeedbackDuration?: number\n\n /**\n * Show processing animation — animated border/glow while content stays visible.\n * `true` = \"working\" speed. Semantic speeds:\n * - `\"ambient\"` (3s) — background sync, file upload\n * - `\"working\"` (2s) — standard API call, generation\n * - `\"urgent\"` (1s) — retry, nearly done\n */\n processing?: boolean | 'ambient' | 'working' | 'urgent'\n\n /** Override processing animation color. Defaults to button's own color. */\n processingColor?: 'accent' | 'error' | 'success' | 'warning' | 'info' | 'neutral'\n\n /** Disable button during processing. Default: true. Set false for cancel-by-click patterns. */\n processingDisabled?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant,\n color,\n weight,\n size,\n asChild = false,\n shape,\n startIcon,\n endIcon,\n loading: loadingProp = false,\n loadingPosition = 'start',\n fullWidth = false,\n disabled,\n onClick,\n onClickAsync,\n asyncFeedbackDuration = 1500,\n processing: processingProp,\n processingColor,\n processingDisabled = true,\n children,\n ...props\n },\n ref,\n ) => {\n const group = useButtonGroup()\n const groupItem = useButtonGroupItem()\n const resolvedVariant = variant ?? group.variant\n const resolvedColor = color ?? group.color\n const resolvedWeight = weight ?? group.weight ?? 'semibold'\n const resolvedShape = shape ?? group.shape ?? 'default'\n const resolvedSize = size ?? group.size ?? 'md'\n // ButtonGroup can propagate disabled to all children\n const resolvedDisabled = disabled ?? group.disabled\n\n // When inside an attached ButtonGroup, adjust border-radius based on position\n const groupRadiusStyle = groupItem && group.attached !== false\n ? getGroupPositionStyle(groupItem.position, group.orientation ?? 'horizontal')\n : undefined\n // Stretch to fill when inside a vertical or fullWidth ButtonGroup\n const groupStretch = group._stretch ?? false\n\n const prefersReduced = useReducedMotion()\n\n // Refs + effect for smooth width transitions (must be before any early returns)\n const wrapperRef = React.useRef<HTMLSpanElement>(null)\n const btnRef = React.useRef<HTMLButtonElement | null>(null)\n const rafRef = React.useRef<number | undefined>(undefined)\n\n \n React.useEffect(() => {\n const btn = btnRef.current\n const wrapper = wrapperRef.current\n if (!btn || !wrapper || fullWidth || groupStretch || prefersReduced) return\n\n rafRef.current = requestAnimationFrame(() => {\n wrapper.style.width = 'auto'\n const w = btn.offsetWidth\n if (w > 0) {\n wrapper.getBoundingClientRect()\n wrapper.style.width = `${w}px`\n }\n })\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current) }\n }) // run on every render to catch content changes\n\n // Async state machine: idle → loading → success | error → idle\n type AsyncState = 'idle' | 'loading' | 'success' | 'error'\n const [asyncState, setAsyncState] = React.useState<AsyncState>('idle')\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isMountedRef = React.useRef(true)\n\n React.useEffect(() => () => {\n isMountedRef.current = false\n clearTimeout(timeoutRef.current)\n }, [])\n\n const handleAsyncClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClickAsync || asyncState !== 'idle') return\n setAsyncState('loading')\n onClickAsync(e)\n .then(() => { if (isMountedRef.current) setAsyncState('success') })\n .catch(() => { if (isMountedRef.current) setAsyncState('error') })\n .finally(() => {\n if (isMountedRef.current) {\n timeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) setAsyncState('idle')\n }, asyncFeedbackDuration)\n }\n })\n }\n\n const isAsync = !!onClickAsync\n const loading = isAsync ? asyncState === 'loading' : loadingProp\n const isAsyncFeedback = asyncState === 'success' || asyncState === 'error'\n\n // Processing: explicit prop takes priority, otherwise auto-processing during onClickAsync.\n // Processing is always OFF during async feedback (success/error) so the feedback colors show.\n const autoProcessing = isAsync && asyncState === 'loading' && !processingProp\n const processingSpeed: ProcessingSpeed | undefined = isAsyncFeedback ? undefined\n : processingProp === true ? 'working'\n : processingProp === false || !processingProp\n ? (autoProcessing ? 'working' : undefined)\n : processingProp\n const isProcessing = !!processingSpeed\n const resolvedProcessingColor = processingColor ?? resolvedColor ?? 'accent'\n\n if (asChild) {\n // Slot merges all props into the child element via cloneElement at runtime.\n // We cast here because SlotProps only types React.HTMLAttributes<HTMLElement>,\n // which excludes button-specific attrs like `disabled`.\n const slotProps = {\n className: cn(\n buttonVariants({ variant: resolvedVariant, color: resolvedColor, weight: resolvedWeight, size: resolvedSize }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n className,\n ),\n ref,\n disabled: resolvedDisabled || loading,\n 'aria-busy': loading || undefined,\n ...props,\n } as React.ComponentPropsWithRef<typeof Slot>\n return (\n <Slot {...slotProps}>\n <Slottable>{children}</Slottable>\n </Slot>\n )\n }\n\n const inset = iconInsetClass[resolvedSize] ?? { start: '', end: '' }\n // Dim icons on filled variants (Radix pattern — icon is decorative, text is primary)\n const dimIcon = resolvedVariant === 'solid' || resolvedVariant === 'soft' || resolvedVariant === 'outline'\n\n const renderStartSlot = () => {\n if (loading && loadingPosition === 'start') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', startIcon && inset.start)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (startIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.start, dimIcon && 'opacity-90')}>\n {normalizeIcon(startIcon)}\n </span>\n )\n }\n return null\n }\n\n const renderEndSlot = () => {\n if (loading && loadingPosition === 'end') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', endIcon && inset.end)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (endIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.end, dimIcon && 'opacity-90')}>\n {normalizeIcon(endIcon)}\n </span>\n )\n }\n return null\n }\n\n // Separate DevalokGrain elements (need to be direct button children for absolute positioning)\n // from text/other content (needs z-elevation above grain)\n const childArray = React.Children.toArray(children)\n const grainElements: React.ReactNode[] = []\n const contentElements: React.ReactNode[] = []\n childArray.forEach((child) => {\n if (React.isValidElement(child) && (child.type as { displayName?: string })?.displayName === 'DevalokGrain') {\n grainElements.push(child)\n } else {\n contentElements.push(child)\n }\n })\n\n const renderChildren = () => {\n if (loading && loadingPosition === 'center') {\n return (\n <span className=\"relative inline-flex items-center justify-center\">\n <span className=\"invisible\">{contentElements}</span>\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n </span>\n )\n }\n // Only wrap in z-elevated span when grain is present (to sit above grain layers).\n // Without grain, render children directly to preserve flex layout.\n if (grainElements.length > 0) {\n return <span>{contentElements}</span>\n }\n return <>{contentElements}</>\n }\n\n // Async feedback: override color to show green/red\n const feedbackColorClass = isAsyncFeedback\n ? asyncState === 'success'\n ? 'bg-success-9 text-success-fg border-transparent hover:bg-success-9'\n : 'bg-error-9 text-error-fg border-transparent hover:bg-error-9'\n : undefined\n\n // Async feedback icon — uses Icon's draw animation for pen-stroke effect\n const asyncFeedbackIcon = isAsyncFeedback ? (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', startIcon && inset.start)}>\n <Icon icon={asyncState === 'success' ? IconCheck : IconX} animate=\"draw\" />\n </span>\n ) : null\n\n const iconSize = BUTTON_TO_ICON_SIZE[resolvedSize] ?? 'md'\n\n const buttonEl = (\n <motion.button\n {...motionProps(props)}\n style={{ ...props.style, ...groupRadiusStyle }}\n className={cn(\n buttonVariants({\n // When processing (and not showing async feedback), force soft variant so ants pop\n variant: isProcessing && !isAsyncFeedback && resolvedVariant !== 'ghost' && resolvedVariant !== 'outline' && resolvedVariant !== 'link' ? 'soft' : resolvedVariant,\n color: resolvedColor,\n weight: resolvedWeight,\n size: resolvedSize,\n }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n // Asymmetric timing: hover-out is slow+relaxed, hover-in is fast+snappy (applied via hover: override)\n !loading && !isAsyncFeedback && 'transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit',\n !loading && !isAsyncFeedback && 'hover:duration-fast-02 hover:ease-productive-entrance',\n !loading && !isAsyncFeedback && 'active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]',\n feedbackColorClass,\n isAsyncFeedback && 'transition-colors duration-moderate-01 ease-productive-standard',\n isProcessing && processingDisabled && 'pointer-events-none cursor-default',\n className,\n )}\n ref={(el: HTMLButtonElement | null) => {\n btnRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = el\n }}\n disabled={resolvedDisabled || (loading && !isProcessing)}\n aria-busy={loading || isProcessing || undefined}\n aria-disabled={isProcessing && processingDisabled || undefined}\n onClick={isAsync ? handleAsyncClick : (isProcessing && processingDisabled ? undefined : onClick)}\n >\n {/* Grain layers render as direct children (need absolute positioning) */}\n {grainElements}\n {/* Content renders above grain via z-[2] span wrapper */}\n {isAsyncFeedback ? asyncFeedbackIcon : renderStartSlot()}\n {isAsyncFeedback ? contentElements : renderChildren()}\n {isAsyncFeedback ? null : renderEndSlot()}\n </motion.button>\n )\n\n // Always wrap in a positioned container so the overlay can render\n // as a sibling OUTSIDE the button (not affected by disabled opacity).\n // Keeping the wrapper always-on prevents React unmount/remount on\n // processing toggle, enabling smooth CSS transitions between states.\n return (\n <IconProvider size={iconSize}>\n <span\n ref={wrapperRef}\n className={cn('relative inline-flex', fullWidth && 'w-full')}\n style={{\n ...(fullWidth || groupStretch || prefersReduced ? undefined : { transition: 'width 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)' }),\n ...groupRadiusStyle,\n }}\n >\n {buttonEl}\n <ProcessingOverlay\n active={isProcessing}\n speed={processingSpeed ?? 'working'}\n color={resolvedProcessingColor}\n />\n </span>\n </IconProvider>\n )\n },\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"],"mappings":"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"}
package/dist/ui/card.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { motionProps as e, springs as t } from "./lib/motion.js";
3
- import { cva as n } from "../_chunks/vendor-utils.js";
4
- import { cn as r } from "./lib/utils.js";
5
- import * as i from "react";
6
- import { jsx as a } from "react/jsx-runtime";
7
- import { motion as o } from "framer-motion";
3
+ import { cn as n } from "./lib/utils.js";
4
+ import * as r from "react";
5
+ import { jsx as i } from "react/jsx-runtime";
6
+ import { motion as a } from "framer-motion";
7
+ import { cva as o } from "class-variance-authority";
8
8
  //#region src/ui/card.tsx
9
- var s = n("relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard", {
9
+ var s = o("relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard", {
10
10
  variants: {
11
11
  variant: {
12
12
  default: "bg-surface-raised border border-card shadow-none",
@@ -39,15 +39,15 @@ var s = n("relative flex text-surface-fg rounded-surface transition-shadow durat
39
39
  size: "md",
40
40
  orientation: "vertical"
41
41
  }
42
- }), c = i.forwardRef(({ className: n, variant: i, color: c, size: l, orientation: u, interactive: d, children: f, ...p }, m) => {
42
+ }), c = r.forwardRef(({ className: r, variant: o, color: c, size: l, orientation: u, interactive: d, children: f, ...p }, m) => {
43
43
  typeof process < "u" && process.env.NODE_ENV !== "production" && x(f);
44
- let h = r(s({
45
- variant: i,
44
+ let h = n(s({
45
+ variant: o,
46
46
  color: c,
47
47
  size: l,
48
48
  orientation: u
49
- }), d && "hover:shadow-raised-hover cursor-pointer transition-shadow duration-fast-02 ease-productive-standard", n);
50
- return d ? /* @__PURE__ */ a(o.div, {
49
+ }), d && "hover:shadow-raised-hover cursor-pointer transition-shadow duration-fast-02 ease-productive-standard", r);
50
+ return d ? /* @__PURE__ */ i(a.div, {
51
51
  ref: m,
52
52
  whileHover: { y: -3 },
53
53
  whileTap: { scale: .98 },
@@ -55,7 +55,7 @@ var s = n("relative flex text-surface-fg rounded-surface transition-shadow durat
55
55
  className: h,
56
56
  ...e(p),
57
57
  children: f
58
- }) : /* @__PURE__ */ a("div", {
58
+ }) : /* @__PURE__ */ i("div", {
59
59
  ref: m,
60
60
  className: h,
61
61
  ...p,
@@ -63,39 +63,39 @@ var s = n("relative flex text-surface-fg rounded-surface transition-shadow durat
63
63
  });
64
64
  });
65
65
  c.displayName = "Card";
66
- var l = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
67
- ref: n,
68
- className: r("flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
66
+ var l = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
67
+ ref: r,
68
+ className: n("flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
69
69
  ...t
70
70
  }));
71
71
  l.displayName = "CardHeader";
72
- var u = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
73
- ref: n,
74
- className: r("font-sans font-semibold leading-ds-none tracking-normal text-surface-fg", e),
72
+ var u = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
73
+ ref: r,
74
+ className: n("font-sans font-semibold leading-ds-none tracking-normal text-surface-fg", e),
75
75
  ...t
76
76
  }));
77
77
  u.displayName = "CardTitle";
78
- var d = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
79
- ref: n,
80
- className: r("text-body-md text-surface-fg-muted", e),
78
+ var d = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
79
+ ref: r,
80
+ className: n("text-body-md text-surface-fg-muted", e),
81
81
  ...t
82
82
  }));
83
83
  d.displayName = "CardDescription";
84
- var f = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
85
- ref: n,
86
- className: r("px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
84
+ var f = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
85
+ ref: r,
86
+ className: n("px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
87
87
  ...t
88
88
  }));
89
89
  f.displayName = "CardContent";
90
- var p = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
91
- ref: n,
92
- className: r("flex items-center gap-ds-03 px-(--card-spacing)", e),
90
+ var p = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
91
+ ref: r,
92
+ className: n("flex items-center gap-ds-03 px-(--card-spacing)", e),
93
93
  ...t
94
94
  }));
95
95
  p.displayName = "CardFooter";
96
- var m = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
97
- ref: n,
98
- className: r("flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)", e),
96
+ var m = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
97
+ ref: r,
98
+ className: n("flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)", e),
99
99
  ...t
100
100
  }));
101
101
  m.displayName = "CardSection";
@@ -105,10 +105,10 @@ var h = {
105
105
  bottom: "-mb-(--card-spacing) rounded-b-surface overflow-hidden",
106
106
  y: "-my-(--card-spacing) rounded-surface overflow-hidden",
107
107
  all: "-my-(--card-spacing) -mx-(--card-spacing) rounded-surface overflow-hidden"
108
- }, g = i.forwardRef(({ className: e, side: t = "x", ...n }, i) => /* @__PURE__ */ a("div", {
109
- ref: i,
110
- className: r(h[t], e),
111
- ...n
108
+ }, g = r.forwardRef(({ className: e, side: t = "x", ...r }, a) => /* @__PURE__ */ i("div", {
109
+ ref: a,
110
+ className: n(h[t], e),
111
+ ...r
112
112
  }));
113
113
  g.displayName = "CardBleed";
114
114
  var _ = {
@@ -116,10 +116,10 @@ var _ = {
116
116
  "top-left": "top-(--card-spacing) left-(--card-spacing)",
117
117
  "bottom-right": "bottom-(--card-spacing) right-(--card-spacing)",
118
118
  "bottom-left": "bottom-(--card-spacing) left-(--card-spacing)"
119
- }, v = i.forwardRef(({ className: e, placement: t = "top-right", tuck: n, ...i }, o) => /* @__PURE__ */ a("div", {
119
+ }, v = r.forwardRef(({ className: e, placement: t = "top-right", tuck: r, ...a }, o) => /* @__PURE__ */ i("div", {
120
120
  ref: o,
121
- className: r("absolute z-[1] flex items-center gap-ds-02", _[t], n && "-m-ds-02", e),
122
- ...i
121
+ className: n("absolute z-[1] flex items-center gap-ds-02", _[t], r && "-m-ds-02", e),
122
+ ...a
123
123
  }));
124
124
  v.displayName = "CardAction";
125
125
  var y = /* @__PURE__ */ new Set([
@@ -138,8 +138,8 @@ var y = /* @__PURE__ */ new Set([
138
138
  "em"
139
139
  ]), b = !1;
140
140
  function x(e) {
141
- b || i.Children.forEach(e, (e) => {
142
- let t = typeof e == "string" && e.trim() !== "", n = i.isValidElement(e) && typeof e.type == "string" && y.has(e.type);
141
+ b || r.Children.forEach(e, (e) => {
142
+ let t = typeof e == "string" && e.trim() !== "", n = r.isValidElement(e) && typeof e.type == "string" && y.has(e.type);
143
143
  (t || n) && (b = !0, console.warn("[shilp-sutra] <Card> received text content as a direct child. Direct children span the full card width and get no horizontal inset — wrap text in <CardContent> (or <CardHeader>/<CardFooter>). See the Card docs, \"Composition\"."));
144
144
  });
145
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../src/ui/checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAE/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AAWtE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC;IAClG,8GAA8G;IAC9G,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qFAAqF;IACrF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAcD,QAAA,MAAM,QAAQ,yFAuGZ,CAAA;AAGF,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"checkbox.d.ts","sourceRoot":"","sources":["../../src/ui/checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,iBAAiB,MAAM,4BAA4B,CAAA;AAE/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AAWtE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC;IAClG,8GAA8G;IAC9G,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qFAAqF;IACrF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAcD,QAAA,MAAM,QAAQ,yFA4GZ,CAAA;AAGF,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -34,6 +34,7 @@ var u = {
34
34
  "aria-describedby": D,
35
35
  "aria-required": O || void 0,
36
36
  ...b,
37
+ id: b.id ?? T.inputId,
37
38
  children: /* @__PURE__ */ s(c, { children: A && /* @__PURE__ */ s(a, {
38
39
  forceMount: !0,
39
40
  asChild: !0,