Autocomplete
A high-quality, unstyled React autocomplete component that renders an input with a list of filtered options.
An input that suggests options as you type.
Usage guidelines
- Avoid when selection state is needed: Use Combobox instead of Autocomplete if the selection should be remembered and the input value cannot be custom. Unlike Combobox, Autocomplete's input can contain free-form text, as its suggestions only optionally autocomplete the text.
- Can be used for filterable command pickers: The input can be used as a filter for command items that perform an action when clicked when rendered inside the popup.
- Form controls must have an accessible name: It can be created using a
<label>element or theFieldcomponent. See the forms guide.
Anatomy
Import the components and place them together:
import { Autocomplete } from '@base-ui/react/autocomplete';
<Autocomplete.Root>
<Autocomplete.Input />
<Autocomplete.Trigger />
<Autocomplete.Icon />
<Autocomplete.Clear />
<Autocomplete.Value />
<Autocomplete.Portal>
<Autocomplete.Backdrop />
<Autocomplete.Positioner>
<Autocomplete.Popup>
<Autocomplete.Arrow />
<Autocomplete.Status />
<Autocomplete.Empty />
<Autocomplete.List>
<Autocomplete.Row>
<Autocomplete.Item />
</Autocomplete.Row>
<Autocomplete.Separator />
<Autocomplete.Group>
<Autocomplete.GroupLabel />
</Autocomplete.Group>
<Autocomplete.Collection />
</Autocomplete.List>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>;TypeScript inference
Autocomplete infers the item type from the items prop passed to <Autocomplete.Root>.
If using itemToStringValue, the value prop on the <Autocomplete.Item> must match the type of an item in the items array.
Examples
Async search
Load items asynchronously while typing and render custom status content.
Inline autocomplete
Autofill the input with the highlighted item while navigating with arrow keys using the mode prop. Accepts aria-autocomplete values list, both, inline, or none.
Grouped
Organize related options with <Autocomplete.Group> and <Autocomplete.GroupLabel> to add section headings inside the popup.
Groups are represented by an array of objects with an items property, which itself is an array of individual items for each group. An extra property, such as value, can be provided for the heading text when rendering the group label.
interface ProduceGroupItem {
value: string;
items: string[];
}
const groups: ProduceGroupItem[] = [
{
value: 'Fruits',
items: ['Apple', 'Banana', 'Orange'],
},
{
value: 'Vegetables',
items: ['Carrot', 'Lettuce', 'Spinach'],
},
];Fuzzy matching
Use fuzzy matching to find relevant results even when the query doesn't exactly match the item text.
Limit results
Limit the number of visible items using the limit prop and guide users to refine their query using <Autocomplete.Status>.
Auto highlight
The first matching item can be automatically highlighted as the user types by specifying the autoHighlight prop on <Autocomplete.Root>. Set the prop's value to "always" if the highlight should always be present, such as when the list is rendered inline within a dialog.
The prop can be combined with the keepHighlight and highlightItemOnHover props to configure how the highlight behaves during mouse interactions.
Command palette
Use the autocomplete input to filter a list of command items that perform an action when clicked.
Grid layout
Display items in a grid layout, wrapping each row in <Autocomplete.Row> components.
Virtualized
Efficiently handle large datasets using a virtualization library like @tanstack/react-virtual.
API reference
Root
| Name | Type | Default | Description |
|---|---|---|---|
modeOptional | 'list' | 'both' | 'inline' | 'none' | undefined | list | Controls how the autocomplete behaves with respect to list filtering and inline autocompletion. - `list` (default): items are dynamically filtered based on the input value. The input value does not change based on the active item. - `both`: items are dynamically filtered based on the input value, which will temporarily change based on the active item (inline autocompletion). - `inline`: items are static (not filtered), and the input value will temporarily change based on the active item (inline autocompletion). - `none`: items are static (not filtered), and the input value will not change based on the active item. |
autoHighlightOptional | boolean | 'always' | undefined | false | Whether the first matching item is highlighted automatically. - `true`: highlight after the user types and keep the highlight while the query changes. - `'always'`: always highlight the first item. |
keepHighlightOptional | boolean | undefined | false | Whether the highlighted item should be preserved when the pointer leaves the list. |
highlightItemOnHoverOptional | boolean | undefined | true | Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state. |
submitOnItemClickOptional | AriaCombobox.Props<ItemValue, 'none'>['submitOnItemClick'] | undefined | false | Whether clicking an item should submit the autocomplete's owning form. By default, clicking an item via a pointer or <kbd>Enter</kbd> key does not submit the owning form. Useful when the autocomplete is used as a single-field form search input. |
Value
| Name | Type | Default | Description |
|---|---|---|---|
childrenOptional | React.ReactNode | ((value: string) => React.ReactNode) | — | — |
Input
| Name | Type | Default | Description |
|---|---|---|---|
disabledOptional | boolean | undefined | false | Whether the component should ignore user interaction. |
Trigger
| Name | Type | Default | Description |
|---|---|---|---|
disabledOptional | boolean | undefined | false | Whether the component should ignore user interaction. |
Clear
| Name | Type | Default | Description |
|---|---|---|---|
disabledOptional | boolean | undefined | false | Whether the component should ignore user interaction. |
keepMountedOptional | boolean | undefined | false | Whether the component should remain mounted in the DOM when not visible. |
List
| Name | Type | Default | Description |
|---|---|---|---|
childrenOptional | React.ReactNode | ((item: any, index: number) => React.ReactNode) | — | — |
Portal
| Name | Type | Default | Description |
|---|---|---|---|
keepMountedOptional | boolean | undefined | false | Whether to keep the portal mounted in the DOM while the popup is hidden. |
Collection
| Name | Type | Default | Description |
|---|---|---|---|
childrenRequired | (item: any, index: number) => React.ReactNode | — | — |
Item
| Name | Type | Default | Description |
|---|---|---|---|
childrenOptional | React.ReactNode | — | — |
onClickOptional | BaseUIComponentProps<'div', ComboboxItemState>['onClick'] | undefined | — | An optional click handler for the item when selected. It fires when clicking the item with the pointer, as well as when pressing `Enter` with the keyboard if the item is highlighted when the `Input` or `List` element has focus. |
indexOptional | number | undefined | — | The index of the item in the list. Improves performance when specified by avoiding the need to calculate the index automatically from the DOM. |
valueOptional | any | null | A unique value that identifies this item. |
disabledOptional | boolean | undefined | false | Whether the component should ignore user interaction. |
Group
| Name | Type | Default | Description |
|---|---|---|---|
itemsOptional | readonly any[] | undefined | — | Items to be rendered within this group. When provided, child `Collection` components will use these items. |
useFilter
Matches items against a query using Intl.Collator for robust string matching.
This hook is used when externally filtering items.
Input parameters
Accepts all Intl.CollatorOptions, plus the following option:
| Name | Type | Default | Description |
|---|---|---|---|
locale | Intl.LocalesArgument | — | The locale to use for string comparison. |
Return value
| Property | Type | Description |
|---|---|---|
contains | (itemValue: any, query: string) => boolean | Returns whether the item matches the query anywhere. |
startsWith | (itemValue: any, query: string) => boolean | Returns whether the item starts with the query. |
endsWith | (itemValue: any, query: string) => boolean | Returns whether the item ends with the query. |
useFilteredItems
Returns the internally filtered items when called inside <Autocomplete.Root>.
Return value
| Property | Type | Description |
|---|---|---|
filteredItems | any[] | The filtered items. |