import { ReactNode, useId } from "react"; import { FieldSize } from "./fieldShell"; export interface ToggleProps { checked: boolean; onChange: (checked: boolean) => void; /** Label shown beside the switch. */ label?: ReactNode; /** Helper text under the label. */ description?: ReactNode; size?: FieldSize; disabled?: boolean; /** Put the label before the switch instead of after. */ labelPosition?: "left" | "right"; className?: string; /** Accessible name when no visible label is provided. */ ariaLabel?: string; } const TRACK: Record = { sm: "w-8 h-4.5", md: "w-10 h-5.5", lg: "w-12 h-6.5", }; const KNOB: Record = { sm: "w-3.5 h-3.5", md: "w-4.5 h-4.5", lg: "w-5.5 h-5.5", }; const TRANSLATE: Record = { sm: "translate-x-3.5", md: "translate-x-4.5", lg: "translate-x-5.5", }; const LABEL_TEXT: Record = { sm: "text-sm", md: "text-sm", lg: "text-base", }; /** A primary-coloured on/off switch with a smoothly sliding knob. */ export default function Toggle({ checked, onChange, label, description, size = "md", disabled = false, labelPosition = "right", className = "", ariaLabel, }: ToggleProps) { const labelId = useId(); const control = ( ); if (!label && !description) { return
{control}
; } return (
{control}
{label && {label}} {description && {description}}
); }