| @@ -11,59 +11,62 @@ type SwitchProps = { | |||
| className?: string | |||
| } | |||
| const Switch = ({ onChange, size = 'md', defaultValue = false, disabled = false, className }: SwitchProps) => { | |||
| const [enabled, setEnabled] = useState(defaultValue) | |||
| useEffect(() => { | |||
| setEnabled(defaultValue) | |||
| }, [defaultValue]) | |||
| const wrapStyle = { | |||
| lg: 'h-6 w-11', | |||
| l: 'h-5 w-9', | |||
| md: 'h-4 w-7', | |||
| sm: 'h-3 w-5', | |||
| } | |||
| const Switch = React.forwardRef( | |||
| ({ onChange, size = 'md', defaultValue = false, disabled = false, className }: SwitchProps, | |||
| propRef: React.Ref<HTMLButtonElement>) => { | |||
| const [enabled, setEnabled] = useState(defaultValue) | |||
| useEffect(() => { | |||
| setEnabled(defaultValue) | |||
| }, [defaultValue]) | |||
| const wrapStyle = { | |||
| lg: 'h-6 w-11', | |||
| l: 'h-5 w-9', | |||
| md: 'h-4 w-7', | |||
| sm: 'h-3 w-5', | |||
| } | |||
| const circleStyle = { | |||
| lg: 'h-5 w-5', | |||
| l: 'h-4 w-4', | |||
| md: 'h-3 w-3', | |||
| sm: 'h-2 w-2', | |||
| } | |||
| const circleStyle = { | |||
| lg: 'h-5 w-5', | |||
| l: 'h-4 w-4', | |||
| md: 'h-3 w-3', | |||
| sm: 'h-2 w-2', | |||
| } | |||
| const translateLeft = { | |||
| lg: 'translate-x-5', | |||
| l: 'translate-x-4', | |||
| md: 'translate-x-3', | |||
| sm: 'translate-x-2', | |||
| } | |||
| return ( | |||
| <OriginalSwitch | |||
| checked={enabled} | |||
| onChange={(checked: boolean) => { | |||
| if (disabled) | |||
| return | |||
| setEnabled(checked) | |||
| onChange?.(checked) | |||
| }} | |||
| className={classNames( | |||
| wrapStyle[size], | |||
| enabled ? 'bg-components-toggle-bg' : 'bg-components-toggle-bg-unchecked', | |||
| 'relative inline-flex flex-shrink-0 cursor-pointer rounded-[5px] border-2 border-transparent transition-colors duration-200 ease-in-out', | |||
| disabled ? '!opacity-50 !cursor-not-allowed' : '', | |||
| className, | |||
| )} | |||
| > | |||
| <span | |||
| aria-hidden="true" | |||
| const translateLeft = { | |||
| lg: 'translate-x-5', | |||
| l: 'translate-x-4', | |||
| md: 'translate-x-3', | |||
| sm: 'translate-x-2', | |||
| } | |||
| return ( | |||
| <OriginalSwitch | |||
| ref={propRef} | |||
| checked={enabled} | |||
| onChange={(checked: boolean) => { | |||
| if (disabled) | |||
| return | |||
| setEnabled(checked) | |||
| onChange?.(checked) | |||
| }} | |||
| className={classNames( | |||
| circleStyle[size], | |||
| enabled ? translateLeft[size] : 'translate-x-0', | |||
| 'pointer-events-none inline-block transform rounded-[3px] bg-components-toggle-knob shadow ring-0 transition duration-200 ease-in-out', | |||
| wrapStyle[size], | |||
| enabled ? 'bg-components-toggle-bg' : 'bg-components-toggle-bg-unchecked', | |||
| 'relative inline-flex flex-shrink-0 cursor-pointer rounded-[5px] border-2 border-transparent transition-colors duration-200 ease-in-out', | |||
| disabled ? '!opacity-50 !cursor-not-allowed' : '', | |||
| className, | |||
| )} | |||
| /> | |||
| </OriginalSwitch> | |||
| ) | |||
| } | |||
| > | |||
| <span | |||
| aria-hidden="true" | |||
| className={classNames( | |||
| circleStyle[size], | |||
| enabled ? translateLeft[size] : 'translate-x-0', | |||
| 'pointer-events-none inline-block transform rounded-[3px] bg-components-toggle-knob shadow ring-0 transition duration-200 ease-in-out', | |||
| )} | |||
| /> | |||
| </OriginalSwitch> | |||
| ) | |||
| }) | |||
| Switch.displayName = 'Switch' | |||