Switch
Turns a setting on or off, with an optional label and description.
import { Switch } from '@aksornproject/aksara-ui'Basic switch
Without a label the Switch renders the track, the thumb and a hidden input. checked, defaultChecked and onCheckedChange work as in Base UI, and onCheckedChange receives the next boolean first. A bare switch needs an aria-label.
<Switch checked={on} onCheckedChange={setOn} aria-label="Show answers" />Label and description
label renders a <label> linked to the hidden input. Clicking it toggles the switch, and it names the switch. description renders under the label and is linked with aria-describedby. TypeScript accepts description, labelPosition and labelSpacing only next to a label.
<Switch
label="Remember me"
description="Save my login details for next time."
/>Settings rows
labelPosition="start" puts the text before the switch, in the DOM as well as on screen. labelSpacing="spread" fills the parent and pins the switch to the far end. The default, hug, fits the text up to 384px wide.
<div className="flex w-full max-w-spacing-384 flex-col gap-spacing-16">
<Switch
label="Email digests"
description="A summary of class activity every Friday."
labelPosition="start"
labelSpacing="spread"
defaultChecked
/>
<Switch
label="Homework reminders"
labelPosition="start"
labelSpacing="spread"
/>
</div>Sizes
medium is 32 by 20px and the default. large is 40 by 24px. The thumb grows when the switch turns on.
<Switch aria-label="Medium, off" />
<Switch aria-label="Medium, on" defaultChecked />
<Switch size="large" aria-label="Large, off" />
<Switch size="large" aria-label="Large, on" defaultChecked />Success status
status="success" recolours the on track and the focus ring. It draws an X in the thumb while off and a check while on.
<Switch status="success" aria-label="Verified, off" />
<Switch status="success" aria-label="Verified, on" defaultChecked />Loading
loading draws a spinner in the thumb, sets aria-busy and blocks every toggle. Focus stays on the switch. Use it while a change waits for the server.
<Switch
label="Sync grades"
checked={on}
loading={saving}
onCheckedChange={save}
/>Icons
checkedIcon and uncheckedIcon fill the thumb while on and while off. Leave one out to keep the status default. Pass null to clear it, such as the X of a success switch.
<Switch
size="large"
aria-label="Notifications"
defaultChecked
checkedIcon={<IconInterfaceEssentialBell3 />}
uncheckedIcon={<IconInterfaceEssentialBellCrossDelete />}
/>
<Switch
status="success"
size="large"
aria-label="Verified"
uncheckedIcon={null}
/>States
disabled greys the switch. The off track is pale with a border and a grey thumb, and the on track is grey with a white thumb. Its cursor is not-allowed. readOnly keeps the default colours without hover and blocks toggling.
<div className="flex flex-col gap-spacing-16">
<Switch label="Disabled" disabled />
<Switch label="Disabled and on" disabled defaultChecked />
<Switch label="Read-only" readOnly defaultChecked />
</div>Accessibility
- The switch has
role="switch"andaria-checked. Space and Enter toggle it. - Name every switch with
labeloraria-label. The types do not require a name, so nothing warns you when it is missing. descriptionjoinsaria-describedbyafter any ids you pass.- The icons and the spinner are hidden from screen readers. The state comes from
aria-checked. - The focus ring draws on keyboard focus only. The deprecated
focusedprop draws it without focus. - The thumb and track stop animating under
prefers-reduced-motion.
API
Switch
className styles the track and thumbClassName the thumb. SwitcherProps is an alias of the same type. Use SwitchProps for type annotations.
Prop
Type