Switch
Binary on/off toggle with controlled and uncontrolled modes.
At a glance
- Renders with
role="switch"on web; maps to RN<Switch>on native, so the platform's native motion + haptics carry over on iOS / Android. - Use Switch for immediate state flips (settings that take effect on toggle). Reach for Checkbox when the user is choosing items in a form they'll submit later.
Preview
checked and defaultChecked
Controlled vs. uncontrolled — same shape as Checkbox.
label
Renders a clickable label next to the track. Pressing the label is the same target as pressing the track itself, with a wider hit area.
Inline label vs Field
The label prop is the inline label (right of the track) — the control's own affordance.
Use it for stand-alone toggles:
For grouped settings with description and error, wrap in <Field>:
See Field for the full API. For custom layouts, use the compound API.
onChange
Fires with the next boolean. Pair with checked for controlled mode,
omit for uncontrolled — the Switch calls it either way.
disabled
Greys out the track and blocks onChange. Forwarded as
aria-disabled so assistive tech narrates "switch, disabled".
asChild
Renders a supplied element as the interactive root. Same composition pattern as Checkbox / Button — pass any focusable element to inherit the Switch's behavior while keeping your own DOM shape.
Accessibility props
When wrapping Switch in <Field>, the following attributes are injected
onto the underlying control automatically:
id— matches thehtmlForof the label generated byField.aria-labelledby— references theField.Labelelement's ID.aria-describedby— referencesField.Descriptionand/orField.Errorwhen present.aria-invalid— set when the enclosingFieldhas a non-nullerror.aria-required— set whenFieldhasrequired={true}.
On native, React Native equivalents are forwarded instead:
accessibilityLabelledBy (mirrors aria-labelledby) and
accessibilityDescribedBy (mirrors aria-describedby).
You can also pass any of these props explicitly when using Switch without a
Field wrapper.
Native preview
Props
| Prop | Type | Default | Description |
|---|---|---|---|
accessibilityDescribedBy | string | — | React Native accessibilityDescribedBy forwarded to the Pressable |
accessibilityLabelledBy | string | — | React Native accessibilityLabelledBy forwarded to the Pressable |
aria-describedby | string | — | aria-describedby forwarded to the Pressable |
aria-invalid | boolean | — | Marks the control as invalid — set by Field.Control when there is an error |
aria-labelledby | string | — | aria-labelledby forwarded to the Pressable |
aria-required | boolean | — | Marks the control as required — set by Field.Control |
asChild | boolean | — | — |
checked | boolean | — | — |
className | string | — | — |
defaultChecked | boolean | false | — |
disabled | boolean | — | — |
id | string | — | DOM id / nativeID forwarded to the Pressable — used by Field.Control |
label | string | — | — |
name | string | — | HTML name attribute (web only) |
onChange | (next: boolean) => void | — | — |
testID | string | — | — |