@nucleux/button 0.5.0 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -31,34 +31,46 @@ var buttonVariants = {
31
31
  cta: "border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90",
32
32
  secondary: "border border-border bg-background text-foreground shadow-sm hover:bg-accent",
33
33
  ghost: "text-foreground hover:bg-accent",
34
- destructive: "border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
34
+ destructive: "border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
35
+ link: "text-foreground underline decoration-from-font underline-offset-2 hover:opacity-70"
35
36
  };
36
37
  var buttonSizes = {
37
38
  sm: "h-8 rounded-lg px-3 text-sm",
38
39
  md: "h-9 rounded-lg px-4 text-sm",
39
40
  lg: "h-10 rounded-lg px-5 text-sm",
40
- icon: "size-9 rounded-lg"
41
+ icon: "size-9 rounded-lg",
42
+ "icon-sm": "size-8 rounded-lg",
43
+ "icon-lg": "size-10 rounded-lg"
41
44
  };
42
45
  var Button = React__namespace.forwardRef(
43
- ({ color, variant = color ?? "primary", size = "md", leftIcon, rightIcon, type = "button", className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
44
- "button",
45
- {
46
- ref,
47
- type,
48
- className: utils.cn(
49
- "inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
50
- buttonVariants[variant],
51
- buttonSizes[size],
52
- className
53
- ),
54
- ...props,
55
- children: [
56
- leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", children: leftIcon }),
57
- children,
58
- rightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", children: rightIcon })
59
- ]
46
+ ({
47
+ color,
48
+ variant = color ?? "primary",
49
+ size = "md",
50
+ asChild = false,
51
+ leftIcon,
52
+ rightIcon,
53
+ type = "button",
54
+ className,
55
+ children,
56
+ ...props
57
+ }, ref) => {
58
+ const classes = utils.cn(
59
+ "inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0",
60
+ buttonVariants[variant],
61
+ buttonSizes[size],
62
+ variant === "link" && "h-auto px-0",
63
+ className
64
+ );
65
+ if (asChild) {
66
+ return /* @__PURE__ */ jsxRuntime.jsx(utils.Slot, { ref, className: classes, ...props, children });
60
67
  }
61
- )
68
+ return /* @__PURE__ */ jsxRuntime.jsxs("button", { ref, type, className: classes, ...props, children: [
69
+ leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", children: leftIcon }),
70
+ children,
71
+ rightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center", children: rightIcon })
72
+ ] });
73
+ }
62
74
  );
63
75
  Button.displayName = "Button";
64
76
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,IAAM,cAAA,GAAgD;AAAA,EACpD,OAAA,EAAS,uFAAA;AAAA,EACT,GAAA,EAAK,8EAAA;AAAA,EACL,SAAA,EAAW,8EAAA;AAAA,EACX,KAAA,EAAO,iCAAA;AAAA,EACP,WAAA,EACE;AACJ,CAAA;AAEA,IAAM,WAAA,GAA0C;AAAA,EAC9C,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,8BAAA;AAAA,EACJ,IAAA,EAAM;AACR,CAAA;AAmBO,IAAM,MAAA,GAAeA,gBAAA,CAAA,UAAA;AAAA,EAC1B,CACE,EAAE,KAAA,EAAO,OAAA,GAAU,KAAA,IAAS,WAAW,IAAA,GAAO,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,OAAO,QAAA,EAAU,SAAA,EAAW,UAAU,GAAG,KAAA,IAClH,GAAA,qBAEAC,eAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAWC,QAAA;AAAA,QACT,4TAAA;AAAA,QACA,eAAe,OAAO,CAAA;AAAA,QACtB,YAAY,IAAI,CAAA;AAAA,QAChB;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA,oBAAYC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,QAC1E,QAAA;AAAA,QACA,SAAA,oBAAaA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAqC,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA;AAGnF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"cta\"\n | \"secondary\"\n | \"ghost\"\n | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\n\n// Canonical spec (Figma \"Button\"): rounded-lg, semibold 14px, subtle border +\n// shadow-sm on filled/outline variants; ghost is chromeless.\nconst buttonVariants: Record<ButtonVariant, string> = {\n primary: \"border border-border bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n cta: \"border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90\",\n secondary: \"border border-border bg-background text-foreground shadow-sm hover:bg-accent\",\n ghost: \"text-foreground hover:bg-accent\",\n destructive:\n \"border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n};\n\nconst buttonSizes: Record<ButtonSize, string> = {\n sm: \"h-8 rounded-lg px-3 text-sm\",\n md: \"h-9 rounded-lg px-4 text-sm\",\n lg: \"h-10 rounded-lg px-5 text-sm\",\n icon: \"size-9 rounded-lg\",\n};\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style: \"primary\" (default), \"cta\", \"secondary\", \"ghost\", or \"destructive\". */\n variant?: ButtonVariant;\n /**\n * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.\n * @deprecated Use `variant` instead. Alias kept so MUI/Chakra-trained\n * agents and users are caught; it maps 1:1.\n */\n color?: ButtonVariant;\n /** Size preset: \"sm\", \"md\" (default), \"lg\", or \"icon\". */\n size?: ButtonSize;\n /** Icon rendered before the label. */\n leftIcon?: React.ReactNode;\n /** Icon rendered after the label. */\n rightIcon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { color, variant = color ?? \"primary\", size = \"md\", leftIcon, rightIcon, type = \"button\", className, children, ...props },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n \"inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n buttonVariants[variant],\n buttonSizes[size],\n className,\n )}\n {...props}\n >\n {leftIcon && <span className=\"inline-flex shrink-0 items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex shrink-0 items-center\">{rightIcon}</span>}\n </button>\n ),\n);\nButton.displayName = \"Button\";\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":["React","cn","Slot","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAM,cAAA,GAAgD;AAAA,EACpD,OAAA,EAAS,uFAAA;AAAA,EACT,GAAA,EAAK,8EAAA;AAAA,EACL,SAAA,EAAW,8EAAA;AAAA,EACX,KAAA,EAAO,iCAAA;AAAA,EACP,WAAA,EACE,mGAAA;AAAA,EACF,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,WAAA,GAA0C;AAAA,EAC9C,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,8BAAA;AAAA,EACJ,IAAA,EAAM,mBAAA;AAAA,EACN,SAAA,EAAW,mBAAA;AAAA,EACX,SAAA,EAAW;AACb,CAAA;AA4BO,IAAM,MAAA,GAAeA,gBAAA,CAAA,UAAA;AAAA,EAC1B,CACE;AAAA,IACE,KAAA;AAAA,IACA,UAAU,KAAA,IAAS,SAAA;AAAA,IACnB,IAAA,GAAO,IAAA;AAAA,IACP,OAAA,GAAU,KAAA;AAAA,IACV,QAAA;AAAA,IACA,SAAA;AAAA,IACA,IAAA,GAAO,QAAA;AAAA,IACP,SAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAUC,QAAA;AAAA,MACd,6UAAA;AAAA,MACA,eAAe,OAAO,CAAA;AAAA,MACtB,YAAY,IAAI,CAAA;AAAA,MAChB,YAAY,MAAA,IAAU,aAAA;AAAA,MACtB;AAAA,KACF;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,sCACGC,UAAA,EAAA,EAAK,GAAA,EAAU,WAAW,OAAA,EAAU,GAAI,OACtC,QAAA,EACH,CAAA;AAAA,IAEJ;AACA,IAAA,uCACG,QAAA,EAAA,EAAO,GAAA,EAAU,MAAY,SAAA,EAAW,OAAA,EAAU,GAAG,KAAA,EACnD,QAAA,EAAA;AAAA,MAAA,QAAA,oBAAYC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,MAC1E,QAAA;AAAA,MACA,SAAA,oBAAaA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAqC,QAAA,EAAA,SAAA,EAAU;AAAA,KAAA,EAC/E,CAAA;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn, Slot } from \"@nucleux/utils\";\n\nexport type ButtonVariant = \"primary\" | \"cta\" | \"secondary\" | \"ghost\" | \"destructive\" | \"link\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\" | \"icon-lg\";\n\n// Canonical spec (Figma \"Button\"): rounded-lg, semibold 14px, subtle border +\n// shadow-sm on filled/outline variants; ghost is chromeless.\nconst buttonVariants: Record<ButtonVariant, string> = {\n primary: \"border border-border bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n cta: \"border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90\",\n secondary: \"border border-border bg-background text-foreground shadow-sm hover:bg-accent\",\n ghost: \"text-foreground hover:bg-accent\",\n destructive:\n \"border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n link: \"text-foreground underline decoration-from-font underline-offset-2 hover:opacity-70\",\n};\n\nconst buttonSizes: Record<ButtonSize, string> = {\n sm: \"h-8 rounded-lg px-3 text-sm\",\n md: \"h-9 rounded-lg px-4 text-sm\",\n lg: \"h-10 rounded-lg px-5 text-sm\",\n icon: \"size-9 rounded-lg\",\n \"icon-sm\": \"size-8 rounded-lg\",\n \"icon-lg\": \"size-10 rounded-lg\",\n};\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style: \"primary\" (default), \"cta\", \"secondary\", \"ghost\", \"destructive\", or \"link\". */\n variant?: ButtonVariant;\n /**\n * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.\n * @deprecated Use `variant` instead. Alias kept so MUI/Chakra-trained\n * agents and users are caught; it maps 1:1.\n */\n color?: ButtonVariant;\n /**\n * Size preset: \"sm\", \"md\" (default), \"lg\", or a square icon-only size\n * (\"icon-sm\", \"icon\", \"icon-lg\"). Icon-only buttons need an `aria-label`.\n */\n size?: ButtonSize;\n /**\n * Render the single child element (e.g. an `<a>` or a router `Link`) with\n * the button's styles instead of a `<button>`. `leftIcon`/`rightIcon` are\n * ignored; put icons inside the child.\n */\n asChild?: boolean;\n /** Icon rendered before the label. */\n leftIcon?: React.ReactNode;\n /** Icon rendered after the label. */\n rightIcon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n color,\n variant = color ?? \"primary\",\n size = \"md\",\n asChild = false,\n leftIcon,\n rightIcon,\n type = \"button\",\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const classes = cn(\n \"inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0\",\n buttonVariants[variant],\n buttonSizes[size],\n variant === \"link\" && \"h-auto px-0\",\n className,\n );\n if (asChild) {\n return (\n <Slot ref={ref} className={classes} {...(props as React.HTMLAttributes<HTMLElement>)}>\n {children}\n </Slot>\n );\n }\n return (\n <button ref={ref} type={type} className={classes} {...props}>\n {leftIcon && <span className=\"inline-flex shrink-0 items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex shrink-0 items-center\">{rightIcon}</span>}\n </button>\n );\n },\n);\nButton.displayName = \"Button\";\n"]}
package/dist/index.d.cts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
 
3
- type ButtonVariant = "primary" | "cta" | "secondary" | "ghost" | "destructive";
4
- type ButtonSize = "sm" | "md" | "lg" | "icon";
3
+ type ButtonVariant = "primary" | "cta" | "secondary" | "ghost" | "destructive" | "link";
4
+ type ButtonSize = "sm" | "md" | "lg" | "icon" | "icon-sm" | "icon-lg";
5
5
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
- /** Visual style: "primary" (default), "cta", "secondary", "ghost", or "destructive". */
6
+ /** Visual style: "primary" (default), "cta", "secondary", "ghost", "destructive", or "link". */
7
7
  variant?: ButtonVariant;
8
8
  /**
9
9
  * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.
@@ -11,8 +11,17 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11
11
  * agents and users are caught; it maps 1:1.
12
12
  */
13
13
  color?: ButtonVariant;
14
- /** Size preset: "sm", "md" (default), "lg", or "icon". */
14
+ /**
15
+ * Size preset: "sm", "md" (default), "lg", or a square icon-only size
16
+ * ("icon-sm", "icon", "icon-lg"). Icon-only buttons need an `aria-label`.
17
+ */
15
18
  size?: ButtonSize;
19
+ /**
20
+ * Render the single child element (e.g. an `<a>` or a router `Link`) with
21
+ * the button's styles instead of a `<button>`. `leftIcon`/`rightIcon` are
22
+ * ignored; put icons inside the child.
23
+ */
24
+ asChild?: boolean;
16
25
  /** Icon rendered before the label. */
17
26
  leftIcon?: React.ReactNode;
18
27
  /** Icon rendered after the label. */
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
 
3
- type ButtonVariant = "primary" | "cta" | "secondary" | "ghost" | "destructive";
4
- type ButtonSize = "sm" | "md" | "lg" | "icon";
3
+ type ButtonVariant = "primary" | "cta" | "secondary" | "ghost" | "destructive" | "link";
4
+ type ButtonSize = "sm" | "md" | "lg" | "icon" | "icon-sm" | "icon-lg";
5
5
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
6
- /** Visual style: "primary" (default), "cta", "secondary", "ghost", or "destructive". */
6
+ /** Visual style: "primary" (default), "cta", "secondary", "ghost", "destructive", or "link". */
7
7
  variant?: ButtonVariant;
8
8
  /**
9
9
  * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.
@@ -11,8 +11,17 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
11
11
  * agents and users are caught; it maps 1:1.
12
12
  */
13
13
  color?: ButtonVariant;
14
- /** Size preset: "sm", "md" (default), "lg", or "icon". */
14
+ /**
15
+ * Size preset: "sm", "md" (default), "lg", or a square icon-only size
16
+ * ("icon-sm", "icon", "icon-lg"). Icon-only buttons need an `aria-label`.
17
+ */
15
18
  size?: ButtonSize;
19
+ /**
20
+ * Render the single child element (e.g. an `<a>` or a router `Link`) with
21
+ * the button's styles instead of a `<button>`. `leftIcon`/`rightIcon` are
22
+ * ignored; put icons inside the child.
23
+ */
24
+ asChild?: boolean;
16
25
  /** Icon rendered before the label. */
17
26
  leftIcon?: React.ReactNode;
18
27
  /** Icon rendered after the label. */
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import * as React from 'react';
3
- import { cn } from '@nucleux/utils';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { cn, Slot } from '@nucleux/utils';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
5
 
6
6
  // src/index.tsx
7
7
  var buttonVariants = {
@@ -9,34 +9,46 @@ var buttonVariants = {
9
9
  cta: "border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90",
10
10
  secondary: "border border-border bg-background text-foreground shadow-sm hover:bg-accent",
11
11
  ghost: "text-foreground hover:bg-accent",
12
- destructive: "border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
12
+ destructive: "border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
13
+ link: "text-foreground underline decoration-from-font underline-offset-2 hover:opacity-70"
13
14
  };
14
15
  var buttonSizes = {
15
16
  sm: "h-8 rounded-lg px-3 text-sm",
16
17
  md: "h-9 rounded-lg px-4 text-sm",
17
18
  lg: "h-10 rounded-lg px-5 text-sm",
18
- icon: "size-9 rounded-lg"
19
+ icon: "size-9 rounded-lg",
20
+ "icon-sm": "size-8 rounded-lg",
21
+ "icon-lg": "size-10 rounded-lg"
19
22
  };
20
23
  var Button = React.forwardRef(
21
- ({ color, variant = color ?? "primary", size = "md", leftIcon, rightIcon, type = "button", className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
22
- "button",
23
- {
24
- ref,
25
- type,
26
- className: cn(
27
- "inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
28
- buttonVariants[variant],
29
- buttonSizes[size],
30
- className
31
- ),
32
- ...props,
33
- children: [
34
- leftIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: leftIcon }),
35
- children,
36
- rightIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: rightIcon })
37
- ]
24
+ ({
25
+ color,
26
+ variant = color ?? "primary",
27
+ size = "md",
28
+ asChild = false,
29
+ leftIcon,
30
+ rightIcon,
31
+ type = "button",
32
+ className,
33
+ children,
34
+ ...props
35
+ }, ref) => {
36
+ const classes = cn(
37
+ "inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0",
38
+ buttonVariants[variant],
39
+ buttonSizes[size],
40
+ variant === "link" && "h-auto px-0",
41
+ className
42
+ );
43
+ if (asChild) {
44
+ return /* @__PURE__ */ jsx(Slot, { ref, className: classes, ...props, children });
38
45
  }
39
- )
46
+ return /* @__PURE__ */ jsxs("button", { ref, type, className: classes, ...props, children: [
47
+ leftIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: leftIcon }),
48
+ children,
49
+ rightIcon && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center", children: rightIcon })
50
+ ] });
51
+ }
40
52
  );
