toolbar and selection toolbar
A toolbar holds the actions for the content below it: a heading that says what they act on, at most one emphasized action, and a menu for what doesn't fit. The selection toolbar is the same row for a list whose rows can be selected.
when to use
- Above a list, a table or a panel, for the actions on it, under a heading that says what they act on: “2,500 missing”.
- With one emphasized action, the step most people take next. A few standard actions sit beside it, and the rarely used ones wait in the overflow menu.
- The selection toolbar, for a list whose rows can be selected. While nothing is selected, it shows the heading. Once rows are selected, it shows the count, “clear”, and the action for exactly that selection: “grab 8 selected”.
when to use something else
- For the buttons at the end of a form or a dialog. Use buttons in a footer; a modal has its own.
- For the actions of one row. Give each row one action menu.
- For search and filters. Use a filter bar, above the toolbar.
- To move between views. Use tabs, or filter tabs to filter one list.
anatomy
The toolbar:
- Frame. A row with a thin border and square corners. When its content doesn't fit on one line, it wraps onto the next.
- Heading (optional). On the left, taking the free width: what the actions act on, in monospace and lowercase.
- Extra content (optional). Content of your own, between the heading and the actions.
- Actions. On the right, a small gap apart, and all of them small buttons: the emphasized one first (or the danger button, when it is also a danger action), then standard buttons (or danger buttons).
- Overflow. An action menu named “more actions”, last. It holds the actions kept in the menu and, when the toolbar is narrow, every action but the emphasized one.
While rows are selected, a selection toolbar adds:
- Selection bar. The frame turns blue, with a thicker, brighter blue bar on its left edge.
- Count. “8 selected”, in blue, in place of the heading.
- Clear and select all (optional). Small quiet buttons after the count.
- Emphasized action. The one action for this selection.
- Announcement. Not shown on the screen: each change of the count is read out to people who use a screen reader, when it has a pause.
variants and states
one emphasized action
Mark at most one action as emphasized. It comes first, as the emphasized button, or as the danger button when it is also a danger action. A second emphasized action shows as a standard button.
The other actions are standard buttons, or danger buttons for an action that deletes something or can't be undone. Disabled and busy actions look and behave as they do on a button.
overflow
An action can stay in the “more actions” menu at every width. And when the toolbar gets narrow, every action but the emphasized one moves into the menu; the exact width is in the specs. In the menu, a disabled or busy action is a disabled item, and a danger action is a danger item.
selection toolbar
With nothing selected, a selection toolbar shows its heading, which says what the list holds, and no emphasized action. Once rows are selected, it shows:
- The count, such as “8 selected”, with a thousands separator in larger numbers.
- A “clear” button.
- A “select all 2,500” button, when that is offered while only the visible rows are selected.
- The emphasized action for exactly that selection.
Its other actions are never emphasized.
behaviour
- A toolbar is one tab stop, and the left and right arrow keys move between its controls, wrapping around at the ends. home and end jump to the first and the last control.
- The arrow keys reach every control in the toolbar, in order, including those in the heading and in your extra content. In a selection toolbar with rows selected, “clear” comes first. Disabled buttons are skipped, and so is a busy one.
- When actions come and go, the toolbar is still one tab stop.
- “more actions” opens the overflow menu, which works as every action menu does.
- When the control that has focus goes away, such as “clear”, “select all 2,500”, or the emphasized action once the selection is empty, the toolbar itself takes focus. Focus stays where the person was, and the change is announced.
- How rows are selected, what select all covers, when a selection is kept and what happens after an action on a selection: all of that is in selection and bulk actions.
The full keyboard map is on the toolbar's React page.
accessibility
- Name the toolbar. A name is required: the accessible name a screen reader announces. Name what the actions act on, such as “missing episodes”. The heading is not the name.
- Keyboard first. One tab stop and the arrow keys mean that a page with a filter bar, a toolbar and a table takes a few presses of tab to cross, not dozens.
- The overflow menu is an action menu, and its button is named “more actions” unless you name it otherwise.
- A selection toolbar's count is on the screen, and a screen reader reads it once per change, when it has a pause: “8 selected”, or “selection cleared” at zero. Nothing is read when the toolbar first shows.
- The blue frame and the blue count repeat what the count's words say.
Today: “selection cleared” is fixed, in English. The count and “clear” can be translated; the announcement that the selection was cleared can't.
content
- The name. What the actions act on, as a noun phrase: “missing episodes”.
- Heading. What the list holds, with the count: “2,500 missing”.
- Actions. A verb and its object. Actions on a selection carry the count: “grab 8 selected”.
- The emphasized action. The next step for most people. Not the newest action, and not the most dangerous one.
- Overflow. What people rarely need: “export csv”, “sweep settings”.
- Select all. With the whole count: “select all 2,500”.
do and don't
related
- Selection and bulk actions: selecting rows, the count, select all, and the actions on a selection.
- Action menu: the overflow menu, and the actions of one row.
- Filter bar: what narrows the list. It sits above the toolbar.
- Worklist: the page that puts filter tabs, a filter bar, the toolbar and the table together.
specs
| part | spec |
|---|---|
| Frame | Toolbar: a div with role="toolbar", named by label (its aria-label). It wraps (flex-wrap: wrap), at least 45px tall, padding 8px 12px, gaps of 8px between lines and 12px between items, a 1px --border frame, --surface fill, border-radius: 0. It can hold focus itself (tabindex="-1"), with a 2px --focus-ring outline inside its frame on keyboard focus. |
| Heading | heading, on the left, taking the free width: JetBrains Mono 600, 13px, --fg, lowercased with text-transform. |
| Extra content | children, between the heading and the actions. |
| Actions | On the right, 8px apart, every one a size="sm" button (28px): the emphasized one first, variant="primary" (or "danger"), then variant="default" buttons (or "danger"). An action's icon goes in the button's leading slot. |
| Overflow | An ActionMenu, last, named by overflowLabel (default “more actions”). |
| Selection state | SelectionToolbar with selectedCount above 0: the frame turns --state-information-border, with a 3px --cloud-blue rule inset on the left; the count is in --cloud-blue. |
| Clear and select all | size="sm", variant="ghost" buttons after the count. |
| Announcement | A visually hidden aria-live="polite" region in the heading: the count, or “selection cleared” at 0, after every change of selectedCount but not on the first render. |
| setting | in code | what it does |
|---|---|---|
| Emphasized | emphasized: true on an action |
At most one. A second one renders as a standard button, and the console warns. |
| Danger | danger: true |
A danger button, or a danger item in the menu. |
| Always in the menu | overflow: true |
Keeps the action in the menu at every width. |
| Narrow | collapseBelow: 560 (px) by default |
Below this width, measured inside the padding, every action but the emphasized one moves into the menu. Until it has been measured, the toolbar lays out as wide. |
| Disabled, busy | disabled, loading |
As on a button. In the menu, either one makes a disabled item; the arrow keys skip both. |
| Count | selectedCount, written by formatSelected (“8 selected” by default, with thousands separators) |
At 0, the heading shows instead of the count. |
| Clear | onClearSelection, and clearLabel (“clear” by default) |
Shows “clear” after the count while something is selected. |
| Select all | selectAll: { label, onSelect }, or null |
Offers to extend the selection: “select all 2,500”. |
| Action for the selection | primaryAction(n), which returns the action, or null for none |
The one emphasized action of a selection toolbar. Build its label from n. |
| Other actions | actions |
In a selection toolbar, never emphasized. |