A button that stays pressed until pressed again, for turning a mode on or off, like Bold or Mute. Group several with ToggleButtonGroup for single or multiple choice.
import { ToggleButton } from "@rdloom/react";
export default function ToggleButtonBasicExample() {
return <ToggleButton>Pin to top</ToggleButton>;
}Installation
npx rdloom add toggle-buttonCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/toggle-button.jsonWorks, but without upgrade tracking.
Usage
import { ToggleButton } from "@rdloom/react";
<ToggleButton>Pin to top</ToggleButton>Group multiple
import { ToggleButton, ToggleButtonGroup } from "@rdloom/react";
export default function ToggleButtonGroupMultipleExample() {
return (
<ToggleButtonGroup label="Text style" selectionMode="multiple" defaultSelectedKeys={["bold"]}>
<ToggleButton id="bold">Bold</ToggleButton>
<ToggleButton id="italic">Italic</ToggleButton>
<ToggleButton id="underline">Underline</ToggleButton>
</ToggleButtonGroup>
);
}Icon only
import { BellIcon, GlobeIcon, ImageIcon, ToggleButton, ToggleButtonGroup } from "@rdloom/react";
export default function ToggleButtonIconOnlyExample() {
return (
<ToggleButtonGroup label="Show in the feed" selectionMode="multiple" defaultSelectedKeys={["images"]}>
<ToggleButton id="images" aria-label="Images">
<ImageIcon />
</ToggleButton>
<ToggleButton id="links" aria-label="Links">
<GlobeIcon />
</ToggleButton>
<ToggleButton id="alerts" aria-label="Alerts">
<BellIcon />
</ToggleButton>
</ToggleButtonGroup>
);
}Outline
import { ToggleButton, ToggleButtonGroup } from "@rdloom/react";
export default function ToggleButtonOutlineExample() {
return (
<div className="flex flex-col items-start gap-4">
<ToggleButton variant="outline">Mute</ToggleButton>
<ToggleButtonGroup label="Alignment" variant="outline" defaultSelectedKeys={["left"]}>
<ToggleButton id="left">Left</ToggleButton>
<ToggleButton id="center">Center</ToggleButton>
<ToggleButton id="right">Right</ToggleButton>
</ToggleButtonGroup>
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
sizeControl height, from the shared control sizes. | "sm" | "md" | "lg" | "md" |
variantDefault is filled when pressed; outline keeps a visible border. | "default" | "outline" | "default" |
isSelectedControlled pressed state. | boolean | none |
defaultSelectedPressed at first when uncontrolled. | boolean | false |
onChangeCalled when the pressed state changes. | (isSelected: boolean) => void | none |
isDisabledDisables the button. | boolean | false |
childrenText or an icon. An icon-only button needs an aria-label. | node | none |
Accessibility
Role button, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Tab moves to the button; in a group, to the group
- Space or Enter toggles the focused button
- In a group, arrow keys move focus between buttons
Screen readers announce
- Announced as a toggle button, pressed or not pressed
- In a single-choice group, as a radio button, checked or not checked
What your code must do
- A toggle button exposes aria-pressed (in a single-choice group, the group is a radiogroup and each button a radio)
- The pressed state is shown by fill and weight, not only by color
- An icon-only button has an accessible name
- A group has an accessible name
Guidelines
Use it when
- A mode that stays on: bold, mute, pin
- A toolbar of formatting options, several allowed at once
Avoid it when
- An on or off setting inside a form: use Switch or Checkbox
- Mutually exclusive views of data: use SegmentedControl
- A one-time action: use Button
Don't
- Changing the label when pressed as well as the state, which reads as the opposite
- Icon-only buttons with no accessible name
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-surface-default--rd-color-surface-subtle--rd-color-border-default--rd-color-border-strong--rd-color-action-primary--rd-color-action-on-primary--rd-color-text-default--rd-color-focus-ring--rd-radius-control