Actions

ToggleButton

Icon-only two-state toggle and its group — pressed icons, variant shift, single- or multi-select toolbars. For labeled toggles, use ToggleTextButton.

Base UI


ToggleButton is the icon-only control with a persistent pressed state. Pass restingIcon (required); optional pressedIcon swaps in when pressed, otherwise the resting glyph stays. Every instance needs aria-label or aria-labelledby. For a visible text label (Bold, Monthly, Sync), use ToggleTextButton instead.

variant defaults to flat at rest; pressedVariant can shift the treatment while pressed so the on state reads clearly in a quiet toolbar. interpolateIcons opts into a short crossfade and rotate between icons; otherwise the swap is instant. Reach for IconButton when there is no pressed state to keep.

When related toggles share one selection model, wrap them in ToggleGroup. Each child needs a distinct value plus an accessible name; children may be ToggleButton, ToggleTextButton, or both. The group root takes value / defaultValue / onValueChange as string[], and multiple for multi-select. Label the group with aria-label or aria-labelledby so assistive tech understands the cluster.


Anatomy

Import the component and assemble its parts:

import { ToggleButton, ToggleGroup, ToggleTextButton } from '@viraui/react';

<ToggleGroup>
  <ToggleButton />
  <ToggleTextButton />
</ToggleGroup>

A lone ToggleButton is valid outside the group. Related selection needs ToggleGroup as the host.


When to use

  • Pin, favorite, view-mode, or formatting controls that stay on until toggled off
  • Related icon toggles that share one selection model (ToggleGroup)
  • Dual icons or a pressed variant so the on state is obvious at a glance

When not to use

  • A labeled two-state toggle with visible text → ToggleTextButton
  • A one-shot click with no pressed state → IconButton
  • A labeled boolean setting that applies immediately → Switch
  • Tabbed panel navigation → Tabs
  • A labeled commit action (Save, Delete) → Button

  • ToggleTextButton — labeled pressed toggles and mixed groups
  • IconButton — fire-and-forget icon actions
  • Button — labeled commits and cancel rows
  • Switch — labeled on/off settings
  • Tabs — switching content panels

Common examples

Icons

restingIcon is required. Pair it with pressedIcon when the pressed state should read as a different glyph (fill weight, lock open, sun after moon). Omit pressedIcon when the same icon is enough and only aria-pressed / variant carry the state.

Pressed variant

Default resting chrome is flat. Pass pressedVariant when the pressed state should look filled or secondary so the on state reads clearly in a quiet toolbar. Turn on interpolateIcons for a short crossfade and rotate between the two icons instead of an instant swap.

On press

onPressedChange is the hook for side effects when the pressed state flips: persist a favorite, fire analytics, show a toast, or celebrate the moment. The demo below uses a short confetti burst as a stand-in for that reaction; swap the body of the callback for whatever the product needs.

In a group

ToggleGroup coordinates exclusive pressed values across ToggleButton children. Give each child a value; use defaultValue (or controlled value / onValueChange) as a string[]. Flat alone barely shows pressed, so pair with pressedVariant (or a pressedIcon) when the on state must read clearly. Wrap the group in a Surface when you want a bordered toolbar shell; spacing between items is owned by the group.

Multi-select

Turn on multiple when several children can stay pressed together (formatting toolbars). Values still move as string[].

Ask your agent

Add a pin toggle and a favorite toggle to this note card toolbar. Each should look pressed when active and swap to a filled icon. Label each control for screen readers.

Last updated on

On this page