41
53
  Button.displayName = "Button";
42
54
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;AAcA,IAAM,cAAA,GAAgD;AAAA,EACpD,OAAA,EAAS,uFAAA;AAAA,EACT,GAAA,EAAK,8EAAA;AAAA,EACL,SAAA,EAAW,8EAAA;AAAA,EACX,KAAA,EAAO,iCAAA;AAAA,EACP,WAAA,EACE;AACJ,CAAA;AAEA,IAAM,WAAA,GAA0C;AAAA,EAC9C,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,8BAAA;AAAA,EACJ,IAAA,EAAM;AACR,CAAA;AAmBO,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EAC1B,CACE,EAAE,KAAA,EAAO,OAAA,GAAU,KAAA,IAAS,WAAW,IAAA,GAAO,IAAA,EAAM,QAAA,EAAU,SAAA,EAAW,OAAO,QAAA,EAAU,SAAA,EAAW,UAAU,GAAG,KAAA,IAClH,GAAA,qBAEA,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,4TAAA;AAAA,QACA,eAAe,OAAO,CAAA;AAAA,QACtB,YAAY,IAAI,CAAA;AAAA,QAChB;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,QAC1E,QAAA;AAAA,QACA,SAAA,oBAAa,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAqC,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA;AAGnF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@nucleux/utils\";\n\nexport type ButtonVariant =\n | \"primary\"\n | \"cta\"\n | \"secondary\"\n | \"ghost\"\n | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\";\n\n// Canonical spec (Figma \"Button\"): rounded-lg, semibold 14px, subtle border +\n// shadow-sm on filled/outline variants; ghost is chromeless.\nconst buttonVariants: Record<ButtonVariant, string> = {\n primary: \"border border-border bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n cta: \"border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90\",\n secondary: \"border border-border bg-background text-foreground shadow-sm hover:bg-accent\",\n ghost: \"text-foreground hover:bg-accent\",\n destructive:\n \"border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n};\n\nconst buttonSizes: Record<ButtonSize, string> = {\n sm: \"h-8 rounded-lg px-3 text-sm\",\n md: \"h-9 rounded-lg px-4 text-sm\",\n lg: \"h-10 rounded-lg px-5 text-sm\",\n icon: \"size-9 rounded-lg\",\n};\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style: \"primary\" (default), \"cta\", \"secondary\", \"ghost\", or \"destructive\". */\n variant?: ButtonVariant;\n /**\n * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.\n * @deprecated Use `variant` instead. Alias kept so MUI/Chakra-trained\n * agents and users are caught; it maps 1:1.\n */\n color?: ButtonVariant;\n /** Size preset: \"sm\", \"md\" (default), \"lg\", or \"icon\". */\n size?: ButtonSize;\n /** Icon rendered before the label. */\n leftIcon?: React.ReactNode;\n /** Icon rendered after the label. */\n rightIcon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { color, variant = color ?? \"primary\", size = \"md\", leftIcon, rightIcon, type = \"button\", className, children, ...props },\n ref,\n ) => (\n <button\n ref={ref}\n type={type}\n className={cn(\n \"inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n buttonVariants[variant],\n buttonSizes[size],\n className,\n )}\n {...props}\n >\n {leftIcon && <span className=\"inline-flex shrink-0 items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex shrink-0 items-center\">{rightIcon}</span>}\n </button>\n ),\n);\nButton.displayName = \"Button\";\n"]}
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;AASA,IAAM,cAAA,GAAgD;AAAA,EACpD,OAAA,EAAS,uFAAA;AAAA,EACT,GAAA,EAAK,8EAAA;AAAA,EACL,SAAA,EAAW,8EAAA;AAAA,EACX,KAAA,EAAO,iCAAA;AAAA,EACP,WAAA,EACE,mGAAA;AAAA,EACF,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,WAAA,GAA0C;AAAA,EAC9C,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,6BAAA;AAAA,EACJ,EAAA,EAAI,8BAAA;AAAA,EACJ,IAAA,EAAM,mBAAA;AAAA,EACN,SAAA,EAAW,mBAAA;AAAA,EACX,SAAA,EAAW;AACb,CAAA;AA4BO,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EAC1B,CACE;AAAA,IACE,KAAA;AAAA,IACA,UAAU,KAAA,IAAS,SAAA;AAAA,IACnB,IAAA,GAAO,IAAA;AAAA,IACP,OAAA,GAAU,KAAA;AAAA,IACV,QAAA;AAAA,IACA,SAAA;AAAA,IACA,IAAA,GAAO,QAAA;AAAA,IACP,SAAA;AAAA,IACA,QAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU,EAAA;AAAA,MACd,6UAAA;AAAA,MACA,eAAe,OAAO,CAAA;AAAA,MACtB,YAAY,IAAI,CAAA;AAAA,MAChB,YAAY,MAAA,IAAU,aAAA;AAAA,MACtB;AAAA,KACF;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,2BACG,IAAA,EAAA,EAAK,GAAA,EAAU,WAAW,OAAA,EAAU,GAAI,OACtC,QAAA,EACH,CAAA;AAAA,IAEJ;AACA,IAAA,4BACG,QAAA,EAAA,EAAO,GAAA,EAAU,MAAY,SAAA,EAAW,OAAA,EAAU,GAAG,KAAA,EACnD,QAAA,EAAA;AAAA,MAAA,QAAA,oBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,MAC1E,QAAA;AAAA,MACA,SAAA,oBAAa,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qCAAqC,QAAA,EAAA,SAAA,EAAU;AAAA,KAAA,EAC/E,CAAA;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn, Slot } from \"@nucleux/utils\";\n\nexport type ButtonVariant = \"primary\" | \"cta\" | \"secondary\" | \"ghost\" | \"destructive\" | \"link\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\" | \"icon-lg\";\n\n// Canonical spec (Figma \"Button\"): rounded-lg, semibold 14px, subtle border +\n// shadow-sm on filled/outline variants; ghost is chromeless.\nconst buttonVariants: Record<ButtonVariant, string> = {\n primary: \"border border-border bg-primary text-primary-foreground shadow-sm hover:bg-primary/90\",\n cta: \"border border-border bg-info text-info-foreground shadow-sm hover:bg-info/90\",\n secondary: \"border border-border bg-background text-foreground shadow-sm hover:bg-accent\",\n ghost: \"text-foreground hover:bg-accent\",\n destructive:\n \"border border-border bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90\",\n link: \"text-foreground underline decoration-from-font underline-offset-2 hover:opacity-70\",\n};\n\nconst buttonSizes: Record<ButtonSize, string> = {\n sm: \"h-8 rounded-lg px-3 text-sm\",\n md: \"h-9 rounded-lg px-4 text-sm\",\n lg: \"h-10 rounded-lg px-5 text-sm\",\n icon: \"size-9 rounded-lg\",\n \"icon-sm\": \"size-8 rounded-lg\",\n \"icon-lg\": \"size-10 rounded-lg\",\n};\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual style: \"primary\" (default), \"cta\", \"secondary\", \"ghost\", \"destructive\", or \"link\". */\n variant?: ButtonVariant;\n /**\n * Alias of `variant` (MUI/Chakra vocabulary). Deprecated — use `variant`.\n * @deprecated Use `variant` instead. Alias kept so MUI/Chakra-trained\n * agents and users are caught; it maps 1:1.\n */\n color?: ButtonVariant;\n /**\n * Size preset: \"sm\", \"md\" (default), \"lg\", or a square icon-only size\n * (\"icon-sm\", \"icon\", \"icon-lg\"). Icon-only buttons need an `aria-label`.\n */\n size?: ButtonSize;\n /**\n * Render the single child element (e.g. an `<a>` or a router `Link`) with\n * the button's styles instead of a `<button>`. `leftIcon`/`rightIcon` are\n * ignored; put icons inside the child.\n */\n asChild?: boolean;\n /** Icon rendered before the label. */\n leftIcon?: React.ReactNode;\n /** Icon rendered after the label. */\n rightIcon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n color,\n variant = color ?? \"primary\",\n size = \"md\",\n asChild = false,\n leftIcon,\n rightIcon,\n type = \"button\",\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const classes = cn(\n \"inline-flex select-none items-center justify-center gap-1.5 whitespace-nowrap font-semibold tracking-[0.005em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:shrink-0\",\n buttonVariants[variant],\n buttonSizes[size],\n variant === \"link\" && \"h-auto px-0\",\n className,\n );\n if (asChild) {\n return (\n <Slot ref={ref} className={classes} {...(props as React.HTMLAttributes<HTMLElement>)}>\n {children}\n </Slot>\n );\n }\n return (\n <button ref={ref} type={type} className={classes} {...props}>\n {leftIcon && <span className=\"inline-flex shrink-0 items-center\">{leftIcon}</span>}\n {children}\n {rightIcon && <span className=\"inline-flex shrink-0 items-center\">{rightIcon}</span>}\n </button>\n );\n },\n);\nButton.displayName = \"Button\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nucleux/button",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.cjs",
@@ -22,7 +22,7 @@
22
22
  "react-dom": ">=18"
23
23
  },
24
24
  "dependencies": {
25
- "@nucleux/utils": "0.5.0"
25
+ "@nucleux/utils": "0.6.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "tsup": "^8.3.5",