-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSwitch.tsx
More file actions
60 lines (54 loc) · 1.53 KB
/
Copy pathSwitch.tsx
File metadata and controls
60 lines (54 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { useState } from 'react';
import { COLORS, SwitchColor } from '@/shared/lib/colors';
type Props = Omit<React.ComponentProps<'button'>, 'onClick'> & {
/**
* color of the switch.
* @default 'primary'
*/
color?: SwitchColor;
checked?: boolean;
defaultChecked?: boolean;
onCheckedChange?: (checked: boolean) => void;
};
export function Switch({
color = 'primary',
checked,
defaultChecked = false,
onCheckedChange,
className,
disabled,
...props
}: Props) {
const [uncontrolledChecked, setUncontrolledChecked] = useState(defaultChecked);
const isChecked = checked ?? uncontrolledChecked;
const handleClick = () => {
if (disabled) return;
const next = !isChecked;
if (checked === undefined) {
setUncontrolledChecked(next);
}
onCheckedChange?.(next);
};
return (
<button
{...props}
type="button"
role="switch"
disabled={disabled}
onClick={handleClick}
aria-checked={isChecked}
data-state={isChecked ? 'checked' : 'unchecked'}
className={[
'group flex h-3.5 w-7 items-center rounded-full shadow-lg',
'data-[state=checked]:bg-[var(--switch-color)]',
'data-[state=unchecked]:bg-gray-500',
className,
]
.filter(Boolean)
.join(' ')}
style={{ '--switch-color': COLORS[color] } as React.CSSProperties}
>
<span className="h-5 w-5 -translate-x-1.5 rounded-full bg-white shadow-inner drop-shadow-md duration-100 group-data-[state=checked]:translate-x-3.5" />
</button>
);
}