# App Bar
> The App Bar represents a meta-level navigation, that allows you to navigate accross different apps or modules.

## Import

```js
import { AppBar } from '@gemini-suite/vera-react';
```

AppBar is a compound component that consists of multiple parts.

- `AppBar.Root`: The root component that wraps the entire app bar.
- `AppBar.Logo`: The logo component that displays the logo of the application.
- `AppBar.Items`: The component that wraps the items in the app bar.
- `AppBar.Item`: The individual item component that represents a single item in the app bar.

## Examples

### Basic

The app bar is a vertical navigation component that provides high-level navigation between distinct applications within a suite, or between the core modules of a single application. It is best suited for scenarios where users need to switch between major sections or products, rather than for navigating between pages or features within a single module.

<Callout variant="tip">

For navigating between pages or features within a single module, use [Sidebar Navigation component](/components/sidebar-navigation) or [Nav Bar component](/components/nav-bar) instead.

</Callout>

```jsx
<Box css={{ height: '500px' }}>
  <AppBar.Root>
    <AppBar.Logo />
    <AppBar.Items>
      {/*
        `data-active` is used to prevent scrolling to active item in the playground.
        You should use `isActive` prop instead.
       */}
      <AppBar.Item iconName="layout" label="Dashboard" data-active />
      <AppBar.Item iconName="pin" label="Map" />
      <AppBar.Item iconName="timeseries" label="Time series" isDisabled />
      <AppBar.Item iconName="settings" label="Settings" />
    </AppBar.Items>
  </AppBar.Root>
</Box>
```

### Sizes

`AppBar` comes in two sizes: `medium` and `small`. By default, it uses `medium` size.

```jsx
<Box css={{ height: '350px' }}>
  <Flex gap="spacingL" css={{ height: '100%' }}>
    <AppBar.Root>
      <AppBar.Logo />
      <AppBar.Items>
        {/*
        `data-active` is used to prevent scrolling to active item in the playground.
        You should use `isActive` prop instead.
       */}
        <AppBar.Item iconName="layout" label="Dashboard" data-active />
        <AppBar.Item iconName="pin" label="Map" />
        <AppBar.Item iconName="timeseries" label="Time series" isDisabled />
        <AppBar.Item iconName="settings" label="Settings" />
      </AppBar.Items>
    </AppBar.Root>
    <AppBar.Root size="small">
      <AppBar.Logo />
      <AppBar.Items>
        <AppBar.Item iconName="layout" label="Dashboard" data-active />
        <AppBar.Item iconName="pin" label="Map" />
        <AppBar.Item iconName="timeseries" label="Time series" isDisabled />
        <AppBar.Item iconName="settings" label="Settings" />
      </AppBar.Items>
    </AppBar.Root>
  </Flex>
</Box>
```

### Items overflow

When the number of items in the app bar exceeds the available vertical space, the app bar automatically becomes scrollable. Users can scroll to access items that are not immediately visible.

Additionally, when an item is set as active using `isActive` property, the app bar will automatically scroll to bring the active item into view.

```jsx
<Box css={{ height: '350px' }}>
  <AppBar.Root>
    <AppBar.Logo />
    <AppBar.Items>
      <AppBar.Item iconName="layout" label="Dashboard" />
      <AppBar.Item iconName="pin" label="Map" />
      <AppBar.Item iconName="timeseries" label="Time series" />
      <AppBar.Item iconName="settings" label="Settings" />
    </AppBar.Items>
  </AppBar.Root>
</Box>
```

### Custom SVG icon

