> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Toolbar - Web

> Toolbars are containers for grouping a set of controls, such as buttons, menubuttons, or checkboxes.

> [!NOTE]
>
> For development, import `Toolbar` from
> `@servicetitan/anvil2`. For design, find it in the
> [Anvil2 file](https://www.figma.com/design/xaNQsvRKczoxu7pj0M6QT8/Anvil2-v3?node-id=2625-37561).

![](https://mintcdn.com/servicetitan/uz2PQSvO75TRhQ38/images/docs/web/components/shared/image-of-a-toolbar.png?fit=max\&auto=format\&n=uz2PQSvO75TRhQ38\&q=85\&s=05d4ef34abf258e0219c35c6f7152eee)

## Anatomy

The Toolbar consists of four primary elements that work together to group a set of controls.

![Image of the anatomy of the toolbar, split into five subsections details
below](https://mintcdn.com/servicetitan/ar8TJanaRSxOpbCO/images/docs/web/components/toolbar/design/image-of-the-anatomy-of-the-toolbar-split-into-five-subsections-details-below.png?fit=max\&auto=format\&n=ar8TJanaRSxOpbCO\&q=85\&s=c628a1b3275ec94ba9a93ff4d5d74fbd)

1. Individual tools
2. Button
3. Select
4. Additional tools overflow menu

## Options

The Toolbar supports the following configurations to accommodate various control grouping scenarios.

### Direction

#### Horizontal Toolbar

toolbar-horizontal

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-horizontal?file=src/App.tsx)

```tsx lines theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ padding: "20px" }}>
      <div>
        <Toolbar associatedContent="basic toolbar" direction="horizontal">
          <Toolbar.Button
            onClick={() => console.log("File button default clicked")}
          >
            File
          </Toolbar.Button>
          <Toolbar.Button
            appearance="primary"
            onClick={() => console.log("File button default clicked")}
          >
            File
          </Toolbar.Button>

          <Toolbar.ButtonToggle
            defaultChecked
            onClick={() =>
              console.log("Bold button toggle uncontrolled clicked")
            }
          >
            Bold
          </Toolbar.ButtonToggle>

          <Toolbar.ButtonLink
            href="#"
            onClick={() => console.log("View Report default clicked")}
          >
            View Report
          </Toolbar.ButtonLink>

          <Toolbar.Select
            accessibleLabel="Status"
            appearance="primary"
            items={[
              { id: "status1", label: "Active" },
              { id: "status2", label: "Pending" },
              { id: "status3", label: "Completed" },
              { id: "status4", label: "Cancelled", disabled: true },
            ]}
            onChange={() => console.log("Status select changed")}
          />

          <Toolbar.Select
            accessibleLabel="Status"
            items={[
              { id: "status1", label: "Active" },
              { id: "status2", label: "Pending" },
              { id: "status3", label: "Completed" },
              { id: "status4", label: "Cancelled", disabled: true },
            ]}
            onChange={() => console.log("Status select changed")}
          />
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

#### Vertical Toolbar

toolbar-vertical

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-vertical?file=src/App.tsx)

```tsx lines theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ padding: "20px" }}>
      <div>
        <Toolbar associatedContent="basic toolbar" direction="vertical">
          <Toolbar.Button
            onClick={() => console.log("File button default clicked")}
          >
            File
          </Toolbar.Button>

          <Toolbar.ButtonToggle
            defaultChecked
            onClick={() =>
              console.log("Bold button toggle uncontrolled clicked")
            }
          >
            Bold
          </Toolbar.ButtonToggle>

          <Toolbar.ButtonLink
            href="#"
            onClick={() => console.log("View Report default clicked")}
          >
            View Report
          </Toolbar.ButtonLink>

          <Toolbar.Select
            accessibleLabel="Status"
            items={[
              { id: "status1", label: "Active" },
              { id: "status2", label: "Pending" },
              { id: "status3", label: "Completed" },
              { id: "status4", label: "Cancelled", disabled: true },
            ]}
            onChange={() => console.log("Status select changed")}
          />
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

| Direction | Description |
| - | - |
| Horizontal | The default behavior, which lays out tools horizontally. |
| Vertical | Lays out tools vertically. |

### Search Beta

Toolbar supports an optional search component that displays a Search Field for filtering or searching content.

