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

## Import

```js
import { ActionBar } from '@gemini-suite/vera-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](/components/menu) component with `...` trigger, signaling 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.

<Callout variant="tip">
  Resize preview box below to notice responsive behavior of the component.
  Resizing the action bar updates the overflow menu.
</Callout>

```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](/components/button) so it accepts same set of variants.

Action bar can contain [icon-only buttons](/components/button#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.

<Callout variant="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.

</Callout>

<Callout variant="tip">

Buttons in action bar are used for triggering actions. Consider using a [toggle button group](/components/button-group#toggle-button-group) control when a button should have a selected state.

</Callout>

```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](/components/dialog). Use `onClick` handler of the button to control open state of `Dialog`.

<Callout variant="tip">

You may use the [danger button variant](/components/button#successdanger) for destructive actions.

</Callout>

```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](/components/layout/flex) 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
<AppFrame.Root css={{ isolation: 'isolate', maxHeight: '60vh' }}>
  <AppFrame.AppHeader
    paddingY="spacingM"
    paddingX={{ '@initial': 'spacingM', '@mqLargeAndUp': 'spacingL' }}
  >
    <Heading variant="delta" margin="none" overflowStrategy="truncate">
      {'Edit view'}
    </Heading>
  </AppFrame.AppHeader>
  <AppFrame.Sidebar>
    <SidebarNavigation.Root
      aria-label="Main navigation"
      withSeparator
      defaultIsExpanded={false}
      expandedWidth="15rem"
    >
      <SidebarNavigation.Header>
        <Logo variant="icon" label="Gemini Suite 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>
  </AppFrame.Sidebar>
  <AppFrame.Main
    as={Flex}
    flow="column"
    gap="none"
    css={{
      backgroundColor: '$backgroundNeutralSubtle'
    }}
  >
    <FlexItem
      shrink={0}
      as={Flex}
      padding="spacingS"
      css={{
        backgroundColor: '$backgroundNeutralMinimal',
        boxShadow: '$elevationS'
      }}
    >
      <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>
  </AppFrame.Main>
</AppFrame.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](/get-started/composition#polymorphism) guide. |          |
| `css`                | `StitchesCss`                                             |            | Apply styles directly to a component in a similar way how you would define inline styles. Vera 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

<Callout variant="tip">

See [Button props](/components/button#api-reference) with exception of `size`.

</Callout>

### 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](/get-started/composition#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                 |          |
