@cloudgrid-io/ui 0.41.0 → 0.42.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.
@@ -93,8 +93,25 @@ export const BRAND_FONT_SIZES = [
93
93
  "eyebrow",
94
94
  "stat",
95
95
  ];
96
+ /**
97
+ * Brand radius names that are not t-shirt shaped (#376).
98
+ *
99
+ * tailwind-merge's `radius` theme accepts only t-shirt names
100
+ * (`^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$`), so `2xs`, `2xl` and `3xl` merge on
101
+ * their own, and these two do not. Unregistered, `cn("rounded-xl rounded-pill")`
102
+ * keeps BOTH, and the stylesheet's order decides which corner paints: Tailwind
103
+ * emits `.rounded-lg`, `.rounded-pill`, `.rounded-xl`. While Button's corner was
104
+ * `rounded-lg` a caller's `rounded-pill` won by that accident; when #376 made the
105
+ * Style Guide button `rounded-xl`, ExpiryNotice's Keep lost its pill. Registered,
106
+ * a caller's radius wins over a component's, as every other utility does.
107
+ * `cn-radius.test.mjs` checks every `--radius-*` in theme.css by behaviour.
108
+ */
109
+ export const BRAND_RADII = ["pill", "container"];
96
110
  const twMerge = extendTailwindMerge({
97
111
  extend: {
112
+ theme: {
113
+ radius: [...BRAND_RADII],
114
+ },
98
115
  classGroups: {
99
116
  "font-size": [{ text: [...BRAND_FONT_SIZES] }],
100
117
  "font-weight": [{ font: [...BRAND_FONT_WEIGHTS] }],
@@ -1 +1 @@
1
- {"version":3,"file":"cloudgrid-cn.js","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAA;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa;IACb,aAAa;IACb,YAAY;IACZ,yEAAyE;IACzE,0EAA0E;IAC1E,4EAA4E;IAC5E,8DAA8D;IAC9D,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,MAAM;CACE,CAAA;AAEV,MAAM,OAAO,GAAG,mBAAmB,CAAC;IAClC,MAAM,EAAE;QACN,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,EAAE,CAAC;YAC9C,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAAC;SACnD;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
1
+ {"version":3,"file":"cloudgrid-cn.js","sourceRoot":"","sources":["../../src/lib/cloudgrid-cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,SAAS,CAAU,CAAA;AAE/D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa;IACb,aAAa;IACb,YAAY;IACZ,yEAAyE;IACzE,0EAA0E;IAC1E,4EAA4E;IAC5E,8DAA8D;IAC9D,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;IACP,SAAS;IACT,MAAM;CACE,CAAA;AAEV;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,WAAW,CAAU,CAAA;AAEzD,MAAM,OAAO,GAAG,mBAAmB,CAAC;IAClC,MAAM,EAAE;QACN,KAAK,EAAE;YACL,MAAM,EAAE,CAAC,GAAG,WAAW,CAAC;SACzB;QACD,WAAW,EAAE;YACX,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,EAAE,CAAC;YAC9C,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,kBAAkB,CAAC,EAAE,CAAC;SACnD;KACF;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { useRender } from "@base-ui/react/use-render";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const badgeVariants: (props?: ({
4
- variant?: "link" | "ghost" | "default" | "secondary" | "destructive" | "outline" | null | undefined;
4
+ variant?: "link" | "ghost" | "default" | "secondary" | "destructive" | "outline" | "tinted" | "outlined" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
6
  declare function Badge({ className, variant, render, ...props }: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
7
7
  export { Badge, badgeVariants };
@@ -1 +1 @@
1
- {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/ui/badge.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE,QAAA,MAAM,aAAa;;8EAqBlB,CAAA;AAED,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,OAAmB,EACnB,MAAM,EACN,GAAG,KAAK,EACT,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,8FAevE;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/ui/badge.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE,QAAA,MAAM,aAAa;;8EAyClB,CAAA;AAED,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,OAAmB,EACnB,MAAM,EACN,GAAG,KAAK,EACT,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,8FAevE;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
package/dist/ui/badge.js CHANGED
@@ -11,6 +11,25 @@ const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-cent
11
11
  outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
12
12
  ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
13
13
  link: "text-primary underline-offset-4 hover:underline",
14
+ // The two pills of the 2026 Figma list (#383; Users table, node
15
+ // 7406:5146): height 20, padding 0/8, radius 32, Regular 13 ink,
16
+ // leading none. A 32 corner on a 20px pill is a full semicircle, so
17
+ // the corner is `rounded-full`: `rounded-3xl` is not 32 in a shadcn
18
+ // app, whose theme redefines it as a multiple of --radius, and
19
+ // tailwind-merge knows `rounded-full` replaces the base's
20
+ // `rounded-4xl` (it does not know `rounded-pill` does).
21
+ //
22
+ // Written as overrides of the shared base, which tailwind-merge
23
+ // resolves, so the six variants above render byte for byte what they
24
+ // did (test/ui-badge-pills.test.mjs).
25
+ //
26
+ // `tinted` is on --cg-violet-150. The frame's fill, #E1E3FE, is bound
27
+ // to no variable; violet-150 (#E3E0FD) is within 3/255 per channel.
28
+ tinted: "rounded-full bg-brand-150 py-0 font-normal leading-none text-ink",
29
+ // `outlined` is white with the N2 hairline ("N2 New", #E6E8EA, which
30
+ // is --cg-border-hairline). Not `outline`: that one is shadcn's,
31
+ // transparent with the shadcn border and medium weight, and unchanged.
32
+ outlined: "rounded-full border-hairline bg-card py-0 font-normal leading-none text-ink",
14
33
  },
15
34
  },
16
35
  defaultVariants: {
@@ -1 +1 @@
1
- {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../src/ui/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,MAAM,aAAa,GAAG,GAAG,CACvB,8eAA8e,EAC9e;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,4DAA4D;YACrE,SAAS,EACP,kEAAkE;YACpE,WAAW,EACT,gKAAgK;YAClK,OAAO,EACL,kFAAkF;YACpF,KAAK,EACH,mEAAmE;YACrE,IAAI,EAAE,iDAAiD;SACxD;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;KACnB;CACF,CACF,CAAA;AAED,SAAS,KAAK,CAAC,EACb,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,MAAM,EACN,GAAG,KAAK,EAC8D;IACtE,OAAO,SAAS,CAAC;QACf,cAAc,EAAE,MAAM;QACtB,KAAK,EAAE,UAAU,CACf;YACE,SAAS,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC;SACrD,EACD,KAAK,CACN;QACD,MAAM;QACN,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,OAAO;SACR;KACF,CAAC,CAAA;AACJ,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../../src/ui/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,MAAM,aAAa,GAAG,GAAG,CACvB,8eAA8e,EAC9e;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,4DAA4D;YACrE,SAAS,EACP,kEAAkE;YACpE,WAAW,EACT,gKAAgK;YAClK,OAAO,EACL,kFAAkF;YACpF,KAAK,EACH,mEAAmE;YACrE,IAAI,EAAE,iDAAiD;YACvD,gEAAgE;YAChE,iEAAiE;YACjE,oEAAoE;YACpE,oEAAoE;YACpE,+DAA+D;YAC/D,0DAA0D;YAC1D,wDAAwD;YACxD,EAAE;YACF,gEAAgE;YAChE,qEAAqE;YACrE,sCAAsC;YACtC,EAAE;YACF,sEAAsE;YACtE,oEAAoE;YACpE,MAAM,EAAE,kEAAkE;YAC1E,qEAAqE;YACrE,iEAAiE;YACjE,uEAAuE;YACvE,QAAQ,EACN,6EAA6E;SAChF;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;KACnB;CACF,CACF,CAAA;AAED,SAAS,KAAK,CAAC,EACb,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,MAAM,EACN,GAAG,KAAK,EAC8D;IACtE,OAAO,SAAS,CAAC;QACf,cAAc,EAAE,MAAM;QACtB,KAAK,EAAE,UAAU,CACf;YACE,SAAS,EAAE,EAAE,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC;SACrD,EACD,KAAK,CACN;QACD,MAAM;QACN,KAAK,EAAE;YACL,IAAI,EAAE,OAAO;YACb,OAAO;SACR;KACF,CAAC,CAAA;AACJ,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
@@ -1,9 +1,11 @@
1
1
  import { Button as ButtonPrimitive } from "@base-ui/react/button";
2
2
  import { type VariantProps } from "class-variance-authority";
3
- declare const buttonVariants: (props?: ({
4
- variant?: "link" | "ghost" | "default" | "secondary" | "destructive" | "outline" | "cta" | "tertiary-soft" | null | undefined;
3
+ declare const buttonCva: (props?: ({
4
+ variant?: "link" | "ghost" | "default" | "secondary" | "destructive" | "outline" | "cta" | "tertiary-soft" | "primary" | null | undefined;
5
5
  size?: "default" | "xs" | "sm" | "lg" | "xl" | "2xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | "icon-2xl" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ type ButtonCvaProps = Parameters<typeof buttonCva>[0];
8
+ declare function buttonVariants(props?: ButtonCvaProps): string;
7
9
  declare function Button({ className, variant, size, ...props }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>): import("react").JSX.Element;
8
10
  export { Button, buttonVariants };
9
11
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE,QAAA,MAAM,cAAc;;;8EA0FnB,CAAA;AAED,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,+BAQ7D;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AA8BjE,QAAA,MAAM,SAAS;;;8EA0Fd,CAAA;AAyBD,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;AAErD,iBAAS,cAAc,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG,MAAM,CAStD;AAED,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,+BAQ7D;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
package/dist/ui/button.js CHANGED
@@ -2,60 +2,79 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Button as ButtonPrimitive } from "@base-ui/react/button";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { cn } from "../lib/cloudgrid-cn.js";
5
- const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-body-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
5
+ /**
6
+ * The Style Guide button (#376): the one button every frame in the CloudGrid
7
+ * 2026 Figma draws ("New Grid", node 7414:5979; "Create Item" and "Cancel",
8
+ * node 7537:8484). The --cg-tertiary ground, the --cg-text-on-accent ink label,
9
+ * Manrope Bold 15 at leading-none, radius 16 (--cg-radius-xl). Its sizes live in
10
+ * the compound variants below, because they are this family's and not shadcn's.
11
+ *
12
+ * It does NOT flip on the dark surfaces, and that is the design rather than an
13
+ * omission (#236). --cg-tertiary, --cg-tertiary-press and --cg-text-on-accent
14
+ * are declared at :root and redeclared on neither [data-cg-surface='panel'] nor
15
+ * [data-cg-surface='ink'], so the label pair measures 10.92:1 in all three
16
+ * scopes by construction. A filled control carries its own ground (#225). The
17
+ * teal measures 4.01:1 against the panel and 10.92:1 against ink, both better
18
+ * than the 1.46:1 it gets on the white the frames draw it on.
19
+ *
20
+ * Hover is the opaque press token, not an alpha wash: a wash composites lighter
21
+ * on white and darker on ink, so the same class would mean two opposite things;
22
+ * --cg-tertiary-press is one value everywhere. Its pair is 9.25:1. Both numbers
23
+ * are pinned in contrast-guardrail.test.mjs.
24
+ */
25
+ const STYLE_GUIDE = "rounded-xl bg-cyan font-ui font-bold leading-none text-on-accent hover:bg-cyan-press aria-expanded:bg-cyan-press";
26
+ /** The variants that wear the Style Guide metrics (sizes below). */
27
+ const STYLE_GUIDE_FAMILY = ["default", "cta", "tertiary-soft"];
28
+ const buttonCva = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-body-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
6
29
  variants: {
7
30
  variant: {
8
- default: "bg-primary text-primary-foreground hover:bg-primary/80",
9
- /* The frames' primary call to action (#236): the brand teal with the ink
10
- on top. Open app, Save, Share, Add secret, Copy command, Verify domain.
11
- `default` stays the brand purple; this is the one the app page reaches
12
- for, and it is the reason the Console no longer paints its own black.
31
+ /* The Style Guide button (#376), what `<Button>` renders. Save, Create,
32
+ Open app, Continue: the frames' primary action, everywhere. */
33
+ default: STYLE_GUIDE,
34
+ /* An alias of `default`, kept so `variant="cta"` (#236: the Console's
35
+ primary action, EmptyCreations' Add, InvitePopup's Copy, the Plugged
36
+ popup's Share) keeps compiling and rendering. Same string, same
37
+ compound sizes: the two cannot drift, and button-styleguide.test.mjs
38
+ compares their rendered classes size by size. New code writes
39
+ nothing (the default) rather than `cta`.
13
40
 
14
41
  Named `cta` and not `accent` because "accent" is already spent twice
15
- here on two different colours: --cg-accent is the brand BLUE (#197,
16
- utility `azure`), and --cg-text-on-accent is the ink this very button
17
- puts on the teal. A third meaning would make the call site unreadable.
18
- The other variants are roles too, not colours.
42
+ here: --cg-accent is the brand BLUE (#197, utility `azure`), and
43
+ --cg-text-on-accent is the ink this button puts on the teal. */
44
+ cta: STYLE_GUIDE,
45
+ /* The Style Guide's secondary (#370, #376): the --cg-cyan-200 ground
46
+ ("Teriary 20" in Figma) inside a drawn --cg-tertiary hairline, ink
47
+ label, the default's type and sizes. "Cancel" beside "Create Item",
48
+ the Plugged popup's Close, the pricing and thegrid footers'
49
+ secondary buttons.
19
50
 
20
- It does NOT flip on the dark surfaces, and that is the whole design
21
- rather than an omission. --cg-tertiary, --cg-tertiary-press and
22
- --cg-text-on-accent are declared at :root and redeclared on neither
23
- [data-cg-surface='panel'] nor [data-cg-surface='ink'], so the label
24
- pair measures 10.92:1 in all three scopes by construction. A filled
25
- control carries its own ground (#225). Compare `default`, which needed
26
- a per-scope --primary in shadcn.css only because --cg-primary IS the
27
- panel surface (#41); the teal has no such collision, and measures
28
- 4.01:1 against the panel and 10.92:1 against ink, both better than the
29
- 1.46:1 it gets on the white the frames draw.
30
-
31
- Hover is the opaque press token, not `/80` the way `default` washes.
32
- An alpha wash composites lighter on white and darker on ink, so the
33
- same class would mean two opposite things; --cg-tertiary-press is one
34
- value everywhere and moves with the hue on a retune. Its pair is
35
- 9.25:1. Both numbers are pinned in contrast-guardrail.test.mjs. */
36
- cta: "bg-cyan text-on-accent hover:bg-cyan-press aria-expanded:bg-cyan-press",
37
- /* The soft tertiary (#370): the --cg-cyan-200 ground ("Teriary 20" in
38
- Figma) inside a drawn --cg-tertiary hairline, ink label. The Plugged
39
- popup's Close, and the pricing and thegrid footers' secondary buttons.
40
-
41
- The FILLED tertiary is `cta` above, already: same ground, same press
42
- token, same ink. A second name for it would be two variants that must
43
- never drift apart, so there is none; a caller that wants the hairline
44
- drawn on the filled one adds `border-cyan`.
45
-
46
- Like `cta`, it does not flip per surface: the tint, the tertiary and
47
- the ink are declared at :root only, so the pair is the same in all
48
- three scopes. Hover deepens to the full tertiary ground with the press
49
- token on the hairline, both opaque, for the reason `cta` gives. Focus
50
- keeps the base's ring; the base's `focus-visible:border-ring` repaints
51
- the hairline while focused. */
52
- "tertiary-soft": "border-cyan bg-cyan-tint text-on-accent hover:border-cyan-press hover:bg-cyan aria-expanded:bg-cyan",
51
+ Like the default, it does not flip per surface: the tint, the
52
+ tertiary and the ink are declared at :root only, so the pair is the
53
+ same in all three scopes. Hover deepens to the full tertiary ground
54
+ with the press token on the hairline, both opaque. Focus keeps the
55
+ base's ring; the base's `focus-visible:border-ring` repaints the
56
+ hairline while focused. */
57
+ "tertiary-soft": "rounded-xl border-cyan bg-cyan-tint font-ui font-bold leading-none text-on-accent hover:border-cyan-press hover:bg-cyan aria-expanded:bg-cyan",
58
+ /* The brand purple filled button: until #376 this was `default`, and it
59
+ renders byte for byte what `default` rendered then, at every size
60
+ (shadcn metrics, Space Grotesk medium, 14px corners). Kept for a
61
+ caller that wants the purple on purpose, and as the one-word
62
+ migration for a consumer who relied on the old default
63
+ (`variant="primary"`). ConfirmDeleteDialog's submit uses it for its
64
+ metrics only; its colours are its own. --primary flips per surface in
65
+ shadcn.css (#41), because --cg-primary IS the panel ground. */
66
+ primary: "bg-primary text-primary-foreground hover:bg-primary/80",
53
67
  outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
54
68
  secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
55
69
  ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
56
70
  destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
57
71
  link: "text-primary underline-offset-4 hover:underline",
58
72
  },
73
+ /* The shadcn sizes, which every variant outside the Style Guide family
74
+ still renders unchanged. For the family, `default`, `lg` and `icon-lg`
75
+ resolve to #389's `xl`, `2xl` and `icon-2xl` (see `buttonVariants`
76
+ below), and `icon` is 40 square; `sm`, `xs`, `icon-sm` and `icon-xs`
77
+ keep these compact metrics (and their own corners) in every variant. */
59
78
  size: {
60
79
  default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
61
80
  xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-caption in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
@@ -77,11 +96,46 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
77
96
  "icon-2xl": "size-12 rounded-xl [&_svg:not([class*='size-'])]:size-5",
78
97
  },
79
98
  },
99
+ /* The family's `icon` is 40 square, the height of the row it sits in
100
+ (`default`, which resolves to `xl`). #389 has no 40 icon rung; its
101
+ `icon-2xl` (48) is what the family's `icon-lg` resolves to. */
102
+ compoundVariants: [{ variant: [...STYLE_GUIDE_FAMILY], size: "icon", class: "size-10" }],
80
103
  defaultVariants: {
81
104
  variant: "default",
82
105
  size: "default",
83
106
  },
84
107
  });
108
+ /**
109
+ * The Style Guide sizes (#376) ARE #389's 2026 sizes, by alias, not by copy.
110
+ *
111
+ * Figma's Button component (4919:688) has S and M, which #389 shipped as `xl`
112
+ * (40 tall, 20 aside, radius 16, gap 12, Bold 15, a 20px glyph) and `2xl` (48,
113
+ * 32 aside), plus the 48 square `icon-2xl`. The Style Guide button's two sizes
114
+ * are those two. So for the family (`default`, `cta`, `tertiary-soft`) the
115
+ * size `default` resolves to `xl`, `lg` to `2xl` and `icon-lg` to `icon-2xl`:
116
+ * `<Button>` and `<Button size="xl">` render the same string, and there is one
117
+ * definition of each size to retune. Every other variant keeps the shadcn
118
+ * `default` and `lg` it has always had.
119
+ *
120
+ * The issue's "min-height 40, padding 10/20" is `xl`'s fixed `h-10` with 20
121
+ * aside: the base sets `whitespace-nowrap`, so a label never wraps and a
122
+ * minimum height would compute the same box; the frame's 10 (14) vertical
123
+ * padding is the centring inside that height (#389's note).
124
+ *
125
+ * Resolved here and not only in `Button`, so a consumer calling
126
+ * `buttonVariants()` on an anchor (PricingTierCards, the Console's
127
+ * PrimaryAction) gets the same classes as the component.
128
+ */
129
+ const STYLE_GUIDE_SIZE = { default: "xl", lg: "2xl", "icon-lg": "icon-2xl" };
130
+ function buttonVariants(props) {
131
+ const variant = props?.variant === undefined ? "default" : props.variant;
132
+ const size = props?.size === undefined ? "default" : props.size;
133
+ const family = STYLE_GUIDE_FAMILY.includes(variant);
134
+ const resolved = family && size !== null && size in STYLE_GUIDE_SIZE
135
+ ? STYLE_GUIDE_SIZE[size]
136
+ : size;
137
+ return buttonCva({ ...props, size: resolved });
138
+ }
85
139
  function Button({ className, variant = "default", size = "default", ...props }) {
86
140
  return (_jsx(ButtonPrimitive, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props }));
87
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAA;AAEjE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,MAAM,cAAc,GAAG,GAAG,CACxB,8lBAA8lB,EAC9lB;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,wDAAwD;YACjE;;;;;;;;;;;;;;;;;;;;;;;;;;iFA0BqE;YACrE,GAAG,EAAE,wEAAwE;YAC7E;;;;;;;;;;;;;;6CAciC;YACjC,eAAe,EACb,qGAAqG;YACvG,OAAO,EACL,iLAAiL;YACnL,SAAS,EACP,gLAAgL;YAClL,KAAK,EACH,kHAAkH;YACpH,WAAW,EACT,6NAA6N;YAC/N,IAAI,EAAE,iDAAiD;SACxD;QACD,IAAI,EAAE;YACJ,OAAO,EACL,sFAAsF;YACxF,EAAE,EAAE,oNAAoN;YACxN,EAAE,EAAE,wNAAwN;YAC5N,EAAE,EAAE,sFAAsF;YAC1F;;;;;kFAKsE;YACtE,EAAE,EAAE,gGAAgG;YACpG,KAAK,EAAE,gGAAgG;YACvG,IAAI,EAAE,QAAQ;YACd,SAAS,EACP,yHAAyH;YAC3H,SAAS,EACP,oFAAoF;YACtF,SAAS,EAAE,QAAQ;YACnB,8EAA8E;YAC9E,UAAU,EAAE,yDAAyD;SACtE;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;KAChB;CACF,CACF,CAAA;AAED,SAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,SAAS,EAChB,GAAG,KAAK,EACoD;IAC5D,OAAO,CACL,KAAC,eAAe,iBACJ,QAAQ,EAClB,SAAS,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,KACvD,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA"}
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"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"}
@@ -27,13 +27,65 @@ declare function DialogClose({ ...props }: DialogPrimitive.Close.Props): React.J
27
27
  * the confirm's backdrop rather than merely beside it.
28
28
  */
29
29
  declare function DialogOverlay({ className, forceRender, ...props }: DialogPrimitive.Backdrop.Props): React.JSX.Element;
30
+ /**
31
+ * The card: the CloudGrid 2026 Figma popup "New Vault Item" (ui#372, node
32
+ * 7537:8484, file 5ouhISIL0mwYGHurvCGoEO).
33
+ *
34
+ * ```
35
+ * .--------------------------------------------- 525 ---.
36
+ * | New Vault Item [x] | 24 top
37
+ * | | 24 gap
38
+ * | (the caller's content: a form, a line, a tile) |
39
+ * | |
40
+ * | [ Cancel ] [ Create Item ] | 24 bottom
41
+ * '------------------------------------------------------'
42
+ * 32 each side
43
+ * ```
44
+ *
45
+ * White in a 1px `--cg-border-hairline`, radius 12 (`--cg-radius-md`), padding
46
+ * 24 top and bottom and 32 left and right, its rows 24 apart. 525 wide from `sm`
47
+ * up; on a phone it fills the width less a 16px gutter each side.
48
+ *
49
+ * The ground is `bg-popover`, the overlay ground (#230), not `bg-card`. The card
50
+ * portals to the document root, where both are white, but `--cg-surface-card` is
51
+ * transparent on the panel and a 4% wash on ink; `--popover` stays opaque in
52
+ * every scope, so the card cannot turn see-through if a page ever puts a dark
53
+ * scope on the root.
54
+ *
55
+ * It is capped at the window's height less 2rem and scrolls inside, because a
56
+ * centred fixed card with no cap pushes its top above the window on a short
57
+ * screen (a phone on its side, 812x375), where no scroll reaches it (#375).
58
+ *
59
+ * The close X is a 20px Phosphor X at the top right, its glyph level with the
60
+ * title and its right edge on the 32px content edge, level with the footer
61
+ * (Figma 7537:8601): `right-6.5` is 26px, and the 32px target centres the glyph
62
+ * 6px in, so 26 + 6 = 32. Named "Close", reachable by Tab, and a real
63
+ * `DialogPrimitive.Close`, so it closes exactly as Escape and the scrim do.
64
+ * `showCloseButton={false}` drops it, as before.
65
+ *
66
+ * Blocks override the card through `className` (tailwind-merge resolves the
67
+ * conflict): `ConfirmDeleteDialog` keeps its 24 padding and 448 width,
68
+ * `PluggedDialog` its own radius and 632 width.
69
+ */
30
70
  declare function DialogContent({ className, children, showCloseButton, ...props }: DialogPrimitive.Popup.Props & {
31
71
  showCloseButton?: boolean;
32
72
  }): React.JSX.Element;
73
+ /** The title and its line. `pr-8` keeps a long title clear of the close X. */
33
74
  declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
75
+ /**
76
+ * The actions row: right-aligned at every width, 8px apart, on the card itself.
77
+ * No grey band and no top rule (the shadcn footer had both; the Figma popup has
78
+ * neither).
79
+ *
80
+ * Documented use, from the Figma popup: Cancel is `variant="tertiary-soft"`, the
81
+ * main action is `variant="cta"` (the filled tertiary), both `size="xl"`: 40
82
+ * tall, radius 16, 20 each side, Manrope Bold 15 on a 15px line (the 2026 Button
83
+ * S, #382). `showCloseButton` adds a Close in the soft tertiary at that size.
84
+ */
34
85
  declare function DialogFooter({ className, showCloseButton, children, ...props }: React.ComponentProps<"div"> & {
35
86
  showCloseButton?: boolean;
36
87
  }): React.JSX.Element;
88
+ /** The Figma popup's H4: Manrope Medium 22/1.2, ink. */
37
89
  declare function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props): React.JSX.Element;
38
90
  declare function DialogDescription({ className, ...props }: DialogPrimitive.Description.Props): React.JSX.Element;
39
91
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAiBjE,iBAAS,MAAM,CAAC,EAAE,KAAY,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAMrE;AAED,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,qBAEjE;AAED,iBAAS,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,qBAE/D;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAE7D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,qBAYhC;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAiCA;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,eAAuB,EACvB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAkBA;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAWxE;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,qBAWnC;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAA"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAiBjE,iBAAS,MAAM,CAAC,EAAE,KAAY,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,qBAMrE;AAED,iBAAS,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,qBAEjE;AAED,iBAAS,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,qBAE/D;AAED,iBAAS,WAAW,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAE7D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,qBAYhC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,eAAsB,EACtB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAiCA;AAED,8EAA8E;AAC9E,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQzE;AAED;;;;;;;;;GASG;AACH,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,eAAuB,EACvB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAC/B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,qBAkBA;AAED,wDAAwD;AACxD,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,qBAWxE;AAED,iBAAS,iBAAiB,CAAC,EACzB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,WAAW,CAAC,KAAK,qBAWnC;AAED,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAA"}
package/dist/ui/dialog.js CHANGED
@@ -52,21 +52,73 @@ function DialogClose({ ...props }) {
52
52
  function DialogOverlay({ className, forceRender = true, ...props }) {
53
53
  return (_jsx(DialogPrimitive.Backdrop, { "data-slot": "dialog-overlay", forceRender: forceRender, className: cn("fixed inset-0 isolate z-50 scrim-overlay duration-100 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0", className), ...props }));
54
54
  }
55
+ /**
56
+ * The card: the CloudGrid 2026 Figma popup "New Vault Item" (ui#372, node
57
+ * 7537:8484, file 5ouhISIL0mwYGHurvCGoEO).
58
+ *
59
+ * ```
60
+ * .--------------------------------------------- 525 ---.
61
+ * | New Vault Item [x] | 24 top
62
+ * | | 24 gap
63
+ * | (the caller's content: a form, a line, a tile) |
64
+ * | |
65
+ * | [ Cancel ] [ Create Item ] | 24 bottom
66
+ * '------------------------------------------------------'
67
+ * 32 each side
68
+ * ```
69
+ *
70
+ * White in a 1px `--cg-border-hairline`, radius 12 (`--cg-radius-md`), padding
71
+ * 24 top and bottom and 32 left and right, its rows 24 apart. 525 wide from `sm`
72
+ * up; on a phone it fills the width less a 16px gutter each side.
73
+ *
74
+ * The ground is `bg-popover`, the overlay ground (#230), not `bg-card`. The card
75
+ * portals to the document root, where both are white, but `--cg-surface-card` is
76
+ * transparent on the panel and a 4% wash on ink; `--popover` stays opaque in
77
+ * every scope, so the card cannot turn see-through if a page ever puts a dark
78
+ * scope on the root.
79
+ *
80
+ * It is capped at the window's height less 2rem and scrolls inside, because a
81
+ * centred fixed card with no cap pushes its top above the window on a short
82
+ * screen (a phone on its side, 812x375), where no scroll reaches it (#375).
83
+ *
84
+ * The close X is a 20px Phosphor X at the top right, its glyph level with the
85
+ * title and its right edge on the 32px content edge, level with the footer
86
+ * (Figma 7537:8601): `right-6.5` is 26px, and the 32px target centres the glyph
87
+ * 6px in, so 26 + 6 = 32. Named "Close", reachable by Tab, and a real
88
+ * `DialogPrimitive.Close`, so it closes exactly as Escape and the scrim do.
89
+ * `showCloseButton={false}` drops it, as before.
90
+ *
91
+ * Blocks override the card through `className` (tailwind-merge resolves the
92
+ * conflict): `ConfirmDeleteDialog` keeps its 24 padding and 448 width,
93
+ * `PluggedDialog` its own radius and 632 width.
94
+ */
55
95
  function DialogContent({ className, children, showCloseButton = true, ...props }) {
56
96
  const modal = React.useContext(DialogModalContext);
57
- return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", "aria-modal": modal !== false ? true : undefined, className: cn("fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-body-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-2 right-2", size: "icon-sm" }), children: [_jsx(CloseIcon, {}), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
97
+ return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", "aria-modal": modal !== false ? true : undefined, className: cn("fixed top-1/2 left-1/2 z-50 grid max-h-[calc(100svh-2rem)] w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-6 overflow-y-auto rounded-md border border-hairline bg-popover px-8 py-6 text-body-sm text-ink duration-100 outline-none sm:max-w-131.25 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-5 right-6.5 text-ink", size: "icon" }), children: [_jsx(CloseIcon, { className: "size-5" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
58
98
  }
99
+ /** The title and its line. `pr-8` keeps a long title clear of the close X. */
59
100
  function DialogHeader({ className, ...props }) {
60
- return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2", className), ...props }));
101
+ return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2 pr-8", className), ...props }));
61
102
  }
103
+ /**
104
+ * The actions row: right-aligned at every width, 8px apart, on the card itself.
105
+ * No grey band and no top rule (the shadcn footer had both; the Figma popup has
106
+ * neither).
107
+ *
108
+ * Documented use, from the Figma popup: Cancel is `variant="tertiary-soft"`, the
109
+ * main action is `variant="cta"` (the filled tertiary), both `size="xl"`: 40
110
+ * tall, radius 16, 20 each side, Manrope Bold 15 on a 15px line (the 2026 Button
111
+ * S, #382). `showCloseButton` adds a Close in the soft tertiary at that size.
112
+ */
62
113
  function DialogFooter({ className, showCloseButton = false, children, ...props }) {
63
- return (_jsxs("div", { "data-slot": "dialog-footer", className: cn("-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end", className), ...props, children: [children, showCloseButton && (_jsx(DialogPrimitive.Close, { render: _jsx(Button, { variant: "outline" }), children: "Close" }))] }));
114
+ return (_jsxs("div", { "data-slot": "dialog-footer", className: cn("flex flex-wrap items-center justify-end gap-2", className), ...props, children: [children, showCloseButton && (_jsx(DialogPrimitive.Close, { render: _jsx(Button, { variant: "tertiary-soft", size: "xl" }), children: "Close" }))] }));
64
115
  }
116
+ /** The Figma popup's H4: Manrope Medium 22/1.2, ink. */
65
117
  function DialogTitle({ className, ...props }) {
66
- return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("font-heading text-body-md leading-none font-medium", className), ...props }));
118
+ return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("m-0 font-ui text-heading-lg font-medium text-ink", className), ...props }));
67
119
  }
68
120
  function DialogDescription({ className, ...props }) {
69
- return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("text-body-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className), ...props }));
121
+ return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("m-0 text-body-sm text-body *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-ink", className), ...props }));
70
122
  }
71
123
  export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
72
124
  //# sourceMappingURL=dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,31 @@
1
1
  import * as React from "react";
2
+ /**
3
+ * The 2026 Figma list (#383): the Users table in the Admin frame, node
4
+ * 7406:5146. An N3 13px header with no rule under it, then rounded rows 2px
5
+ * apart, every other one on N1 at half strength, starting with the first.
6
+ *
7
+ * ## Rounded zebra rows on a real <table>
8
+ *
9
+ * This stays a `<table>`, so a screen reader keeps announcing rows and columns.
10
+ * Two things a table does not do on its own are done like this:
11
+ *
12
+ * - **The 2px between rows** is `border-separate` with `border-spacing: 0 2px`.
13
+ * Spacing is the only gap a table can put between rows. It also adds 2px
14
+ * above the header and below the last row, at the table's outer edges.
15
+ * - **The 12px corner** is on the CELLS, not the row: the first cell rounds
16
+ * its left corners and the last its right. A `<tr>` cannot clip its own
17
+ * background to its cells' corners, so the row paints nothing. Every ground
18
+ * (zebra, hover, selected) is painted by the cells, keyed off the row through
19
+ * `group/row`, so the corners clip it.
20
+ *
21
+ * Horizontal rhythm: the frame's rows are auto-layout with padding 12 and a
22
+ * 16px gap. Cells get 8px each side (8 + 8 = 16 between neighbours), and the
23
+ * first and last cell take 12 at the row's two ends.
24
+ *
25
+ * Row states, cell grounds over the zebra: hover (and a row whose menu is
26
+ * open) takes N1 at full strength, `bg-page`; `data-state="selected"` takes
27
+ * the primary tint, `bg-brand-tint`.
28
+ */
2
29
  declare function Table({ className, ...props }: React.ComponentProps<"table">): React.JSX.Element;
3
30
  declare function TableHeader({ className, ...props }: React.ComponentProps<"thead">): React.JSX.Element;
4
31
  declare function TableBody({ className, ...props }: React.ComponentProps<"tbody">): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAapE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQ1E;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAW1E;AAED,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWpE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWrE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWrE;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,qBAQjC;AAED,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,GACb,CAAA"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAgBpE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQ1E;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAQxE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,qBAW1E;AAED,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAapE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAWrE;AAED,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,qBAcrE;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,qBAQjC;AAED,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,GACb,CAAA"}
package/dist/ui/table.js CHANGED
@@ -2,26 +2,59 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "../lib/cloudgrid-cn.js";
5
+ /**
6
+ * The 2026 Figma list (#383): the Users table in the Admin frame, node
7
+ * 7406:5146. An N3 13px header with no rule under it, then rounded rows 2px
8
+ * apart, every other one on N1 at half strength, starting with the first.
9
+ *
10
+ * ## Rounded zebra rows on a real <table>
11
+ *
12
+ * This stays a `<table>`, so a screen reader keeps announcing rows and columns.
13
+ * Two things a table does not do on its own are done like this:
14
+ *
15
+ * - **The 2px between rows** is `border-separate` with `border-spacing: 0 2px`.
16
+ * Spacing is the only gap a table can put between rows. It also adds 2px
17
+ * above the header and below the last row, at the table's outer edges.
18
+ * - **The 12px corner** is on the CELLS, not the row: the first cell rounds
19
+ * its left corners and the last its right. A `<tr>` cannot clip its own
20
+ * background to its cells' corners, so the row paints nothing. Every ground
21
+ * (zebra, hover, selected) is painted by the cells, keyed off the row through
22
+ * `group/row`, so the corners clip it.
23
+ *
24
+ * Horizontal rhythm: the frame's rows are auto-layout with padding 12 and a
25
+ * 16px gap. Cells get 8px each side (8 + 8 = 16 between neighbours), and the
26
+ * first and last cell take 12 at the row's two ends.
27
+ *
28
+ * Row states, cell grounds over the zebra: hover (and a row whose menu is
29
+ * open) takes N1 at full strength, `bg-page`; `data-state="selected"` takes
30
+ * the primary tint, `bg-brand-tint`.
31
+ */
5
32
  function Table({ className, ...props }) {
6
- return (_jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: _jsx("table", { "data-slot": "table", className: cn("w-full caption-bottom text-body-sm", className), ...props }) }));
33
+ return (_jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: _jsx("table", { "data-slot": "table", className: cn("w-full caption-bottom border-separate border-spacing-x-0 border-spacing-y-0.5 text-body-sm text-ink", className), ...props }) }));
7
34
  }
