Toolbar

A row or column of related controls, such as actions, filters or formatting, with optional leading, center and trailing regions.
Stable
Web
iOS
Android
@advui/core
Source
JSX
<Toolbar aria-label="Actions">
  <Toolbar.Group aria-label="History">
    <IconButton size="sm" aria-label="Undo" icon={<RotateCcwIcon />} />
    <IconButton size="sm" aria-label="Redo" icon={<RotateCwIcon />} />
  </Toolbar.Group>
  <Toolbar.Separator />
  <Toolbar.Group aria-label="File">
    <IconButton size="sm" aria-label="Copy" icon={<CopyIcon />} />
    <IconButton size="sm" aria-label="Download" icon={<DownloadIcon />} />
  </Toolbar.Group>
</Toolbar>
role
orientation
variant
size
align
distribute

Installation

pnpm
pnpm add @advui/core
npm
npm install @advui/core

Usage

import { Button, Toolbar } from '@advui/core'

<Toolbar aria-label="Project actions" variant="outline">
  <Button size="sm">New</Button>
  <Button size="sm" variant="outline">Edit</Button>
  <Toolbar.Separator />
  <Button size="sm" variant="outline">Delete</Button>
</Toolbar>

Examples

Action toolbar

Controls as children, in a row.

Groups and separators

`Toolbar.Group` keeps related actions together; `Toolbar.Separator` divides them.

Search toolbar

`leading`, `center` and `trailing`. The center takes the free space; the field fills it up to `maxWidth`.

Users

Data table toolbar

A title and count, then a filter field and actions at the end. `ghost` sits flush above a table; `wrap` moves the actions below on phones.

Users

128

Bulk actions

A filled bar for the selected rows. Text alone is as tall as a bar of buttons.
3 selected

Formatting toolbar

`role="toolbar"`: one Tab stop, and the arrow keys move across the Toggle Groups and buttons.

Vertical editor toolbar

A column of tools with tooltips to the side; Up and Down move between them.

Variants

`default`, `outline`, `filled` and `ghost` style the container only.
default
outline
filled
ghost

Sizes

The size sets gap, padding and height; the buttons are given the same size.

Custom styling

A pill: style props for the background, border color, radius and padding.

Wrapping on narrow screens

In a phone-width frame, `wrap` moves the field and the actions onto their own lines; the actions stay at the end edge.

Orders

API reference

Toolbar

PropTypeDefaultDescription
role'group' | 'toolbar''group'`group`: a named set of controls, each its own Tab stop; right for bars with fields. `toolbar`: the WAI-ARIA toolbar, one Tab stop with the arrow keys moving between controls (web); for buttons, toggles and menus.
aria-labelstring—Names the bar, e.g. "Formatting". Recommended; needed when a page has several.
aria-labelledbystring—The id of a visible heading that names the bar, in place of `aria-label`.
orientation'horizontal' | 'vertical''horizontal'A row or a column. Sets the arrow keys of `role="toolbar"`, the direction of groups and of separators. A column hugs its controls (`alignSelf="flex-start"`).
variant'default' | 'outline' | 'filled' | 'ghost''default'The container only: `default` the page background (opaque, for sticky bars), `outline` adds a border, `filled` a muted surface, `ghost` no fill, border or padding, for a bar inside a card or panel. Controls keep their own look.
size'sm' | 'md' | 'lg''md'Gap, padding and minimum height (a control of the same size plus the padding). Controls keep their own `size`: set it on them too.
align'start' | 'center' | 'end' | 'stretch' | 'baseline'or a breakpoint map'center' in a row, 'stretch' in a columnWhere controls sit across the bar (the cross axis), in groups and regions too. A value or a map such as `{ base: "stretch", md: "center" }`.
distribute'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'or a breakpoint map'start'How free space is shared along the bar (the main axis). With `center` or `trailing`, that region takes the free space instead.
wrapbooleanfalseLet controls wrap onto more lines when the bar is too narrow, in groups and regions too. Turn it on for bars that must fit phone widths.
leadingReactNode—Content at the start edge, such as a title or a back button. A string is shown as Text.
centerReactNode—Content that takes the free space between the others, centered in it: a title, a search field (give it `flex={1}`), a Toggle Group.
trailingReactNode—Content kept at the end edge, such as the main actions. A fragment holds several.
gapSpaceTokens | numberfrom `size`Space between controls and between regions.
paddingSpaceTokens | numberfrom `size`, none for `ghost``paddingHorizontal`, `paddingVertical` and the shorthands work too.
backgroundColorColorTokensfrom `variant`Overrides the variant surface.
borderColorColorTokens'border' (outline)Overrides the outline color. Other variants show it with a `borderWidth`.
borderRadiusRadiusTokens | number'lg'Corner radius of the container.