toolbar-search

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-search?file=src/App.tsx)

```tsx lines theme={null}
import { Toolbar } from "@servicetitan/anvil2/beta";
import { useState, type ChangeEvent } from "react";

function App() {
  const [searchValue, setSearchValue] = useState("");

  return (
    <div style={{ padding: "20px" }}>
      <div>
        <Toolbar associatedContent="data table toolbar">
          <Toolbar.Search
            placeholder="Search records..."
            value={searchValue}
            onChange={(e: ChangeEvent<HTMLInputElement>) =>
              setSearchValue(e.target.value)
            }
            onClear={() => setSearchValue("")}
          />

          <Toolbar.Button onClick={() => console.log("Export button clicked")}>
            Export
          </Toolbar.Button>
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

The Search Field should be placed on the left as the first item in the toolbar when used.

### Size

Toolbar supports four size options that control the dimensions of all child components. The size propagates to buttons, toggles, links, and selects within the toolbar via context.

| Size | Description |
| - | - |
| XSmall | Minimal sizing for highly compact or space-constrained layouts. |
| Small | Compact sizing for dense layouts or secondary toolbars. |
| Medium | The default size, suitable for most toolbar use cases. |
| Large | Larger sizing for increased touch targets or prominent toolbars. |

## Behavior

The Toolbar responds to space constraints with wrapping and collapse behaviors while maintaining consistent control grouping.

### Wrapping

#### Toolbar with Wrapping Behavior

toolbar-overflow-wrap

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-overflow-wrap?file=src/App.tsx)

```tsx lines theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ padding: "20px" }}>
      <div
        style={{
          maxWidth: "220px",
        }}
      >
        <Toolbar associatedContent="basic toolbar">
          <Toolbar.Button
            onClick={() => console.log("File button default clicked")}
          >
            File
          </Toolbar.Button>

          <Toolbar.ButtonToggle
            defaultChecked
            onClick={() =>
              console.log("Bold button toggle uncontrolled clicked")
            }
          >
            Bold
          </Toolbar.ButtonToggle>

          <Toolbar.ButtonLink
            href="#"
            onClick={() => console.log("View Report default clicked")}
          >
            View Report
          </Toolbar.ButtonLink>

          <Toolbar.Select
            accessibleLabel="Status"
            items={[
              { id: "status1", label: "Active" },
              { id: "status2", label: "Pending" },
              { id: "status3", label: "Completed" },
              { id: "status4", label: "Cancelled", disabled: true },
            ]}
            onChange={() => console.log("Status select changed")}
          />
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

#### Toolbar with Collapse Behavior

toolbar-overflow-collapse

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-overflow-collapse?file=src/App.tsx)