8
35
  function TableHeader({ className, ...props }) {
9
- return (_jsx("thead", { "data-slot": "table-header", className: cn("[&_tr]:border-b", className), ...props }));
36
+ return (_jsx("thead", { "data-slot": "table-header", className: className, ...props }));
10
37
  }
11
38
  function TableBody({ className, ...props }) {
12
- return (_jsx("tbody", { "data-slot": "table-body", className: cn("[&_tr:last-child]:border-0", className), ...props }));
39
+ return (_jsx("tbody", { "data-slot": "table-body", className: className, ...props }));
13
40
  }
14
41
  function TableFooter({ className, ...props }) {
15
42
  return (_jsx("tfoot", { "data-slot": "table-footer", className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props }));
16
43
  }
17
44
  function TableRow({ className, ...props }) {
18
- return (_jsx("tr", { "data-slot": "table-row", className: cn("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted", className), ...props }));
45
+ return (_jsx("tr", { "data-slot": "table-row", className: cn(
46
+ // No ground of its own: see the docblock on Table. The cells read
47
+ // the row's parity, hover and selection through this group.
48
+ "group/row", className), ...props }));
19
49
  }
20
50
  function TableHead({ className, ...props }) {
21
- return (_jsx("th", { "data-slot": "table-head", className: cn("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0", className), ...props }));
51
+ return (_jsx("th", { "data-slot": "table-head", className: cn("px-2 py-2 text-left align-middle text-caption font-normal whitespace-nowrap text-steel first:pl-3 last:pr-3 [&:has([role=checkbox])]:pr-0", className), ...props }));
22
52
  }
