Phi
Toolbar
@dicehub/phiv1.0.0-beta.1

Toolbar

Compose explicit toolbar controls into one clean grouped card.

<script setup>
import { InputGroup } from "@dicehub/phi/components/input-group";
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhFunnelSimple, PhGearSix, PhMagnifyingGlass } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar class="toolbar-demo__wide">
    <Toolbar.InputGroup aria-label="Search DNS records" class="toolbar-demo__grow">
      <InputGroup.Addon>
        <PhMagnifyingGlass />
      </InputGroup.Addon>
      <InputGroup.Input placeholder="Search DNS records" />
    </Toolbar.InputGroup>
    <Toolbar.Button :icon="PhFunnelSimple" aria-label="Filter" />
    <Toolbar.Button :icon="PhGearSix" aria-label="Settings" />
  </Toolbar>
</template>

Installation

Barrel

import { Toolbar } from "@dicehub/phi";

Granular

import { Toolbar } from "@dicehub/phi/components/toolbar";

Usage

Use Toolbar when multiple controls should read as one compact toolbar or filter card. UseToolbar.Button, Toolbar.Link, Toolbar.Input, and Toolbar.InputGroup to opt controls into toolbar sizing and grouped presentation. Compose Select and Combobox triggers with those controls instead of rebuilding their popup behavior.

<script setup>
import { InputGroup } from "@dicehub/phi/components/input-group";
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhFunnelSimple, PhMagnifyingGlass } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar>
    <Toolbar.InputGroup aria-label="Search DNS records">
      <InputGroup.Addon>
        <PhMagnifyingGlass />
      </InputGroup.Addon>
      <InputGroup.Input placeholder="Search DNS records" />
    </Toolbar.InputGroup>
    <Toolbar.Button :icon="PhFunnelSimple" aria-label="Filter" />
  </Toolbar>
</template>

Behavior

Toolbar item components intentionally own grouped control presentation:

  • Toolbar.Button, Toolbar.Link, Toolbar.Input, and Toolbar.InputGroup inherit the toolbar size.
  • Toolbar.Button always renders with quiet toolbar button styling.
  • Toolbar.Link renders a LinkButton with quiet styling and participates in arrow-key navigation.
  • Toolbar.InputGroup passes props directly to InputGroup with the toolbar size.
  • The Select trigger slot forwards Ark UI trigger behavior to its single child.
  • Combobox.TriggerInput and Combobox.TriggerValue forward behavior when as-child is set.
  • Composed popup controls keep selection, filtering, form state, and popup positioning.
  • Use aria-label or aria-labelledby for a composed popup control. Keep field labels and helper text outside the compact toolbar.
  • Adjacent toolbar items share borders and only the outer corners are rounded.
  • Arrow keys move between items. In an editable input, left and right arrows first move the text cursor until it reaches an edge.

Examples

Select

Use the Select trigger slot to apply Ark UI behavior to a Toolbar.Button.

<script setup>
import { Select } from "@dicehub/phi/components/select";
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhFunnelSimple, PhGearSix } from "@phosphor-icons/vue";

const sortItems = { name: "Name", created: "Created date", status: "Status" };
</script>

<template>
  <Toolbar>
    <Toolbar.Button :icon="PhFunnelSimple">Filter</Toolbar.Button>
    <Select aria-label="Sort records" default-value="name" :items="sortItems">
      <template #trigger="{ label }">
        <Toolbar.Button>{{ label }}</Toolbar.Button>
      </template>
    </Select>
    <Toolbar.Button :icon="PhGearSix" aria-label="View settings" />
  </Toolbar>
</template>

Combobox

Use as-child with Combobox.TriggerInput or Combobox.TriggerValue to keep regular Combobox behavior in a toolbar control.

<script setup>
import { Combobox } from "@dicehub/phi/components/combobox";
import { Toolbar } from "@dicehub/phi/components/toolbar";

const statusItems = ["All records", "Active", "Paused", "Failed"];
</script>

<template>
  <Toolbar>
    <Toolbar.Button>Status</Toolbar.Button>
    <Combobox :default-value="['All records']" :items="statusItems">
      <Combobox.TriggerInput as-child>
        <Toolbar.Input aria-label="Filter status" placeholder="Filter status…" />
      </Combobox.TriggerInput>
      <Combobox.Content>
        <Combobox.Empty />
        <Combobox.List>
          <template #default="{ item }">
            <Combobox.Item :item="item">{{ item }}</Combobox.Item>
          </template>
        </Combobox.List>
      </Combobox.Content>
    </Combobox>
  </Toolbar>

  <Toolbar>
    <Combobox :default-value="['All records']" :items="statusItems">
      <Combobox.TriggerValue v-slot="{ label }" as-child aria-label="Choose status">
        <Toolbar.Button>{{ label }}</Toolbar.Button>
      </Combobox.TriggerValue>
      <Combobox.Content>
        <Combobox.List>
          <template #default="{ item }">
            <Combobox.Item :item="item">{{ item }}</Combobox.Item>
          </template>
        </Combobox.List>
      </Combobox.Content>
    </Combobox>
    <Toolbar.Button>Apply</Toolbar.Button>
  </Toolbar>