```tsx lines theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function App() {
  return (
    <div style={{ padding: "20px" }}>
      <div
        style={{
          maxWidth: "220px",
        }}
      >
        <Toolbar associatedContent="basic toolbar" overflow="collapse">
          <Toolbar.Button
            onClick={() => console.log("File button default clicked")}
          >
            File
          </Toolbar.Button>

          <Toolbar.ButtonToggle
            defaultChecked
            onClick={() =>
              console.log("Bold button toggle uncontrolled clicked")
            }
          >
            Bold
          </Toolbar.ButtonToggle>

          <Toolbar.ButtonLink
            href="#"
            onClick={() => console.log("View Report default clicked")}
          >
            View Report
          </Toolbar.ButtonLink>

          <Toolbar.Select
            accessibleLabel="Status"
            items={[
              { id: "status1", label: "Active" },
              { id: "status2", label: "Pending" },
              { id: "status3", label: "Completed" },
              { id: "status4", label: "Cancelled", disabled: true },
            ]}
            onChange={() => console.log("Status select changed")}
          />
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

| Overflow Handling | Description |
| - | - |
| Wrap | The default behavior, which wraps filters on resize. |
| Collapse | Collapses filters on resize behind an overflow menu. |

### Collapse Overflow

Overflow collapses in the same order as the DOM. The topmost item in the overflow menu is the first to reappear in the DOM when resizing to a wider width.

## Usage Guidelines

| Standard | Requirement |
| - | - |
| DoUse across WYSIWYGs and quick actions | Use Toolbar in multiple places such as WYSIWYGs, table quick actions, page header actions, or the Toolbelt experience. |
| DoProvide contextual actions below | Use Toolbar to provide contextual actions to users on the items below it, such as an emoji reaction to a comment or a font-styling option in a rich text editor. |
| Don'tUse for many actions | Avoid using Toolbar when there are many actions users can take on the items below. Use Toolbar to provide quick, contextual, and relevant actions. |
| Don'tBatch filter API calls | Avoid using Toolbar when you need to batch filter API calls based on user actions. |
| Don'tUse for complex filters | Avoid using Toolbar for complex filters. |

## Content

Content within the Toolbar should provide clear, contextual actions through grouped controls.

## Keyboard Interaction

Users can navigate the Toolbar using standard keyboard controls.

| Key | Interaction |
| - | - |
| Tab and Shift + Tab | Move focus into and out of the toolbar |
| Left Arrow / Up Arrow | Moves focus to the previous control. This wraps to last control if current control is the first. Note that this is on DOM level so direction doesn't matter. |
| Right Arrow/ Down Arrow | Moves focus to the next control. This wraps to first control if current control is the last. Note that this is on DOM level so direction doesn't matter. |
| Home | Moves focus to the first control |
| End | Moves focus to the last control |

### Accessibility

#### Accessibility

Keyboard interaction and aria guideline to follow [WCAG Toolbar pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/).

Since some ScreenReaders do not read disabled elements properly, we will enable focus for disabled controls using `disabled` as prop but internal assigning that to `aria-disabled` with style and function to block user interaction.

For more guidance on form field labels and context, see [input field context association best practices](https://anvil.servicetitan.com/docs/accessibility/labels-and-ctas.md#input-field-context-association).

## Code

**Implementation**

toolbar-playground

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-playground?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Toolbar } from "@servicetitan/anvil2";
import Edit from "@servicetitan/anvil2/assets/icons/material/round/edit.svg";
import Warning from "@servicetitan/anvil2/assets/icons/material/round/warning.svg";

function App() {
  const selectItems = [
    { id: "status1", label: "Active" },
    { id: "status2", label: "Pending" },
    { id: "status3", label: "Completed" },
    { id: "status4", label: "Cancelled", disabled: true },
  ];

  const additionalItems = [
    <Toolbar.Button key="1" onClick={console.log}>
      Additional Action 1
    </Toolbar.Button>,
    <Toolbar.Button key="2" onClick={console.log}>
      Additional Action 2
    </Toolbar.Button>,
  ];

  return (
    <div>
      <Toolbar
        associatedContent="playground toolbar"
        additionalItems={additionalItems}
        overflow="collapse"
      >
        <Toolbar.Button
          icon={Edit}
          onClick={console.log}
          aria-label="Edit option"
        />

        <Toolbar.ButtonToggle onClick={console.log}>Bold</Toolbar.ButtonToggle>

        <Toolbar.ButtonLink
          href="https://anvil.servicetitan.com/"
          target="_blank"
          icon={{ before: Warning }}
          appearance="primary"
        >
          View Report
        </Toolbar.ButtonLink>

        <Toolbar.Select
          accessibleLabel="Status"
          items={selectItems}
          onChange={console.log}
        />
      </Toolbar>
    </div>
  );
}

export default App;
```

## Common Examples

```tsx theme={null}
import {Toolbar} from "@servicetitan/anvil2";

function ExampleComponent() {
  const selectItems = [
      ...
    ];

  const additionalItems = [
    ...
  ];

  return (
    <Toolbar
      associatedContent="..."
      additionalItems={additionalItems}
      overflow="collapse">
        <Toolbar.Button
          icon={...}
          onClick={...}
          aria-label="..."
        />

        <Toolbar.ButtonToggle
          onClick={...}>
          ...
        </Toolbar.ButtonToggle>

        <Toolbar.ButtonLink
          href={...}>
           ...
        </Toolbar.ButtonLink>

        <Toolbar.Select
          accessibleLabel="..."
          items={selectItems}
          onChange={...} />
    </Toolbar>
  )
}
```

### Toolbar Components

The Anvil2 toolbar is made up a main `Toolbar` component and a few sub-components that can be used together to build simple or complex bars.