Toolbar.Group

Related controls kept together, with a tighter gap than the toolbar. A `role="group"` that takes the toolbar orientation, alignment and wrapping. Any other style prop works too.
PropTypeDefaultDescription
aria-labelstring—Names the group, e.g. "History".
orientation'horizontal' | 'vertical'the toolbar orientationLay this group out the other way, such as a column of zoom buttons.
gapSpaceTokens | numberfrom the toolbar's `size`Space between the controls in the group.

Toolbar.Separator

A 1px line between groups, across the toolbar direction (vertical in a row). Built on Separator.
PropTypeDefaultDescription
decorativebooleantrueHidden from assistive technology. Set `false` for `role="separator"`, when the line separates meaningful sets.

Regions

Each region given gets one box; a missing one adds nothing. Children go between leading and center.

GivenLayout
children onlyThe children, unwrapped, laid out by distribute.
leading + trailingLeading at the start; trailing takes the free space and keeps its content at the end.
leading + center + trailingThe center takes the free space and centers its content in it.
center + trailingNo empty start box: the center starts at the edge.

Accessibility

  • By default a group named by aria-label: every control keeps its own Tab stop and its own name.
  • role="toolbar" is the WAI-ARIA toolbar on web: one Tab stop (the control used last, else the first), and the arrow keys along the orientation, Home and End move between enabled controls, wrapping at the ends. It sets aria-orientation. Use it for buttons, toggles, Toggle Groups, checkboxes and menu triggers.
  • In a toolbar, text fields, selects, sliders and spin buttons keep their own Tab stop and their arrow keys (the caret, the value); the arrow keys pass over them. With several fields, keep the default group.
  • Keys a control uses first are left to it: an open menu (portalled content is ignored), or any handler that prevents the default. A Toggle Group inside a toolbar hands its arrow keys to the toolbar, so they move out of the group; Space or Enter chooses.
  • Disabled controls are skipped by the arrow keys. Toolbar has no disabled of its own: disable controls one by one, or put fields in a disabled Form.
  • Separators are decorative (hidden from assistive technology) unless decorative={false}. Groups are role="group"; name them when the name helps.
  • Toolbar never clips its content, so focus rings stay visible; it sets no fixed height, so larger text grows it.
Keyboard interactions
KeyAction
Tab`group`: moves through the controls one by one. `toolbar`: moves into the toolbar, to a field in it, and out.
Arrow Right / Arrow Left`toolbar`, horizontal: the next or previous control (mirrored right-to-left).
Arrow Down / Arrow Up`toolbar`, vertical: the next or previous control.
Home / End`toolbar`: the first or last control.

Responsive behavior

Toolbar fills the width of a column and sizes to its content in a row. On narrow screens leading and center shrink first (a title wraps, a search field with flex={1} narrows); trailing keeps its size. On web, leading, trailing and a text center never shrink below their content, so they do not run into each other; a center holding a control that cannot shrink (a Toggle Group) needs wrap. Give bars that must fit phone widths wrap: controls and regions move onto new lines, a wrapped trailing region wraps its own controls, and it stays at the end edge (the left one in right-to-left layouts). align and distribute take breakpoint maps; for anything else use flat values such as gap="2 md:3". Toolbar never turns controls into a menu: show a Dropdown Menu for the overflow yourself (with Show / Hide).

Platform notes

Web
A div with role="group" or role="toolbar"; the arrow keys are web only. Fields, sliders and nested toolbars are left alone, and so are keys from portalled content such as an open menu.
iOS
The container is not one accessible element (no accessible), so VoiceOver reaches each control; role and aria-label go to the native view. There are no arrow keys.
Android
Same as iOS, for TalkBack.
Since v0.13.0Last updated Nov 2, 2026Edit this page on GitHub