Toggle
When to use
Section titled “When to use”- A formatting button in an editor: Bold, Italic
- A mode that stays on: Mute, Pin
- A group of options that apply at once: alignment, list or grid view — with ToggleGroup
Not for a setting in a form or a settings list — use a Checkbox or a Switch.
Choosing between rows of controls:
| Component | Use it for | For example |
|---|---|---|
| Toolbar | Several controls acting on one thing, reached with one Tab stop and the arrow keys | An editor’s formatting bar |
| ToggleGroup | A set of Toggles sharing one value | Text alignment, bold / italic / underline |
| Buttons in a row | A few independent actions, each its own Tab stop | Cancel / Save at the end of a form |
Choosing between Checkbox, Switch or Toggle:
| Component | Use it for | For example |
|---|---|---|
| Checkbox | A yes/no choice, or one of several independent options, that applies when the form is submitted | “I agree to the terms”, “Email me updates” |
| Switch | A setting that takes effect the moment it is flipped, with no Save button | “Dark mode”, “Wi-Fi”, “Notifications on” |
| Toggle | A button that stays pressed, usually in a toolbar, for a mode or formatting | “Bold”, “Mute”, “Pin” |
import { useState } from 'react';import { Toggle, ToggleGroup } from '@arun-dev/ui';
export default function ToggleBasics() { const [muted, setMuted] = useState(true); const [align, setAlign] = useState<string[]>(['left']); return ( <div style={{ display: 'flex', flexWrap: 'wrap', gap: 'var(--space-md)', alignItems: 'center' }} > {/* The name stays "Mute notifications"; aria-pressed says whether it's on, and the icon follows the same state. */} <Toggle pressed={muted} onPressedChange={setMuted} aria-label="Mute notifications"> <span aria-hidden>{muted ? '🔕' : '🔔'}</span> Mute </Toggle> {/* One at a time: Tab reaches the pressed one, the arrow keys move along. */} <ToggleGroup aria-label="Alignment" value={align} onValueChange={setAlign}> <Toggle value="left">Left</Toggle> <Toggle value="center">Center</Toggle> <Toggle value="right">Right</Toggle> </ToggleGroup> <ToggleGroup aria-label="Style" multiple defaultValue={['bold']}> <Toggle value="bold">B</Toggle> <Toggle value="italic">I</Toggle> <Toggle value="underline">U</Toggle> </ToggleGroup> </div> );}Toggle is a <button aria-pressed>: a button that stays pressed, such as Mute or Bold. Screen
readers say “pressed” or “not pressed”.
To show the state in the content too, as the bell does, control the Toggle with pressed and
onPressedChange and pick the icon from the same state. Keep the name the same in both states
(“Mute notifications”): aria-pressed already says whether it’s on, and a name that changed to
“Unmute” would describe the opposite action.
ToggleGroup
Section titled “ToggleGroup”ToggleGroup holds the values of its pressed Toggles:
- One at a time by default: pressing one releases the others, and pressing the pressed one releases it.
- Several with
multiple. - One Tab stop: Tab reaches the pressed Toggle (or the first), and the arrow keys move along, skipping disabled ones.
<ToggleGroup aria-label="Alignment" value={align} onValueChange={setAlign}> <Toggle value="left">Left</Toggle> <Toggle value="center">Center</Toggle></ToggleGroup>Inside a Toolbar, a ToggleGroup’s Toggles join the toolbar’s arrow keys.
Toggle
Section titled “Toggle”| Prop | Type | Default | Description |
|---|---|---|---|
pressed | boolean | Controlled state. Provide onPressedChange alongside it. | |
defaultPressed | boolean | false | Initial state when uncontrolled. |
onPressedChange | (pressed: boolean) => void | Called on every press. | |
value | string | Its value in a ToggleGroup: pressed while the group holds it. | |
disabled | boolean | false | Not pressable, and skipped by the arrow keys. |
className | string | Concatenated with the component's own classes, never replacing them. | |
render | ReactElement | Element or component to render instead of the default. Props, className, event handlers and ref are merged onto it. | |
ref | Ref<HTMLElement> | Ref to the rendered element. Merged with any ref on the render element. | |
…rest | HTMLAttributes | Anything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM. |
ToggleGroup
Section titled “ToggleGroup”| Prop | Type | Default | Description |
|---|---|---|---|
value | string[] | Controlled: the pressed Toggles' values. | |
defaultValue | string[] | [] | Initial value when uncontrolled. |
onValueChange | (value: string[]) => void | Called on every press. | |
multiple | boolean | false | Lets more than one be pressed. Without it, pressing one releases the others. |
disabled | boolean | false | Disables every Toggle. |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Which arrow keys move between the Toggles. |
className | string | Concatenated with the component's own classes, never replacing them. | |
render | ReactElement | Element or component to render instead of the default. Props, className, event handlers and ref are merged onto it. | |
ref | Ref<HTMLElement> | Ref to the rendered element. Merged with any ref on the render element. | |
…rest | HTMLAttributes | Anything else is spread onto the rendered element, so id, aria-*, data-* and event handlers all reach the DOM. |