* `Toolbar`: The parent component to configure toolbars.
* `Toolbar.Button`: Used to create simple actions that need to be triggered via a button such as opening up a dialog.
* `Toolbar.ButtonToggle`: Used to create simple actions that rely on a boolean response such as text font styles for a rich text editor.
* `Toolbar.ButtonLink`: Used to create links to other sources such as download links.
* `Toolbar.Select`: Used to create a single select drop down for items such as heading size selection for a rich text editor.
* `Toolbar.Search` Beta: Used to create a search input field for filtering or searching content.

The components above should be the only items used within a toolbar to ensure look, feel, and overflow interactions remain consistent.

### Using Toolbar with FilterBar Beta

When a page needs both toolbar actions and filters, compose Toolbar and [FilterBar](https://anvil.servicetitan.com/docs/components/filter-bar/code#filters-with-additional-toolbar-items) as siblings in a horizontal Flex row. Constrain the Toolbar with `style={{ flex: "0 0 auto", width: "fit-content" }}` and give FilterBar `flexGrow={1}` so the Toolbar does not expand and collapse the filters.

filter-bar-with-toolbar

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/filter-bar-with-toolbar?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Flex } from "@servicetitan/anvil2";
import AttachFile from "@servicetitan/anvil2/assets/icons/material/round/attach_file.svg";
import FormatBold from "@servicetitan/anvil2/assets/icons/material/round/format_bold.svg";
import { FilterBar, Toolbar, type Filter } from "@servicetitan/anvil2/beta";
import { useState } from "react";

function App() {
  const [filters, setFilters] = useState<Filter[]>([
    {
      id: "activeFilter",
      type: "boolean",
      label: "Active only",
      checked: false,
    },
    {
      id: "statusFilter",
      type: "singleSelect",
      label: "Status",
      options: [
        { id: "active", label: "Active" },
        { id: "inactive", label: "Inactive" },
      ],
    },
    {
      id: "categoryFilter",
      type: "multiSelect",
      label: "Category",
      options: [
        { id: "plumbing", label: "Plumbing" },
        { id: "hvac", label: "HVAC" },
        { id: "electrical", label: "Electrical" },
      ],
      selectedOptions: [],
    },
  ]);

  return (
    // minWidth is demo-only so this preview stays wide enough for inline
    // filters. Omit it in your app; width: "100%" is the layout.
    <Flex alignItems="center" style={{ width: "100%", minWidth: "800px" }}>
      <FilterBar
        associatedContent="jobs table"
        filters={filters}
        flexGrow={1}
        onFilterChange={setFilters}
      />
      <Toolbar
        associatedContent="jobs table actions"
        style={{ flex: "0 0 auto", width: "fit-content" }}
      >
        <Toolbar.Button icon={AttachFile} aria-label="Attach file" />
        <Toolbar.Button icon={FormatBold} aria-label="Format bold" />
      </Toolbar>
    </Flex>
  );
}

export default App;
```

See the [FilterBar code docs](https://anvil.servicetitan.com/docs/components/filter-bar/code#filters-with-additional-toolbar-items) for the full layout and keyboard details.

### Using Toolbar.Search Beta

The `Toolbar.Search` component provides a search input field for filtering or searching content within the context of a toolbar.

toolbar-search

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/toolbar-search?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Toolbar } from "@servicetitan/anvil2/beta";
import { useState, type ChangeEvent } from "react";

function App() {
  const [searchValue, setSearchValue] = useState("");

  return (
    <div style={{ padding: "20px" }}>
      <div>
        <Toolbar associatedContent="data table toolbar">
          <Toolbar.Search
            placeholder="Search records..."
            value={searchValue}
            onChange={(e: ChangeEvent<HTMLInputElement>) =>
              setSearchValue(e.target.value)
            }
            onClear={() => setSearchValue("")}
          />

          <Toolbar.Button onClick={() => console.log("Export button clicked")}>
            Export
          </Toolbar.Button>
        </Toolbar>
      </div>
    </div>
  );
}

export default App;
```

## React Accessibility

* Keyboard interaction and aria guideline to follow [WCAG Toolbar pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/).
* For controls that have the option to be icon only in view, aria-labels are required.
* The `Toolbar` component has a required prop of `associatedContent` to properly populate an `aria-label` for the component itself.
* `Toolbar.Select` has an `accessibleLabel` prop to properly link the list of select items to the trigger.
* `Toolbar.Search` uses a search input with a clear button that is keyboard accessible via arrow keys.

