60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import { Switch as AriaSwitch, SwitchProps as AriaSwitchProps } from 'react-aria-components';
|
|
|
|
import clsx from 'clsx';
|
|
import { tv } from 'tailwind-variants';
|
|
|
|
export interface SwitchProps extends Omit<AriaSwitchProps, 'children'> {
|
|
children?: ReactNode;
|
|
}
|
|
|
|
const track = tv({
|
|
base: 'flex h-4.5 w-8 box-border px-1 items-center rounded-full transition duration-200 ease-in-out',
|
|
variants: {
|
|
isSelected: {
|
|
false: 'bg-dabeeo-gray-99',
|
|
true: 'bg-dabeeo-green-main',
|
|
},
|
|
isDisabled: {
|
|
true: 'bg-dabeeo-gray-eb',
|
|
},
|
|
isReadOnly: {
|
|
true: 'opacity-50',
|
|
},
|
|
isFocusVisible: {
|
|
true: 'ring-2 ring-offset-2 ring-primary',
|
|
},
|
|
},
|
|
});
|
|
|
|
const handle = tv({
|
|
base: 'h-3 w-3 transform rounded-full outline outline-1 -outline-offset-1 outline-transparent shadow-[0_1px_3px_0_rgba(5,48,48,0.35)] transition duration-200 ease-in-out',
|
|
variants: {
|
|
isSelected: {
|
|
false: 'translate-x-0 bg-white',
|
|
true: 'translate-x-[11px] bg-white',
|
|
},
|
|
},
|
|
});
|
|
|
|
export function Switch({ children, ...props }: SwitchProps) {
|
|
return (
|
|
<AriaSwitch
|
|
{...props}
|
|
className={clsx(
|
|
props.className,
|
|
'relative flex gap-2 items-center text-dabeeo-black-34 text-sm transition [-webkit-tap-highlight-color:transparent] cursor-pointer'
|
|
)}
|
|
>
|
|
{(renderProps) => (
|
|
<>
|
|
<div className={track(renderProps)}>
|
|
<span className={handle(renderProps)} />
|
|
</div>
|
|
{children}
|
|
</>
|
|
)}
|
|
</AriaSwitch>
|
|
);
|
|
}
|