Toolbar

A toolbar is a container for a set of interactive controls, such as buttons, dropdown menus, or checkboxes, with arrow key navigation.

installyarn add react-aria-components
version1.4.1
usageimport {Toolbar} from 'react-aria-components'

Example#


import {Button, Checkbox, Group, Separator, ToggleButton, Toolbar} from 'react-aria-components';

<Toolbar aria-label="Text formatting">
  <Group aria-label="Style">
    <ToggleButton aria-label="Bold">
      <b>B</b>
    </ToggleButton>
    <ToggleButton aria-label="Italic">
      <i>I</i>
    </ToggleButton>
    <ToggleButton aria-label="Underline">
      <u>U</u>
    </ToggleButton>
  </Group>
  <Separator orientation="vertical" />
  <Group aria-label="Clipboard">
    <Button>Copy</Button>
    <Button>Paste</Button>
    <Button>Cut</Button>
  </Group>
  <Separator orientation="vertical" />
  <Checkbox>
    <div className="checkbox">
      <svg viewBox="0 0 18 18" aria-hidden="true">
        <polyline points="1 9 7 14 15 4" />
      </svg>
    </div>
    Night Mode
  </Checkbox>
</Toolbar>
import {
  Button,
  Checkbox,
  Group,
  Separator,
  ToggleButton,
  Toolbar
} from 'react-aria-components';

<Toolbar aria-label="Text formatting">
  <Group aria-label="Style">
    <ToggleButton aria-label="Bold">
      <b>B</b>
    </ToggleButton>
    <ToggleButton aria-label="Italic">
      <i>I</i>
    </ToggleButton>
    <ToggleButton aria-label="Underline">
      <u>U</u>
    </ToggleButton>
  </Group>
  <Separator orientation="vertical" />
  <Group aria-label="Clipboard">
    <Button>Copy</Button>
    <Button>Paste</Button>
    <Button>Cut</Button>
  </Group>
  <Separator orientation="vertical" />
  <Checkbox>
    <div className="checkbox">
      <svg viewBox="0 0 18 18" aria-hidden="true">
        <polyline points="1 9 7 14 15 4" />
      </svg>
    </div>
    Night Mode
  </Checkbox>
</Toolbar>
import {
  Button,
  Checkbox,
  Group,
  Separator,
  ToggleButton,
  Toolbar
} from 'react-aria-components';

<Toolbar aria-label="Text formatting">
  <Group aria-label="Style">
    <ToggleButton aria-label="Bold">
      <b>B</b>
    </ToggleButton>
    <ToggleButton aria-label="Italic">
      <i>I</i>
    </ToggleButton>
    <ToggleButton aria-label="Underline">
      <u>U</u>
    </ToggleButton>
  </Group>
  <Separator orientation="vertical" />
  <Group aria-label="Clipboard">
    <Button>
      Copy
    </Button>
    <Button>
      Paste
    </Button>
    <Button>
      Cut
    </Button>
  </Group>
  <Separator orientation="vertical" />
  <Checkbox>
    <div className="checkbox">
      <svg
        viewBox="0 0 18 18"
        aria-hidden="true"
      >
        <polyline points="1 9 7 14 15 4" />
      </svg>
    </div>
    Night Mode
  </Checkbox>
</Toolbar>
Show CSS
@import "@react-aria/example-theme";

.react-aria-Toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;

  &[data-orientation=horizontal] {
    flex-direction: row;
  }

  .react-aria-Group {
    display: contents;
  }

  .react-aria-ToggleButton {
    width: 32px;
  }
}

.react-aria-Separator {
  align-self: stretch;
  background-color: var(--border-color);

  &[aria-orientation=vertical] {
    width: 1px;
    margin: 0px 10px;
  }
}
@import "@react-aria/example-theme";

.react-aria-Toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;

  &[data-orientation=horizontal] {
    flex-direction: row;
  }

  .react-aria-Group {
    display: contents;
  }

  .react-aria-ToggleButton {
    width: 32px;
  }
}

.react-aria-Separator {
  align-self: stretch;
  background-color: var(--border-color);

  &[aria-orientation=vertical] {
    width: 1px;
    margin: 0px 10px;
  }
}
@import "@react-aria/example-theme";

.react-aria-Toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;

  &[data-orientation=horizontal] {
    flex-direction: row;
  }

  .react-aria-Group {
    display: contents;
  }

  .react-aria-ToggleButton {
    width: 32px;
  }
}

.react-aria-Separator {
  align-self: stretch;
  background-color: var(--border-color);

  &[aria-orientation=vertical] {
    width: 1px;
    margin: 0px 10px;
  }
}

Features#


