Skip to content

ToggleButton

A button that stays pressed, alone or in a group (Bold, Italic; Follow).

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Button (toggle, aria-pressed)

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Show the code

Default, code

<ToggleButton>Follow</ToggleButton>

Pressed

Show the code

Pressed, code

<ToggleButton defaultSelected>Following</ToggleButton>

With an icon

Show the code

With an icon, code

<ToggleButton icon={Bell}>Notify me</ToggleButton>

Icon only

Show the code

Icon only, code

<ToggleButton icon={Star} 'aria-label'="Favourite">{undefined}</ToggleButton>

Icon only, pressed

Show the code

Icon only, pressed, code

<ToggleButton
  icon={Star}
  'aria-label'="Favourite"
  defaultSelected
>
  {undefined}
</ToggleButton>

Small

Show the code

Small, code

<div className="flex flex-wrap gap-gap-md">
  <ToggleButton size="sm">Bold</ToggleButton>
  <ToggleButton size="sm" defaultSelected>Bold</ToggleButton>
  <ToggleButton size="sm" icon={Star} aria-label="Favourite" />
  <ToggleButton size="sm" icon={Star} aria-label="Favourite, pressed" defaultSelected />
</div>

Disabled

Show the code

Disabled, code

<ToggleButton isDisabled>Follow</ToggleButton>

Group

Show the code

Group, code

<ToggleButtonGroup aria-label="Show" selectionMode="multiple" defaultSelectedKeys={['open']}>
  <ToggleButton id="open">Open</ToggleButton>
  <ToggleButton id="closed">Closed</ToggleButton>
  <ToggleButton id="draft">Draft</ToggleButton>
</ToggleButtonGroup>

Tokens

The 20 design tokens ToggleButton reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 20 tokens
Tokens ToggleButton reads
TokenValue nowCSS variable
button.disabled.bg…--sd-button-disabled-bg
button.disabled.border…--sd-button-disabled-border
button.disabled.fg…--sd-button-disabled-fg
button.gap…--sd-button-gap
button.height.md…--sd-button-height-md
button.height.sm…--sd-button-height-sm
button.outline.bg…--sd-button-outline-bg
button.outline.bg-hover…--sd-button-outline-bg-hover
button.outline.bg-pressed…--sd-button-outline-bg-pressed
button.outline.border…--sd-button-outline-border
button.outline.fg…--sd-button-outline-fg
button.padding-x.md…--sd-button-padding-x-md
color.bg.brand-subtle…--sd-color-bg-brand-subtle
color.border.brand…--sd-color-border-brand
color.text.default…--sd-color-text-default
motion.duration.fast…--sd-motion-duration-fast
motion.easing.standard…--sd-motion-easing-standard
shape.radius-control…--sd-shape-radius-control
spacing.gap.xs…--sd-spacing-gap-xs
target.min…--sd-target-min

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { ToggleButton, ToggleButtonGroup } from "@superduperui/react"

Props

ToggleButton also takes the props of the React Aria component it’s built on.

ToggleButton props
PropTypeWhat it does
childrenReactNodeVisible label. For an icon-only toggle pass `icon` and `aria-label` instead.
iconLucideIconDecorative Lucide icon before the label (or alone, with aria-label).
size'sm' | 'default'Default 'default'sm 36px visual (44px hit area), default 44px.

When to use it

Use it for

  • Formatting and view toggles in toolbars
  • A state the button itself names (Follow, Mute)

Use something else for

  • A setting that reads as on or off: use Switch
  • Choosing one view of several: use SegmentedControl

Accessibility

Screen readers announce "Bold, toggle button, pressed".

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Keep the label the same when pressed (screen readers announce the pressed state)

This release’s test results

Test results for ToggleButton in this release
axe-core (WCAG A, AA, AAA and best practice)180 runs across every story, theme, density and width: 0 violations
Rendered text contrast115 text runs: 0 below 7:1, lowest 15.48:1
Target size54 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)24 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 5 of 5, Firefox 5 of 5, WebKit 5 of 5

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

ToggleButton keyboard steps
KeyWhat happens
TabTab enters the group
ArrowRightRight moves to the next toggle
SpaceSpace presses it
EnterEnter releases it
ArrowLeftLeft moves back

In Figma

The Figma component is ToggleButton, with Pressed (False, True); State (Default, Hover, Focus, Disabled); Size (Small, Default); Icon only (False, True). The Figma library isn’t published yet.

Figma to code: Pressed → defaultSelected (False = false, True = true); State (Default, Hover, Focus, Disabled = isDisabled); Size → size (Small = "sm", Default = "default"); Label → children when Show label; Icon → icon when Show icon; Icon only (False, True; preview only).