Autocomplete
An always-visible, filterable list: a search input on top of a ListBox. As the user types, items are filtered locally; arrow keys move a virtual focus through the list while DOM focus stays in the input. Unlike ComboBox, there is no popover and no open/closed state.
Selected: none
Anatomy
Selection lives in the inner list — pass selectionMode, value / defaultValue and onChange to Autocomplete.List, exactly like a plain ListBox. The Autocomplete only owns the search query, filtering and 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>Multiple selection
Pass selectionMode="multiple" to Autocomplete.List. Selected items show an indicator and stay selected as you keep filtering.
0 selected
External filtering
Set filter={null} on Autocomplete.Root to disable local filtering and compute the list yourself (e.g. from a backend) using bind:inputValue.
Usage guidelines
- Wrap all parts in
Autocomplete.Root. - Put selection props (
selectionMode,value,defaultValue,onChange) onAutocomplete.List. - Use controlled
inputValue+onInputChangeonAutocomplete.Rootonly when you need external state (e.g. server-side/async filtering). Setfilter={null}to disable local filtering when results come pre-filtered from a backend. - Provide an accessible label on
Autocomplete.Input(aria-labeloraria-labelledby). - Render
Autocomplete.Emptyfor the "no results" state andAutocomplete.Statusto announce the result count to screen readers. - Provide a stable
idonAutocomplete.Rootin SSR environments to keep ARIA ids deterministic.
Accessibility
- The input is a
role="searchbox"witharia-controlspointing to the list andaria-activedescendantpointing to the highlighted item. There is noaria-expanded/aria-haspopupbecause there is no popup. - The list is a
role="listbox"; items arerole="option". ArrowDown/ArrowUpmove the virtual focus through results,PageDown/PageUpjump by a page,Enterselects the highlighted item, andEscapeclears the query.Autocomplete.Statusis a visually-hiddenaria-live="polite"region that announces the result count.
API reference
Root
State container for the autocomplete. Owns the search query, local filtering, and virtual focus, and wires the ARIA relationship between the input and the list.
* required. Native HTML attributes of the underlying element are also accepted.
Input
Search input with role="searchbox". Keeps DOM focus while arrow keys move a virtual focus through the list via aria-activedescendant.
* required. Native HTML attributes of the underlying element are also accepted.
List
The always-visible listbox of filtered options. Accepts the same selection props as ListBox.Root (selectionMode, value, defaultValue, onChange).
* required. Native HTML attributes of the underlying element are also accepted.
Item
A selectable option inside the list. Matched against the query through its textValue and exposes selection and focus state through data attributes.
* required. Native HTML attributes of the underlying element are also accepted.
ItemIndicator
Visual indicator rendered inside an item while it is selected. Defaults to a checkmark icon.
* required. Native HTML attributes of the underlying element are also accepted.
Empty
Empty state shown when no options match the current query.
* required. Native HTML attributes of the underlying element are also accepted.
Status
Visually hidden aria-live="polite" region that announces the number of visible results to screen readers.
* required. Native HTML attributes of the underlying element are also accepted.