There is no built-in HTML toolbar element. Toolbar helps achieve accessible toolbars with arrow key navigation that can be styled as needed.

  • Flexible – Support for interactive children such as buttons, checkboxes, dropdown menus, etc. in a horizontal or vertical orientation.
  • Accessible – Follows the ARIA toolbar pattern with support for arrow key navigation as a single tab stop.

Anatomy#


ToolbarGroupCutCutCutCutCutPasteCopyButtonCutCutCutCutGroupSeparator

A toolbar consists of a container element for a set of interactive controls. It provides arrow key navigation between its children, in either horizontal or vertical orientation.

import {Toolbar} from 'react-aria-components';

<Toolbar>
  {/* ... */}
</Toolbar>
import {Toolbar} from 'react-aria-components';

<Toolbar>
  {/* ... */}
</Toolbar>
import {Toolbar} from 'react-aria-components';

<Toolbar>
  {/* ... */}
</Toolbar>

Starter kits#


To help kick-start your project, we offer starter kits that include example implementations of all React Aria components with various styling solutions. All components are fully styled, including support for dark mode, high contrast mode, and all UI states. Each starter comes with a pre-configured Storybook that you can experiment with, or use as a starting point for your own component library.

Vanilla CSS
Download ZIP
Preview
Tailwind CSS
Download ZIP
Preview

Orientation#


By default, toolbars are horizontally oriented. The orientation prop can be set to "vertical" to change the arrow key navigation behavior.

import Move from '@spectrum-icons/workflow/Move';
import Select from '@spectrum-icons/workflow/Select';
import Polygon from '@spectrum-icons/workflow/PolygonSelect';
import Brush from '@spectrum-icons/workflow/Brush';
import Pencil from '@spectrum-icons/workflow/Edit';

<Toolbar aria-label="Tools" orientation="vertical">
  <Group aria-label="Select">
    <Button aria-label="Move"><Move size="S" /></Button>
    <Button aria-label="Rectangle"><Select size="S" /></Button>
    <Button aria-label="Polygon"><Polygon size="S" /></Button>
  </Group>
  <Separator orientation="horizontal" />
  <Group aria-label="Draw">
    <Button aria-label="Brush"><Brush size="S" /></Button>
    <Button aria-label="Pencil"><Pencil size="S" /></Button>
  </Group>
</Toolbar>
import Move from '@spectrum-icons/workflow/Move';
import Select from '@spectrum-icons/workflow/Select';
import Polygon from '@spectrum-icons/workflow/PolygonSelect';
import Brush from '@spectrum-icons/workflow/Brush';
import Pencil from '@spectrum-icons/workflow/Edit';

<Toolbar aria-label="Tools" orientation="vertical">
  <Group aria-label="Select">
    <Button aria-label="Move">
      <Move size="S" />
    </Button>
    <Button aria-label="Rectangle">
      <Select size="S" />
    </Button>
    <Button aria-label="Polygon">
      <Polygon size="S" />
    </Button>
  </Group>
  <Separator orientation="horizontal" />
  <Group aria-label="Draw">
    <Button aria-label="Brush">
      <Brush size="S" />
    </Button>
    <Button aria-label="Pencil">
      <Pencil size="S" />
    </Button>
  </Group>
</Toolbar>
import Move from '@spectrum-icons/workflow/Move';
import Select from '@spectrum-icons/workflow/Select';
import Polygon from '@spectrum-icons/workflow/PolygonSelect';
import Brush from '@spectrum-icons/workflow/Brush';
import Pencil from '@spectrum-icons/workflow/Edit';

<Toolbar
  aria-label="Tools"
  orientation="vertical"
>
  <Group aria-label="Select">
    <Button aria-label="Move">
      <Move size="S" />
    </Button>
    <Button aria-label="Rectangle">
      <Select size="S" />
    </Button>
    <Button aria-label="Polygon">
      <Polygon size="S" />
    </Button>
  </Group>
  <Separator orientation="horizontal" />
  <Group aria-label="Draw">
    <Button aria-label="Brush">
      <Brush size="S" />
    </Button>
    <Button aria-label="Pencil">
      <Pencil size="S" />
    </Button>
  </Group>
</Toolbar>
Show CSS
.react-aria-Toolbar {
  width: fit-content;

  &[data-orientation=vertical] {
    flex-direction: column;
    align-items: start;
  }
}

.react-aria-Separator {
  &:not([aria-orientation=vertical]) {
    border: none;
    height: 1px;
    width: 100%;
    margin: 10px 0;
  }
}
.react-aria-Toolbar {
  width: fit-content;

  &[data-orientation=vertical] {
    flex-direction: column;
    align-items: start;
  }
}

