Toggle
A two-state button that can be either on or off.
When to Use
Use Toggle when you need to:
- Let users switch a single option on or off (bold, italic, bookmark)
- Provide a two-state button in a toolbar or action bar
- Create stateful icon buttons that visually reflect their pressed state
- Build formatting controls for rich-text editors
When Not to Use
- Multiple related options that work together - use Toggle Group
- Settings or preferences with on/off semantics - use Switch
- One-shot actions like submit or navigate - use Button
- Binary choices in forms (agree/disagree) - use Checkbox
Default
A toggle button with custom styling when pressed. Uses data-[state=on] for pressed state styling.
Variants
Available style variants: default (transparent, no border) and outline (visible border with shadow).
Outline
Outline variant with a visible border, ideal for toolbar-style controls.
With Text
Toggle with both an icon and text label. The gap between icon and text is handled automatically.
Sizes
Available size options: sm (32px), default (36px), and lg (40px).
Disabled
Disabled toggles prevent user interaction. Both unpressed and pressed states are shown.
Controlled
Controlled toggle with external state management via pressed and onPressedChange props.
UX & Design Guidelines
Visual Hierarchy
Use variant="default" for toolbar toggles that sit alongside other controls, and variant="outline" when the toggle needs to stand on its own or requires a visible boundary. The pressed state uses bg-accent with text-accent-foreground to clearly differentiate on and off states.
Spacing & Layout
When grouping toggles in a toolbar, use gap-1 for tight formatting toolbars or gap-2 for standard spacing. For related toggle groups, prefer the Toggle Group component which handles spacing and selection logic automatically.
Responsive Behavior
On mobile, consider using size="lg" for better touch targets (minimum 40px). Icon-only toggles should include text labels on larger screens when space permits. Use the min-w-* property to maintain consistent square dimensions for icon-only toggles.
Color & Contrast
The default pressed state uses bg-accent with text-accent-foreground for sufficient contrast. When customizing pressed styles with data-[state=on]: classes, ensure the on/off states have distinct visual contrast. Disabled states reduce opacity to 50% while maintaining readability.
Accessibility
Keyboard Navigation
- Tab — Move focus to/from the toggle
- Space — Toggle the pressed state
- Enter — Toggle the pressed state
Screen Reader Support
- Built on Radix UI Toggle primitive with full ARIA support
- Automatically manages
aria-pressedstate (true/false) - Icon-only toggles require
aria-labelfor screen reader users - Disabled state is announced via the
disabledattribute
Focus Management
Visible focus ring with 3px width using focus-visible:ring-[3px]. Focus states meet WCAG 2.1 Level AA requirements. The ring uses ring-ring/50 with border-ring for consistent theming.
Touch Targets
Default size is 36px height (h-9) with min-w-9, meeting minimum touch target recommendations. Use size="lg" (40px) for critical touch interactions. The min-w-* property ensures square hit areas for icon-only toggles.
ARIA Attributes
{/* Icon-only toggle — requires aria-label */}
<Toggle aria-label="Toggle bold">
<Bold />
</Toggle>
{/* Toggle with visible text — label is read automatically */}
<Toggle aria-label="Toggle italic">
<Italic />
Italic
</Toggle>
{/* Controlled toggle with live region for state feedback */}
<Toggle
pressed={isBold}
onPressedChange={setIsBold}
aria-label="Toggle bold"
>
<Bold />
</Toggle>
<span role="status" className="sr-only">
{isBold ? "Bold enabled" : "Bold disabled"}
</span>Related Components
Toggle Group
Group of toggles for mutually exclusive or multi-select options.
Switch
A control for toggling between on and off, ideal for settings and preferences.
Button
Standard button for one-shot actions like submit, save, or navigate.
Checkbox
A form control for binary choices, typically used in forms and lists.
API Reference
The Toggle component accepts the following props in addition to standard button attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "outline" | "default" | The visual style variant of the toggle. |
| size | "default" | "sm" | "lg" | "default" | The size of the toggle button. |
| pressed | boolean | — | The controlled pressed state of the toggle. |
| defaultPressed | boolean | false | The default pressed state when initially rendered (uncontrolled). |
| onPressedChange | (pressed: boolean) => void | — | Event handler called when the pressed state changes. |
| disabled | boolean | false | When true, prevents user interaction and applies disabled styles. |
| className | string | — | Additional CSS classes to apply to the toggle. |