sonance-brand-mcp 1.3.108 → 1.3.110

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.
@@ -3,8 +3,10 @@ import { cva, type VariantProps } from "class-variance-authority";
3
3
  import { AlertCircle, CheckCircle, Info, AlertTriangle, X } from "lucide-react";
4
4
  import { cn } from "@/lib/utils";
5
5
 
6
+ export type AlertState = "default" | "hover" | "focus";
7
+
6
8
  const alertVariants = cva(
7
- "relative flex w-full items-start gap-4 border p-4 transition-colors",
9
+ "relative flex w-full items-start border transition-all duration-200",
8
10
  {
9
11
  variants: {
10
12
  variant: {
@@ -14,13 +16,34 @@ const alertVariants = cva(
14
16
  warning: "border-warning/30 bg-warning-light text-warning",
15
17
  info: "border-info/30 bg-info-light text-info",
16
18
  },
19
+ size: {
20
+ xs: "gap-2 p-2 rounded-lg text-xs",
21
+ sm: "gap-2.5 p-3 rounded-xl text-xs",
22
+ md: "gap-3 p-4 rounded-xl text-sm",
23
+ lg: "gap-4 p-5 rounded-2xl text-sm",
24
+ },
17
25
  },
18
26
  defaultVariants: {
19
27
  variant: "default",
28
+ size: "sm",
20
29
  },
21
30
  }
22
31
  );
23
32
 
33
+ const iconSizes = {
34
+ xs: "h-3.5 w-3.5",
35
+ sm: "h-4 w-4",
36
+ md: "h-5 w-5",
37
+ lg: "h-5 w-5",
38
+ };
39
+
40
+ const closeSizes = {
41
+ xs: "h-3 w-3",
42
+ sm: "h-3.5 w-3.5",
43
+ md: "h-4 w-4",
44
+ lg: "h-4 w-4",
45
+ };
46
+
24
47
  const iconMap = {
25
48
  default: Info,
26
49
  success: CheckCircle,
@@ -35,10 +58,12 @@ interface AlertProps
35
58
  title?: string;
36
59
  dismissible?: boolean;
37
60
  onClose?: () => void;
61
+ /** Visual state for Storybook/Figma documentation */
62
+ state?: AlertState;
38
63
  }
39
64
 
40
65
  export const Alert = forwardRef<HTMLDivElement, AlertProps>(
41
- ({ className, variant = "default", title, children, dismissible, onClose, ...props }, ref) => {
66
+ ({ className, variant = "default", size = "sm", title, children, dismissible, onClose, state, ...props }, ref) => {
42
67
  const Icon = iconMap[variant || "default"];
43
68
  const showCloseButton = dismissible || onClose;
44
69
 
@@ -47,18 +72,18 @@ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
47
72
  data-sonance-name="alert"
48
73
  ref={ref}
49
74
  role="alert"
50
- className={cn(alertVariants({ variant }), className)}
75
+ className={cn(alertVariants({ variant, size }), className)}
51
76
  {...props}
52
77
  >
53
- <Icon className="h-5 w-5 shrink-0" />
54
- <div className="flex-1">
78
+ <Icon className={cn("shrink-0", iconSizes[size || "sm"])} />
79
+ <div className="flex-1 min-w-0">
55
80
  {title && (
56
- <h5 id="icon-h5-title" className="mb-1 font-medium leading-none tracking-tight">
81
+ <h5 id="icon-h5-title" className="mb-0.5 font-medium leading-tight tracking-tight">
57
82
  {title}
58
83
  </h5>
59
84
  )}
60
85
  {children && (
61
- <div data-sonance-name="alert" className={cn("text-sm", variant === "default" && "text-foreground-secondary")}>
86
+ <div data-sonance-name="alert" className={cn(variant === "default" && "text-foreground-secondary")}>
62
87
  {children}
63
88
  </div>
64
89
  )}
@@ -66,9 +91,9 @@ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
66
91
  {showCloseButton && (
67
92
  <button
68
93
  onClick={onClose}
69
- className="shrink-0 rounded-sm p-1 opacity-70 transition-opacity hover:opacity-100"
94
+ className="shrink-0 rounded-lg p-1 opacity-70 transition-all duration-150 hover:opacity-100 hover:bg-secondary-hover"
70
95
  >
71
- <X className="h-4 w-4" />
96
+ <X className={closeSizes[size || "sm"]} />
72
97
  <span id="icon-span-close" className="sr-only">Close</span>
73
98
  </button>
74
99
  )}
@@ -79,3 +104,4 @@ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
79
104
 
80
105
  Alert.displayName = "Alert";
81
106
 
107
+ export { alertVariants };
@@ -1,58 +1,86 @@
1
1
  import { cva, type VariantProps } from "class-variance-authority";
2
2
  import { cn } from "@/lib/utils";
3
3
 
4
+ export type BadgeState = "default" | "hover";
5
+
4
6
  const badgeVariants = cva(
5
- "inline-flex items-center font-medium transition-colors",
7
+ "inline-flex items-center font-medium transition-all duration-150",
6
8
  {
7
9
  variants: {
8
10
  variant: {
9
- default: "bg-background-secondary text-foreground border border-border",
10
- primary: "bg-primary text-primary-foreground",
11
- secondary: "bg-secondary-hover text-secondary-foreground border border-border",
12
- success: "bg-success text-white",
13
- error: "bg-error text-white",
14
- warning: "bg-warning text-white",
15
- info: "bg-info text-white",
16
- outline: "border border-border text-foreground bg-transparent",
11
+ default: "bg-background-secondary text-foreground border border-border hover:bg-secondary-hover",
12
+ primary: "bg-primary text-primary-foreground hover:bg-primary-hover",
13
+ secondary: "bg-secondary-hover text-secondary-foreground border border-border hover:bg-secondary",
14
+ success: "bg-success text-white hover:bg-success/90",
15
+ error: "bg-error text-white hover:bg-error/90",
16
+ warning: "bg-warning text-white hover:bg-warning/90",
17
+ info: "bg-info text-white hover:bg-info/90",
18
+ outline: "border border-border text-foreground bg-transparent hover:bg-secondary-hover",
19
+ glass: "bg-primary/20 text-primary border border-primary/30 backdrop-blur-sm hover:bg-primary/30",
17
20
  },
18
21
  size: {
19
- sm: "px-2 py-0.5 text-xs",
20
- md: "px-2.5 py-0.5 text-xs",
21
- lg: "px-3 py-1 text-sm",
22
+ xs: "px-1.5 py-0.5 text-[10px] rounded-md",
23
+ sm: "px-2 py-0.5 text-xs rounded-lg",
24
+ md: "px-2.5 py-0.5 text-xs rounded-full",
25
+ lg: "px-3 py-1 text-sm rounded-full",
22
26
  },
23
27
  },
24
28
  defaultVariants: {
25
29
  variant: "default",
26
- size: "md",
30
+ size: "sm",
27
31
  },
28
32
  }
29
33
  );
30
34
 
31
35
  interface BadgeProps
32
36
  extends React.HTMLAttributes<HTMLSpanElement>,
33
- VariantProps<typeof badgeVariants> {}
37
+ VariantProps<typeof badgeVariants> {
38
+ /** Visual state for Storybook/Figma documentation */
39
+ state?: BadgeState;
40
+ }
34
41
 
35
- export function Badge({ className, variant, size, ...props }: BadgeProps) {
42
+ export function Badge({ className, variant, size, state, ...props }: BadgeProps) {
36
43
  return (
37
- <span id="badge-span" data-sonance-name="badge" className={cn(badgeVariants({ variant, size }), className)} {...props} />
44
+ <span
45
+ id="badge-span"
46
+ data-sonance-name="badge"
47
+ className={cn(
48
+ badgeVariants({ variant, size }),
49
+ state === "hover" && "bg-secondary-hover",
50
+ className
51
+ )}
52
+ {...props}
53
+ />
38
54
  );
39
55
  }
40
56
 
57
+ const closeIconSizes = {
58
+ xs: "h-2.5 w-2.5",
59
+ sm: "h-3 w-3",
60
+ md: "h-3 w-3",
61
+ lg: "h-3.5 w-3.5",
62
+ };
63
+
41
64
  // Chip variant with optional close button
42
65
  interface ChipProps extends BadgeProps {
43
66
  onClose?: () => void;
44
67
  }
45
68
 
46
- export function Chip({ className, variant, size, onClose, children, ...props }: ChipProps) {
69
+ export function Chip({ className, variant, size = "sm", onClose, children, ...props }: ChipProps) {
47
70
  return (
48
- <span id="chip-span" className={cn(badgeVariants({ variant, size }), "gap-1", className)} data-sonance-name="badge" {...props}>
71
+ <span
72
+ id="chip-span"
73
+ className={cn(badgeVariants({ variant, size }), "gap-1", className)}
74
+ data-sonance-name="badge"
75
+ {...props}
76
+ >
49
77
  {children}
50
78
  {onClose && (
51
79
  <button
52
80
  onClick={onClose}
53
- className="ml-1 rounded-full p-0.5 hover:bg-black/10 dark:hover:bg-white/10"
81
+ className="ml-0.5 rounded-full p-0.5 transition-colors hover:bg-black/10 dark:hover:bg-white/10"
54
82
  >
55
- <svg className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
83
+ <svg className={closeIconSizes[size || "sm"]} fill="none" viewBox="0 0 24 24" stroke="currentColor">
56
84
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
57
85
  </svg>
58
86
  <span id="chip-span-remove" className="sr-only">Remove</span>
@@ -62,3 +90,4 @@ export function Chip({ className, variant, size, onClose, children, ...props }:
62
90
  );
63
91
  }
64
92
 
93
+ export { badgeVariants };
@@ -5,28 +5,31 @@ import { forwardRef } from "react";
5
5
  export type ButtonState = "default" | "hover" | "active" | "focus" | "disabled";
6
6
 
7
7
  const buttonVariants = cva(
8
- "inline-flex items-center justify-center font-medium uppercase tracking-wide transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
8
+ "inline-flex items-center justify-center font-medium uppercase tracking-wide transition-all duration-200 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/20 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98]",
9
9
  {
10
10
  variants: {
11
11
  variant: {
12
12
  primary:
13
- "bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active",
13
+ "bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active shadow-sm hover:shadow-md",
14
14
  secondary:
15
- "bg-secondary text-secondary-foreground border border-border hover:bg-secondary-hover hover:border-border-hover",
15
+ "bg-secondary text-secondary-foreground border border-border hover:bg-secondary-hover hover:border-border-hover shadow-sm hover:shadow-md",
16
16
  ghost: "text-foreground hover:bg-secondary-hover",
17
17
  inverted:
18
- "bg-sonance-white text-sonance-charcoal hover:opacity-90",
18
+ "bg-sonance-white text-sonance-charcoal hover:opacity-90 shadow-sm hover:shadow-md",
19
+ glass:
20
+ "bg-primary/90 text-primary-foreground backdrop-blur-sm border border-white/10 hover:bg-primary/80 shadow-lg",
19
21
  },
20
22
  size: {
21
- sm: "h-9 px-4 text-xs",
22
- md: "h-11 px-6 text-sm",
23
- lg: "h-14 px-8 text-sm",
24
- icon: "h-10 w-10",
23
+ xs: "h-6 px-2.5 text-[10px] rounded-md",
24
+ sm: "h-8 px-3.5 text-xs rounded-lg",
25
+ md: "h-9 px-4 text-sm rounded-lg",
26
+ lg: "h-10 px-5 text-sm rounded-xl",
27
+ icon: "h-9 w-9 rounded-full",
25
28
  },
26
29
  },
27
30
  defaultVariants: {
28
31
  variant: "primary",
29
- size: "md",
32
+ size: "sm",
30
33
  },
31
34
  }
32
35
  );
@@ -37,27 +40,33 @@ const getStateStyles = (variant: string | null | undefined, state?: ButtonState)
37
40
 
38
41
  const stateMap: Record<string, Record<string, string>> = {
39
42
  primary: {
40
- hover: "bg-primary-hover",
41
- active: "bg-primary-active",
42
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
43
+ hover: "bg-primary-hover shadow-md",
44
+ active: "bg-primary-active scale-[0.98]",
45
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
43
46
  disabled: "opacity-50 pointer-events-none",
44
47
  },
45
48
  secondary: {
46
- hover: "bg-secondary-hover border-border-hover",
47
- active: "bg-secondary-hover",
48
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
49
+ hover: "bg-secondary-hover border-border-hover shadow-md",
50
+ active: "bg-secondary-hover scale-[0.98]",
51
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
49
52
  disabled: "opacity-50 pointer-events-none",
50
53
  },
51
54
  ghost: {
52
55
  hover: "bg-secondary-hover",
53
- active: "bg-secondary-hover",
54
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
56
+ active: "bg-secondary-hover scale-[0.98]",
57
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
55
58
  disabled: "opacity-50 pointer-events-none",
56
59
  },
57
60
  inverted: {
58
- hover: "opacity-90",
59
- active: "opacity-80",
60
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
61
+ hover: "opacity-90 shadow-md",
62
+ active: "opacity-80 scale-[0.98]",
63
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
64
+ disabled: "opacity-50 pointer-events-none",
65
+ },
66
+ glass: {
67
+ hover: "bg-primary/80 shadow-lg",
68
+ active: "bg-primary/70 scale-[0.98]",
69
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
61
70
  disabled: "opacity-50 pointer-events-none",
62
71
  },
63
72
  };
@@ -1,49 +1,90 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
1
2
  import { cn } from "@/lib/utils";
2
3
  import { forwardRef } from "react";
3
4
 
4
5
  export type CardState = "default" | "hover" | "focus";
5
6
 
6
- interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
7
- variant?: "default" | "elevated";
7
+ const cardVariants = cva(
8
+ "bg-card border border-card-border transition-all duration-200",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "hover:border-border-hover hover:bg-card-hover",
13
+ elevated: "shadow-md hover:shadow-lg",
14
+ glass: "bg-card/80 backdrop-blur-sm border-white/10 hover:bg-card/90",
15
+ },
16
+ size: {
17
+ compact: "rounded-lg",
18
+ default: "rounded-xl",
19
+ spacious: "rounded-2xl",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: "default",
24
+ size: "default",
25
+ },
26
+ }
27
+ );
28
+
29
+ const cardPaddingSizes = {
30
+ compact: "p-3",
31
+ default: "p-4",
32
+ spacious: "p-6",
33
+ };
34
+
35
+ interface CardProps extends React.HTMLAttributes<HTMLDivElement>,
36
+ VariantProps<typeof cardVariants> {
8
37
  /** Visual state for Storybook/Figma documentation */
9
38
  state?: CardState;
10
39
  }
11
40
 
12
41
  // State styles for Storybook/Figma visualization
13
- const getStateStyles = (variant: string, state?: CardState) => {
42
+ const getStateStyles = (variant: string | null | undefined, state?: CardState) => {
14
43
  if (!state || state === "default") return "";
15
44
 
16
45
  if (variant === "elevated") {
17
46
  const stateMap: Record<string, string> = {
18
47
  hover: "shadow-lg",
19
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
48
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
49
+ };
50
+ return stateMap[state] || "";
51
+ }
52
+
53
+ if (variant === "glass") {
54
+ const stateMap: Record<string, string> = {
55
+ hover: "bg-card/90",
56
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
20
57
  };
21
58
  return stateMap[state] || "";
22
59
  }
23
60
 
24
61
  const stateMap: Record<string, string> = {
25
62
  hover: "border-border-hover bg-card-hover",
26
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
63
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
27
64
  };
28
65
 
29
66
  return stateMap[state] || "";
30
67
  };
31
68
 
69
+ // Create a context for passing size to children
70
+ import { createContext, useContext } from "react";
71
+ const CardSizeContext = createContext<"compact" | "default" | "spacious">("default");
72
+
32
73
  export const Card = forwardRef<HTMLDivElement, CardProps>(
33
- ({ className, variant = "default", state, ...props }, ref) => {
74
+ ({ className, variant, size = "default", state, ...props }, ref) => {
34
75
  return (
35
- <div
36
- data-sonance-name="card"
37
- ref={ref}
38
- className={cn(
39
- "bg-card border border-card-border transition-all duration-200",
40
- variant === "elevated" && "shadow-md hover:shadow-lg",
41
- variant === "default" && "hover:border-border-hover hover:bg-card-hover",
42
- getStateStyles(variant, state),
43
- className
44
- )}
45
- {...props}
46
- />
76
+ <CardSizeContext.Provider value={size || "default"}>
77
+ <div
78
+ data-sonance-name="card"
79
+ ref={ref}
80
+ className={cn(
81
+ cardVariants({ variant, size }),
82
+ getStateStyles(variant, state),
83
+ className
84
+ )}
85
+ {...props}
86
+ />
87
+ </CardSizeContext.Provider>
47
88
  );
48
89
  }
49
90
  );
@@ -53,9 +94,12 @@ Card.displayName = "Card";
53
94
  export const CardHeader = forwardRef<
54
95
  HTMLDivElement,
55
96
  React.HTMLAttributes<HTMLDivElement>
56
- >(({ className, ...props }, ref) => (
57
- <div ref={ref} className={cn("p-6", className)} data-sonance-name="card" {...props} />
58
- ));
97
+ >(({ className, ...props }, ref) => {
98
+ const size = useContext(CardSizeContext);
99
+ return (
100
+ <div ref={ref} className={cn(cardPaddingSizes[size], className)} data-sonance-name="card" {...props} />
101
+ );
102
+ });
59
103
 
60
104
  CardHeader.displayName = "CardHeader";
61
105
 
@@ -66,7 +110,7 @@ export const CardTitle = forwardRef<
66
110
  <h3
67
111
  id="card-title-h3"
68
112
  ref={ref}
69
- className={cn("text-lg font-medium text-foreground", className)}
113
+ className={cn("text-base font-medium text-foreground", className)}
70
114
  {...props}
71
115
  />
72
116
  ));
@@ -91,22 +135,32 @@ CardDescription.displayName = "CardDescription";
91
135
  export const CardContent = forwardRef<
92
136
  HTMLDivElement,
93
137
  React.HTMLAttributes<HTMLDivElement>
94
- >(({ className, ...props }, ref) => (
95
- <div ref={ref} className={cn("p-6 pt-0", className)} data-sonance-name="card" {...props} />
96
- ));
138
+ >(({ className, ...props }, ref) => {
139
+ const size = useContext(CardSizeContext);
140
+ const paddingClass = size === "compact" ? "px-3 pb-3" : size === "spacious" ? "px-6 pb-6" : "px-4 pb-4";
141
+ return (
142
+ <div ref={ref} className={cn(paddingClass, "pt-0", className)} data-sonance-name="card" {...props} />
143
+ );
144
+ });
97
145
 
98
146
  CardContent.displayName = "CardContent";
99
147
 
100
148
  export const CardFooter = forwardRef<
101
149
  HTMLDivElement,
102
150
  React.HTMLAttributes<HTMLDivElement>
103
- >(({ className, ...props }, ref) => (
104
- <div
105
- ref={ref}
106
- className={cn("flex items-center p-6 pt-0", className)}
107
- data-sonance-name="card"
108
- {...props}
109
- />
110
- ));
151
+ >(({ className, ...props }, ref) => {
152
+ const size = useContext(CardSizeContext);
153
+ const paddingClass = size === "compact" ? "px-3 pb-3" : size === "spacious" ? "px-6 pb-6" : "px-4 pb-4";
154
+ return (
155
+ <div
156
+ ref={ref}
157
+ className={cn("flex items-center pt-0", paddingClass, className)}
158
+ data-sonance-name="card"
159
+ {...props}
160
+ />
161
+ );
162
+ });
111
163
 
112
164
  CardFooter.displayName = "CardFooter";
165
+
166
+ export { cardVariants };
@@ -2,11 +2,37 @@
2
2
 
3
3
  import { forwardRef, useId } from "react";
4
4
  import { Check } from "lucide-react";
5
+ import { cva, type VariantProps } from "class-variance-authority";
5
6
  import { cn } from "@/lib/utils";
6
7
 
7
8
  export type CheckboxState = "default" | "hover" | "focus" | "checked" | "disabled";
8
9
 
9
- interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type"> {
10
+ const checkboxVariants = cva(
11
+ "peer shrink-0 appearance-none border border-border bg-input transition-all duration-150 hover:border-border-hover checked:border-primary checked:bg-primary focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
12
+ {
13
+ variants: {
14
+ size: {
15
+ xs: "h-3.5 w-3.5 rounded",
16
+ sm: "h-4 w-4 rounded-md",
17
+ md: "h-5 w-5 rounded-md",
18
+ lg: "h-6 w-6 rounded-lg",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ size: "sm",
23
+ },
24
+ }
25
+ );
26
+
27
+ const checkIconSizes = {
28
+ xs: "h-2.5 w-2.5",
29
+ sm: "h-3 w-3",
30
+ md: "h-3.5 w-3.5",
31
+ lg: "h-4 w-4",
32
+ };
33
+
34
+ interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "size">,
35
+ VariantProps<typeof checkboxVariants> {
10
36
  label?: string;
11
37
  description?: string;
12
38
  /** Visual state for Storybook/Figma documentation */
@@ -21,7 +47,7 @@ const getStateStyles = (state?: CheckboxState) => {
21
47
 
22
48
  const stateMap: Record<string, string> = {
23
49
  hover: "border-border-hover",
24
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
50
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
25
51
  checked: "border-primary bg-primary",
26
52
  disabled: "opacity-50 cursor-not-allowed",
27
53
  };
@@ -30,7 +56,7 @@ const getStateStyles = (state?: CheckboxState) => {
30
56
  };
31
57
 
32
58
  export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
33
- ({ className, label, description, id, state, disabled, checked, defaultChecked, onChange, onCheckedChange, style, ...props }, ref) => {
59
+ ({ className, label, description, id, state, disabled, checked, defaultChecked, onChange, onCheckedChange, style, size = "sm", ...props }, ref) => {
34
60
  const uniqueId = useId();
35
61
  const inputId = id || `checkbox-${uniqueId}`;
36
62
  const isDisabled = disabled || state === "disabled";
@@ -46,7 +72,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
46
72
  };
47
73
 
48
74
  return (
49
- <label data-sonance-name="checkbox" className="flex items-start gap-3 cursor-pointer">
75
+ <label data-sonance-name="checkbox" className="flex items-start gap-2.5 cursor-pointer">
50
76
  <div className="relative flex items-center justify-center">
51
77
  <input
52
78
  type="checkbox"
@@ -61,12 +87,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
61
87
  )}
62
88
  readOnly={isControlled && !onChange && !onCheckedChange}
63
89
  className={cn(
64
- "peer h-5 w-5 shrink-0 appearance-none border border-border bg-input",
65
- "hover:border-border-hover",
66
- "checked:border-primary checked:bg-primary",
67
- "focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2 focus:ring-offset-background",
68
- "disabled:cursor-not-allowed disabled:opacity-50",
69
- "transition-colors duration-150",
90
+ checkboxVariants({ size }),
70
91
  getStateStyles(state),
71
92
  className
72
93
  )}
@@ -74,8 +95,9 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
74
95
  />
75
96
  <Check
76
97
  className={cn(
77
- "pointer-events-none absolute h-3.5 w-3.5 text-primary-foreground opacity-0 peer-checked:opacity-100 transition-opacity",
78
- state === "checked" && "opacity-100"
98
+ "pointer-events-none absolute text-primary-foreground opacity-0 peer-checked:opacity-100 transition-all duration-150 peer-checked:scale-100 scale-75",
99
+ checkIconSizes[size || "sm"],
100
+ state === "checked" && "opacity-100 scale-100"
79
101
  )}
80
102
  />
81
103
  </div>
@@ -100,3 +122,5 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
100
122
 
101
123
  Checkbox.displayName = "Checkbox";
102
124
 
125
+ export { checkboxVariants };
126
+