On this page
Import
import { Toolbar } from '@envsemble/envui';
Usage
Toolbar.Root, named by its aria-label, holds Toolbar.Button, Toolbar.Link, Toolbar.Group and Toolbar.Separator.
- A Toolbar.Button takes its
iconand itslabel, which names it and shows in its tooltip with itsshortcut, such asCtrl+B, announced asaria-keyshortcuts. - With
pressedit is a toggle, announced as pressed and drawn selected. - Its
variantis Button's,ghostby default from the toolbar, andpendingreplaces the icon with a spinner. - A Toolbar.Link takes an
href, through the link component ofLinkProvider, with itsiconandlabel. - A Toolbar.Group, named by its own
aria-label, holds controls that belong together.
import { useState } from 'react';
import { Toolbar } from '@envsemble/envui';
import { IconFormatBold } from '@envsemble/envui/icons/FormatBold';
import { IconFormatItalic } from '@envsemble/envui/icons/FormatItalic';
import { IconFormatListBulleted } from '@envsemble/envui/icons/FormatListBulleted';
import { IconFormatListNumbered } from '@envsemble/envui/icons/FormatListNumbered';
import { IconRedo } from '@envsemble/envui/icons/Redo';
import { IconUndo } from '@envsemble/envui/icons/Undo';
export default function FormattingToolbar() {
const [bold, setBold] = useState(false);
const [italic, setItalic] = useState(true);
return (
<Toolbar.Root aria-label="Formatting">
<Toolbar.Group aria-label="Text style">
<Toolbar.Button
icon={<IconFormatBold />}
label="Bold"
shortcut="Ctrl+B"
pressed={bold}
onClick={() => setBold((current) => !current)}
/>
<Toolbar.Button
icon={<IconFormatItalic />}
label="Italic"
shortcut="Ctrl+I"
pressed={italic}
onClick={() => setItalic((current) => !current)}
/>
</Toolbar.Group>
<Toolbar.Separator />
<Toolbar.Group aria-label="Lists">
<Toolbar.Button icon={<IconFormatListBulleted />} label="Bulleted list" />
<Toolbar.Button icon={<IconFormatListNumbered />} label="Numbered list" />
</Toolbar.Group>
<Toolbar.Separator />
<Toolbar.Button icon={<IconUndo />} label="Undo" shortcut="Ctrl+Z" />
<Toolbar.Button icon={<IconRedo />} label="Redo" shortcut="Ctrl+Shift+Z" disabled />
</Toolbar.Root>
);
}Orientation and size
orientation is horizontal, the default, or vertical, and sets which arrow keys move.
sizeissm,mdorlg; without it the buttons take their container's control height.loopFocus, on by default, moves from the last control to the first and back.tooltipDelayis how long, in milliseconds, the pointer rests on a button or link before its tooltip opens, 400 by default, as Tooltip'sdelay; keyboard focus opens it at once.disabledon Toolbar.Root or a Toolbar.Group disables every control inside, links included.
A Surface with radius="full" floats a small toolbar over content, as the ViewControls example does:
<Surface
padding={1}
radius="full"
render={<Toolbar.Root aria-label="Diagram view" size="sm" tooltipDelay={0} />}
style={{ inlineSize: 'fit-content' }}
>
<Toolbar.Button icon={<IconZoomOut />} label="Zoom out" shortcut="Ctrl+-" />
<Toolbar.Button icon={<IconZoomIn />} label="Zoom in" shortcut="Ctrl+=" />
<Toolbar.Separator />
<Toolbar.Link href="/help/diagrams" icon={<IconHelp />} label="Diagram help" />
</Surface>
Buttons of your own
Buttons inside a toolbar take the ghost variant unless they set another.
- A Button of the application's own keeps its own tab stop, outside the arrow keys' path.
- A Toolbar.Button can be the
triggerof a Menu.Root or a Popover, for a dropdown in the toolbar: it stays in the arrow keys' path, with its name in its tooltip, which stays closed while its popup is open.
Other bars
A bar with a field, a Select or labelled actions is a Row:
<Row wrap align="center" justify="between">for a section's heading and its actions.- PageHeader's
toolbarfor a page's search, filters and primary action, as the PageToolbar example does: a Row whose field keeps its arrow keys, every control a tab stop, the primary action at the end. - A TopBar with
titleBarfor a window's title bar, with small ghost buttons in itsactions.
<PageHeader
title="Tasks"
toolbar={
<Row wrap align="center" justify="between" gap={3}>
<Row wrap align="center" gap={3}>
<SearchField label="Search tasks" placeholder="Search tasks" />
<SegmentedControl
aria-label="Status"
value={status}
onValueChange={setStatus}
items={statuses}
/>
</Row>
<Button startIcon={<IconAdd />}>New task</Button>
</Row>
}
/>
Composition
The parts are the toolbar, env-toolbar; its groups, env-toolbar-group; its buttons and links, env-toolbar-button; its separators, env-toolbar-separator; and a button's tooltip, env-toolbar-tooltip. render on Toolbar.Root or Toolbar.Group renders it as another element, such as a ButtonGroup that connects its buttons, or onto a Surface that floats it.
Accessibility
You provide
- An
aria-labelon the toolbar, and on groups that share a name. - The behaviour behind each button and shortcut.
envUI provides
role="toolbar"witharia-orientation, and a group role on each group.- One tab stop, with disabled buttons and links out of the arrow keys' path.
- Names from
label,aria-pressedon toggles andaria-keyshortcutsfromshortcut.
Props
Toolbar.Root
A row, or a column, of controls for one subject, such as a text editor's formatting: one tab stop, with the arrow keys moving between its controls (the APG toolbar pattern). Buttons the application puts inside take the ghost variant unless they set another.
| Prop | Type | Description |
|---|---|---|
aria-label | string | Names the toolbar for assistive technology, such as Formatting. |
orientationDefault 'horizontal' | 'horizontal''vertical' | The direction the controls run in, and which arrow keys move between them. |
size | 'sm''md''lg' | The height of the buttons inside, as on every control: sm, md or lg in the current scale. Without it, the control height of the container. |
disabledDefault false | boolean | Disables every control inside. |
loopFocusDefault true | boolean | Whether the arrow keys move from the last control to the first and back. |
tooltipDelayDefault 400 | number | Milliseconds the pointer rests on a button or link before its tooltip opens, as Tooltip's delay; keyboard focus opens it at once. 0 shows every name at once, for a toolbar people scan by pointing, such as a canvas's view controls. |
render | ReactElement | Another element to render the toolbar as, such as a ButtonGroup that connects its buttons; the toolbar's class, attributes and keyboard handling merge into its props. |
children | ReactNode | The controls: Toolbar.Button, Toolbar.Link, Toolbar.Group and Toolbar.Separator. |
Also accepts the native props of <div>, such as ref, className and aria-* attributes.
Toolbar.Group
Controls of a toolbar that belong together, such as the text styles.
| Prop | Type | Description |
|---|---|---|
aria-label | string | Names the group, such as Text style, where its controls belong together. |
disabledDefault false | boolean | Disables every control in the group. |
render | ReactElement | Another element to render the group as, such as a ButtonGroup. |
Also accepts the native props of <div>, such as ref, className and aria-* attributes.
Toolbar.Separator
A line between groups of a toolbar's controls, across the toolbar's direction.
No props of its own.
Also accepts the native props of <div>, such as ref, className and aria-* attributes.
Toolbar.Button
An icon-only button of a toolbar, named by its label, which a tooltip shows; disabled, it leaves the arrow keys' path.
| Prop | Type | Description |
|---|---|---|
iconrequired | ReactNode | The icon, such as FormatBold. |
labelrequired | string | The action's name, such as Bold: assistive technology announces it, and the tooltip shows it on hover and focus. |
pressed | boolean | For a button that turns something on and off, such as Bold: whether it is on. It is announced as pressed and drawn selected. Leave it out for a button that acts once, such as Undo. |
shortcut | string | The keyboard shortcut that does the same, such as Ctrl+B, with keys joined by +: the tooltip shows it, and aria-keyshortcuts announces it, in ARIA's key names, such as Control+B. A sequence, such as Ctrl+K Ctrl+B, shows its keys without the attribute, as in Menu. |
variant | 'primary''secondary''outline''ghost''text' | As Button's; ghost by default, from the toolbar. |
toneDefault 'neutral' | 'neutral''danger' | As Button's: danger for an action that destroys, such as Delete, so it keeps its warning without a label. |
pendingDefault false | boolean | As Button's: a spinner replaces the icon while the work runs. |
Also accepts the native props of <button>, such as ref, className and aria-* attributes.
Toolbar.Link
An icon-only link of a toolbar, named by its label, which a tooltip shows. In a disabled toolbar or group it has no destination: it reports aria-disabled, leaves the arrow keys' path and has no tooltip, as a disabled button does.
| Prop | Type | Description |
|---|---|---|
hrefrequired | string | The destination, through the LinkProvider's link component. |
iconrequired | ReactNode | The icon, such as Help. |
labelrequired | string | The destination's name, which assistive technology announces and the tooltip shows. |
Also accepts the native props of <a>, such as ref, className and aria-* attributes.
Part names
Each part's class and state attributes are public and versioned, for an application's CSS to style.
env-toolbar- The toolbar.
env-toolbar-button- A button.
env-toolbar-group- A group of buttons.
env-toolbar-separator- The line between groups.
env-toolbar-tooltip- A button's tooltip.
data-orientationhorizontal·verticalon env-toolbar, env-toolbar-group, env-toolbar-separatordata-sizelg·md·sm
Changelog
- 1.0.0
Toolbar, on Base UI's Toolbar.
- 1.0.0-prerelease.6
Toolbar.Buttontakestone="danger"for an action that destroys, such as Delete.A disabled toolbar or group disables its Toolbar.Link too: the link reports
aria-disabled, has no destination and leaves the arrow keys' path.- 1.0.0-prerelease.4
tooltipDelayon Toolbar.Root sets how long the pointer rests on a button or link before its tooltip opens; 0 shows every name at once.