Skip to content

Actions

Toolbar

A labelled strip of controls that share one tab stop.

When to use it: Use it when several related controls would otherwise each cost a Tab press.

On this page

Example

Toolbar.tsxtsx
import { ToggleButton, ToggleButtonGroup } from "@comp0/react";
import { Toolbar } from "@comp0/react";
import { BoldIcon, ItalicIcon, UnderlineIcon } from "@heroicons/react/16/solid";

export function Example() {
  return (
    <Toolbar
      aria-label="Text formatting"
      className="flex items-center gap-2 rounded border border-zinc-950/10 p-1.5 dark:border-white/10"
    >
      <ToggleButtonGroup
        type="multiple"
        defaultValue={["bold"]}
        aria-label="Text style"
        className="flex gap-1"
      >
        <ToggleButton
          value="bold"
          aria-label="Bold"
          className="rounded px-3 py-2.5 text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          <BoldIcon className="size-4" aria-hidden="true" />
        </ToggleButton>
        <ToggleButton
          value="italic"
          aria-label="Italic"
          className="rounded px-3 py-2.5 text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          <ItalicIcon className="size-4" aria-hidden="true" />
        </ToggleButton>
        <ToggleButton
          value="underline"
          aria-label="Underline"
          className="rounded px-3 py-2.5 text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          <UnderlineIcon className="size-4" aria-hidden="true" />
        </ToggleButton>
      </ToggleButtonGroup>
      <span aria-hidden="true" className="h-6 w-px bg-zinc-950/10 dark:bg-white/10" />
      <ToggleButtonGroup
        type="single"
        defaultValue="left"
        aria-label="Alignment"
        className="flex gap-1"
      >
        <ToggleButton
          value="left"
          className="rounded px-3 py-2.5 text-base text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 sm:text-sm dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          Left
        </ToggleButton>
        <ToggleButton
          value="center"
          className="rounded px-3 py-2.5 text-base text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 sm:text-sm dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          Center
        </ToggleButton>
        <ToggleButton
          value="right"
          className="rounded px-3 py-2.5 text-base text-zinc-950 data-selected:bg-teal-100 data-selected:text-teal-950 sm:py-2 sm:text-sm dark:text-zinc-50 dark:data-selected:bg-teal-950 dark:data-selected:text-teal-50"
        >
          Right
        </ToggleButton>
      </ToggleButtonGroup>
    </Toolbar>
  );
}

Anatomy

Dashed frames are invisible state providers; shaded shapes own real DOM. Numbered pins match the list below.

A wireframe sketch of the assembled component. Each numbered marker matches a part in the list that follows.

  1. Toolbar

    Row of controls that shares one tab stop; arrow keys move between them. Owns a DOM element.

  2. ToggleButtonGroupOptional

    Optional selection group inside the toolbar; it announces the relationship and can manage which values are on. Owns a DOM element.

  3. ToggleButtonOptional

    Native button that owns one press target. Owns a DOM element.

Step by step

  1. 1

    Add the main part

    Wrap the controls in Toolbar and give it an aria-label.

  2. 2

    Add the supporting parts

    Group related toggles in ToggleButtonGroup so their relationship is announced.

  3. 3

    Make the behavior clear

    Pick orientation to match the layout; arrow keys follow it automatically.

    Exampletsx
    <Toolbar aria-label="Text formatting"><ToggleButtonGroup type="multiple" aria-label="Text style"><ToggleButton value="bold">Bold</ToggleButton></ToggleButtonGroup></Toolbar>

Keyboard

Moves into the toolbar to the last-used control; Tab again leaves.
Moves to the next control without wrapping. · horizontal
Moves to the previous control without wrapping. · horizontal
Moves to the next control. · vertical
Moves to the previous control. · vertical
Home
Moves to the first control.
End
Moves to the last control.
Presses the focused control.
Space
Presses the focused control.

Forms and accessibility

A toolbar does not create form values; its controls submit their own.

Accessibility checklist

  • Give the toolbar an aria-label that names the task, such as Text formatting.
  • Keep controls in a visual order that matches the arrow-key order.
  • Nested composites like a listbox or menu keep their own arrow keys; do not double-handle them.

API reference

Importtsx
import { Toolbar, ToggleButton, ToggleButtonGroup } from "@comp0/react";

Toolbar

DOM element

Row of controls that shares one tab stop; arrow keys move between them.

PropTypeDescription
aria-labelstringNames the toolbar for assistive technology.
orientation"horizontal" | "vertical"Arrow-key direction, announced via aria-orientation; defaults to "horizontal".

ToggleButtonGroup

OptionalDOM element

Optional selection group inside the toolbar; it announces the relationship and can manage which values are on.

PropTypeDescription
aria-labelstringNames the group for assistive technology.
type"single" | "multiple"Whether the group keeps one value or many.
valuestring | string[]Controlled selection: a string for single, a string[] for multiple.
defaultValuestring | string[]Initial selection: a string for single, a string[] for multiple.
onChange(value: string | string[]) => voidReceives the next selection; "" when a single group empties.

ToggleButton

OptionalDOM element

Native button that owns one press target.

PropTypeDescription
valuestringIdentifies the button inside a selection-managing group.
disabledbooleanRemoves the button from the toolbar's arrow-key order.

Style hooks

Attributes that appear while a state is true. Target them with Tailwind data variants such as data-open:bg-zinc-100, or with any CSS selector.

[data-orientation]

on Toolbar

The arrow-key direction.
[data-selected]

on ToggleButton

The button is on.

Keep exploring