</template>

Input Shorthand

Use Toolbar.Input for simple text inputs that do not need addons.

<script setup>
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhFunnelSimple, PhGearSix } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar class="toolbar-demo__wide">
    <Toolbar.Input
      aria-label="Search DNS records"
      class="toolbar-demo__grow"
      placeholder="Search DNS records"
    />
    <Toolbar.Button :icon="PhFunnelSimple" aria-label="Filter" />
    <Toolbar.Button :icon="PhGearSix" aria-label="Settings" />
  </Toolbar>
</template>

Input Group

Use Toolbar.InputGroup when one toolbar item needs its own inline addon or suffix.

<script setup>
import { InputGroup } from "@dicehub/phi/components/input-group";
import { Toolbar } from "@dicehub/phi/components/toolbar";
</script>

<template>
  <Toolbar class="toolbar-demo__wide toolbar-demo__wide--lg">
    <Toolbar.InputGroup aria-label="Worker subdomain" class="toolbar-demo__grow">
      <InputGroup.Input placeholder="my-worker" />
      <InputGroup.Suffix>.workers.dev</InputGroup.Suffix>
    </Toolbar.InputGroup>
    <Toolbar.Button>Visit</Toolbar.Button>
  </Toolbar>
</template>

Sizes

The size prop supports xs, sm, base, and lg. Every supported toolbar item is locked to the same size.

<script setup>
import { Toolbar, type ToolbarSize } from "@dicehub/phi/components/toolbar";

const sizes: ToolbarSize[] = ["xs", "sm", "base", "lg"];
</script>

<template>
  <div class="toolbar-demo-sizes">
    <div v-for="size in sizes" :key="size" class="toolbar-demo-size-row">
      <span class="toolbar-demo-size-label">{{ size }}</span>
      <Toolbar :size="size">
        <Toolbar.Input :aria-label="`${size} search`" placeholder="Search..." />
        <Toolbar.Button>Apply</Toolbar.Button>
      </Toolbar>
    </div>
  </div>
</template>

Button Actions

Toolbar buttons use quiet styling so grouped actions remain visually quiet and consistent.

<script setup>
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhDownloadSimple, PhUploadSimple } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar>
    <Toolbar.Button :icon="PhUploadSimple">Upload</Toolbar.Button>
    <Toolbar.Button :icon="PhDownloadSimple">Download</Toolbar.Button>
  </Toolbar>
</template>

Use Toolbar.Link for navigation. It uses LinkButton behavior with toolbar size, quiet styling, and arrow-key navigation.

<script setup>
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhBookOpen, PhDownloadSimple } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar>
    <Toolbar.Link href="/docs/components/button" :icon="PhBookOpen">Button docs</Toolbar.Link>
    <Toolbar.Button :icon="PhDownloadSimple">Download</Toolbar.Button>
  </Toolbar>
</template>

Accessible Labels

Use aria-label for compact toolbar controls that do not have visible labels.

<script setup>
import { Toolbar } from "@dicehub/phi/components/toolbar";
import { PhMagnifyingGlass } from "@phosphor-icons/vue";
</script>

<template>
  <Toolbar class="toolbar-demo__wide toolbar-demo__wide--lg">
    <Toolbar.Input
      aria-label="Search records"
      class="toolbar-demo__grow"
      placeholder="Search"
    />
    <Toolbar.Button :icon="PhMagnifyingGlass" aria-label="Search" />
  </Toolbar>
</template>

API Reference

Prop / SlotTypeDefaultDescription
defaultslot-Toolbar controls rendered as one grouped card.
size"xs" | "sm" | "base" | "lg""base"Locks every supported toolbar item to this size.
classstring-Additional CSS classes merged onto the toolbar root.

Select composition

Put one Toolbar.Button in the named Select trigger slot. The slot provideslabel, value, items, empty, and open state.

<Select aria-label="Sort records" :items="sortItems">
  <template #trigger="{ label }">
    <Toolbar.Button>{{ label }}</Toolbar.Button>
  </template>
</Select>

Combobox composition

Set as-child on an editable or value trigger. Give it exactly one toolbar control so Ark UI can merge the Combobox attributes and event handlers into that control.

<Combobox.TriggerInput as-child>
  <Toolbar.Input aria-label="Filter records" />
</Combobox.TriggerInput>

<Combobox.TriggerValue v-slot="{ label }" as-child>
  <Toolbar.Button>{{ label }}</Toolbar.Button>
</Combobox.TriggerValue>