Toggle
A React source recipe with Base UI behavior and the public TIS Toggle classes and tokens.
Design
Functional preview
Running with the React source recipe distributed through shadcn and based on Base UI.
Loading functional preview…
Open the React · shadcn/Base UI playground
Anatomy
1
2
3
4
1 Input (
2 Track — CSS background that changes color based on checked state.
3 Thumb — CSS pseudo-element that slides left/right.
4 Content Frame (
.ds-toggle) — styled <input type="checkbox"> with role="switch".2 Track — CSS background that changes color based on checked state.
3 Thumb — CSS pseudo-element that slides left/right.
4 Content Frame (
.ds-toggle__content) — wraps label, description and helper text.
Default
With description and helper text
Sizes
Disabled
States
| State | CSS trigger | Visual change | Token |
|---|---|---|---|
| Off | --- | Neutral track with dark thumb | component.toggle.track.fill.off.default, component.toggle.thumb.fill.off.default |
| Off hover | :hover | Darker neutral track/thumb | component.toggle.track.fill.off.hover, component.toggle.thumb.fill.off.hover |
| On | :checked | Primary track with light thumb | component.toggle.track.fill.on.default, component.toggle.thumb.fill.on.default |
| On hover | :checked:hover | Darker primary track | component.toggle.track.fill.on.hover, component.toggle.thumb.fill.on.hover |
| Focus | :focus-visible | 2px outline ring | component.toggle.focus-ring.radius.default + component.focus-ring.* |
| Disabled | [disabled] | Muted track, thumb and label | component.toggle.track.fill.*.disabled, semantic.content.disabled |
Usage
When to use
- The setting takes effect immediately when turned on or off.
- The current state must remain visible after interaction.
When not to use
- The choice is only applied when a form is submitted; use Checkbox.
- The person must choose one alternative among several; use Radio.
React composition
import {
Switch,
SwitchContent,
SwitchLabel,
SwitchTitle,
} from "@/components/ui/switch"
<SwitchLabel>
<Switch name="alerts" defaultChecked />
<SwitchContent>
<SwitchTitle>Alertas de segurança</SwitchTitle>
</SwitchContent>
</SwitchLabel>Implementation
- Status
- Beta
- Distribution
- Source via shadcn
Installation
Configure the namespace once in the React integration guide.
npx shadcn@latest add @tis/switchpnpm dlx shadcn@latest add @tis/switchyarn dlx shadcn@latest add @tis/switchbunx --bun shadcn@latest add @tis/switchPublic contract
- Registry item
@tis/switch- Provider
- Base UI
- Distribution
- Source copied into the application
- Status
- Beta
Accessibility
Keyboard interaction
| Key | Action |
|---|---|
Tab | Moves focus to the toggle |
Space | Toggles on/off |
Enter | Does NOT toggle (standard switch behavior) |
Disabled toggles ([disabled]) are removed from tab order automatically by the browser.
Accessibility
| WCAG criterion | Requirement | Status |
|---|---|---|
| 4.1.2 Name, Role, Value (A) | role="switch" + aria-checked managed by native checkbox | ✓ |
| 2.4.11 Focus Appearance (AA) | Focus ring visible via :focus-visible | ✓ |
| 2.5.8 Target Size min (AA) | Label extends click target beyond the toggle itself | ✓ |
| 1.4.1 Use of Color (A) | Position + color both communicate state (thumb slides left/right) | ✓ |
ARIA attributes summary
role="switch" — required on the checkbox so screen readers announce it as a switch.aria-checked — managed automatically by the native <input type="checkbox">.Textual content must be inside
.ds-toggle__content.
Output responsibility
Preserve Base UI semantics and test real content, focus visibility, and accessible names in the consuming application.
Validation evidence
Covered by its independent Storybook output plus browser, responsive, keyboard, Axe, and bundle checks.