<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, andToolbar.InputGroupinherit the toolbarsize.Toolbar.Buttonalways renders with quiet toolbar button styling.Toolbar.Linkrenders aLinkButtonwith quiet styling and participates in arrow-key navigation.Toolbar.InputGrouppasses props directly toInputGroupwith the toolbarsize.- The Select
triggerslot forwards Ark UI trigger behavior to its single child. Combobox.TriggerInputandCombobox.TriggerValueforward behavior whenas-childis set.- Composed popup controls keep selection, filtering, form state, and popup positioning.
- Use
aria-labeloraria-labelledbyfor 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>Links
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 / Slot | Type | Default | Description |
|---|---|---|---|
default | slot | - | Toolbar controls rendered as one grouped card. |
size | "xs" | "sm" | "base" | "lg" | "base" | Locks every supported toolbar item to this size. |
class | string | - | 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>