@biem/ui

Toggle Group

A set of two-state buttons that lets users press one option or several.

A toggle group joins several two-state buttons into one control and tracks which of them are pressed. Users press one item at a time by default, and pressing another item releases the one before it. Unlike a radio group, a toggle group can be empty, because pressing the pressed item again releases it. The group is a single tab stop, and the arrow keys move focus between its items.

Usage

toggle-group-default.tsx
import { ToggleGroup, ToggleGroupItem } from "@biem/ui/components/ui/toggle-group";

export function ToggleGroupDefault() {
	return (
		<ToggleGroup aria-label="Stock level">
			<ToggleGroupItem value="in-stock">In stock</ToggleGroupItem>
			<ToggleGroupItem value="low-stock">Low stock</ToggleGroupItem>
			<ToggleGroupItem value="out-of-stock">Out of stock</ToggleGroupItem>
		</ToggleGroup>
	);
}

Examples

Multiple

Filters often work together, for example when users narrow a product list to several categories at once. With multiple, pressing an item no longer releases the others, so users press as many items as the task needs and release each one on its own.

Pressed by Default

A view rarely starts from nothing, because most lists open with the filter that users apply most often. Through defaultValue, the matching items are pressed when the view appears, and users adjust the selection from there.

Controlled

When other parts of the interface depend on the selection, the application holds it itself. The selection then follows value and onValueChange, so a saved view can restore the pressed items and a reset action can release all of them at once.

Outline

In a dense filter bar, items that stand out only once they are pressed are easy to overlook. Set to "outline", variant gives every item a visible boundary, so users recognize each option as something to press before they have pressed any of them.

Small

Above a table or inside a card header, a toggle group shares little space with the content it filters. With size set to "sm", every item takes less room, so the control stays secondary to the figures.

Default Size

Forms, dialogs and page headers call for a toggle group of regular scale, the same in every product. Items take the size "default" unless another one is set, and size set to "default" on the group states it for all of them at once.

Large

One choice can shape a whole screen, such as switching a dashboard between the stores of a region. Given the size "lg", every item gains weight, so users find that choice at once.

Custom Spacing

Every layout has its own density, and a toggle group adapts to it. Through spacing, the gap between the items follows the spacing unit of the system, so a larger value separates the options more clearly and a smaller one keeps them close together.

Without Spacing

Closely related options, such as the levels of detail of a report, read best as one control. Set to 0, spacing joins the items, so users perceive the group as a whole and each item as one of its positions.

Outline without Spacing

The joined form gains clarity when each option keeps a boundary of its own. Combined with variant set to "outline", spacing set to 0 lets neighboring items share one border, so the group reads as a single segmented control in which every option stays distinct.

Vertical

Long option names or a narrow sidebar leave no room for a row. With orientation set to "vertical", the items stack in a column, and users move between them with the up and down arrow keys.

With Icon

Options that users switch between many times a day become familiar at a glance. An icon helps them recognize each option before they read it, and the label keeps the meaning clear for users who meet the option for the first time.

Disabled

While the data behind a view is still loading, its filters have nothing to act on. Marked as disabled, the toggle group ignores every press and drops out of the keyboard order, while the current selection stays visible and assistive technology receives the disabled state.

Disabled Item

Some options do not apply everywhere, for example a pickup service that a particular store does not offer. Set on a single item, disabled takes that option out of reach, and keyboard focus passes over it while users choose freely among the others.

Invalid

A form can require a choice before users continue, for example the type of a price change. Through aria-invalid on its items, the group marks the choice as invalid, so users see where the form needs their attention before they submit it.

API Reference

ToggleGroup

Propvalue
Typereadonly string[]
Default–
DescriptionSets the values of the pressed items and makes the toggle group controlled. Update it in onValueChange.
PropdefaultValue
Typereadonly string[]
Default–
DescriptionSets the values of the items that are pressed at first render. The toggle group then tracks the pressed items itself.
ProponValueChange
Type(groupValue: string[], eventDetails: ToggleGroupChangeEventDetails) => void
Default–
DescriptionRuns when users press or release an item. It receives the values of the items that are pressed afterwards.
Propmultiple
Typeboolean
Defaultfalse
DescriptionLets users press several items at the same time. Without it, pressing an item releases the pressed one.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from pressing or releasing any item and exposes the disabled state to assistive technology.
Propvariant
Type"default" | "outline"
Default–
DescriptionSets the visual style of all items. Outline draws a border around each item. Without it, each item uses its own variant.
Propsize
Type"default" | "sm" | "lg"
Default–
DescriptionSets the dimensions of all items. Without it, each item uses its own size.
Propspacing
Typenumber
Default2
DescriptionSets the gap between the items as a multiple of the spacing unit. With 0, the items join: only the two ends of the group keep rounded corners, and outline items share their inner borders.
Proporientation
Type"horizontal" | "vertical"
Default"horizontal"
DescriptionSets the direction in which the group lays out its items. Horizontal places them in a row, vertical stacks them in a column.
ProploopFocus
Typeboolean
Defaulttrue
DescriptionReturns focus to the first item when users move past the last one with the arrow keys, and to the last item when they move back past the first one.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the toggle group with another component.

ToggleGroupItem

Propvalue
Typestring
Default–
DescriptionIdentifies the item in value, defaultValue and onValueChange of the toggle group. Without it, the item gets a generated ID.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from pressing or releasing the item and exposes the disabled state to assistive technology. A disabled toggle group disables the item as well.
ProponPressedChange
Type(pressed: boolean, eventDetails: ToggleChangeEventDetails) => void
Default–
DescriptionRuns when users press or release the item, before onValueChange of the toggle group runs. It receives the state that follows.
Proppressed
Typeboolean
Default–
DescriptionHas no effect inside a toggle group. The value of the toggle group decides whether the item is pressed.
PropdefaultPressed
Typeboolean
Defaultfalse
DescriptionHas no effect inside a toggle group. The defaultValue of the toggle group decides whether the item is pressed at first render.
Propvariant
Type"default" | "outline"
Default"default"
DescriptionSets the visual style of the item. It applies only while the toggle group sets no variant.
Propsize
Type"default" | "sm" | "lg"
Default"default"
DescriptionSets the dimensions of the item. It applies only while the toggle group sets no size.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the item with another component.
PropnativeButton
Typeboolean
Defaulttrue
DescriptionDeclares whether the rendered element is a native button. Set it to false when render returns a different element.