Autocomplete
This is a list that the user always sees and can filter. It is a search input above a ListBox. When the user types, the component filters the items locally. The arrow keys move a virtual focus through the list, but the DOM focus stays in the input. A ComboBox has a popover and an open state. An Autocomplete has neither.
Selected: none
Anatomy
The inner list holds the selection. Put selectionMode, value, defaultValue, and onChange on Autocomplete.List, like a plain ListBox. The Autocomplete controls only the search text, the filter, and the virtual focus.
<script>
import { Autocomplete } from '@human-kit/ui';
</script>
<Autocomplete.Root aria-label="Fruits">
<Autocomplete.Input aria-label="Search fruits" placeholder="Search…" />
<Autocomplete.Status />
<Autocomplete.List selectionMode="single" bind:value>
<Autocomplete.Item id="apple">
Apple
<Autocomplete.ItemIndicator />
</Autocomplete.Item>
<Autocomplete.Empty />
</Autocomplete.List>
</Autocomplete.Root>More than one selection
Put selectionMode="multiple" on Autocomplete.List. A selected item shows an indicator, and it stays selected while the user continues to filter.
0 selected
External filter
Set filter={null} on Autocomplete.Root to stop the local filter. Then calculate the list in your own code, for example from a server, and use bind:inputValue.
Usage guidelines
- Put all of the parts in
Autocomplete.Root. - Put the selection props (
selectionMode,value,defaultValue, andonChange) onAutocomplete.List. - Use
inputValueandonInputChangeonAutocomplete.Rootonly when you need external state, for example an asynchronous filter on a server. If the server sends the filtered results, setfilter={null}to stop the local filter. - Give
Autocomplete.Inputan accessible label witharia-labeloraria-labelledby. - Use
Autocomplete.Emptyfor the "no results" state. UseAutocomplete.Statusto announce the number of the results to a screen reader. - On a server, give
Autocomplete.Roota stableid. Thus the ARIA ids stay the same.
Accessibility
- The input has
role="searchbox". Itsaria-controlsattribute points at the list, and itsaria-activedescendantattribute points at the item with the virtual focus. There is no popup, thus there is noaria-expandedattribute and noaria-haspopupattribute. - The list has
role="listbox", and each item hasrole="option". - The
ArrowDownkey and theArrowUpkey move the virtual focus through the results. ThePageDownkey and thePageUpkey move it by one page. TheEnterkey selects the item with the virtual focus. TheEscapekey removes the search text. Autocomplete.Statusis a hiddenaria-live="polite"region. It announces the number of the results.
API reference
Root
The container with the state. It holds the search text, the local filter, and the virtual focus. It also sets the ARIA relation between the input and the list.
* required. Native HTML attributes of the underlying element are also accepted.
Input
The search input, with role="searchbox". It keeps the DOM focus while the arrow keys move a virtual focus through the list with aria-activedescendant.
* required. Native HTML attributes of the underlying element are also accepted.
List
The listbox of filtered options, which the user always sees. It accepts the same selection props as ListBox.Root: selectionMode, value, defaultValue, and onChange.
* required. Native HTML attributes of the underlying element are also accepted.
Item
An option in the list that the user can select. The filter compares its textValue with the search text. It shows its selection state and its focus state in data attributes.
* required. Native HTML attributes of the underlying element are also accepted.
ItemIndicator
The mark in an item while the item is selected. The default is a check mark icon.
* required. Native HTML attributes of the underlying element are also accepted.
Empty
What the list shows when no option agrees with the search text.
* required. Native HTML attributes of the underlying element are also accepted.
Status
A hidden aria-live="polite" region. It announces the number of the results to a screen reader.
* required. Native HTML attributes of the underlying element are also accepted.