| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { useState } from 'react'
- import { View } from '@tarojs/components'
- import { cn } from '@/utils/cn'
- interface SwitchProps {
- checked?: boolean
- onChange?: (checked: boolean) => void
- disabled?: boolean
- color?: string
- size?: 'sm' | 'md' | 'lg'
- className?: string
- }
- export function Switch({
- checked = false,
- onChange,
- disabled = false,
- color = '#1976D2',
- size = 'md',
- className,
- }: SwitchProps) {
- const [isChecked, setIsChecked] = useState(checked)
- const handleToggle = () => {
- if (disabled) return
-
- const newValue = !isChecked
- setIsChecked(newValue)
- onChange?.(newValue)
- }
- const sizes = {
- sm: {
- track: 'w-10 h-5',
- thumb: 'w-4 h-4',
- translate: 'translate-x-5',
- },
- md: {
- track: 'w-12 h-6',
- thumb: 'w-5 h-5',
- translate: 'translate-x-6',
- },
- lg: {
- track: 'w-14 h-7',
- thumb: 'w-6 h-6',
- translate: 'translate-x-7',
- },
- }
- const currentSize = sizes[size]
- return (
- <View
- className={cn(
- 'relative inline-flex items-center rounded-full cursor-pointer transition-colors duration-200 ease-in-out',
- currentSize.track,
- isChecked ? '' : 'bg-gray-300',
- disabled && 'opacity-50 cursor-not-allowed',
- className,
- )}
- style={{
- backgroundColor: isChecked ? color : undefined,
- }}
- onClick={handleToggle}
- hoverClass={disabled ? '' : 'opacity-80'}
- >
- <View
- className={cn(
- 'absolute left-1 bg-white rounded-full shadow-lg transition-transform duration-200 ease-in-out',
- currentSize.thumb,
- isChecked ? currentSize.translate : '',
- )}
- />
- </View>
- )
- }
|