Combobox
Accessible, unstyled Combobox: an editable APG combobox with a typed listbox popup. Popup structure is shared with Select: ComboboxContent, ComboboxItem, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxViewport, ComboboxItemIndicator, ComboboxScrollButton, and ComboboxVirtualizer are the Select parts, which publish data-vize-ui="combobox-*" inside a ComboboxRoot.
|
|
| Package |
@vizejs/ui/combobox |
| Maturity |
stable |
| Own the source |
vize lib pull combobox |
| Requires |
collection, composite-navigation, context, controllable-state, dismissable-layer, id, portal, positioner, presence, select, typeahead, virtualizer |
| Aliases |
combobox, autocomplete, typeahead select, searchable select, multi select chips |
| Covers |
WAI-ARIA combobox pattern (listbox popup), Radix/Reka UI Combobox, React Aria ComboBox, Headless UI Combobox, Ark UI Combobox |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { Combobox, ComboboxRoot, ComboboxAnchor, ComboboxChip, ComboboxChipRemove, ComboboxCreateItem, ComboboxEmpty, ComboboxInput, ComboboxLoading, ComboboxTrigger, ComboboxContent, ComboboxGroup, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxScrollButton, ComboboxSeparator, ComboboxViewport, ComboboxVirtualizer } from "@vizejs/ui/combobox";
Or copy the source into your project with vize lib pull combobox (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Editable combobox that filters a list of time zones as the user types. -->
<script setup lang="ts">
import { ref, useId } from "vue";
import {
Combobox,
ComboboxAnchor,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxItemIndicator,
ComboboxTrigger,
} from "@vizejs/ui/combobox";
const timeZones = [
"Europe/London",
"Europe/Berlin",
"Asia/Tokyo",
"America/New_York",
"Australia/Sydney",
];
const timeZone = ref<string | null>(null);
const labelId = useId();
</script>
<template>
<div>
<span :id="labelId">Time zone</span>
<Combobox v-slot="{ filteredItems }" v-model="timeZone" :items="timeZones" name="timeZone">
<ComboboxAnchor>
<ComboboxInput :aria-labelledby="labelId" placeholder="Search time zones" />
<ComboboxTrigger />
</ComboboxAnchor>
<ComboboxContent>
<ComboboxItem v-for="zone in filteredItems" :key="zone" :value="zone">
{{ zone }}
<ComboboxItemIndicator>✓</ComboboxItemIndicator>
</ComboboxItem>
<ComboboxEmpty>No matching time zones</ComboboxEmpty>
</ComboboxContent>
</Combobox>
<output>Selected: {{ timeZone ?? "none" }}</output>
</div>
</template>
API
Combobox<T, Multiple extends boolean = false>
Source: src/families/selection/combobox/combobox-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
SelectModelValue<T, Multiple> |
undefined |
Controlled selection: T | null, or readonly T[] when multiple is true. |
defaultValue |
SelectModelValue<T, Multiple> |
undefined |
Initial selection for uncontrolled use and the value restored by reset. |
multiple |
Multiple |
false |
Allow selecting several options, rendered as chips. The literal type decides the model type. |
items |
readonly T[] |
undefined |
Every option value. Enables typed inference, root-side filtering exposed as filteredItems, closed-state labels, and virtualization. |
loadItems |
ComboboxLoader<T> |
undefined |
Async item source called (debounced) with the typed query. Its results replace items. |
debounce |
number |
200 |
Debounce in milliseconds before loadItems runs for a new query. |
by |
SelectBy<T> |
undefined |
Compare values by a property key or with a custom equality function. |
itemText |
(value: T) => string |
undefined |
Human-readable text for a value: the input label after selection, chip text, and filter text. |
itemDisabled |
(value: T) => boolean |
undefined |
Disable individual values. |
formValue |
(value: T) => string |
undefined |
Serialize a value for native form submission. |
filter |
ComboboxFilter<T> | false |
undefined |
Filter deciding option visibility; false disables filtering (server-side or custom lists). Defaults to an accent- and case-insensitive "contains" match. |
autocomplete |
ComboboxAutocomplete |
"list" |
APG autocomplete behavior, mirrored to aria-autocomplete. |
strict |
boolean |
true |
Restrict the value to listed options. When false, free text is kept and submitted. |
createOption |
(text: string) => T |
undefined |
Build a value from free text, enabling the create option and Enter-to-create. |
inputValue |
string |
undefined |
Controlled input text. undefined selects uncontrolled behavior. |
defaultInputValue |
string |
"" |
Initial input text for uncontrolled use. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
openOnFocus |
boolean |
false |
Open the popup when the input gains focus. |
autoHighlight |
boolean |
true |
Highlight the first visible option while typing. |
closeOnSelect |
boolean |
undefined |
Close after an option is chosen. undefined closes in single mode only. |
clearOnEscape |
boolean |
true |
Let Escape clear the text (and single selection) while the popup is closed. |
loop |
boolean |
false |
Wrap arrow-key navigation at the first and last option. |
disabled |
boolean |
false |
Disable the input, options, and form submission. |
readonly |
boolean |
false |
Keep the value visible and submittable but prevent editing. |
required |
boolean |
false |
Require a selection (or free text when not strict) for native validation. |
name |
string |
undefined |
Form control name used by the hidden inputs. |
form |
string |
undefined |
Id of the form owner when the combobox renders outside its <form>. |
dir |
"ltr" | "rtl" |
"ltr" |
Reading direction published to parts. |
ariaInvalid |
ComboboxAriaInvalid |
false |
Invalid state announced to assistive technology. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: SelectModelValue<T, Multiple>] |
Fired when the selection requests a new controlled value (T | null or readonly T[]). |
change |
[ value: SelectModelValue<T, Multiple>, previous: SelectModelValue<T, Multiple>, nativeEvent: Event, ] |
Fired after a user interaction changes the selection: next value, previous value, and the native event. |
update:inputValue |
[text: string] |
Fired when the input text requests a new controlled value. |
update:open |
[open: boolean] |
Fired when the popup requests a controlled open value. |
open-change |
[open: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request with the next state, previous state, and triggering event. |
create |
[value: T, text: string] |
Fired when createOption builds a new value from the typed text, before it is selected. |
Slots
| Slot |
Slot props |
Description |
default |
ComboboxSlotState<T> |
Compound Combobox parts. Receives selection, text, filtered items, and loader state. |
Exposed
| Member |
Type |
Description |
clear |
— |
|
deselect |
— |
|
focus |
— |
|
inputValue |
— |
|
open |
— |
|
reload |
— |
|
reset |
— |
|
select |
— |
|
selected |
— |
|
setInputValue |
— |
|
setOpen |
— |
|
ComboboxRoot<T, Multiple extends boolean = false>
Source: src/families/selection/combobox/combobox-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
SelectModelValue<T, Multiple> |
undefined |
Controlled selection: T | null, or readonly T[] when multiple is true. |
defaultValue |
SelectModelValue<T, Multiple> |
undefined |
Initial selection for uncontrolled use and the value restored by reset. |
multiple |
Multiple |
false |
Allow selecting several options, rendered as chips. The literal type decides the model type. |
items |
readonly T[] |
undefined |
Every option value. Enables typed inference, root-side filtering exposed as filteredItems, closed-state labels, and virtualization. |
loadItems |
ComboboxLoader<T> |
undefined |
Async item source called (debounced) with the typed query. Its results replace items. |
debounce |
number |
200 |
Debounce in milliseconds before loadItems runs for a new query. |
by |
SelectBy<T> |
undefined |
Compare values by a property key or with a custom equality function. |
itemText |
(value: T) => string |
undefined |
Human-readable text for a value: the input label after selection, chip text, and filter text. |
itemDisabled |
(value: T) => boolean |
undefined |
Disable individual values. |
formValue |
(value: T) => string |
undefined |
Serialize a value for native form submission. |
filter |
ComboboxFilter<T> | false |
undefined |
Filter deciding option visibility; false disables filtering (server-side or custom lists). Defaults to an accent- and case-insensitive "contains" match. |
autocomplete |
ComboboxAutocomplete |
"list" |
APG autocomplete behavior, mirrored to aria-autocomplete. |
strict |
boolean |
true |
Restrict the value to listed options. When false, free text is kept and submitted. |
createOption |
(text: string) => T |
undefined |
Build a value from free text, enabling the create option and Enter-to-create. |
inputValue |
string |
undefined |
Controlled input text. undefined selects uncontrolled behavior. |
defaultInputValue |
string |
"" |
Initial input text for uncontrolled use. |
open |
boolean |
undefined |
Controlled open state. undefined selects uncontrolled behavior. |
defaultOpen |
boolean |
false |
Initial open state for uncontrolled use. |
openOnFocus |
boolean |
false |
Open the popup when the input gains focus. |
autoHighlight |
boolean |
true |
Highlight the first visible option while typing. |
closeOnSelect |
boolean |
undefined |
Close after an option is chosen. undefined closes in single mode only. |
clearOnEscape |
boolean |
true |
Let Escape clear the text (and single selection) while the popup is closed. |
loop |
boolean |
false |
Wrap arrow-key navigation at the first and last option. |
disabled |
boolean |
false |
Disable the input, options, and form submission. |
readonly |
boolean |
false |
Keep the value visible and submittable but prevent editing. |
required |
boolean |
false |
Require a selection (or free text when not strict) for native validation. |
name |
string |
undefined |
Form control name used by the hidden inputs. |
form |
string |
undefined |
Id of the form owner when the combobox renders outside its <form>. |
dir |
"ltr" | "rtl" |
"ltr" |
Reading direction published to parts. |
ariaInvalid |
ComboboxAriaInvalid |
false |
Invalid state announced to assistive technology. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: SelectModelValue<T, Multiple>] |
Fired when the selection requests a new controlled value (T | null or readonly T[]). |
change |
[ value: SelectModelValue<T, Multiple>, previous: SelectModelValue<T, Multiple>, nativeEvent: Event, ] |
Fired after a user interaction changes the selection: next value, previous value, and the native event. |
update:inputValue |
[text: string] |
Fired when the input text requests a new controlled value. |
update:open |
[open: boolean] |
Fired when the popup requests a controlled open value. |
open-change |
[open: boolean, previous: boolean, nativeEvent: Event | null] |
Fired after any distinct open-state request with the next state, previous state, and triggering event. |
create |
[value: T, text: string] |
Fired when createOption builds a new value from the typed text, before it is selected. |
Slots
| Slot |
Slot props |
Description |
default |
ComboboxSlotState<T> |
Compound Combobox parts. Receives selection, text, filtered items, and loader state. |
Exposed
| Member |
Type |
Description |
selected |
readonly T[] |
Selected values. |
inputValue |
string |
Current input text. |
open |
boolean |
Whether the popup is open. |
setOpen |
(open: boolean, event?: Event | null) => boolean |
Request a specific open state. |
setInputValue |
(text: string) => void |
Replace the input text as if typed (filters and loads). |
select |
(value: T) => boolean |
Select a value (toggle in multiple mode). |
deselect |
(value: T) => boolean |
Deselect a value. |
clear |
() => boolean |
Clear the selection and the text. |
reset |
() => void |
Restore defaults for selection and text. |
reload |
() => void |
Re-run the async loader for the current query. |
focus |
(options?: FocusOptions) => void |
Focus the input. |
ComboboxAnchor
Source: src/families/selection/combobox/combobox-anchor.vue
Slots
| Slot |
Slot props |
Description |
default |
— |
Chips, the input, and the toggle button. The popup is positioned against this box. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
ComboboxChip<T>
Source: src/families/selection/combobox/combobox-chip.vue
Props
| Prop |
Type |
Default |
Description |
value (required) |
T |
required |
Selected value rendered by this chip. |
Slots
| Slot |
Slot props |
Description |
default |
ComboboxChipSlotState<T> |
Chip content, usually the text plus a ComboboxChipRemove. |
ComboboxChipRemove
Source: src/families/selection/combobox/combobox-chip-remove.vue
Props
| Prop |
Type |
Default |
Description |
ariaLabel |
string |
undefined |
Accessible name. Defaults to Remove <chip text>. |
Slots
| Slot |
Slot props |
Description |
default |
— |
Decorative remove icon. |
ComboboxCreateItem
Source: src/families/selection/combobox/combobox-create-item.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned option id. null and undefined select a deterministic fallback. |
Slots
| Slot |
Slot props |
Description |
default |
{ readonly query: string; readonly active: boolean } |
Create-option label, e.g. Create "{{ query }}". Receives the typed text and highlight state. |
ComboboxEmpty
Source: src/families/selection/combobox/combobox-empty.vue
Slots
| Slot |
Slot props |
Description |
default |
{ readonly query: string } |
Message shown when no option is visible and nothing is loading. Receives the query. |
Source: src/families/selection/combobox/combobox-input.vue
Props
| Prop |
Type |
Default |
Description |
placeholder |
string |
undefined |
Hint text shown while the input is empty. |
ariaLabel |
string |
undefined |
Accessible name when no visible label supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids of visible labels; also labels the listbox. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the combobox. |
ariaErrormessage |
string |
undefined |
Id of the validation message announced while invalid. |
autocomplete |
string |
"off" |
Native browser autofill hint; off keeps browser suggestions out of the listbox's way. |
spellcheck |
boolean |
false |
Native spellchecking. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
focus |
— |
|
ComboboxLoading
Source: src/families/selection/combobox/combobox-loading.vue
Slots
| Slot |
Slot props |
Description |
default |
{ readonly query: string } |
Content shown while loadItems is pending. Receives the query being loaded. |
ComboboxTrigger
Source: src/families/selection/combobox/combobox-trigger.vue
Props
| Prop |
Type |
Default |
Description |
ariaLabel |
string |
"Show suggestions" |
Accessible name of the toggle button. |
Slots
| Slot |
Slot props |
Description |
default |
{ readonly open: boolean } |
Decorative toggle content such as a chevron. Receives the open state. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
ComboboxContent
Source: src/families/selection/select/select-content.vue
Props
| Prop |
Type |
Default |
Description |
position |
SelectPosition |
"popper" |
popper anchors below the trigger; item-aligned overlays the selected option on the trigger. |
placement |
Placement |
"bottom-start" |
Preferred popper placement before collision handling. |
strategy |
PositionerStrategy |
"fixed" |
CSS positioning mode published on the floating host. |
offset |
number |
4 |
Gap between trigger and listbox in popper mode. |
collisionPadding |
number |
8 |
Viewport padding the listbox should not cross. |
flip |
boolean |
true |
Flip to the opposite side when the preferred side overflows more (popper mode). |
shift |
boolean |
true |
Shift the listbox back into the viewport. |
size |
boolean |
true |
Publish available-size CSS variables and constrain the host. |
hide |
boolean |
true |
Hide when the trigger scrolls out of view. |
forceMount |
boolean |
false |
Keep options mounted (hidden) while closed so labels and typeahead work before first open. |
to |
string | HTMLElement |
"body" |
CSS selector or element the popup is moved into. |
portalDisabled |
boolean |
false |
Render in place instead of teleporting. |
defer |
boolean |
true |
Keep content in place until the portal target exists, avoiding SSR mismatch. |
closeOnEscape |
boolean |
true |
Let Escape close the popup. |
closeOnPointerDownOutside |
boolean |
true |
Let an outside pointer-down close the popup. |
ariaLabel |
string |
undefined |
Accessible name for the listbox when the trigger label is not enough. |
ariaLabelledby |
string |
undefined |
Space-separated ids labelling the listbox. Defaults to the trigger. |
Events
| Event |
Payload |
Description |
escape-key-down |
[event: SelectEscapeKeyDownEvent] |
Fired before Escape closes the popup. Call preventDefault() to keep it open. |
pointer-down-outside |
[event: SelectPointerDownOutsideEvent] |
Fired before an outside pointer-down closes the popup. Call preventDefault() to keep it open. |
dismiss |
[event: SelectDismissEvent] |
Fired after an unprevented dismissal request closes the popup. |
Slots
| Slot |
Slot props |
Description |
default |
SelectContentSlotState |
Options, groups, separators, viewport, and scroll buttons. Receives open state and placement. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
ComboboxGroup
Source: src/families/selection/select/select-group.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned group id. null and undefined select a deterministic fallback. |
ariaLabel |
string |
undefined |
Accessible group name used instead of a SelectLabel. |
Slots
| Slot |
Slot props |
Description |
default |
— |
A SelectLabel followed by the group's options. |
ComboboxItem<T>
Source: src/families/selection/select/select-item.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned option id. null and undefined select a deterministic fallback. |
value (required) |
T |
required |
Option value compared with the root selection through by. |
disabled |
boolean |
false |
Disable this option. |
textValue |
string |
undefined |
Explicit label for typeahead and SelectValue. undefined extracts the option text. |
index |
number |
undefined |
Absolute index inside the root items, required inside SelectVirtualizer. |
ariaLabel |
string |
undefined |
Accessible name when the option text is not enough. |
Slots
| Slot |
Slot props |
Description |
default |
SelectItemSlotState<T> |
Option content. Receives selected, active, and disabled state. |
Exposed
| Member |
Type |
Description |
active |
— |
|
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
select |
— |
|
selected |
— |
|
value |
— |
|
ComboboxItemIndicator
Source: src/families/selection/select/select-item-indicator.vue
Props
| Prop |
Type |
Default |
Description |
forceMount |
boolean |
false |
Render while the option is unselected too, publishing data-state for CSS transitions. |
Slots
| Slot |
Slot props |
Description |
default |
{ readonly selected: boolean } |
Indicator content such as a check mark. Receives the option selection state. |
ComboboxLabel
Source: src/families/selection/select/select-label.vue
Slots
| Slot |
Slot props |
Description |
default |
— |
Visible group heading text. |
Source: src/families/selection/select/select-scroll-button.vue
Props
| Prop |
Type |
Default |
Description |
direction (required) |
SelectScrollDirection |
required |
Scroll direction driven while hovered or pressed. |
step |
number |
32 |
Pixels scrolled per tick. |
interval |
number |
50 |
Milliseconds between ticks while hovered or pressed. |
Slots
| Slot |
Slot props |
Description |
default |
{ readonly direction: SelectScrollDirection } |
Decorative arrow content. Receives the scroll direction. |
Exposed
| Member |
Type |
Description |
scrollOnce |
— |
|
update |
— |
|
visible |
— |
|
ComboboxSeparator
Source: src/families/selection/select/select-separator.vue
Slots
| Slot |
Slot props |
Description |
default |
— |
Optional decorative separator content. |
ComboboxViewport
Source: src/families/selection/select/select-viewport.vue
Slots
| Slot |
Slot props |
Description |
default |
— |
Scrollable options region. Scroll buttons and SelectVirtualizer observe this element. |
Exposed
| Member |
Type |
Description |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
ComboboxVirtualizer<T>
Source: src/families/selection/select/select-virtualizer.vue
Props
| Prop |
Type |
Default |
Description |
items (required) |
readonly T[] |
required |
Every option value in display order; only the visible window is rendered. |
estimateItemSize |
number |
32 |
Estimated option height in CSS pixels used until options are measured. |
overscan |
number |
4 |
Options rendered beyond each edge of the visible window. |
initialViewportHeight |
number |
256 |
Viewport height assumed for server rendering and before measurement. |
getItemKey |
(item: T, index: number) => string | number |
undefined |
Stable render key for an option. Defaults to its index. |
Slots
| Slot |
Slot props |
Description |
default |
SelectVirtualItemSlotState<T> |
Render one SelectItem with :value="item" and :index="index". |
Exposed
| Member |
Type |
Description |
scrollToIndex |
— |
|
totalSize |
— |
|
virtualItems |
— |
|
Behavior
Contract
Combobox is a headless, strongly typed editable combobox following the WAI-ARIA
APG combobox with listbox popup pattern. combobox-root.vue is generic over
the option value type T and a Multiple literal: the model is T | null, or
readonly T[] (rendered as chips) when multiple is true. T is inferred
from items, loadItems, modelValue, defaultValue, or createOption.
combobox-input.vue renders a native <input role="combobox"> that keeps DOM
focus and exposes the highlighted option through aria-activedescendant and
aria-autocomplete. The popup reuses Select's structural parts — content,
item, group, label, separator, viewport, scroll button, item indicator, and
virtualizer — which publish data-vize-ui="combobox-*" inside a Combobox and
share the collection registry, composite navigation, positioner, dismissable
layer, and virtualizer. combobox-anchor.vue is the positioning box that keeps
presses inside the input, combobox-trigger.vue a non-tabbable toggle button,
combobox-chip.vue and combobox-chip-remove.vue render multiple selections,
combobox-create-item.vue offers to create a value from free text, and
combobox-empty.vue/combobox-loading.vue render status content.
Filtering is injectable (filter), accent- and case-insensitive by default,
and disabled with filter: false. loadItems(query, { signal }) is an async
item hook with debouncing and abort-on-supersede. Named comboboxes submit
through hidden inputs; the visible input never submits.
Public Surface
| Surface |
Contract |
ComboboxRoot props |
id, modelValue, defaultValue, multiple, items, loadItems, debounce, by, itemText, itemDisabled, formValue, filter, autocomplete, strict, createOption, inputValue, defaultInputValue, open, defaultOpen, openOnFocus, autoHighlight, closeOnSelect, clearOnEscape, loop, disabled, readonly, required, name, form, dir, ariaInvalid |
ComboboxRoot emits |
update:modelValue(value), change(value, previous, nativeEvent), update:inputValue(text), update:open(open), open-change(open, previous, nativeEvent), create(value, text) |
ComboboxRoot slot state |
selected, selectedText, inputValue, query, filteredItems, open, empty, loading, status, error, disabled, selectionMode, state, remove |
ComboboxRoot expose |
selected, inputValue, open, setOpen, setInputValue, select, deselect, clear, reset, reload, focus |
ComboboxInput props |
placeholder, ariaLabel, ariaLabelledby, ariaDescribedby, ariaErrormessage, autocomplete, spellcheck |
ComboboxChip |
value; slot default({ value, text, disabled, remove }) |
| Parts |
root, anchor, input, trigger, chip, chip-remove, create-item, empty, loading, native, plus the shared popup parts |
| Root data attributes |
data-vize-ui="combobox", data-state, data-selection-mode, data-autocomplete, data-disabled, data-readonly, data-required, data-invalid, data-empty, data-loading |
Normative Behavior
| # |
State |
Input |
Outcome |
Proven by |
| C1 |
closed |
render |
text input with role="combobox", aria-autocomplete, aria-expanded="false", no aria-controls, autocomplete="off"; no popup |
renders APG combobox semantics on a native text input |
| C2 |
list |
type |
opens, filters accent- and case-insensitively, highlights the first visible option; Enter selects, fills the label, closes; change carries the key event |
typing opens, filters accent-insensitively, highlights the first match, and Enter selects |
| C3 |
items mode |
type |
root exposes filteredItems; injected filters replace the default; filter: false keeps every option; empty content shows when nothing matches |
items mode exposes filteredItems and filter functions are injectable |
| C4 |
inline |
type / delete |
completes the first matching option after the typed prefix, selects the completion, highlights it, does not filter; deletions never re-complete |
inline autocomplete completes the first match and selects the completion |
| C5 |
both |
type |
filters and completes inline |
both autocomplete filters and completes |
| C6 |
none |
type |
lists every option and highlights nothing |
autocomplete none lists everything without highlighting |
| C7 |
strict / free text |
blur |
strict restores the selected label; strict: false keeps and submits the typed text without changing the selection |
strict mode restores the selected label on blur; free text survives otherwise |
| C8 |
strict single |
clear the text |
clears the selection |
clearing the text clears a strict single selection |
| C9 |
createOption |
type a new value / Enter |
shows the create option (hidden on exact matches), highlights it first, emits create(value, text) then selects the created value |
createOption offers a create option unless the text matches exactly |
| C10 |
create option visible |
click |
creates the typed value |
clicking the create option creates the typed value |
| C11 |
multiple |
choose / Backspace on empty / chip remove |
renders chips, clears the text, keeps the popup open; Backspace at caret 0 removes the last chip; the non-tabbable remove button removes its chip |
multiple mode renders chips, keeps the popup open, and deletes with Backspace |
| K1 |
closed / open |
ArrowDown / ArrowUp / Alt+ArrowDown / Alt+ArrowUp / PageDown / Escape / Tab / Home |
ArrowDown opens on the selection, ArrowUp on the last option, Alt+ArrowDown opens without highlight, Alt+ArrowUp and Escape close, Tab closes without preventing focus, Home/End keep caret movement, Escape while closed clears text and single selection |
keyboard matrix: arrows, Alt+arrows, PageDown, Escape, and Tab |
| K2 |
nothing highlighted |
Enter |
not prevented, so native form submission proceeds |
Enter without a highlighted option keeps native form submission |
| P1 |
any |
toggle button / option pointer-down / anchor press |
toggle opens without taking focus (tabindex=-1); option and anchor presses keep focus in the input |
the toggle button and anchor keep focus in the input |
| P2 |
openOnFocus |
focus |
opens |
openOnFocus opens when the input gains focus |
| P3 |
disabled / readonly |
keys / Backspace |
disabled inputs never open; readonly inputs keep the value and chips |
disabled and readonly inputs refuse edits |
| P4 |
controlled inputValue |
type |
emits update:inputValue and renders the parent text |
controlled inputValue waits for the parent |
| P5 |
no provider |
mount a part |
throws VIZE_UI_CONTEXT_MISSING |
parts require a Combobox provider |
| P6 |
shared popup parts |
render inside a Combobox |
publish combobox-* part names; the listbox is labelled by the input's ariaLabelledby |
Select popup parts publish combobox part names inside a ComboboxRoot |
| A1 |
loadItems |
open / type / newer query / reject / unmount |
loads on open and per query, publishes loading and hides empty content meanwhile, aborts superseded requests, keeps last results on error, aborts on unmount |
loadItems runs on open and per query, exposes loading, and ignores stale responses |
| A2 |
loadItems, debounce |
rapid typing |
opening loads at once; later keystrokes load only the settled query |
loadItems is debounced |
| V1 |
virtualized |
type / PageDown / Enter |
only a window of filtered results renders; navigation reaches options outside it |
virtualized combobox lists navigate filtered results beyond the window |
| F1 |
named |
submit |
hidden inputs carry formValue/by serialization; the visible input has no name |
submits the serialized selection through hidden inputs, not the visible text |
| F2 |
named, multiple |
submit |
one hidden input per value |
multiple selections submit one hidden input per value |
| F3 |
required |
checkValidity() |
the input is natively required until a value is selected; failure marks aria-invalid |
required uses native validation on the input until something is selected |
| F4 |
form |
reset |
restores the default selection and text |
form reset restores the default selection and text |
| U1 |
helpers |
normalize / filter / complete |
normalizeComboboxText, containsComboboxFilter, startsWithComboboxFilter, inlineComboboxCompletion are pure |
filter helpers normalize accents, case, and inline completion |
SSR
Ids come from the deterministic-id primitive, the popup renders in place until
the portal hydrates, and the loader never runs on the server. Closed single and
open multiple trees render byte-identical markup and hydrate without warnings
(renders byte-identical single Combobox markup with the selected label,
renders byte-identical open multiple Combobox markup with chips, hydrates closed single and open multiple Comboboxes without mismatches). Pass itemText
so the input renders the selected label on the server.