Switch
Turns a setting on or off right away. 48 by 24px, with an optional check icon, and hover, focus, read-only, disabled and error states.
Version 0.4.1 ·
Installation
bunx --bun shadcn@latest add @dga/switchInstalls Field too.
Usage
import { Field, FieldContent, FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";
export function UpdatesField() {
return (
<Field orientation="horizontal" className="items-center justify-between">
<FieldContent>
<FieldLabel>Send me updates about this request</FieldLabel>
</FieldContent>
<Switch name="updates" defaultChecked />
</Field>
);
}Use a Switch for a setting that takes effect the moment it is flipped: notifications, a feature on or off. If the choice is only applied when a form is submitted, use Checkbox. Label what the switch does, not its state: "Request updates", not "On".
Anatomy
- Track (
<span role="switch">and a hidden<input>): 48 by 24px. - Thumb: the white circle that slides; it holds the check icon when
iconis set. - Label, helper text and error: from Field. Put the switch after FieldContent to trail it.
Examples
States
Off, on, with a check icon, read-only, disabled and error.
Trailing switch
Put the Switch after FieldContent and use justify-between for a settings list, with the switch at the end of each row.
RTL
The thumb moves along the logical axis: it starts on the right and slides left when on, the way the track reads. Nothing is flipped by hand; a trailing switch sits on the left.
Accessibility
| Key | Action |
|---|---|
| Tab | Moves focus to the switch. |
| Space | Turns it on or off. |
- The
switchrole witharia-checked, and a hidden native input for forms. - The label is from Field; clicking it flips the switch.
- The off track and its white thumb, and the on track and thumb, are 3:1 or better in light and dark (WCAG 1.4.11). State is also shown by the thumb position, not colour alone.
- Focus is a 2px outline 2px outside the track. An error adds a 2px error outline and a message with an icon.
- Respects reduced motion: the thumb moves without animation.
API Reference
Switch
Turns a setting on or off right away (DGA: Switch). Use a Checkbox for choices that are only applied when the form is submitted. Label it with a Field (`orientation="horizontal"`).
| Prop | Type | Default |
|---|---|---|
booleanShows a check mark in the thumb while the switch is on. | false | |
| ||
booleanWhether the switch is currently active. To render an uncontrolled switch, use the `defaultChecked` prop instead. | No default | |
| ||
booleanWhether the switch is initially active. To render a controlled switch, use the `checked` prop instead. | No default | |
| ||
booleanWhether the component should ignore user interaction. | No default | |
| ||
stringIdentifies the field when a form is submitted. | No default | |
| ||
(checked: boolean, details) => voidEvent handler called when the switch is activated or deactivated. | No default | |
| ||
booleanWhether the user should be unable to activate or deactivate the switch. | No default | |
| ||
booleanWhether the user must activate the switch before submitting a form. | No default | |
| ||
Also accepts every prop of the Base UI Switch (opens in a new tab).
Deviations from DGA
- The off track is
control-border(4.8:1) instead of #ccc (1.6:1), with a white thumb (new tokencontrol-thumb). - Hover and press on the on track keep green-600 in dark mode (see Checkbox).
| Change | Reason |
|---|---|
--control-thumb (new) | The Switch thumb is white in both modes. Figma has no token for it (background-white turns dark in dark mode, and the white thumb on the off track would be 1.1:1). |
Checkbox, Radio, Switch: focus ring | Keyboard-only focus (WCAG 2.4.7). The outline follows the control's shape and does not shift the label. |
Switch: off track | #ccc is 1.6:1 on white. control-border is 4.8:1, so the off track and its white thumb pass 3:1. |
Switch: error | The error must be visible on the control as well as in the text, without relying on colour alone. |
Contrast
56 pairs checked · all pass WCAG 2.1 AAShow 14 statesHide
| Variant / state | Light | Dark |
|---|---|---|
| off / track | 4.57:1 3:1 | 3.80:1 3:1 |
| on / track | 4.54:1 3:1 | 3.68:1 3:1 |
| on / track, hovered | 8.18:1 3:1 | 3.68:1 3:1 |
| on / track, pressed | 10.34:1 3:1 | 3.68:1 3:1 |
| focus ring | 17.31:1 3:1 | 17.49:1 3:1 |
| border, error | 4.62:1 3:1 | 4.65:1 3:1 |
| border, read-only | 4.57:1 3:1 | 3.80:1 3:1 |
| off / thumb | 4.77:1 3:1 | 4.59:1 3:1 |
| on / thumb | 4.74:1 3:1 | 4.74:1 3:1 |
| on / thumb, hovered | 8.55:1 3:1 | 4.74:1 3:1 |
| on / thumb, pressed | 10.81:1 3:1 | 4.74:1 3:1 |
| on / check icon | 4.74:1 3:1 | 4.74:1 3:1 |
| label | 14.53:1 AAA | 15.87:1 AAA |
| helper text | 4.77:1 AA | 6.32:1 AA |
Text needs 4.5:1, icons and focus rings 3:1. Disabled states are exempt. Full contrast report