# Action Bar
> A responsive container for grouping a set of actions.

## Import

```js
import { ActionBar } from '@volue/wave-react';
```

Action Bar is a compound component that consists of multiple parts.

- `ActionBar.Root`: A container for all the parts of the Action Bar.
- `ActionBar.Button`: A button for a single action.
- `ActionBar.Separator`: A visual line between items in the toolbar.

## Examples

### Basic

Use an Action Bar to render row of buttons that form responsive, toolbar-like component.
Buttons can be split into groups by adding an `ActionBar.Separator`. When there is no space to render all elements, overflowing actions will be moved to [Menu](https://next.wave-design-system.pages.dev/components/menu.md) component with `...` trigger, signalling that there are more actions available.
Clicking on the trigger opens a menu with the remaining actions that didn't fit in the available space.

> **Tip**
>
> Resize preview box below to notice responsive behaviour of the component. Resizing the Action Bar updates the overflow menu.

```jsx resizable=true
<ActionBar.Root aria-label="Toolbar">
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
    {'Create'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
    {'Edit'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
    {'Duplicate'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="move" />}>
    {'Move'}
  </ActionBar.Button>
</ActionBar.Root>
```

### Sizes

Action Bar can be used in two sizes: `medium` (default) and `small`.

```jsx resizable=true
<Flex flow="column">
  <ActionBar.Root aria-label="Toolbar medium size">
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
      {'Add'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
      {'Edit'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
      {'Duplicate'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="move" />}>
      {'Move'}
    </ActionBar.Button>
  </ActionBar.Root>
  <ActionBar.Root size="small" aria-label="Toolbar small size">
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
      {'Add'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
      {'Edit'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
      {'Duplicate'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="move" />}>
      {'Move'}
    </ActionBar.Button>
  </ActionBar.Root>
</Flex>
```

### Separators

Related buttons can be grouped with help of `ActionBar.Separator` .
Separators from the Action Bar are preserved in the overflow menu.

```jsx resizable=true
<ActionBar.Root aria-label="Toolbar medium size">
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
    {'Add'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
    {'Edit'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
    {'Duplicate'}
  </ActionBar.Button>
  <ActionBar.Separator />
  <ActionBar.Button
    variant="outline"
    leftIcon={<SvgIcon iconName="download" />}
  >
    {'Export'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="upload" />}>
    {'Import'}
  </ActionBar.Button>
</ActionBar.Root>
```

### Buttons

Buttons are the only controls allowed in an Action Bar.

`ActionBar.Button` implements [Button](https://next.wave-design-system.pages.dev/components/button.md) so it accepts same set of variants.

Action Bar can contain [icon-only buttons](https://next.wave-design-system.pages.dev/components/button.md#icon-only-button) as well as buttons with text labels and optional icons.

Buttons should default to the `outline` or `ghost` variant. Mixing variants within the same Action Bar is not recommended.

> **Tip**
>
> Provide `aria-label` that describes the action when using icon-only buttons.
> When hovering over a button, a tooltip with action description will appear.
>
> You can control the label of `...` Menu button by
> setting `moreMenuLabel` prop.

> **Tip**
>
> Buttons in Action Bar are used for triggering actions. Consider using a [Toggle Button Group](https://next.wave-design-system.pages.dev/components/button-group.md#toggle-button-group) control when a button should have a selected state.

```jsx resizable=true
<Flex flow="column">
  <ActionBar.Root
    aria-label="Toolbar with outline buttons"
    moreMenuLabel="More tools"
  >
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
      {'Add'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
      {'Duplicate'}
    </ActionBar.Button>
    <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="trash" />}>
      {'Delete'}
    </ActionBar.Button>
    <ActionBar.Separator />
    <ActionBar.Button
      variant="outline"
      leftIcon={<SvgIcon iconName="download" />}
      isDisabled
    >
      {'Export'}
    </ActionBar.Button>
  </ActionBar.Root>
  <ActionBar.Root
    aria-label="Toolbar with outline buttons"
    moreMenuLabel="More tools"
  >
    <ActionBar.Button variant="ghost" leftIcon={<SvgIcon iconName="add" />}>
      {'Add'}
    </ActionBar.Button>
    <ActionBar.Button variant="ghost" leftIcon={<SvgIcon iconName="copy" />}>
      {'Duplicate'}
    </ActionBar.Button>
    <ActionBar.Button variant="ghost" leftIcon={<SvgIcon iconName="trash" />}>
      {'Delete'}
    </ActionBar.Button>
    <ActionBar.Separator />
    <ActionBar.Button
      variant="ghost"
      leftIcon={<SvgIcon iconName="download" />}
      isDisabled
    >
      {'Export'}
    </ActionBar.Button>
  </ActionBar.Root>
  <ActionBar.Root
    aria-label="Toolbar with ghost buttons"
    moreMenuLabel="More tools"
  >
    <ActionBar.Button variant="ghost" withLoneIcon aria-label="Add">
      <SvgIcon iconName="add" />
    </ActionBar.Button>
    <ActionBar.Button variant="ghost" withLoneIcon aria-label="Duplicate">
      <SvgIcon iconName="copy" />
    </ActionBar.Button>
    <ActionBar.Button variant="ghost" withLoneIcon aria-label="Delete">
      <SvgIcon iconName="trash" />
    </ActionBar.Button>
    <ActionBar.Separator />
    <ActionBar.Button variant="ghost" withLoneIcon aria-label="Export">
      <SvgIcon iconName="download" />
    </ActionBar.Button>
  </ActionBar.Root>
</Flex>
```

### With dialog

`ActionBar.Button` can open new context via [dialogs](https://next.wave-design-system.pages.dev/components/dialog.md). Use `onClick` handler of the button to control open state of `Dialog`.

> **Tip**
>
> You may use the [danger button variant](https://next.wave-design-system.pages.dev/components/button.md#successdanger) for destructive actions.

```jsx resizable=true
() => {
  const [isConfirmDialogOpen, setIsConfirmDialogOpen] = React.useState(false);

  return (
    <Box>
      <ActionBar.Root>
        <ActionBar.Button
          aria-label="Add"
          variant="outline"
          isDisabled
          leftIcon={<SvgIcon iconName="add" />}
        >
          {'Add'}
        </ActionBar.Button>
        <ActionBar.Button
          variant="outline"
          leftIcon={<SvgIcon iconName="edit" />}
          isDisabled
        >
          {'Edit'}
        </ActionBar.Button>
        <ActionBar.Button
          variant="outline"
          color="danger"
          onClick={() => {
            setIsConfirmDialogOpen(true);
          }}
          leftIcon={<SvgIcon iconName="trash" />}
        >
          {'Delete'}
        </ActionBar.Button>
      </ActionBar.Root>
      <Dialog.Root
        isOpen={isConfirmDialogOpen}
        onIsOpenChange={setIsConfirmDialogOpen}
      >
        <Dialog.Box
          width="22rem"
          padding="spacingM"
          shouldCloseOnOverlayClick={false}
        >
          <Flex
            flow="column"
            cross="center"
            paddingTop="spacingL"
            paddingBottom="spacingXl"
          >
            <Box className="iconCircle iconCircle--medium fill-neutral">
              <SvgIcon iconName="help" size="medium" />
            </Box>
            <Dialog.Title variant="delta">Are you sure?</Dialog.Title>
          </Flex>
          <Flex main="space-between">
            <Dialog.Close as={Button} variant="ghost">
              {'Cancel'}
            </Dialog.Close>
            <Button color="danger">{'Yes, delete'}</Button>
          </Flex>
        </Dialog.Box>
      </Dialog.Root>
    </Box>
  );
};
```

### Alignment

Use `alignItems` prop to control alignment of the Action Bar items.

```jsx resizable=true
<ActionBar.Root alignItems="end" aria-label="Right-aligned action bar">
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
    {'Add'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
    {'Edit'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
    {'Duplicate'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="adjust" />}>
    {'Adjust'}
  </ActionBar.Button>
</ActionBar.Root>
```

### Layout

Action Bar can be used full width taking up the entire space or inline next to other content.

```tsx resizable=true
<Flex>
  <FlexItem shrink={0}>
    <Text color="foregroundNeutralModerate">{'Edited 1 hour ago'}</Text>
  </FlexItem>
  <FlexItem grow={1} shrinkPastContentSize>
    <ActionBar.Root alignItems="end" size="small">
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="Bold">
        <SvgIcon iconName="bold" />
      </ActionBar.Button>
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="Italic">
        <SvgIcon iconName="italic" />
      </ActionBar.Button>
      <ActionBar.Button
        withLoneIcon
        variant="ghost"
        aria-label="Strike through"
      >
        <SvgIcon iconName="underline" />
      </ActionBar.Button>
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="Link">
        <SvgIcon iconName="link" />
      </ActionBar.Button>
      <ActionBar.Separator />
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="List">
        <SvgIcon iconName="list" />
      </ActionBar.Button>
      <ActionBar.Separator />
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="Left aligned">
        <SvgIcon iconName="alignLeft" />
      </ActionBar.Button>
      <ActionBar.Button
        withLoneIcon
        variant="ghost"
        aria-label="Center aligned"
      >
        <SvgIcon iconName="alignCenter" />
      </ActionBar.Button>
      <ActionBar.Button withLoneIcon variant="ghost" aria-label="Right aligned">
        <SvgIcon iconName="alignRight" />
      </ActionBar.Button>
    </ActionBar.Root>
  </FlexItem>
</Flex>
```

### Fixed actions

You can use [Flex layout](https://next.wave-design-system.pages.dev/components/layout/flex.md) to combine Action Bar with important, primary action(s) that should not overflow.

```jsx resizable=true
<Flex>
  <FlexItem grow={1} shrinkPastContentSize>
    <ActionBar.Root alignItems="end">
      <ActionBar.Button variant="outline">{'Action 1'}</ActionBar.Button>
      <ActionBar.Button variant="outline">{'Action 2'}</ActionBar.Button>
      <ActionBar.Button variant="outline">{'Action 3'}</ActionBar.Button>
    </ActionBar.Root>
  </FlexItem>
  <Separator orientation="vertical" size="medium" />
  <FlexItem as={Flex} shrink={0}>
    <Button variant="outline">{'Cancel'}</Button>
    <Button>{'Save'}</Button>
  </FlexItem>
</Flex>
```

### Minimum number of items in menu

By default, minimum number of items in the overflow menu is set to 2. You can change this value by setting `minItemsInMoreMenu` prop.

```jsx resizable=true
<ActionBar.Root
  aria-label="Toolbar with minimum 3 items in menu"
  size="small"
  minItemsInMoreMenu={3}
>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="add" />}>
    {'Add'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="edit" />}>
    {'Edit'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="copy" />}>
    {'Duplicate'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="trash" />}>
    {'Delete'}
  </ActionBar.Button>
  <ActionBar.Separator />
  <ActionBar.Button
    variant="outline"
    leftIcon={<SvgIcon iconName="download" />}
  >
    {'Export'}
  </ActionBar.Button>
  <ActionBar.Button variant="outline" leftIcon={<SvgIcon iconName="upload" />}>
    {'Import'}
  </ActionBar.Button>
  <ActionBar.Separator />
  <ActionBar.Button
    variant="outline"
    aria-label="Reload data"
    leftIcon={<SvgIcon iconName="reload" />}
  >
    {'Reload'}
  </ActionBar.Button>
</ActionBar.Root>
```

### Toolbar with many items

```jsx resizable=true
<AppFrameWithSidebar.Root css={{ isolation: 'isolate', maxHeight: '60vh' }}>
  <AppFrameWithSidebar.Header
    paddingY="spacingM"
    paddingX={{ '@initial': 'spacingM', '@mqLargeAndUp': 'spacingL' }}
  >
    <Heading
      variant="delta"
      color="foregroundNeutralModerate"
      margin="none"
      overflowStrategy="truncate"
    >
      {'Edit view'}
    </Heading>
  </AppFrameWithSidebar.Header>
  <AppFrameWithSidebar.Sidebar>
    <SidebarNavigation.Root
      aria-label="Main navigation"
      withSeparator
      defaultIsExpanded={false}
      expandedWidth="15rem"
    >
      <SidebarNavigation.Header>
        <SidebarNavigation.Logo label="Volue logo" />
        <SidebarNavigation.AppTitle>
          {'Product name'}
        </SidebarNavigation.AppTitle>
      </SidebarNavigation.Header>
      <SidebarNavigation.Body>
        <SidebarNavigation.Section title="Section name">
          <SidebarNavigation.Items>
            <SidebarNavigation.Item iconName="home" label="Dashboard" />
            <SidebarNavigation.Item iconName="edit" label="Edit view" />
          </SidebarNavigation.Items>
        </SidebarNavigation.Section>
      </SidebarNavigation.Body>
      <SidebarNavigation.Footer>
        <SidebarNavigation.Section>
          <SidebarNavigation.Items>
            <SidebarNavigation.Item
              leadingVisual={
                <Avatar.Root of="Torvald Halvor" size="small">
                  <Avatar.Initials />
                </Avatar.Root>
              }
              label="Torvald Halvor"
            />
          </SidebarNavigation.Items>
        </SidebarNavigation.Section>
      </SidebarNavigation.Footer>
      <SidebarNavigation.Toggle label="Toggle panel" />
    </SidebarNavigation.Root>
  </AppFrameWithSidebar.Sidebar>
  <AppFrameWithSidebar.Main
    as={Flex}
    flow="column"
    gap="none"
    background="neutralSubtle"
  >
    <FlexItem
      shrink={0}
      as={Flex}
      padding="spacingS"
      css={{
        backgroundColor: '$backgroundNeutralMinimal',
        borderBottom: '1px solid $borderNeutralSubtle'
      }}
    >
      <FlexItem grow={1} shrinkPastContentSize>
        <ActionBar.Root aria-label="Toolbar with many items" size="small">
          <ActionBar.Button aria-label="Add" variant="ghost" withLoneIcon>
            <SvgIcon iconName="add" />
          </ActionBar.Button>
          <ActionBar.Button aria-label="Duplicate" variant="ghost" withLoneIcon>
            <SvgIcon iconName="copy" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Group with others"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="layers" />
          </ActionBar.Button>
          <ActionBar.Separator />
          <ActionBar.Button
            aria-label="Remove element"
            variant="ghost"
            withLoneIcon
            color="danger"
          >
            <SvgIcon iconName="trash" />
          </ActionBar.Button>
          <ActionBar.Separator />
          <ActionBar.Button
            aria-label="Adjust entry properties"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="adjust" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Set measures"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="measure" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Set location"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="pin" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Assign owners"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="roles" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Set visibility"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="show" />
          </ActionBar.Button>
          <ActionBar.Button aria-label="Schedule" variant="ghost" withLoneIcon>
            <SvgIcon iconName="calendar" />
          </ActionBar.Button>
          <ActionBar.Separator />
          <ActionBar.Button aria-label="Zoom in" variant="ghost" withLoneIcon>
            <SvgIcon iconName="zoomIn" />
          </ActionBar.Button>
          <ActionBar.Button aria-label="Zoom out" variant="ghost" withLoneIcon>
            <SvgIcon iconName="zoomOut" />
          </ActionBar.Button>
          <ActionBar.Separator />
          <ActionBar.Button
            aria-label="Add documentation"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="comment" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Export to SVG"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="upload" />
          </ActionBar.Button>
          <ActionBar.Button
            aria-label="Publish draft"
            variant="ghost"
            withLoneIcon
          >
            <SvgIcon iconName="cloud" />
          </ActionBar.Button>
        </ActionBar.Root>
      </FlexItem>
      <FlexItem shrink={0}>
        <Button
          size={'small'}
          leftIcon={<SvgIcon iconName="save" />}
          variant="outline"
        >
          {'Save'}
        </Button>
      </FlexItem>
    </FlexItem>
    <FlexItem as={Flex} grow="1" cross="center" main="center">
      <Text color="foregroundNeutralSubtle">{'Editor placeholder'}</Text>
    </FlexItem>
  </AppFrameWithSidebar.Main>
</AppFrameWithSidebar.Root>
```

---

## Accessibility

<ul>
  <li iconName="check">

Action Bar has an [ARIA role of toolbar](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/toolbar_role).

  </li>
  <li iconName="check">

Action Bar has a single tab stop. Focus movement is managed using [roving focus technique](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#x6-6-keyboard-navigation-inside-components) when using a keyboard to navigate.

  </li>
</ul>

---

## API reference

### ActionBar.Root

| Name                 | Type                                                      | Default    | Description                                                                                                                                                                                                                                                                                                                              | Required |
| -------------------- | --------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`                 | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`      | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css`                | `StitchesCss`                                             |            | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |
| `size`               | `"medium" \| "small"`                                     | `"medium"` | The size of the Action Bar items.                                                                                                                                                                                                                                                                                                        |          |
| `alignItems`         | `"start" \| "end"`                                        | `"start"`  | Defines the alignment of the Action Bar items.                                                                                                                                                                                                                                                                                           |          |
| `minItemsInMoreMenu` | `number`                                                  |            | When there is no space to render all Action Bar items, at least this number of items will be moved to the overflow menu.                                                                                                                                                                                                                 |          |
| `moreMenuLabel`      | `string`                                                  | `"More"`   | Content of the overflow menu button tooltip.                                                                                                                                                                                                                                                                                             |          |

### ActionBar.Button

> **Tip**
>
> See [Button props](https://next.wave-design-system.pages.dev/components/button.md#api-reference) with exception of `size`.

### ActionBar.Separator

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                                                              | Required |
| ----- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |
