"use client" import * as React from "react" import { Loader2Icon } from "lucide-react" import { cn } from "@/lib/utils" export type SwitchProps = Omit< React.ComponentPropsWithoutRef<"button">, "onChange" | "value" > & { checked?: boolean defaultChecked?: boolean onCheckedChange?: (checked: boolean) => void size?: "sm" | "md" | "lg" loading?: boolean invalid?: boolean label?: React.ReactNode description?: React.ReactNode labelPlacement?: "start" | "end" | "top" | "bottom" switchClassName?: string labelClassName?: string descriptionClassName?: string } const switchSizeClassName = { sm: "h-5 w-9", md: "h-6.5 w-11.5", lg: "h-8 w-14", } satisfies Record, string> const thumbSizeClassName = { sm: "size-4 data-[state=checked]:translate-x-4.5 data-[state=unchecked]:translate-x-0.5", md: "size-5 data-[state=checked]:translate-x-5.5 data-[state=unchecked]:translate-x-0.5", lg: "size-6 data-[state=checked]:translate-x-7 data-[state=unchecked]:translate-x-1", } satisfies Record, string> const Switch = React.forwardRef( ( { className, checked, defaultChecked = false, onCheckedChange, size = "md", loading = false, invalid = false, label, description, labelPlacement = "end", switchClassName, labelClassName, descriptionClassName, disabled, onClick, ...props }, ref ) => { const isControlled = checked !== undefined const [internalChecked, setInternalChecked] = React.useState(defaultChecked) const currentChecked = isControlled ? checked : internalChecked const isDisabled = disabled || loading const handleClick: React.MouseEventHandler = (event) => { if (isDisabled) return const nextChecked = !currentChecked if (!isControlled) { setInternalChecked(nextChecked) } onCheckedChange?.(nextChecked) onClick?.(event) } const control = ( ) if (!label && !description) return control const labelBlock = ( {label ? {label} : null} {description ? {description} : null} ) return ( ) } ) Switch.displayName = "Switch" export { Switch }