.react-aria-Separator {
  &:not([aria-orientation=vertical]) {
    border: none;
    height: 1px;
    width: 100%;
    margin: 10px 0;
  }
}
.react-aria-Toolbar {
  width: fit-content;

  &[data-orientation=vertical] {
    flex-direction: column;
    align-items: start;
  }
}

.react-aria-Separator {
  &:not([aria-orientation=vertical]) {
    border: none;
    height: 1px;
    width: 100%;
    margin: 10px 0;
  }
}

Props#


Toolbar#

NameTypeDefaultDescription
orientationOrientation'horizontal'The orientation of the entire toolbar.
childrenReactNode( (values: ToolbarRenderProps{
defaultChildren: ReactNodeundefined
} )) => ReactNode
The children of the component. A function may be provided to alter the children based on component state.
classNamestring( (values: ToolbarRenderProps{
defaultClassName: stringundefined
} )) => string
The CSS className for the element. A function may be provided to compute the class based on component state.
styleCSSProperties( (values: ToolbarRenderProps{
defaultStyle: CSSProperties
} )) => CSSPropertiesundefined
The inline style for the element. A function may be provided to compute the style based on component state.
Layout
NameTypeDescription
slotstringnull

A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.

Accessibility
NameTypeDescription
aria-labelstringDefines a string value that labels the current element.
aria-labelledbystringIdentifies the element (or elements) that labels the current element.
aria-describedbystringIdentifies the element (or elements) that describes the object.
aria-detailsstringIdentifies the element (or elements) that provide a detailed, extended description for the object.

Separator#

A <Separator> can be placed between elements and groups in a toolbar.

Show props
NameTypeDefaultDescription
orientationOrientation'horizontal'The orientation of the separator.
elementTypestringThe HTML element type that will be used to render the separator.
classNamestringThe CSS className for the element.
styleCSSPropertiesThe inline style for the element.
Layout
NameTypeDescription
slotstringnull

A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.

Accessibility
NameTypeDescription
idstringThe element's unique identifier. See MDN.
aria-labelstringDefines a string value that labels the current element.
aria-labelledbystringIdentifies the element (or elements) that labels the current element.
aria-describedbystringIdentifies the element (or elements) that describes the object.
aria-detailsstringIdentifies the element (or elements) that provide a detailed, extended description for the object.

Styling#


React Aria components can be styled in many ways, including using CSS classes, inline styles, utility classes (e.g. Tailwind), CSS-in-JS (e.g. Styled Components), etc. By default, all components include a builtin className attribute which can be targeted using CSS selectors. These follow the react-aria-ComponentName naming convention.

.react-aria-Toolbar {
  /* ... */
}
.react-aria-Toolbar {
  /* ... */
}
.react-aria-Toolbar {
  /* ... */
}

A custom className can also be specified on any component. This overrides the default className provided by React Aria with your own.

<Toolbar className="my-toolbar">
  {/* ... */}
</Toolbar>
<Toolbar className="my-toolbar">
  {/* ... */}
</Toolbar>
<Toolbar className="my-toolbar">
  {/* ... */}
</Toolbar>

The className and style props also accept functions which receive states for styling. This lets you dynamically determine the classes or styles to apply, which is useful when using utility CSS libraries like Tailwind.

<Toolbar
  className={({ orientation }) =>
    orientation === 'vertical' ? 'flex-col' : 'flex-row'}
>
  {/* ... */}
</Toolbar>
<Toolbar
  className={({ orientation }) =>
    orientation === 'vertical' ? 'flex-col' : 'flex-row'}
>
  {/* ... */}
</Toolbar>
<Toolbar
  className={(
    { orientation }
  ) =>
    orientation ===
        'vertical'
      ? 'flex-col'
      : 'flex-row'}
>
  {/* ... */}
</Toolbar>

The selectors and render props for each component used in a Toolbar are documented below.

Toolbar#

A Toolbar can be targeted with the .react-aria-Toolbar CSS selector, or by overriding with a custom className. It supports the following states and render props:

NameCSS SelectorDescription
orientation[data-orientation]The current orientation of the toolbar.

Separator#

A Separator can be targeted with the .react-aria-Separator CSS selector, or by overriding with a custom className.

Advanced customization#


Contexts#

All React Aria Components export a corresponding context that can be used to send props to them from a parent element. This enables you to build your own compositional APIs similar to those found in React Aria Components itself. You can send any prop or ref via context that you could pass to the corresponding component. The local props and ref on the component are merged with the ones passed via context, with the local props taking precedence (following the rules documented in mergeProps).

ComponentContextPropsRef
ToolbarToolbarContextToolbarPropsHTMLDivElement

Hooks#

If you need to customize things further, such as customizing the DOM structure, you can drop down to the lower level Hook-based API. See useToolbar for more details.