Skip to content

Commit a9fc9f1

Browse files
committed
refactor: add component swith
1 parent accdc88 commit a9fc9f1

File tree

6 files changed

+200
-0
lines changed

6 files changed

+200
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { ComponentRef } from 'react';
2+
import { forwardRef } from 'react';
3+
4+
import SwitchRoot from './SwitchRoot';
5+
import SwitchThumb from './SwitchThumb';
6+
import type { SwitchProps } from './types';
7+
8+
const Switch = forwardRef<ComponentRef<typeof SwitchRoot>, SwitchProps>((props, ref) => {
9+
const { children, className, classNames, size, ...rest } = props;
10+
11+
return (
12+
<SwitchRoot
13+
className={className || classNames?.root}
14+
ref={ref}
15+
size={size}
16+
{...rest}
17+
>
18+
<SwitchThumb
19+
className={classNames?.thumb}
20+
size={size}
21+
>
22+
{children}
23+
</SwitchThumb>
24+
</SwitchRoot>
25+
);
26+
});
27+
28+
Switch.displayName = 'Switch';
29+
30+
export default Switch;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Switch } from '@radix-ui/react-switch';
2+
import type { ComponentRef } from 'react';
3+
import { forwardRef } from 'react';
4+
5+
import { cn } from '@/lib/utils';
6+
7+
import { switchVariants } from './switch-varianst';
8+
import type { SwitchRootProps } from './types';
9+
10+
const SwitchRoot = forwardRef<ComponentRef<typeof Switch>, SwitchRootProps>((props, ref) => {
11+
const { className, color, size, ...rest } = props;
12+
13+
const { root } = switchVariants({ color, size });
14+
15+
const mergedCls = cn(root(), className);
16+
17+
return (
18+
<Switch
19+
className={mergedCls}
20+
ref={ref}
21+
{...rest}
22+
/>
23+
);
24+
});
25+
26+
SwitchRoot.displayName = 'SwitchRoot';
27+
28+
export default SwitchRoot;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Thumb } from '@radix-ui/react-switch';
2+
import type { ComponentRef } from 'react';
3+
import { forwardRef } from 'react';
4+
5+
import { cn } from '@/lib/utils';
6+
7+
import { switchVariants } from './switch-varianst';
8+
import type { SwitchThumbProps } from './types';
9+
10+
const SwitchThumb = forwardRef<ComponentRef<typeof Thumb>, SwitchThumbProps>((props, ref) => {
11+
const { className, size, ...rest } = props;
12+
13+
const { thumb } = switchVariants({ size });
14+
15+
const mergedCls = cn(thumb(), className);
16+
17+
return (
18+
<Thumb
19+
className={mergedCls}
20+
id="switch-thumb"
21+
ref={ref}
22+
{...rest}
23+
/>
24+
);
25+
});
26+
27+
SwitchThumb.displayName = 'SwitchThumb';
28+
29+
export default SwitchThumb;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { default as Switch } from './Switch';
2+
export { default as SwitchRoot } from './SwitchRoot';
3+
export { default as SwitchThumb } from './SwitchThumb';
4+
5+
export * from './types';
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// @unocss-include
2+
import { tv } from 'tailwind-variants';
3+
import type { VariantProps } from 'tailwind-variants';
4+
5+
export const switchVariants = tv({
6+
base: [],
7+
defaultVariants: {
8+
color: 'primary',
9+
shape: 'rounded',
10+
size: 'md'
11+
},
12+
slots: {
13+
root: [
14+
`peer shrink-0 inline-flex items-center rounded-full border-0 shadow-sm transition-colors duration-200`,
15+
`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-background`,
16+
`disabled:cursor-not-allowed disabled:opacity-50`,
17+
`data-[state=unchecked]:bg-input`
18+
],
19+
thumb: `flex justify-center items-center rounded-full shadow-lg transition-transform duration-200 bg-background pointer-events-none data-[state=unchecked]:translate-x-0.5`
20+
},
21+
variants: {
22+
color: {
23+
accent: {
24+
root: `data-[state=checked]:bg-accent-foreground/20 focus-visible:ring-accent-foreground/20`
25+
},
26+
carbon: {
27+
root: `data-[state=checked]:bg-carbon focus-visible:ring-carbon`
28+
},
29+
destructive: {
30+
root: `data-[state=checked]:bg-destructive focus-visible:ring-destructive`
31+
},
32+
info: {
33+
root: `data-[state=checked]:bg-info focus-visible:ring-info`
34+
},
35+
primary: {
36+
root: `data-[state=checked]:bg-primary focus-visible:ring-primary`
37+
},
38+
secondary: {
39+
root: `data-[state=checked]:bg-secondary-foreground/20 focus-visible:ring-secondary-foreground/20`
40+
},
41+
success: {
42+
root: `data-[state=checked]:bg-success focus-visible:ring-success`
43+
},
44+
warning: {
45+
root: `data-[state=checked]:bg-warning focus-visible:ring-warning`
46+
}
47+
},
48+
shape: {
49+
rounded: {
50+
root: 'rounded-full',
51+
thumb: 'rounded-full'
52+
},
53+
square: {
54+
root: 'rounded-md',
55+
thumb: 'rounded-sm'
56+
}
57+
},
58+
size: {
59+
'2xl': {
60+
root: 'h-7 w-13',
61+
thumb: 'size-6 data-[state=checked]:translate-x-6.5'
62+
},
63+
lg: {
64+
root: 'h-5.5 w-10',
65+
thumb: 'size-4.5 data-[state=checked]:translate-x-5'
66+
},
67+
md: {
68+
root: 'h-5 w-9',
69+
thumb: 'size-4 data-[state=checked]:translate-x-4.5'
70+
},
71+
sm: {
72+
root: 'h-4.5 w-8',
73+
thumb: 'size-3.5 data-[state=checked]:translate-x-4'
74+
},
75+
xl: {
76+
root: 'h-6 w-11',
77+
thumb: 'size-5 data-[state=checked]:translate-x-5.5'
78+
},
79+
xs: {
80+
root: 'h-4 w-7',
81+
thumb: 'size-3 data-[state=checked]:translate-x-3.5'
82+
}
83+
}
84+
}
85+
});
86+
87+
type SwitchVariants = VariantProps<typeof switchVariants>;
88+
89+
export type SwitchSlots = keyof typeof switchVariants.slots;
90+
91+
export type SwitchShape = NonNullable<SwitchVariants['shape']>;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { SwitchProps as _SwitchRootProps, SwitchThumbProps as _SwitchThumbProps } from '@radix-ui/react-switch';
2+
3+
import type { BaseNodeProps, ClassValue, ThemeColor } from '@/types/other';
4+
5+
import type { SwitchSlots } from './switch-varianst';
6+
7+
export interface SwitchRootProps extends BaseNodeProps<_SwitchRootProps> {
8+
color?: ThemeColor;
9+
}
10+
11+
export type SwitchThumbProps = BaseNodeProps<_SwitchThumbProps>;
12+
13+
export type ClassNames = Partial<Record<SwitchSlots, ClassValue>>;
14+
15+
export interface SwitchProps extends SwitchRootProps {
16+
classNames?: ClassNames;
17+
}

0 commit comments

Comments
 (0)