23
53
  function TableCell({ className, ...props }) {
24
- return (_jsx("td", { "data-slot": "table-cell", className: cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className), ...props }));
54
+ return (_jsx("td", { "data-slot": "table-cell", className: cn("px-2 py-2 align-middle whitespace-nowrap transition-colors first:rounded-l-md first:pl-3 last:rounded-r-md last:pr-3 [&:has([role=checkbox])]:pr-0",
55
+ // The zebra, then the states over it. Odd first: the first body row
56
+ // is tinted.
57
+ "group-odd/row:bg-page/50 group-hover/row:bg-page group-has-aria-expanded/row:bg-page group-data-[state=selected]/row:bg-brand-tint", className), ...props }));
25
58
  }
26
59
  function TableCaption({ className, ...props }) {
27
60
  return (_jsx("caption", { "data-slot": "table-caption", className: cn("mt-4 text-body-sm text-muted-foreground", className), ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC,SAAS,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACnE,OAAO,CACL,2BACY,iBAAiB,EAC3B,SAAS,EAAC,iCAAiC,YAE3C,6BACY,OAAO,EACjB,SAAS,EAAE,EAAE,CAAC,oCAAoC,EAAE,SAAS,CAAC,KAC1D,KAAK,GACT,GACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACzE,OAAO,CACL,6BACY,cAAc,EACxB,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,SAAS,CAAC,KACvC,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACvE,OAAO,CACL,6BACY,YAAY,EACtB,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,KAClD,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACzE,OAAO,CACL,6BACY,cAAc,EACxB,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACnE,OAAO,CACL,0BACY,WAAW,EACrB,SAAS,EAAE,EAAE,CACX,2GAA2G,EAC3G,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACpE,OAAO,CACL,0BACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,8GAA8G,EAC9G,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACpE,OAAO,CACL,0BACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,kEAAkE,EAClE,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACwB;IAChC,OAAO,CACL,+BACY,eAAe,EACzB,SAAS,EAAE,EAAE,CAAC,yCAAyC,EAAE,SAAS,CAAC,KAC/D,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,GACb,CAAA"}
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAS,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACnE,OAAO,CACL,2BACY,iBAAiB,EAC3B,SAAS,EAAC,iCAAiC,YAE3C,6BACY,OAAO,EACjB,SAAS,EAAE,EAAE,CACX,qGAAqG,EACrG,SAAS,CACV,KACG,KAAK,GACT,GACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACzE,OAAO,CACL,6BACY,cAAc,EACxB,SAAS,EAAE,SAAS,KAChB,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACvE,OAAO,CACL,6BACY,YAAY,EACtB,SAAS,EAAE,SAAS,KAChB,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiC;IACzE,OAAO,CACL,6BACY,cAAc,EACxB,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACnE,OAAO,CACL,0BACY,WAAW,EACrB,SAAS,EAAE,EAAE;QACX,kEAAkE;QAClE,4DAA4D;QAC5D,WAAW,EACX,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACpE,OAAO,CACL,0BACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,2IAA2I,EAC3I,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA8B;IACpE,OAAO,CACL,0BACY,YAAY,EACtB,SAAS,EAAE,EAAE,CACX,oJAAoJ;QACpJ,oEAAoE;QACpE,aAAa;QACb,oIAAoI,EACpI,SAAS,CACV,KACG,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,SAAS,YAAY,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACwB;IAChC,OAAO,CACL,+BACY,eAAe,EACzB,SAAS,EAAE,EAAE,CAAC,yCAAyC,EAAE,SAAS,CAAC,KAC/D,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,SAAS,EACT,YAAY,GACb,CAAA"}
package/dist/ui/tabs.d.ts CHANGED
@@ -49,7 +49,7 @@ import { type VariantProps } from "class-variance-authority";
49
49
  declare function scrollActiveTabIntoView(list: HTMLElement | null | undefined): void;
50
50
  declare function Tabs({ className, orientation, ...props }: TabsPrimitive.Root.Props): React.JSX.Element;
51
51
  declare const tabsListVariants: (props?: ({
52
- variant?: "line" | "default" | "pill" | null | undefined;
52
+ variant?: "pill" | "line" | "default" | null | undefined;
53
53
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
54
54
  declare function TabsList({ className, variant, ref, ...props }: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>): React.JSX.Element;
55
55
  declare function TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props): React.JSX.Element;