Skip to main content
Vuetify0 is now in alpha!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

createCombobox

Low-level combobox coordinator for custom implementations. Most users should use the Combobox component instead.

Usage

ts
import { createCombobox } from '@vuetify/v0'

const combobox = createCombobox({ strict: true })

// Register items with the underlying selection
combobox.selection.register({ id: 'apple', value: 'Apple' })
combobox.selection.register({ id: 'banana', value: 'Banana' })
combobox.selection.register({ id: 'cherry', value: 'Cherry' })

// Open the dropdown
combobox.open()

// Select an item — in single mode this updates the query and closes
combobox.select('banana')
// combobox.query.value === 'Banana'
// combobox.isOpen.value === false

// Filter is pristine after selection — all items still visible
// combobox.pristine.value === true

// Once user types, the filter activates
combobox.query.value = 'ch'
// combobox.pristine.value === false
// combobox.filtered.value === Set { 'cherry' }

Architecture

createCombobox orchestrates four independent primitives without extending their chains — it composes them. The adapter translates queries into a filtered set; virtual focus uses that set to skip hidden items.

Reactivity

PropertyTypeReactiveNotes
queryShallowRef<string>Current input text
pristineShallowRef<boolean>true after selection; false once user types
filteredRef<Set<ID>>IDs that pass the current filter
isEmptyRef<boolean>true when filtered set is empty
isLoadingShallowRef<boolean>Forwarded from adapter
isOpenShallowRef<boolean>Popover open state
selectionSelectionContextFull selection API
popoverPopoverReturnPopover positioning API
cursorVirtualFocusReturnKeyboard focus API
inputElShallowRef<HTMLElement | null>Reference to the <input> element

Options

ts
interface ComboboxOptions {
  multiple?: MaybeRefOrGetter<boolean>   // Enable multi-select
  mandatory?: MaybeRefOrGetter<boolean>  // Prevent deselecting last item
  disabled?: MaybeRefOrGetter<boolean>   // Disable all interaction
  strict?: MaybeRefOrGetter<boolean>     // Revert query on close if no match
  adapter?: ComboboxAdapter              // Filtering strategy (default: ClientComboboxAdapter)
  displayValue?: (value: unknown) => string  // Format selected value for display in input
  id?: string                            // Base ID for ARIA attributes
  name?: string                          // Hidden input name for form submission
  form?: string                          // Associated form ID
}

Context Object

createCombobox returns a ComboboxContext with the following API surface:

MemberTypeDescription
open()() => voidOpens the dropdown
close()() => voidCloses; applies strict revert if needed
toggle()() => voidOpens or closes
select(id)(id: ID) => voidSelects an item by ID
clear()() => voidResets query and deselects all
idstringBase ID used for ARIA relationships
inputIdstring${id}-input
listboxIdstring${id}-listbox
multiplebooleanResolved multiple flag
strictMaybeRefOrGetter<boolean>Strict option ref
disabledMaybeRefOrGetter<boolean>Disabled option ref
namestring | undefinedForm field name
formstring | undefinedAssociated form ID

Adapters

Adapters extend ComboboxAdapter and translate a reactive query into a filtered ID set.

ts
abstract class ComboboxAdapter {
  abstract setup (context: ComboboxAdapterContext): ComboboxAdapterResult
}

interface ComboboxAdapterResult {
  filtered: Ref<Set<ID>>          // IDs that should be visible
  isLoading: ShallowRef<boolean>  // shows loading state in the UI
  isEmpty: Ref<boolean>           // true when no items match the query
}

The context exposes query (the current search string), selection (the underlying selection context), and items (all registered IDs). Return the three refs above and the combobox wires them to the dropdown state automatically.

ClientComboboxAdapter

The default. Filters registered items locally using substring matching (case-insensitive). Pass custom filter options to override the matching logic:

ts
import { ClientComboboxAdapter, createCombobox } from '@vuetify/v0'

const combobox = createCombobox({
  adapter: new ClientComboboxAdapter({
    filter: (query, value) => String(value).toLowerCase().startsWith(query.toLowerCase()),
  }),
})

ServerComboboxAdapter

A pass-through adapter that shows all registered items and sets isLoading to false. Use this when filtering is performed server-side — watch combobox.query to drive your own fetch:

ts
import { ServerComboboxAdapter, createCombobox, useCombobox } from '@vuetify/v0'
import { watch } from 'vue'

const combobox = createCombobox({ adapter: new ServerComboboxAdapter() })

// In a component that injects the context:
const { query } = useCombobox()

watch(query, async q => {
  const results = await fetch(`/api/search?q=${q}`).then(r => r.json())
  // Update items via combobox.selection.register / unregister
})
Tip

See the Combobox server example for a complete integration.

Strict Mode

When strict: true, closing the dropdown without an active selection reverts the query:

  • If an item is selected, query resets to that item’s label.

  • If nothing is selected, query resets to ''.

Non-strict mode (default) leaves whatever text the user typed in place.

Tip

aria-autocomplete="both" is set automatically on the input when strict is enabled, per the WAI-ARIA combobox pattern.

Pristine Flag

pristine tracks whether the query reflects the current selection or is a live filter:

  • Starts as true (no user input yet).

  • Becomes false when the user types — the adapter receives the raw query.

  • Resets to true after a selection (select(id)), so reopening the dropdown always shows all items instead of the previous typed query.

ts
// The adapter receives `search`, not `query` directly
const search = toRef(() => pristine.value ? '' : query.value)
const { filtered } = adapter.setup({ query: search, items })

Multi-Select Behavior

In multiple mode, select(id) differs from single mode:

  • Toggles the item (select → deselect on second click) via selection.toggle().

  • Clears the query so the user can search for the next item.

  • Keeps the dropdown open.

  • Highlights the clicked item via cursor.highlight(id) so ArrowDown continues from that position.

  • Refocuses the input so keyboard navigation continues immediately.

Dependency Injection

Use createComboboxContext to get a DI-aware trinity for component-based setups:

ts
import { createComboboxContext, useCombobox } from '@vuetify/v0'

// In a Root component
const [useMyCombobox, provideMyCombobox, context] = createComboboxContext({
  namespace: 'my-combobox',
  strict: true,
})
provideMyCombobox(context)

// In any child component
const combobox = useCombobox('my-combobox')

useCombobox(namespace?) injects the nearest combobox context (default namespace: 'v0:combobox').

Examples

API Reference

The following API details are for the createCombobox composable.
Was this page helpful?

Ctrl+/