reakit
Version:
Toolkit for building accessible rich web apps with React
452 lines (330 loc) • 14.5 kB
Markdown
---
path: /docs/toolbar/
redirect_from:
- /components/toolbar/
- /components/toolbar/toolbarcontent/
- /components/toolbar/toolbarfocusable/
---
# Toolbar
Accessible `Toolbar` component that follows the [WAI-ARIA Toolbar Pattern](https://www.w3.org/TR/wai-aria-practices/#toolbar). It's a container for grouping a set of controls.
<carbon-ad></carbon-ad>
## Installation
```sh
npm install reakit
```
Learn more in [Get started](/docs/get-started/).
## Usage
```jsx
import {
useToolbarState,
Toolbar,
ToolbarItem,
ToolbarSeparator,
} from "reakit/Toolbar";
import { Button } from "reakit/Button";
function Example() {
const toolbar = useToolbarState({ loop: true });
return (
<Toolbar {...toolbar} aria-label="My toolbar">
<ToolbarItem {...toolbar} as={Button}>
Item 1
</ToolbarItem>
<ToolbarItem {...toolbar} as={Button}>
Item 2
</ToolbarItem>
<ToolbarSeparator {...toolbar} />
<ToolbarItem {...toolbar} as={Button}>
Item 3
</ToolbarItem>
</Toolbar>
);
}
```
### `Toolbar` with `Menu`
You can render [Menu](/docs/menu/) within a `Toolbar` using the same techinique to make a [Submenu](/docs/menu/#submenu).
```jsx
import React from "react";
import { useToolbarState, Toolbar, ToolbarItem } from "reakit/Toolbar";
import { useMenuState, MenuButton, Menu, MenuItem } from "reakit/Menu";
import { Button } from "reakit/Button";
const MoreItems = React.forwardRef((props, ref) => {
const menu = useMenuState({ placement: "bottom-end" });
return (
<>
<MenuButton {...menu} {...props} ref={ref} aria-label="More items" />
<Menu {...menu} aria-label="More items">
<MenuItem {...menu}>Item 3</MenuItem>
<MenuItem {...menu}>Item 4</MenuItem>
<MenuItem {...menu}>Item 5</MenuItem>
</Menu>
</>
);
});
function Example() {
const toolbar = useToolbarState();
return (
<Toolbar {...toolbar} aria-label="My toolbar">
<ToolbarItem {...toolbar} as={Button}>
Item 1
</ToolbarItem>
<ToolbarItem {...toolbar} as={Button}>
Item 2
</ToolbarItem>
<ToolbarItem {...toolbar} as={MoreItems} />
</Toolbar>
);
}
```
## Accessibility
- `Toolbar` has role `toolbar`.
- `Toolbar` extends the accessibility features of [Composite](/docs/composite/#accessibility).
- `ToolbarItem` extends the accessibility features of [CompositeItem](/docs/composite/#accessibility).
Learn more in [Accessibility](/docs/accessibility/).
## Composition
- `Toolbar` uses [Composite](/docs/composite/).
- `ToolbarItem` uses [CompositeItem](/docs/composite/).
- `ToolbarSeparator` uses [Separator](/docs/separator/).
Learn more in [Composition](/docs/composition/#props-hooks).
## Props
<!-- Automatically generated -->
### `useToolbarState`
- **`baseId`**
<code>string</code>
ID that will serve as a base for all the items IDs.
- **`unstable_virtual`** <span title="Experimental">⚠️</span>
<code>boolean</code>
If enabled, the composite element will act as an
[aria-activedescendant](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant)
container instead of
[roving tabindex](https://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex).
DOM focus will remain on the composite while its items receive virtual focus.
- **`rtl`**
<code>boolean</code>
Determines how `next` and `previous` functions will behave. If `rtl` is
set to `true`, they will be inverted. This only affects the composite
widget behavior. You still need to set `dir="rtl"` on HTML/CSS.
- **`orientation`**
<code>"horizontal" | "vertical" | undefined</code>
Defines the orientation of the composite widget. If the composite has a
single row or column (one-dimensional), the `orientation` value determines
which arrow keys can be used to move focus:
- `undefined`: all arrow keys work.
- `horizontal`: only left and right arrow keys work.
- `vertical`: only up and down arrow keys work.
It doesn't have any effect on two-dimensional composites.
- **`currentId`**
<code>string | null | undefined</code>
The current focused item `id`.
- `undefined` will automatically focus the first enabled composite item.
- `null` will focus the base composite element and users will be able to
navigate out of it using arrow keys.
- If `currentId` is initially set to `null`, the base composite element
itself will have focus and users will be able to navigate to it using
arrow keys.
- **`loop`**
<code>boolean | "horizontal" | "vertical"</code>
On one-dimensional composites:
- `true` loops from the last item to the first item and vice-versa.
- `horizontal` loops only if `orientation` is `horizontal` or not set.
- `vertical` loops only if `orientation` is `vertical` or not set.
- If `currentId` is initially set to `null`, the composite element will
be focused in between the last and first items.
On two-dimensional composites:
- `true` loops from the last row/column item to the first item in the
same row/column and vice-versa. If it's the last item in the last row, it
moves to the first item in the first row and vice-versa.
- `horizontal` loops only from the last row item to the first item in
the same row.
- `vertical` loops only from the last column item to the first item in
the column row.
- If `currentId` is initially set to `null`, vertical loop will have no
effect as moving down from the last row or up from the first row will
focus the composite element.
- If `wrap` matches the value of `loop`, it'll wrap between the last
item in the last row or column and the first item in the first row or
column and vice-versa.
- **`wrap`**
<code>boolean | "horizontal" | "vertical"</code>
**Has effect only on two-dimensional composites**. If enabled, moving to
the next item from the last one in a row or column will focus the first
item in the next row or column and vice-versa.
- `true` wraps between rows and columns.
- `horizontal` wraps only between rows.
- `vertical` wraps only between columns.
- If `loop` matches the value of `wrap`, it'll wrap between the last
item in the last row or column and the first item in the first row or
column and vice-versa.
- **`shift`**
<code>boolean</code>
**Has effect only on two-dimensional composites**. If enabled, moving up
or down when there's no next item or the next item is disabled will shift
to the item right before it.
### `Toolbar`
- **`disabled`**
<code>boolean | undefined</code>
Same as the HTML attribute.
- **`focusable`**
<code>boolean | undefined</code>
When an element is `disabled`, it may still be `focusable`. It works
similarly to `readOnly` on form elements. In this case, only
`aria-disabled` will be set.
<details><summary>12 state props</summary>
> These props are returned by the state hook. You can spread them into this component (`{...state}`) or pass them separately. You can also provide these props from your own state logic.
- **`baseId`**
<code>string</code>
ID that will serve as a base for all the items IDs.
- **`unstable_virtual`** <span title="Experimental">⚠️</span>
<code>boolean</code>
If enabled, the composite element will act as an
[aria-activedescendant](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant)
container instead of
[roving tabindex](https://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex).
DOM focus will remain on the composite while its items receive virtual focus.
- **`orientation`**
<code>"horizontal" | "vertical" | undefined</code>
Defines the orientation of the composite widget. If the composite has a
single row or column (one-dimensional), the `orientation` value determines
which arrow keys can be used to move focus:
- `undefined`: all arrow keys work.
- `horizontal`: only left and right arrow keys work.
- `vertical`: only up and down arrow keys work.
It doesn't have any effect on two-dimensional composites.
- **`currentId`**
<code>string | null | undefined</code>
The current focused item `id`.
- `undefined` will automatically focus the first enabled composite item.
- `null` will focus the base composite element and users will be able to
navigate out of it using arrow keys.
- If `currentId` is initially set to `null`, the base composite element
itself will have focus and users will be able to navigate to it using
arrow keys.
- **`wrap`**
<code>boolean | "horizontal" | "vertical"</code>
**Has effect only on two-dimensional composites**. If enabled, moving to
the next item from the last one in a row or column will focus the first
item in the next row or column and vice-versa.
- `true` wraps between rows and columns.
- `horizontal` wraps only between rows.
- `vertical` wraps only between columns.
- If `loop` matches the value of `wrap`, it'll wrap between the last
item in the last row or column and the first item in the first row or
column and vice-versa.
- **`unstable_moves`** <span title="Experimental">⚠️</span>
<code>number</code>
Stores the number of moves that have been performed by calling `move`,
`next`, `previous`, `up`, `down`, `first` or `last`.
- **`groups`**
<code>Group[]</code>
Lists all the composite groups with their `id` and DOM `ref`. This state
is automatically updated when `registerGroup` and `unregisterGroup` are
called.
- **`items`**
<code>Item[]</code>
Lists all the composite items with their `id`, DOM `ref`, `disabled` state
and `groupId` if any. This state is automatically updated when
`registerItem` and `unregisterItem` are called.
- **`setCurrentId`**
<code title="(value: SetStateAction<string | null | undefined>) => void">(value: SetStateAction<string | null | undefine...</code>
Sets `currentId`. This is different from `composite.move` as this only
updates the `currentId` state without moving focus. When the composite
widget gets focused by the user, the item referred by the `currentId`
state will get focus.
- **`first`**
<code>() => void</code>
Moves focus to the first item.
- **`last`**
<code>() => void</code>
Moves focus to the last item.
- **`move`**
<code>(id: string | null) => void</code>
Moves focus to a given item ID.
</details>
### `ToolbarItem`
- **`disabled`**
<code>boolean | undefined</code>
Same as the HTML attribute.
- **`focusable`**
<code>boolean | undefined</code>
When an element is `disabled`, it may still be `focusable`. It works
similarly to `readOnly` on form elements. In this case, only
`aria-disabled` will be set.
- **`id`**
<code>string | undefined</code>
Same as the HTML attribute.
<details><summary>15 state props</summary>
> These props are returned by the state hook. You can spread them into this component (`{...state}`) or pass them separately. You can also provide these props from your own state logic.
- **`baseId`**
<code>string</code>
ID that will serve as a base for all the items IDs.
- **`unstable_virtual`** <span title="Experimental">⚠️</span>
<code>boolean</code>
If enabled, the composite element will act as an
[aria-activedescendant](https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant)
container instead of
[roving tabindex](https://www.w3.org/TR/wai-aria-practices/#kbd_roving_tabindex).
DOM focus will remain on the composite while its items receive virtual focus.
- **`orientation`**
<code>"horizontal" | "vertical" | undefined</code>
Defines the orientation of the composite widget. If the composite has a
single row or column (one-dimensional), the `orientation` value determines
which arrow keys can be used to move focus:
- `undefined`: all arrow keys work.
- `horizontal`: only left and right arrow keys work.
- `vertical`: only up and down arrow keys work.
It doesn't have any effect on two-dimensional composites.
- **`unstable_moves`** <span title="Experimental">⚠️</span>
<code>number</code>
Stores the number of moves that have been performed by calling `move`,
`next`, `previous`, `up`, `down`, `first` or `last`.
- **`currentId`**
<code>string | null | undefined</code>
The current focused item `id`.
- `undefined` will automatically focus the first enabled composite item.
- `null` will focus the base composite element and users will be able to
navigate out of it using arrow keys.
- If `currentId` is initially set to `null`, the base composite element
itself will have focus and users will be able to navigate to it using
arrow keys.
- **`items`**
<code>Item[]</code>
Lists all the composite items with their `id`, DOM `ref`, `disabled` state
and `groupId` if any. This state is automatically updated when
`registerItem` and `unregisterItem` are called.
- **`setCurrentId`**
<code title="(value: SetStateAction<string | null | undefined>) => void">(value: SetStateAction<string | null | undefine...</code>
Sets `currentId`. This is different from `composite.move` as this only
updates the `currentId` state without moving focus. When the composite
widget gets focused by the user, the item referred by the `currentId`
state will get focus.
- **`first`**
<code>() => void</code>
Moves focus to the first item.
- **`last`**
<code>() => void</code>
Moves focus to the last item.
- **`registerItem`**
<code>(item: Item) => void</code>
Registers a composite item.
- **`unregisterItem`**
<code>(id: string) => void</code>
Unregisters a composite item.
- **`next`**
<code>(unstable_allTheWay?: boolean | undefined) => void</code>
Moves focus to the next item.
- **`previous`**
<code>(unstable_allTheWay?: boolean | undefined) => void</code>
Moves focus to the previous item.
- **`up`**
<code>(unstable_allTheWay?: boolean | undefined) => void</code>
Moves focus to the item above.
- **`down`**
<code>(unstable_allTheWay?: boolean | undefined) => void</code>
Moves focus to the item below.
</details>
### `ToolbarSeparator`
<details><summary>1 state props</summary>
> These props are returned by the state hook. You can spread them into this component (`{...state}`) or pass them separately. You can also provide these props from your own state logic.
- **`orientation`**
<code>"horizontal" | "vertical" | undefined</code>
Separator's orientation.
</details>