"use client"; import { type ButtonHTMLAttributes, forwardRef, useState } from "react"; import { cn } from "@/lib/utils"; export type SwitchSize = "sm" | "md"; export interface SwitchProps extends Omit, "onChange" | "value" | "defaultValue"> { /** Controlled on state. */ checked?: boolean; /** Starting state when uncontrolled. Default false. */ defaultChecked?: boolean; /** Called with the next state each time the switch is toggled. */ onCheckedChange?: (checked: boolean) => void; /** Track size. Default "md". */ size?: SwitchSize; } const SIZES: Record = { sm: { track: "h-5 w-9", thumb: "h-4 w-4 group-data-[state=on]:translate-x-4" }, md: { track: "h-6 w-11", thumb: "h-5 w-5 group-data-[state=on]:translate-x-5" }, }; /** * An on and off switch. Put it inside a label and the whole row becomes the * tap target, with no dead space between the text and the track. */ export const Switch = forwardRef(function Switch( { checked, defaultChecked = false, onCheckedChange, size = "md", className, onClick, ...props }, ref, ) { const [uncontrolled, setUncontrolled] = useState(defaultChecked); const isControlled = checked !== undefined; const on = isControlled ? checked : uncontrolled; return ( ); });