// preview in
saved for every page

Toolbar

A row of related controls, such as the formatting buttons of an editor, that takes one Tab stop. The arrow keys move between them.

Built on Base UIPattern WAI-ARIA ToolbarClient componentSource ↗
minimal · light · #3fa34d
orientation
loopFocus
disabled

Installation

Set up Camaleo once (Installation), then import what you need. It renders on the client.

import { Toolbar, ToolbarGroup, ToolbarButton, ToolbarToggle, ToolbarLink, ToolbarInput, ToolbarSeparator } from "@camaleo/react";

Anatomy

A div with role="toolbar". Only one control in it is in the Tab order at a time; the arrow keys move that spot. A ToggleGroup inside joins the same order when its toggles render through ToolbarButton.

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above. Click into one, then use Tab and the arrow keys.

minimal · light · #3fa34d
Opening hours for the holidaysFrom 12/24 to 01/02 the shop opens from 9 AM to 2 PM. Orders placed online ship on 01/05.
2 selected
  • #4821Padaria Estrela$186.40
  • #4822Café Aurora$92.00
  • #4823Mercado Sol$412.75

Actions for selected rows

Select orders and press Export. The search field sits next to the toolbar, not inside it: it searches the table, not the selection, so it keeps its own Tab stop.

Store floor planTool: Pen

Vertical tool palette

With orientation="vertical" the Up and Down arrows move focus. The tools are a ToggleGroup, so only one is pressed at a time.

Icon buttons with names

Every icon-only button needs an aria-label. A tooltip with the same words shows that name to sighted people too.

Ana Ribeiro03/12/2026March price listHi! Attached are the new prices for the 250 g bags. Can you check them before Friday?

Overflow into More

Narrow the window. Under 420 px only Reply and Reply all stay; everything else moves into the More menu instead of wrapping.

Nothing to undo yet.

Disabled but still reachable

Disabled toolbar buttons stay in the arrow-key order, so people find Undo and hear why it is off. Pass focusableWhenDisabled={false} to skip one.

A field inside the toolbar

Type a page number and press Enter. ToolbarInput joins the arrow-key order; inside it the arrows move the caret and leave the field only at either end of the text.

Home pageDraft · edited by Ana

Links next to buttons

ToolbarLink goes to another page and ToolbarButton acts on this one; both share the same arrow-key order.

In context

These are whole pieces of UI you can copy, in the skin you picked.

Ana Ribeiro03/12/2026
March price listHi! Attached are the new prices for the 250 g bags. Can you check them before Friday?

Email readerCard · Toolbar · Tooltip · Menu · Avatar
Files
  • Contracts—
  • invoice-0326.pdf182 KB
  • price-list-april.xlsx48 KB
  • storefront.jpg2.4 MB
File managerCard · Toolbar · ToggleGroup · Tooltip · Menu
storefront.jpg · 2400 × 1600
100%
Image viewerCard · Toolbar · Tooltip

Guidelines

DoGroup related controls.

History, formatting and insert each get a ToolbarGroup with a name, split by separators.

Don’tOne long row in no order.

Bold next to Undo next to Image: people scan the whole row every time.

DoWords for uncommon actions.

Bold and Undo are known by their icons. "Levels" and "Vignette" are not.

Don’tIcons only, for actions nobody recognises.

Screen readers hear the names, but everyone else has to guess, or hover each one.

Props

PropTypeDefaultDescription
aria-labelstring—Names the toolbar, for example "Text formatting".
disabledboolean—Disables every control in the toolbar.
orientation"horizontal" | "vertical"'horizontal'Which arrow keys move focus: Left and Right, or Up and Down. Also lays the toolbar out as a column.
loopFocusbooleantrueWhether the arrow keys wrap from the last control to the first.

ToolbarToggle takes pressed and is controlled: flip it in onClick. ToolbarButton takes disabled and focusableWhenDisabled (default true). ToolbarGroup takes disabled and an aria-label. ToolbarInput takes the props of <input>; name it with aria-label.

Styling hooks

Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the toolbar itself.

Attributes

data-orientationhorizontal · vertical
aria-pressed · data-pressedon a pressed ToolbarToggle
data-disabledon a disabled control
data-focusableon a disabled control that stays focusable

Tokens it reads

Color

--cml-border-control--cml-border-subtle--cml-brand-50--cml-brand-700--cml-fg--cml-fg-secondary--cml-focus-ring--cml-surface-raised

Shape & size

--cml-border-width--cml-radius-control

Type & motion

--cml-font-body

This component only

--cml-item-hover--cml-toolbar-bg--cml-toolbar-btn-size--cml-toolbar-radius--cml-toolbar-shadow--cml-toolbar-toggle-active-fg
/* bigger targets in the drawing app */
.canvas-tools [data-slot="toolbar"] {
  --cml-toolbar-btn-size: 2.5rem;
}

Accessibility

TabMoves into the toolbar, to the control that had focus last, and then out of it. The whole toolbar is one Tab stop.
Right Arrow / Left ArrowMoves to the next or previous control, toggles in a ToggleGroup included. From the last one it wraps to the first (loopFocus).
Down Arrow / Up ArrowThe same, in a toolbar with orientation="vertical". Left and Right do nothing there.
Enter / SpaceActivates the button, presses or releases the toggle, or opens the menu with focus on its first item.
Home / EndMoves to the first or last control. In a ToolbarInput they move the caret instead.
EscapeIn a menu opened from the toolbar, closes it and puts focus back on its button.
Was this page helpful? · Edit this page on GitHub