-
-
Notifications
You must be signed in to change notification settings - Fork 393
/
Switch.tsx
55 lines (53 loc) · 1.57 KB
/
Switch.tsx
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
import { ComponentChildren, FunctionalComponent } from 'preact';
import { useState } from 'preact/hooks';
import { HTMLProps } from 'react';
import {
CustomCheckboxContainer,
CustomCheckboxInput,
CustomCheckboxInputProps,
} from '@reach/checkbox';
import '@reach/checkbox/styles.css';
export type SwitchProps = HTMLProps<HTMLInputElement> & {
checked?: boolean;
onChange: (checked: boolean) => void;
className?: string;
children?: ComponentChildren;
role?: string;
};
export const Switch: FunctionalComponent<SwitchProps> = (
props: SwitchProps
) => {
const [checkedState, setChecked] = useState(props.checked || false);
const checked = props.checked ?? checkedState;
const className = props.className ?? '';
return (
<label
className={`sn-component flex justify-between items-center cursor-pointer px-3 ${className}`}
{...(props.role ? { role: props.role } : {})}
>
{props.children}
<CustomCheckboxContainer
checked={checked}
onChange={(event) => {
setChecked(event.target.checked);
props.onChange(event.target.checked);
}}
className={`sn-switch ${checked ? 'bg-info' : 'bg-neutral'}`}
>
<CustomCheckboxInput
{...({
...props,
className: undefined,
children: undefined,
} as CustomCheckboxInputProps)}
/>
<span
aria-hidden
className={`sn-switch-handle ${
checked ? 'sn-switch-handle--right' : ''
}`}
/>
</CustomCheckboxContainer>
</label>
);
};