import type { ControlSize } from "@charcuterie/tokens"; import type { ReactNode } from "react"; export type SwitchProps = { className?: string; /** * **Initial** only. The `Switch` owns it from then on — the same * uncontrolled contract as `Checkbox` and `SegmentedControl`, so * `onChange` reports the new state and there is no controlled * `checked` prop to keep in step. */ isChecked?: boolean; isDisabled?: boolean; /** * Shows the state at full contrast but refuses to flip it — a * setting you may read here and change elsewhere. Unlike * `isDisabled` it does not dim, and it announces `aria-readonly`. */ isReadOnly?: boolean; /** The visible text, and the switch's accessible name. */ label: ReactNode; onChange?: (isChecked: boolean) => void; size?: ControlSize; }; /** * A boolean that takes effect the moment it is flipped — a setting, * not a form value. * * A `Checkbox` and a `Switch` are the same state kind and a * different affordance, and the split is meaning rather than looks: * a checkbox is a value you submit ("I agree"), a switch is a state * you toggle and live with immediately ("dark mode on"). ARIA gives * the second its own role, and a screen reader announces "on/off" * for a `switch` where it announces "checked/unchecked" for a * checkbox. * * ### A `button role="switch"`, not an `input` * * The sliding track and thumb are the whole point of the affordance, * and a `