Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit bfff818

Browse files
committed
feat: extract cva class
1 parent b3fc0c1 commit bfff818

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1301
-1124
lines changed

.idea/codeStyles/Project.xml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/codefixlabs.iml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ui/src/accordion.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import {
24
Content,
35
Header,

packages/ui/src/alert-dialog.tsx

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import {
24
Action,
35
Cancel,
@@ -10,11 +12,11 @@ import {
1012
Trigger,
1113
} from '@radix-ui/react-alert-dialog';
1214
import type { VariantProps } from 'class-variance-authority';
13-
import { cva, cx } from 'class-variance-authority';
15+
import { cx } from 'class-variance-authority';
1416
import * as React from 'react';
1517
import { createContext, forwardRef, useContext } from 'react';
1618
import { twMerge } from 'tailwind-merge';
17-
import { buttonVariants } from './button';
19+
import { alertDialogContentVariants, buttonVariants } from './cva';
1820

1921
/* -----------------------------------------------------------------------------
2022
* Provider: AlertDialogContext
@@ -44,22 +46,6 @@ export function AlertDialog({
4446
/* -----------------------------------------------------------------------------
4547
* Component: AlertDialogContent
4648
* -------------------------------------------------------------------------- */
47-
const alertDialogContentVariants = cva(
48-
[
49-
'bg-background relative rounded-lg border shadow-lg focus:outline-none',
50-
'data-state-open:animate-content-show data-state-closed:animate-content-hide',
51-
],
52-
{
53-
defaultVariants: {
54-
scrollable: false,
55-
},
56-
variants: {
57-
scrollable: {
58-
true: 'flex max-h-full flex-col',
59-
},
60-
},
61-
},
62-
);
6349

6450
export const AlertDialogContent = forwardRef<
6551
React.ElementRef<typeof Content>,

packages/ui/src/alert.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,15 @@
1+
'use client';
2+
13
import type { VariantProps } from 'class-variance-authority';
2-
import { cva } from 'class-variance-authority';
34
import * as React from 'react';
45
import { forwardRef } from 'react';
56
import { twMerge } from 'tailwind-merge';
7+
import { alertVariants } from './cva';
68

79
/* -----------------------------------------------------------------------------
810
* Component: Alert
911
* -------------------------------------------------------------------------- */
1012

11-
const alertVariants = cva(
12-
[
13-
'relative w-full rounded-lg border p-4',
14-
'[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4',
15-
'[&>svg+div]:translate-y-[-3px]',
16-
'[&:has(svg)]:pl-11',
17-
],
18-
{
19-
defaultVariants: {
20-
variant: 'default',
21-
},
22-
variants: {
23-
variant: {
24-
default: ['bg-background text-foreground', '[&>svg]:text-foreground'],
25-
destructive: [
26-
'border-destructive/50 text-destructive dark:border-destructive',
27-
'[&>svg]:text-destructive',
28-
],
29-
},
30-
},
31-
},
32-
);
33-
3413
export const Alert = forwardRef<
3514
React.ElementRef<'div'>,
3615
React.ComponentProps<'div'> & VariantProps<typeof alertVariants>

packages/ui/src/aspect-ratio.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
'use client';
2+
13
export { AspectRatio } from '@radix-ui/react-aspect-ratio';

packages/ui/src/avatar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
'use client';
2+
3+
import { getFirstInitials } from '@codefixlabs/lib';
14
import { Fallback, Image, Root } from '@radix-ui/react-avatar';
25
import * as React from 'react';
36
import { forwardRef } from 'react';
47
import { twMerge } from 'tailwind-merge';
5-
import { getFirstInitials } from '@codefixlabs/lib';
68

79
/* -----------------------------------------------------------------------------
810
* Component: Avatar

packages/ui/src/badge.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
1+
'use client';
2+
13
import type { VariantProps } from 'class-variance-authority';
2-
import { cva } from 'class-variance-authority';
34
import * as React from 'react';
45
import { twMerge } from 'tailwind-merge';
6+
import { badgeVariants } from './cva';
57

68
/* -----------------------------------------------------------------------------
79
* Component: Badge
810
* -------------------------------------------------------------------------- */
911

10-
const badgeVariants = cva(
11-
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold',
12-
{
13-
defaultVariants: {
14-
variant: 'primary',
15-
},
16-
variants: {
17-
variant: {
18-
destructive:
19-
'bg-destructive text-destructive-foreground border-transparent',
20-
outline: 'border-input',
21-
primary: 'bg-primary text-primary-foreground border-transparent',
22-
secondary: 'bg-secondary text-secondary-foreground border-transparent',
23-
},
24-
},
25-
},
26-
);
27-
2812
export function Badge({
2913
className,
3014
variant,

packages/ui/src/button.tsx

Lines changed: 5 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,28 @@
1+
'use client';
2+
13
import type { VariantProps } from 'class-variance-authority';
2-
import { cva } from 'class-variance-authority';
3-
import type { ClassValue } from 'clsx';
44
import { Loader2Icon } from 'lucide-react';
55
import * as React from 'react';
66
import { Children, forwardRef, useMemo } from 'react';
77
import { twMerge } from 'tailwind-merge';
8+
import { buttonVariants, innerButtonVariants } from './cva';
89
import type { IconType } from './icons';
910

1011
/* -----------------------------------------------------------------------------
1112
* Component: Button
1213
* -------------------------------------------------------------------------- */
1314

14-
type ButtonSize = 'lg' | 'md' | 'sm';
15-
16-
type ButtonVariant =
17-
| 'destructive'
18-
| 'ghost'
19-
| 'outline'
20-
| 'primary'
21-
| 'secondary';
22-
23-
const sizes: {
24-
icon: boolean;
25-
sizes: {
26-
className: ClassValue;
27-
size: ButtonSize;
28-
variant: ButtonVariant[];
29-
}[];
30-
}[] = [
31-
{
32-
icon: true,
33-
sizes: [
34-
{
35-
className: 'px-2 h-8',
36-
size: 'sm',
37-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
38-
},
39-
{
40-
className: 'px-1.75 h-8',
41-
size: 'sm',
42-
variant: ['outline'],
43-
},
44-
// ---
45-
{
46-
className: 'px-3 h-10',
47-
size: 'md',
48-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
49-
},
50-
{
51-
className: 'px-2.75 h-10',
52-
size: 'md',
53-
variant: ['outline'],
54-
},
55-
// ---
56-
{
57-
className: 'px-4 h-12',
58-
size: 'lg',
59-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
60-
},
61-
{
62-
className: 'px-3.75 h-12',
63-
size: 'lg',
64-
variant: ['outline'],
65-
},
66-
],
67-
},
68-
{
69-
icon: false,
70-
sizes: [
71-
{
72-
className: 'px-4 h-8',
73-
size: 'sm',
74-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
75-
},
76-
{
77-
className: 'px-3.75 h-8',
78-
size: 'sm',
79-
variant: ['outline'],
80-
},
81-
// ---
82-
{
83-
className: 'px-5 h-10',
84-
size: 'md',
85-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
86-
},
87-
{
88-
className: 'px-4.75 h-10',
89-
size: 'md',
90-
variant: ['outline'],
91-
},
92-
// ---
93-
{
94-
className: 'px-6 h-12',
95-
size: 'lg',
96-
variant: ['primary', 'secondary', 'destructive', 'ghost'],
97-
},
98-
{
99-
className: 'px-5.75 h-12',
100-
size: 'lg',
101-
variant: ['outline'],
102-
},
103-
],
104-
},
105-
];
106-
107-
// Flatten the array and group variants if the size is the same
108-
const compoundSizes = sizes.flatMap<{
109-
className: ClassValue;
110-
icon: boolean;
111-
size: ButtonSize;
112-
variant: ButtonVariant[];
113-
}>(({ icon, sizes: _sizes }) =>
114-
_sizes.map(({ variant, size, className }) => ({
115-
className,
116-
icon,
117-
size,
118-
variant,
119-
})),
120-
);
121-
122-
export const buttonVariants = cva(
123-
[
124-
'relative select-none items-center gap-2 whitespace-nowrap text-sm font-medium transition-colors',
125-
'focus:ring-ring/40 focus:outline-none focus:ring-2',
126-
'data-disabled:cursor-not-allowed',
127-
],
128-
{
129-
compoundVariants: [
130-
{
131-
className: 'data-disabled:bg-opacity-50',
132-
variant: ['primary', 'secondary', 'destructive'],
133-
},
134-
{
135-
className: 'data-disabled:opacity-50',
136-
variant: ['ghost', 'outline'],
137-
},
138-
...compoundSizes,
139-
],
140-
defaultVariants: {
141-
block: false,
142-
icon: false,
143-
justify: 'center',
144-
shape: 'rounded',
145-
size: 'md',
146-
variant: 'primary',
147-
},
148-
variants: {
149-
block: {
150-
false: 'inline-flex',
151-
true: 'flex w-full',
152-
},
153-
icon: {
154-
false: '',
155-
true: '',
156-
},
157-
justify: {
158-
between: 'justify-between',
159-
center: 'justify-center',
160-
},
161-
shape: {
162-
pill: 'rounded-full',
163-
rounded: 'rounded-md',
164-
square: 'rounded-sm',
165-
},
166-
size: {
167-
lg: '',
168-
md: '',
169-
sm: '',
170-
},
171-
variant: {
172-
destructive:
173-
'bg-destructive text-destructive-foreground [&:not([data-disabled])]:hover:bg-destructive/90',
174-
ghost: '[&:not([data-disabled])]:hover:bg-accent',
175-
link: 'text-primary rounded-none hover:underline',
176-
outline:
177-
'border-input [&:not([data-disabled])]:hover:bg-accent [&:not([data-disabled])]:hover:text-accent-foreground border',
178-
primary:
179-
'bg-primary text-primary-foreground [&:not([data-disabled])]:hover:bg-primary/90',
180-
secondary:
181-
'bg-secondary text-secondary-foreground [&:not([data-disabled])]:hover:bg-secondary/90',
182-
},
183-
},
184-
},
185-
);
186-
187-
const innerButtonVariants = cva('h-4 w-4 shrink-0 text-base text-opacity-100', {
188-
defaultVariants: {
189-
loading: false,
190-
},
191-
variants: {
192-
loading: {
193-
false: undefined,
194-
true: 'animate-spin',
195-
},
196-
},
197-
});
198-
19915
export const Button = forwardRef<
20016
React.ElementRef<'button'>,
20117
VariantProps<typeof buttonVariants> &
202-
React.ComponentPropsWithoutRef<'button'> &
203-
VariantProps<typeof innerButtonVariants> & {
18+
React.ComponentPropsWithoutRef<'button'> & {
20419
endIcon?: IconType;
20520
startIcon?: IconType;
20621
classNames?: {
20722
startIcon?: string;
20823
endIcon?: string;
20924
};
25+
loading?: boolean;
21026
}
21127
>(
21228
(

packages/ui/src/calendar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import { Slot } from '@radix-ui/react-slot';
24
import { cx } from 'class-variance-authority';
35
import { format } from 'date-fns';
@@ -30,7 +32,7 @@ import {
3032
useSelectRange,
3133
} from 'react-day-picker';
3234
import { twMerge } from 'tailwind-merge';
33-
import { buttonVariants } from './button';
35+
import { buttonVariants } from './cva';
3436
import type { FormControl } from './form';
3537
import { Input } from './input';
3638
import { Label } from './label';

0 commit comments

Comments
 (0)