Combobox
A headless autocomplete input that filters options as the user types, with client and server-side filtering support.
Usage
The Combobox component follows the same compound pattern as Select, but replaces the activator button with a Control input that accepts free text. Filtering happens automatically as the user types.
Selected: None
Anatomy
<script setup lang="ts">
import { Combobox } from '@vuetify/v0'
</script>
<template>
<Combobox.Root>
<Combobox.Activator>
<Combobox.Control />
<Combobox.Cue />
</Combobox.Activator>
<Combobox.Description />
<Combobox.Error />
<Combobox.Content>
<Combobox.Item />
<Combobox.Empty />
</Combobox.Content>
</Combobox.Root>
</template>Architecture
Root creates selection, virtual focus, popover, and adapter contexts. Control drives the query string — the adapter translates queries into a filtered ID set. Items register with selection and use v-show (not v-if) against the filtered set, preserving selection state even when hidden. Empty renders when the filtered set is empty. Description and Error provide accessible help text and validation messages linked to Control via ARIA attributes.
Examples
Recipes
Form Submission
Set name on Root to auto-render hidden inputs for form submission — one per selected value in multi-select mode:
<template>
<Combobox.Root v-model="value" name="country">
<!-- ... -->
</Combobox.Root>
</template>Custom Client Filtering
Pass a ClientComboboxAdapter with a custom filter function to override the default substring matching:
<script setup lang="ts">
import { Combobox, ClientComboboxAdapter } from '@vuetify/v0'
const adapter = new ClientComboboxAdapter({
filter: (query, value) => String(value).toLowerCase().startsWith(query.toLowerCase()),
})
</script>
<template>
<Combobox.Root :adapter>
<!-- ... -->
</Combobox.Root>
</template>Open on Input Only
By default the dropdown opens on focus. Set open-on="input" on Control to only open when the user starts typing — useful for server search where an empty query should not trigger a fetch:
<template>
<Combobox.Control open-on="input" placeholder="Type to search…" />
</template>Data Attributes
Style interactive states without slot props:
| Attribute | Values | Component |
|---|---|---|
data-selected | true | Item |
data-highlighted | "" | Item |
data-disabled | true | Item |
data-state | "open" / "closed" | Activator, Cue |
Accessibility
The Combobox implements the WAI-ARIA Combobox↗︎ pattern with a listbox popup.
ARIA Attributes
| Attribute | Value | Component |
|---|---|---|
role | combobox | Control |
role | listbox | Content |
role | option | Item |
aria-autocomplete | list / both | Control |
aria-expanded | true / false | Control |
aria-haspopup | listbox | Control |
aria-controls | listbox ID | Control |
aria-activedescendant | highlighted option ID | Control |
aria-describedby | description ID | Control (when Description mounted) |
aria-errormessage | error ID | Control (when Error mounted and errors exist) |
aria-invalid | true | Control (when invalid) |
aria-selected | true / false | Item |
aria-disabled | true | Item (when disabled) |
aria-multiselectable | true | Content (when multiple) |
aria-hidden | true | Cue |
aria-live | polite | Error |
aria-autocomplete="both" is set automatically when strict is enabled (versus "list" when free-text is allowed), signaling to assistive tech that the field resolves to one of the listed options.
Keyboard Navigation
| Key | Action |
|---|---|
ArrowDown / ArrowUp | Open dropdown, or move highlight down / up |
Enter | Select highlighted item, or commit the typed value (unless strict) |
Escape | Close dropdown and discard the typed value |
Tab | Accept the highlighted item if one is active, otherwise commit the typed value, then close and move focus |
Home / End | Move the caret in the input; list highlight is cleared |
Click-outside and blur always commit() the query (ignores leftover virtual focus) then close. Tab accepts a highlight when one exists, otherwise commits. Escape / close() cancel without committing.
FAQ
Combobox accepts free text and filters options as the user types. Select is the non-typeahead equivalent, where the user picks from a fixed list without typing.
Pass a ServerComboboxAdapter to Combobox.Root to disable client-side filtering, then debounce the query and run your async lookup. The default ClientComboboxAdapter filters the in-memory list by substring.
Items render with v-show (not v-if) against the filtered set, so they’re hidden rather than unmounted. Selection state is preserved even when an option isn’t currently matched.
Set strict on Combobox.Root. By default, confirming with Enter, Tab, click-outside, or blur commits unmatched text as a free-text value through v-model; with strict, unmatched text is discarded on confirm and the input reverts to the selected option’s value — or clears if nothing is selected — so only registered options can be chosen. Escape (and close()) still cancel.
Set name on Combobox.Root and it auto-renders one hidden input per selected value. Combobox doesn’t export a hidden-input sub-component, so you never place one by hand.