`AppBar.Item` accepts subset of [SVG Icon props](/components/svg-icon#api-reference), so you can reference any icon from [our set](/tokens/icons#browse-icons) via the `iconName` property.
You can also provide your own SVG path data via the `pathData` property to display a custom icon.
For full control, you can even pass a custom SVG element as a child of `AppBar.Item`.

```jsx
<Box css={{ height: '350px' }}>
  <AppBar.Root>
    <AppBar.Logo />
    <AppBar.Items>
      <AppBar.Item
        label="Custom path data"
        svgSize="20"
        pathData="M7 2a1 1 0 0 0-.707 1.707L7 4.414v3.758a1 1 0 0 1-.293.707l-4 4C.817 14.769 2.156 18 4.828 18h10.343c2.673 0 4.012-3.231 2.122-5.121l-4-4A1 1 0 0 1 13 8.172V4.414l.707-.707A1 1 0 0 0 13 2zm2 6.172V4h2v4.172a3 3 0 0 0 .879 2.12l1.027 1.028a4 4 0 0 0-2.171.102l-.47.156a4 4 0 0 1-2.53 0l-.563-.187-.114-.035 1.063-1.063A3 3 0 0 0 9 8.172"
      />
      <AppBar.Item label="Custom SVG element">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
        >
          <path
            d="M3 8h7a3 3 0 1 0-3-3M4 16h11a3 3 0 1 1-3 3M2 12h17a3 3 0 1 0-3-3"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </AppBar.Item>
    </AppBar.Items>
  </AppBar.Root>
</Box>
```

### With app frame

To integrate the `AppBar` seamlessly into your application's layout, use it in conjunction with [App Frame component](/components/app-frame). The `AppFrame.AppBar` provides a dedicated slot for placing the `AppBar`.

```jsx
<AppFrame.Root css={{ maxHeight: '50vh' }}>
  <AppFrame.AppHeader>
    <AppHeader.Root size="small">
      <AppHeader.Title>{'Product name'}</AppHeader.Title>
      <AppHeader.ActionList aria-label="Header actions">
        <Tooltip content="Settings" delay={300}>
          <AppHeader.ActionListItem>
            <SvgIcon iconName="settings" />
          </AppHeader.ActionListItem>
        </Tooltip>
        <Tooltip content="Notifications" delay={300}>
          <AppHeader.ActionListItem>
            <SvgIcon iconName="bell" />
          </AppHeader.ActionListItem>
        </Tooltip>
        <AppHeader.ActionListItem>
          <Avatar.Root of={'Max Mustermann'} size="small">
            <Avatar.Initials />
          </Avatar.Root>
        </AppHeader.ActionListItem>
      </AppHeader.ActionList>
    </AppHeader.Root>
  </AppFrame.AppHeader>
  <AppFrame.AppBar>
    <AppBar.Root size="small">
      <AppBar.Logo />
      <AppBar.Items>
        <AppBar.Item iconName="layout" label="Dashboard" />
        <AppBar.Item iconName="pin" label="Map" />
        <AppBar.Item iconName="timeseries" label="Time series" />
      </AppBar.Items>
    </AppBar.Root>
  </AppFrame.AppBar>
</AppFrame.Root>
```

### With routing

If you need to use the `Link` component provided by your routing package (e.g. [React Router](https://reactrouter.com/en/main) or [Next.js](https://nextjs.org/docs/api-reference/next/link)), it's recommended to compose it with `AppBar.Item` via a custom component:

```jsx
import { Link, useMatch, useResolvedPath } from 'react-router-dom';
import { AppBar } from '@gemini-suite/vera-react';

function AppBarItem({ to, ...props }) {
  const resolved = useResolvedPath(to);
  const isActive = Boolean(useMatch({ path: resolved.pathname, end: true }));

  return <AppBar.Item as={Link} to={to} isActive={isActive} {...props} />;
}

function App() {
  return (
    <AppBar.Root>
      <AppBar.Logo />
      <AppBar.Items>
        <AppBarItem iconName="layout" label="Dashboard" to="/dashboard" />
        <AppBarItem iconName="heart" label="Favorites" to="/favorites" />
        <AppBarItem iconName="pin" label="Maps" to="/maps" />
        <AppBarItem iconName="settings" label="Settings" to="/settings" />
      </AppBar.Items>
    </AppBar.Root>
  );
}
```

<Card
  href="https://next--698f15fa99e7b146f9002f64.chromatic.com/?path=/story/components-appbar--with-router"
  title="See complete example in Storybook"
  actionIcon="externalLink"
/>

---

## API Reference

### AppBar.Root

| Name   | Type                  | Default    | Description                    | Required |
| ------ | --------------------- | ---------- | ------------------------------ | -------- |
| `size` | `"medium" \| "small"` | `"medium"` | The size of the app bar items. |          |

### AppBar.Logo

| Name  | Type          | Default | Description                                                                                                                                                                                                                                  | Required |
| ----- | ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `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. |          |

### AppBar.Items

| Name  | Type          | Default | Description                                                                                                                                                                                                                                  | Required |
| ----- | ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `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. |          |

### AppBar.Item

| Name         | Type                                                      | Default  | Description                                                                                                                                                                                                                                                                                  | Required |
| ------------ | --------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`         | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `button` | 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.                                                 |          |
| `label`      | `string`                                                  |          | Text label for the item. Displayed as a tooltip on hover.                                                                                                                                                                                                                                    | Yes      |
| `iconName`   | `IconToken`                                               |          | The name of the icon to display.                                                                                                                                                                                                                                                             |          |
| `pathData`   | `string \| string[]`                                      |          | Path of a custom SVG to display.                                                                                                                                                                                                                                                             |          |
| `svgSize`    | `number`                                                  |          | The size of the visible area of the icon, called `viewBox`. Expands to `0 0 ${svgSize} ${svgSize}` which is a square.                                                                                                                                                                        |          |
| `isActive`   | `boolean`                                                 | `false`  | Set to `true` to represent the currently active item. The item is highlighted and scrolled into view.                                                                                                                                                                                        |          |
| `isDisabled` | `boolean`                                                 | `false`  | When `true`, the item will be disabled, preventing the user from interacting with it.                                                                                                                                                                                                        |          |
