Combobox
Combobox combines free-form text entry with option picking, making it useful for searchable single- and multi-select flows.
Combobox shares Select's size and menu-color preferences; see Select for sizes and Menu Appearance for colors. Its labelClearance prop inherits from fieldContextKey. Preserve the surrounding layout's intended density and add clearance only when its floating label needs it. See the field layout guide.
Props
| Name | Description | Default | Control |
|---|---|---|---|
shapeOptional | Corner style; inherits the shared shape default. M3Shape | undefined | - | - |
sizeOptional | The trigger height. Matches the 32px, 40px, and 56px TextField and Button sizes. TextFieldSize | undefined | - | - |
disabledOptional | Whether the control is disabled. boolean | undefined | - | |
nameOptional | Name used for hidden inputs during form submission. string | undefined | - | |
multipleOptional | Enables multi-select behavior. boolean | undefined | - | - |
labelOptional | Floating label, or accessible-name fallback in external mode. Otherwise supply an external label or ARIA name. string | undefined | - | |
labelBehaviorOptional | Floating label or externally arranged visible label; label remains an accessible-name fallback. FieldLabelBehavior | undefined | - | - |
idOptional | Optional explicit id for the trigger element. string | undefined | - | |
optionsRequired | Selectable options rendered in the menu. SelectOption[] | - | - |
filterModeOptional | Consumer-owned search results bypass local filtering. localexternal | - | |
resolveLabelOptional | Resolve selected values absent from current results; reactive caches are supported. ((value: SelectOptionValue) => string | undefined) | undefined | - | |
supportingTextOptional | Supporting text shown below the field when not in error state. string | undefined | - | |
errorOptional | Error text shown below the field. When provided, field is invalid. string | undefined | - | |
requiredOptional | Whether the control is required. boolean | undefined | - | |
placeholderOptional | Placeholder shown when nothing is selected. string | undefined | - | |
labelClearanceOptional | CSS length reserved at block-start for the floating label. Overrides FieldContext. string | undefined | - | |
showSelectedIconOptional | Show selected checkmarks; inherits Select defaults, then falls back to true. boolean | undefined | undefined | |
clearableOptional | Shows a trailing button that clears the current selection. boolean | undefined | - | |
clearLabelOptional | Accessible label for the clear button. string | undefined | - | |
menuColorOptional | Visual color style of the dropdown menu. MenuColor | undefined | - | - |
displaySeparatorOptional | Separator used when showing multiple selected labels. string | undefined | - | |
filterPlaceholderOptional | Placeholder shown in the field while filtering. string | undefined | - | |
filterNoResultsTextOptional | Message shown when filtering returns no matching options. string | undefined | - | |
modelValueOptional | - SelectModelValue | - | - |
queryOptional | - string | undefined | "" | |
openOptional | - boolean | undefined | false |
Events7
| Name | Type | Description |
|---|---|---|
update:open | [value: boolean] | - |
closed | [] | - |
update:modelValue | [value: SelectModelValue] | - |
update:query | [value: string] | - |
change | [value: SelectModelValue] | - |
focus | [event: FocusEvent] | - |
blur | [event: FocusEvent] | - |
Slots7
| Name | Parameters | Description |
|---|---|---|
list | - | - |
leading | - | - |
prefix | - | - |
suffix | - | - |
trailing | - | - |
optionLeading | - | - |
optionTrailing | - | - |
Combobox forwards Select's closed event after its dropdown menu finishes exiting. Use it instead of update:open(false) when releasing data used by option slots.
INFO
Combobox wraps Select and shares its select scope. See Select Anatomy.
showSelectedIcon and selectDefaults are shared with Select; see selected checkmarks.
Labels follow the shared fieldLabelBehavior default (floating, or external in compact). Override it with label-behavior. External mode omits the visible label and notch, ignores labelClearance, and uses label only as an accessible-name fallback. See Field layout for custom label layouts.
Virtual lists and external search
Combobox forwards list, v-model:query, filterMode, and resolveLabel to Select. Use the same SelectItem composition for virtual rows; filtering and navigation operate on the complete logical result set while focus stays in the input. See external virtual lists and selected label resolution.
Examples
Default
Multiple Selection
Composable
Combobox shares the same composable as Select.
useSelect
Full type signature
function useSelect(opts: UseSelectOptions): { filterQuery: import("vue").Ref<string, string>; selectedOptions: import("vue").ComputedRef<UseSelectOption[]>; hasValue: import("vue").ComputedRef<boolean>; displayText: import("vue").ComputedRef<string>; submittedValues: import("vue").ComputedRef<string[]>; filteredOptionEntries: import("vue").ComputedRef<import("./selectModel").SelectOptionEntry[]>; hasFilteredOptions: import("vue").ComputedRef<boolean>; activeIndex: import("vue").ComputedRef<number>; activeDescendant: import("vue").ComputedRef<string | undefined>; list: import("vue").ComputedRef<{ entries: import("./selectModel").SelectOptionEntry[]; scrollElement: HTMLElement | undefined; activeIndex: number; open: boolean; setScrollToIndex: (callback: ((index: number) => void) | undefined) => void; }>; optionProps: (index: number, option: UseSelectOption) => { id: string; 'aria-posinset': number; 'aria-setsize': number; 'data-active': string | undefined; 'data-keyboard-active': string | undefined; 'data-first': string | undefined; 'data-last': string | undefined; ref: (instance: Element | ComponentPublicInstance | null) => void; onMousedown: (event: MouseEvent) => void; onPointermove: () => void; onClick: () => void; }; isOptionSelected: (option: UseSelectOption) => boolean; toggleOption: (option: UseSelectOption) => void; clearValue: () => void; focus: () => void; blur: () => void; show: () => Promise<void>; hide: () => void; toggle: () => void; openMenu: (target?: "first" | "last") => void; closeMenu: () => void; handleFieldClick: () => void; handleFieldInput: () => void; handleFilterKeydown: (event: KeyboardEvent) => void; handleMenuClosed: () => void; }Source: src/composables/useSelect.ts
| Field | Type | Required | Description | Default |
|---|---|---|---|---|
options | () => UseSelectOption[] | Yes | Unique, stable values identify the complete logical result set. | - |
multiple | () => boolean | Yes | - | - |
filterable | () => boolean | Yes | - | - |
disabled | () => boolean | Yes | - | - |
displaySeparator | () => string | Yes | - | - |
locale | (() => string | undefined) | undefined | No | - | - |
filterMode | (() => "local" | "external") | undefined | No | Disable local filtering when the consumer supplies search results. | - |
resolveLabel | ((value: UseSelectOptionValue) => string | undefined) | undefined | No | Resolve values missing from current results. Falls back to String(value). | - |
query | Ref<string, string> | undefined | No | - | - |
modelValue | Ref<UseSelectModelValue, UseSelectModelValue> | Yes | - | - |
open | Ref<boolean, boolean> | Yes | - | - |
onChange | ((value: UseSelectModelValue) => void) | undefined | No | - | - |
onClosed | (() => void) | undefined | No | - | - |
id | () => string | Yes | Stable listbox id, normally derived from useId(). | - |
focus | () => void | Yes | - | - |
blur | () => void | Yes | - | - |
showMenu | () => void | Yes | Use the shared Menu overlay, including source anchoring and close completion. | - |
hideMenu | () => void | Yes | - | - |
scrollElement | () => HTMLElement | undefined | Yes | The MenuContainer is the single scroll owner. | - |
| Field | Type | Required | Description | Default |
|---|---|---|---|---|
filterQuery | import("vue").Ref<string, string> | Yes | - | - |
selectedOptions | import("vue").ComputedRef<UseSelectOption[]> | Yes | - | - |
hasValue | import("vue").ComputedRef<boolean> | Yes | - | - |
displayText | import("vue").ComputedRef<string> | Yes | - | - |
submittedValues | import("vue").ComputedRef<string[]> | Yes | - | - |
filteredOptionEntries | import("vue").ComputedRef<import("./selectModel").SelectOptionEntry[]> | Yes | - | - |
hasFilteredOptions | import("vue").ComputedRef<boolean> | Yes | - | - |
activeIndex | import("vue").ComputedRef<number> | Yes | - | - |
activeDescendant | import("vue").ComputedRef<string | undefined> | Yes | - | - |
list | import("vue").ComputedRef<{ entries: import("./selectModel").SelectOptionEntry[]; scrollElement: HTMLElement | undefined; activeIndex: number; open: boolean; setScrollToIndex: (callback: ((index: number) => void) | undefined) => void; }> | Yes | - | - |
optionProps | (index: number, option: UseSelectOption) => { id: string; 'aria-posinset': number; 'aria-setsize': number; 'data-active': string | undefined; 'data-keyboard-active': string | undefined; 'data-first': string | undefined; 'data-last': string | undefined; ref: (instance: Element | ComponentPublicInstance | null) => void; onMousedown: (event: MouseEvent) => void; onPointermove: () => void; onClick: () => void; } | Yes | - | - |
isOptionSelected | (option: UseSelectOption) => boolean | Yes | - | - |
toggleOption | (option: UseSelectOption) => void | Yes | - | - |
clearValue | () => void | Yes | - | - |
focus | () => void | Yes | - | - |
blur | () => void | Yes | - | - |
show | () => Promise<void> | Yes | - | - |
hide | () => void | Yes | - | - |
toggle | () => void | Yes | - | - |
openMenu | (target?: "first" | "last") => void | Yes | - | - |
closeMenu | () => void | Yes | - | - |
handleFieldClick | () => void | Yes | - | - |
handleFieldInput | () => void | Yes | - | - |
handleFilterKeydown | (event: KeyboardEvent) => void | Yes | - | - |
handleMenuClosed | () => void | Yes | - | - |