For more guidance on form field labels and context, see [input field context association best practices](https://anvil.servicetitan.com/docs/accessibility/labels-and-ctas.md#input-field-context-association).

## Testing

The toolbar's leaf controls, overflow menu, and (in beta) search field carry a stable `data-anv-part` attribute so end-to-end tests can target them directly. The library owns the part names; you supply the instance identifier.

Attach your own `data-*` attribute (such as `data-cy` or `data-testid`) to the `Toolbar`. It is forwarded to the root element, letting you scope queries to a single instance:

```tsx theme={null}
<Toolbar data-cy="editor-toolbar" associatedContent="document editor" {...rest} />
```

```ts theme={null}
// Target a leaf button by part + accessible name
cy.get('[data-cy="editor-toolbar"] [data-anv-part="item"]').contains("Save").click();

// Open the overflow menu, then target a menu item
cy.get('[data-cy="editor-toolbar"] [data-anv-part="trigger"]').click();
cy.get('[data-anv-part="overflow-item"]').first().click();
```

Collapsed overflow items also carry `data-id` matching the item's id, so you can target a specific row with `[data-anv-part="overflow-item"][data-id="…"]`. Discriminate repeated `item` parts with `aria-label`, `id`, or a consumer `data-*` on the leaf control.

| `data-anv-part` | Element |
| - | - |
| `item` | A leaf `Toolbar.Button` / `Toolbar.ButtonToggle` |
| `trigger` | Overflow menu trigger button |
| `menu` | Overflow menu list (`role="menu"`) |
| `overflow-item` | A single overflow menu row (`role="menuitem"`) |
| `input` | Search field text input (`Toolbar.Search`, beta only) |

`Toolbar.ButtonLink` and `Toolbar.Select` do not receive a library `item` part yet — pass your own `data-*` attributes on those components when you need to target them. Callers may override `item` (for example, FilterBar stamps `trigger` on boolean toggles).

> [!NOTE]
>
> The overflow menu renders in the browser's top layer (`menu` and `overflow-item` parts), outside the Toolbar root. Descendant queries scoped to your wrapper attribute will not match those parts after the menu opens. Target them by their part attribute directly. Only one overflow menu is open at a time.

**Toolbar Props**

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function ExampleComponent() {
  return (
    <Toolbar
      associatedContent="document editor"
      direction="horizontal"
      overflow="wrap"
      size="xsmall"
      additionalItems={[]}
    >
      {/* Toolbar content */}
    </Toolbar>
  );
}
```

## `Toolbar` Props

**associatedContent** `string` *required*

Denotes what content the toolbar is associated with so that it can properly
populate the aria-label.

**additionalItems** `ReactElement[]`

Secondary actions that will be put in a menu at the end of the toolbar. While
the type for this is a generic ReactElement, it is recommended that additional
items only be `Toolbar.Button`, `Toolbar.ButtonLink`, `Toolbar.ButtonToggle`,
and `Toolbar.Select`. **Note:** This menu also gets the items that get moved due
to size constraints when the overflow is set to collapse.

**direction** `"horizontal" | "vertical"` (default: horizontal)

Determines the direction the toolbar flows.

Note: The direction determines which arrow keys are used for navigating through the toolbar via keyboard actions.

**overflow** `"wrap" | "collapse"` (default: wrap)

Determines if the toolbar controls will wrap to a new line when they run out
of space or if they will be added to an overflow menu that gets appended to
the end of the toolbar.

**size** `"xsmall" | "small" | "medium" | "large"` (default: xsmall)

Controls the size of all toolbar child components. The size propagates to
all `Toolbar.Button`, `Toolbar.ButtonToggle`, `Toolbar.ButtonLink`, and
`Toolbar.Select` items via context.

**Toolbar.Button Props**

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function ExampleComponent() {
return (

<Toolbar.Button
  appearance="ghost"
  icon={Icon}
  aria-label="Button label"
  onClick={() => {}}
/>
); }

```

## `Toolbar.Button` Props

In addition to the props listed below, the `Toolbar.Button` component can accept any of the [Button](https://anvil.servicetitan.com/docs/components/button/react-native.md) props with the exception of `appearance`, which is custom for this component.

For accessibility compliance, if the button is icon-only, an `aria-label` becomes a required prop.

**onClick** `(e: MouseEvent) =\> void` *required*

Callback when the button is clicked.

**appearance** `"ghost" | "primary"` (default: ghost)

**Toolbar.ButtonLink Props**

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function ExampleComponent() {
  return (
    <Toolbar.ButtonLink
      appearance="ghost"
      href="/example"
    >
      Link Text
    </Toolbar.ButtonLink>
  );
}
```

## `Toolbar.ButtonLink` Props

In addition to the props listed below, the `Toolbar.ButtonLink` component can accept any of the [ButtonLink](https://anvil.servicetitan.com/docs/components/button/react-native.md) props with the exception of `appearance`, which is custom for this component.

**appearance** `"ghost" | "primary"` (default: ghost)

**Toolbar.ButtonToggle Props**

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function ExampleComponent() {
return (

<Toolbar.ButtonToggle aria-label="Toggle label" defaultChecked={false}>
  Toggle
</Toolbar.ButtonToggle>
); }

```

## `Toolbar.ButtonToggle` Props

The `Toolbar.ButtonToggle` component can accept any of the [A2 ButtonToggle](https://anvil.servicetitan.com/docs/components/button-toggle/code) props, as well as any other HTML `button` props.

`Toolbar.ButtonToggle` can be either controlled or uncontrolled.

For accessibility compliance, if the button toggle is an icon only button an `aria-label` becomes a required prop.

**Toolbar.Select Props**

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2";

function ExampleComponent() {
  return (
    <Toolbar.Select
      accessibleLabel="Select label"
      items={items}
      selected="item-1"
      appearance="ghost"
      onChange={(id) => console.log(id)}
    />
  );
}
```

## `Toolbar.Select` Props

The `Toolbar.Select` is comprised of an [A2 Popover](https://anvil.servicetitan.com/docs/components/popover) with an [A2 Listbox](https://anvil.servicetitan.com/docs/components/listbox) for its dropdown.

In addition to the props listed below, the `Toolbar.Select` can accept any of the [A2 Popover Button](https://anvil.servicetitan.com/docs/components/popover/code) props with the exceptions of appearance and onChange, which are custom for this component.

**accessibleLabel** `string`

Label for the select that gets appended to aria tag for the select menu.
Example: "State" becomes "State Options" for the select list label.

**appearance** `"ghost" | "primary"` (default: ghost)

**items** `ItemType & \{ id: string \}[]`

The options for the single select. The label is what will be visible in the
option and in the select trigger upon selection.

**onChange** `(optionId: string) =\> void`

Sets the selected item to your select as well as triggers any further onChange
you pass to the component.

**selected** `string` (default: first item id)

By default the first item in the items array is set to the selected item.

**Toolbar.Search Props**

Beta

```tsx theme={null}
import { Toolbar } from "@servicetitan/anvil2/beta";

function ExampleComponent() {
  return (
    <Toolbar.Search
      placeholder="Search..."
      onChange={...}
      onClear={...}
    />
  );
}
```

## `Toolbar.Search` Props

The `Toolbar.Search` component is a specialized search input field designed for use within toolbars. It wraps the [SearchField](https://anvil.servicetitan.com/docs/components/search-field/code) component and automatically inherits its size from the parent Toolbar context.

In addition to the props listed below, the `Toolbar.Search` component can accept any of the standard HTML input attributes and [SearchField](https://anvil.servicetitan.com/docs/components/search-field/code) props with the exception of `size`, which is inherited from the parent Toolbar.

**autoComplete** `string` (default: off)

Controls the browser's autocomplete behavior for the search field.

**className** `string`

Additional CSS classes to apply to the search field.

**disabled** `boolean` (default: false)

Whether the search field is disabled.

**onChange** `(e: ChangeEvent\<HTMLInputElement\>) =\> void`

Callback function triggered when the input value changes.

**onClear** `() =\> void`

Callback function triggered when the clear button is clicked or activated via keyboard (Enter or Space).

**placeholder** `string` (default: Search...)

Placeholder text displayed when the input is empty.

**value** `string`

The controlled value of the search field. Use with `onChange` for controlled components.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.