Autocomplete
Address- and search-style Autocomplete: a thin Combobox preset with free text, open-on-focus, and recent history. AutocompleteInput, AutocompleteContent, AutocompleteItem, AutocompleteEmpty, and AutocompleteLoading are the Combobox parts under preset names.
|
|
| Package |
@vizejs/ui/autocomplete |
| Maturity |
stable |
| Own the source |
vize lib pull autocomplete |
| Requires |
combobox, controllable-state, select |
| Aliases |
autocomplete, address autocomplete, search suggestions, recent searches |
| Covers |
WAI-ARIA combobox pattern (list autocomplete), Algolia Autocomplete recent searches, Google Places Autocomplete |
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 { AutocompleteContent, AutocompleteItem, AutocompleteInput, AutocompleteEmpty, AutocompleteLoading, Autocomplete, AutocompleteRoot } from "@vizejs/ui/autocomplete";
Or copy the source into your project with vize lib pull autocomplete (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
<!-- Search box that suggests matching cities and remembers recent choices while the query is empty. -->
<script setup lang="ts">
import { ref, useId } from "vue";
import {
Autocomplete,
AutocompleteContent,
AutocompleteEmpty,
AutocompleteInput,
AutocompleteItem,
} from "@vizejs/ui/autocomplete";
const cities = ["Amsterdam", "Barcelona", "Lisbon", "Osaka", "Tokyo", "Toronto"];
const city = ref<string | null>(null);
const recent = ref<readonly string[]>(["Lisbon"]);
const labelId = useId();
</script>
<template>
<div>
<span :id="labelId">Destination</span>
<Autocomplete
v-slot="{ suggestions, showingHistory, clearHistory }"
v-model="city"
v-model:history="recent"
:items="cities"
name="destination"
>
<AutocompleteInput :aria-labelledby="labelId" placeholder="Search cities" />
<AutocompleteContent>
<AutocompleteItem v-for="entry in suggestions" :key="entry" :value="entry">
{{ entry }}
</AutocompleteItem>
<AutocompleteEmpty>No matching cities</AutocompleteEmpty>
<button v-if="showingHistory" type="button" @click="clearHistory">Clear recent</button>
</AutocompleteContent>
</Autocomplete>
<output>Destination: {{ city ?? "none" }}</output>
</div>
</template>
API
AutocompleteContent
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. |
AutocompleteItem<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 |
— |
|
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 |
— |
|
AutocompleteEmpty
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. |
AutocompleteLoading
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. |
Autocomplete<T>
Source: src/families/selection/autocomplete/autocomplete-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
T | null |
undefined |
Controlled chosen suggestion. undefined selects uncontrolled behavior. |
defaultValue |
T | null |
undefined |
Initial chosen suggestion for uncontrolled use. |
items |
readonly T[] |
undefined |
Static suggestions filtered by the typed text. |
loadItems |
ComboboxLoader<T> |
undefined |
Async suggestion source (address lookup, search API) called with the query. |
debounce |
number |
200 |
Debounce in milliseconds before loadItems runs. |
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 suggestion. |
filter |
ComboboxFilter<T> | false |
undefined |
Suggestion filter; false shows suggestions as returned by loadItems. |
inputValue |
string |
undefined |
Controlled input text. |
history |
readonly T[] |
undefined |
Controlled recent history, newest first. undefined selects uncontrolled behavior. |
defaultHistory |
readonly T[] |
[] |
Initial recent history for uncontrolled use. |
maxHistory |
number |
5 |
Maximum number of remembered entries. |
historyStorage |
AutocompleteHistoryStorage<T> |
undefined |
Persistence adapter read after mount and written on every change. |
fromText |
(text: string) => T |
undefined |
Turn submitted free text into a history entry (search-style). Omit to record chosen suggestions only. |
openOnFocus |
boolean |
true |
Open the popup (showing history) when the input gains focus. |
disabled |
boolean |
false |
Disable the input and suggestions. |
name |
string |
undefined |
Form field name; submits the typed text. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: T | null] |
Fired when a suggestion is chosen (or cleared with null). |
update:inputValue |
[text: string] |
Fired when the input text changes. |
update:history |
[history: readonly T[]] |
Fired when the recent history changes. |
submit |
[text: string, value: T | null] |
Fired when the user submits: the typed text and the chosen suggestion, if any. |
Slots
| Slot |
Slot props |
Description |
default |
AutocompleteSlotState<T> |
Combobox parts. Render suggestions as ComboboxItems: history while the query is empty, otherwise the (filtered or loaded) suggestions. |
Exposed
| Member |
Type |
Description |
clearHistory |
— |
|
forget |
— |
|
history |
— |
|
remember |
— |
|
AutocompleteRoot<T>
Source: src/families/selection/autocomplete/autocomplete-root.vue
Props
| Prop |
Type |
Default |
Description |
id |
string | null |
undefined |
Consumer-owned base id. null and undefined select a deterministic fallback. |
modelValue |
T | null |
undefined |
Controlled chosen suggestion. undefined selects uncontrolled behavior. |
defaultValue |
T | null |
undefined |
Initial chosen suggestion for uncontrolled use. |
items |
readonly T[] |
undefined |
Static suggestions filtered by the typed text. |
loadItems |
ComboboxLoader<T> |
undefined |
Async suggestion source (address lookup, search API) called with the query. |
debounce |
number |
200 |
Debounce in milliseconds before loadItems runs. |
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 suggestion. |
filter |
ComboboxFilter<T> | false |
undefined |
Suggestion filter; false shows suggestions as returned by loadItems. |
inputValue |
string |
undefined |
Controlled input text. |
history |
readonly T[] |
undefined |
Controlled recent history, newest first. undefined selects uncontrolled behavior. |
defaultHistory |
readonly T[] |
[] |
Initial recent history for uncontrolled use. |
maxHistory |
number |
5 |
Maximum number of remembered entries. |
historyStorage |
AutocompleteHistoryStorage<T> |
undefined |
Persistence adapter read after mount and written on every change. |
fromText |
(text: string) => T |
undefined |
Turn submitted free text into a history entry (search-style). Omit to record chosen suggestions only. |
openOnFocus |
boolean |
true |
Open the popup (showing history) when the input gains focus. |
disabled |
boolean |
false |
Disable the input and suggestions. |
name |
string |
undefined |
Form field name; submits the typed text. |
Events
| Event |
Payload |
Description |
update:modelValue |
[value: T | null] |
Fired when a suggestion is chosen (or cleared with null). |
update:inputValue |
[text: string] |
Fired when the input text changes. |
update:history |
[history: readonly T[]] |
Fired when the recent history changes. |
submit |
[text: string, value: T | null] |
Fired when the user submits: the typed text and the chosen suggestion, if any. |
Slots
| Slot |
Slot props |
Description |
default |
AutocompleteSlotState<T> |
Combobox parts. Render suggestions as ComboboxItems: history while the query is empty, otherwise the (filtered or loaded) suggestions. |
Exposed
| Member |
Type |
Description |
history |
readonly T[] |
Recent history, newest first. |
remember |
(value: T) => void |
Add an entry to the history. |
forget |
(value: T) => void |
Remove an entry from the history. |
clearHistory |
() => void |
Clear the history. |
Behavior
Contract
Autocomplete is a thin, typed preset over Combobox for address- and
search-style inputs. autocomplete-root.vue wraps ComboboxRoot with free
text (strict: false), list autocompletion, open-on-focus, and a recent-history
list that is shown while the query is empty. History is controllable
(v-model:history), de-duplicated under by, capped by maxHistory, and can
persist through an injectable historyStorage adapter that is read only after
mount; slot state exposes forget and clearHistory. All
Combobox parts (input, content, items, async loading, virtualization) apply.
Normative Behavior
| # |
State |
Input |
Outcome |
Proven by |
| A1 |
any |
render / focus |
Combobox root marked data-vize-ui-preset="autocomplete", list autocomplete, opens on focus |
is a free-text combobox preset that opens on focus and marks itself |
| A2 |
typing |
Enter on a highlighted match |
selects it, records it in history, emits submit(text, value) |
choosing a suggestion records it in history and emits submit |
| A3 |
empty query |
focus |
suggestions are the history (newest first, de-duplicated, capped); typing switches to results |
an empty query shows history first, newest first, deduplicated and capped |
| A4 |
free text |
Enter with nothing highlighted |
emits submit(text, null); fromText records search-style history; the model is untouched |
free-text Enter submits the text and fromText records search-style history |
| A5 |
history present |
slot clearHistory |
empties history and returns to plain suggestions |
slot clearHistory empties the history |
| A6 |
historyStorage |
mount / change |
reads after mount, writes every change |
history storage is read after mount and written on change |
| A7 |
pure helpers |
push / remove / storage errors |
deterministic; storage failures are swallowed |
history helpers are pure and storage failures are swallowed |
SSR
History is rendered from defaultHistory on the server; storage is read only
after mount, so markup is byte-identical and hydrates without warnings
(renders byte-identical Autocomplete markup with history suggestions,
hydrates Autocomplete without mismatches or node replacement).