visual-novel-web/src/components/ui/inputs/switch.tsx

59 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { cn } from '@/lib';
import { useControllableValue } from 'ahooks';
import { InputLeft } from '.';
import { Switch as SwitchPrimitive } from 'radix-ui';
const { Root, Thumb } = SwitchPrimitive;
type SwitchProps = {
value?: boolean;
onChange?: (value: boolean) => void;
icon?: any;
text?: string;
} & React.HTMLAttributes<HTMLDivElement>;
export default function Switch(props: SwitchProps) {
const {
icon,
text,
onChange: onChangeProps,
value: valueProps,
...rest
} = props;
const [value, onChange] = useControllableValue(props);
return (
<div {...rest} className={cn('input-view justify-between', rest.className)}>
<InputLeft icon={icon} text={text} />
<Root
checked={value}
onCheckedChange={onChange}
className={cn(
'relative inline-flex h-[28px] w-[52px] shrink-0 items-center',
'cursor-pointer rounded-full',
'transition-colors duration-200 ease-in-out',
'focus-visible:ring-2 focus-visible:ring-white/20 focus-visible:outline-none',
'disabled:cursor-not-allowed disabled:opacity-50',
// 未选中状态 - 灰色背景
'bg-white/20',
// 选中状态 - 绿色背景
'data-[state=checked]:bg-[rgb(0,110,74)]' // 注意RGB 值之间不能有空格
)}
>
<Thumb
className={cn(
'pointer-events-none block h-[24px] w-[24px] rounded-full',
'bg-white shadow-lg',
'transition-transform duration-200 ease-in-out',
// 未选中时在左侧2px 偏移)
'translate-x-[2px]',
// 选中时移到右侧52px - 24px - 2px = 26px
'data-[state=checked]:translate-x-[26px]'
)}
/>
</Root>
</div>
);
}