Skip to content

Toggle Group

Shared state for a series of Toggles. Renders a <div role="group">, makes the whole set one tab stop, and owns the list of pressed values.

toggle-group/basic.tsx

Like a radio group this is a keyboard mode as well as a state container. Unlike a radio group, moving does not select: arrowing past a toggle leaves it untouched, and Space or Enter is what presses it. That makes a toggle group safe for choices a RadioGroup is not, including ones that fire a request.

Import

import { Toggle, ToggleGroup } from "@forte-ui/react";

Every toggle in a group needs a value. The group's value is the list of pressed toggles' values, so one without a value can never appear in it — Base UI logs an error in development when that happens.

Examples

Multiple

multiple lets any number of toggles be pressed at once. This is Base UI's own example, styled with our tokens.

toggle-group/multiple.tsx

Without it, pressing one unpresses the rest. Note what that still is not: a radio group. Pressing the pressed toggle turns it off, so an empty selection stays reachable either way — which is exactly why a toggle group is the wrong control for a required choice.

toggle-group/single.tsx

Rendering at balanced quality.

Segmented

segmented puts one padded panel behind the whole set. It is deliberately the same surface, padding and radius that Tabs uses for its pill variant, so a segmented group and a pill tab strip on the same screen read as the same kind of object. Pair it with variant="solid" for the classic filled segmented control, and fullWidth to split the container equally between the toggles.

toggle-group/segmented.tsx

Use segmented when the toggles are alternatives — one strip, one decision. Leave it off when they are neighbours in a toolbar, like the alignment and formatting groups above.

Shared appearance

variant, tone and size set on the group become the default for every toggle inside it, so a strip stays uniform without repeating three props per item. A toggle's own prop still wins.

toggle-group/appearance.tsx

This is React context rather than CSS inheritance, and it has to be. The appearance knobs are declared on each toggle's own root rule — that placement is what lets you re-skin a single toggle, because an element's own declaration beats an inherited one — so a value set on the group would be inherited and then immediately overwritten. The data-* attributes the rules key off are resolved in JavaScript and written onto each toggle.

Orientation

orientation="vertical" stacks the toggles and moves the arrow keys onto the block axis.

toggle-group/orientation.tsx

Controlled

Pass value and onValueChange for a controlled group; defaultValue for an uncontrolled one. The callback receives the new array first and Base UI's event details second.

toggle-group/controlled.tsx

Showing: status, updated.

Disabled

disabled on the group reaches every toggle inside it.

toggle/disabled.tsx

Accessibility

Keyboard interactions
KeyBehaviour
TabMoves focus into the group, landing on the last-focused toggle — or the first one. The whole group is a single tab stop.
ArrowRight then ArrowDownMoves focus to the next toggle without pressing it, wrapping from the last to the first. Only the arrows on the group's own axis are bound.
ArrowLeft then ArrowUpMoves focus to the previous toggle, wrapping from the first to the last.
Home then EndMoves focus to the first or last toggle.
Space then EnterPresses the focused toggle. Moving focus never presses anything.

Disabled toggles are skipped by the arrow keys as well as removed from the tab order. Set loopFocus={false} to stop the arrows wrapping at the ends.

Each toggle still needs its own name too: text children, or an aria-label when it is icon-only. See Toggle for the rest — the pressed state, forced colours and motion all belong to the individual button.

Theming

The group declares its own properties on the group element; the toggles inside are themed through the --forte-toggle-* properties documented on Toggle.

Theming tokens for Toggle
PropertyControlsDefault
--forte-toggle-group-gapGap between toggles. var(--forte-space-1) when segmented.var(--forte-space-2)
--forte-toggle-group-paddingPadding inside the strip. var(--forte-space-1) when segmented.0px
--forte-toggle-group-radiusCorner radius of the strip. var(--forte-radius-4) when segmented.0px
--forte-toggle-group-bgFill behind the strip. var(--forte-color-panel) when segmented.transparent
--forte-toggle-group-border-widthBorder width of the strip.1px
--forte-toggle-group-border-colorBorder colour of the strip.transparent

API reference

ToggleGroup

Props for ToggleGroup
PropTypeDefaultDescription
classNamestringAdditional class name(s). Applied after the internal styles so consumer utilities (e.g. Tailwind) win without needing `!important`.
defaultValuereadonly Value[]The values pressed on mount when uncontrolled.
disabledbooleanfalseDisable every toggle in the group.
fullWidthbooleanfalseStretch the group to fill its container and share the space equally between the toggles. Mostly useful with `segmented`, where an evenly divided strip is the expected shape.
multiplebooleanfalseAllow several toggles to be pressed at once. With it off, pressing one unpresses the rest — but pressing the pressed one still turns it off, so "nothing selected" stays reachable in a way a radio group never allows.
orientationToggleGroupOrientationhorizontalDirection the toggles are laid out in, and the axis the arrow keys move along. Unlike `RadioGroup`'s, this is not layout-only: Base UI binds the arrows to the named axis, so a vertical group answers to Up and Down and leaves Left and Right to the page.
refRef<HTMLDivElement>Ref to the group element. Declared as a prop rather than through `forwardRef` because the component is generic — a `forwardRef` wrapper would erase `Value` and with it the typing of `onValueChange`.
segmentedbooleanfalseDraw the group as a segmented control: one padded panel behind the whole set, with the toggles closed up inside it. Off, the group is just a row of separate buttons — right for a toolbar, where the toggles are neighbours rather than alternatives. Pair it with `variant="solid"` for the classic filled segmented control.
sizeToggleSizemdDefault `size` for every `Toggle` inside the group. A toggle's own `size` still wins.
toneToggleToneprimaryDefault `tone` for every `Toggle` inside the group. A toggle's own `tone` still wins.
valuereadonly Value[]The values of every pressed toggle. Pairs with `onValueChange` for a controlled group; use `defaultValue` for an uncontrolled one. Always an array, including when `multiple` is false — it is then empty or holds one value.
variantToggleVariantsoftDefault `variant` for every `Toggle` inside the group. A toggle's own `variant` still wins.

onValueChange, loopFocus, render and the rest of Base UI's ToggleGroup props pass through unchanged.

Toggle

See Toggle for the full prop table.