11import  {  Checkbox  as  CheckboxPrimitive  }  from  '@base-ui-components/react/checkbox' ; 
2- import  {  CheckIcon  }  from  'lucide-react' ; 
2+ import  {  cva  }  from  'class-variance-authority' ; 
3+ import  {  CheckIcon ,  MinusIcon  }  from  'lucide-react' ; 
34import  React  from  'react' ; 
45
56import  {  cn  }  from  '@/lib/tailwind/utils' ; 
67
8+ const  labelVariants  =  cva ( 'flex items-center gap-2.5 text-primary' ,  { 
9+   variants : { 
10+     size : { 
11+       default : 'text-base' , 
12+       sm : 'gap-2 text-sm' , 
13+       lg : 'gap-3 text-lg' , 
14+     } , 
15+   } , 
16+   defaultVariants : { 
17+     size : 'default' , 
18+   } , 
19+ } ) ; 
20+ 
21+ const  checkboxVariants  =  cva ( 
22+   'flex flex-none cursor-pointer items-center justify-center rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-muted-foreground disabled:opacity-20 data-checked:bg-primary data-checked:text-primary-foreground data-indeterminate:border data-indeterminate:border-primary/20 data-unchecked:border data-unchecked:border-primary/20' , 
23+   { 
24+     variants : { 
25+       size : { 
26+         default : 'size-5 [&_svg]:size-3.5 [&_svg]:stroke-3' , 
27+         sm : 'size-4 rounded-[5px] [&_svg]:size-2.5 [&_svg]:stroke-4' , 
28+         lg : 'size-6 [&_svg]:size-4 [&_svg]:stroke-3' , 
29+       } , 
30+     } , 
31+     defaultVariants : { 
32+       size : 'default' , 
33+     } , 
34+   } 
35+ ) ; 
36+ 
737export  type  CheckboxProps  =  Omit < CheckboxPrimitive . Root . Props ,  'type' >  &  { 
838  /** 
939   * By default, the checkbox is wrapped in a `<label>`. Set to `false` if you do not want it. 
1040   */ 
1141  noLabel ?: boolean ; 
1242  labelProps ?: React . ComponentProps < 'label' > ; 
43+   size ?: 'default'  |  'sm'  |  'lg' ; 
1344} ; 
1445
1546export  function  Checkbox ( { 
1647  children, 
1748  className, 
1849  noLabel, 
1950  labelProps, 
51+   size, 
2052  ...props 
2153} : CheckboxProps )  { 
2254  const  Comp  =  noLabel  ? React . Fragment  : 'label' ; 
@@ -25,33 +57,27 @@ export function Checkbox({
2557    ? { } 
2658    : { 
2759        ...labelProps , 
28-         className : cn ( 
29-           'flex items-center gap-2 text-base text-primary' , 
30-           labelProps ?. className 
31-         ) , 
60+         className : cn ( labelVariants ( {  size } ) ,  labelProps ?. className ) , 
3261      } ; 
3362
3463  return  ( 
3564    < Comp  { ...compProps } > 
3665      < CheckboxPrimitive . Root 
37-         className = { cn ( 
38-           'flex size-5 cursor-pointer items-center justify-center rounded-sm outline-none' , 
39-           'focus-visible:ring-[3px] focus-visible:ring-ring/50' , 
40-           'data-checked:bg-primary data-unchecked:border data-unchecked:border-primary/50' , 
41-           'disabled:cursor-not-allowed disabled:bg-muted-foreground disabled:opacity-20' , 
42-           className 
43-         ) } 
66+         className = { cn ( checkboxVariants ( {  size } ) ,  className ) } 
4467        { ...props } 
4568      > 
4669        < CheckboxPrimitive . Indicator 
4770          keepMounted = { true } 
4871          className = { cn ( 
4972            'flex transition-transform duration-150 ease-in-out' , 
50-             'data-checked:scale-100 data-checked:rotate-0 data-unchecked:invisible data-unchecked:scale-50 data-unchecked:rotate-45' 
73+             'data-checked:scale-100 data-unchecked:invisible data-unchecked:scale-75' 
74+           ) } 
75+           render = { ( props ,  state )  =>  ( 
76+             < span  { ...props } > 
77+               { state . indeterminate  ? < MinusIcon  />  : < CheckIcon  /> } 
78+             </ span > 
5179          ) } 
52-         > 
53-           < CheckIcon  className = "size-3.5 stroke-3 text-primary-foreground"  /> 
54-         </ CheckboxPrimitive . Indicator > 
80+         /> 
5581      </ CheckboxPrimitive . Root > 
5682      { children } 
5783    </ Comp > 
0 commit comments