Documentation Index
Fetch the complete documentation index at: https://mintlify.com/mui/base-ui/llms.txt
Use this file to discover all available pages before exploring further.
The Autocomplete component provides intelligent input completion with keyboard navigation, filtering, and accessibility support.
import * as Autocomplete from '@base-ui/react/Autocomplete';
Basic Usage
import * as Autocomplete from '@base-ui/react/Autocomplete';
const countries = [
'Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola',
'Argentina', 'Armenia', 'Australia', 'Austria', 'Azerbaijan',
// ...
];
function CountryAutocomplete() {
return (
<Autocomplete.Root items={countries}>
<Autocomplete.Trigger>
<Autocomplete.Input placeholder="Search countries..." />
<Autocomplete.Clear>×</Autocomplete.Clear>
</Autocomplete.Trigger>
<Autocomplete.Portal>
<Autocomplete.Positioner>
<Autocomplete.Popup>
<Autocomplete.List>
{countries.map((country) => (
<Autocomplete.Item key={country} value={country}>
{country}
</Autocomplete.Item>
))}
</Autocomplete.List>
<Autocomplete.Empty>No results found</Autocomplete.Empty>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>
);
}
Sub-components
Autocomplete.Root
Groups all parts of the autocomplete. Doesn’t render its own HTML element.
Key Props:
items: Array of items or groups. Can be flat array or array with { label, items } structure
value: Controlled input value
defaultValue: Uncontrolled default input value
onValueChange: Called when input value changes
mode: Behavior mode - 'list' | 'both' | 'inline' | 'none' (default: 'list')
list: Items filtered dynamically, input stays as typed
both: Items filtered + inline autocompletion
inline: Static items + inline autocompletion
none: Static items, no autocompletion
open: Controlled popup open state
defaultOpen: Uncontrolled default open state
onOpenChange: Called when popup opens/closes
filter: Custom filter function
autoHighlight: Whether to highlight first match (false | true | 'always')
keepHighlight: Whether to preserve highlight when pointer leaves (default: false)
highlightItemOnHover: Whether hovering highlights items (default: true)
disabled: Whether component is disabled (default: false)
name: Form field name
required: Whether field is required (default: false)
readOnly: Whether input is read-only (default: false)
itemToStringValue: Convert object items to string
onItemHighlighted: Called when item is highlighted/unhighlighted
submitOnItemClick: Whether selecting item submits form (default: false)
openOnInputClick: Whether clicking input opens popup (default: false)
Autocomplete.Trigger
Container for the input and clear button.
Autocomplete.Input
The text input element. Renders an <input> element.
Autocomplete.Clear
Button to clear the current input value.
Autocomplete.Portal
Portals the popup to a different part of the DOM (default: document.body).
Autocomplete.Positioner
Positions the popup relative to the trigger.
The container for the list of items.
Autocomplete.List
Scrollable list container for items.
Autocomplete.Item
An individual item in the list. Renders a <div> by default.
Props:
value: The value this item represents
disabled: Whether this item is disabled
Autocomplete.Empty
Displayed when no items match the filter.
Autocomplete.Group
Groups related items together.
Autocomplete.GroupLabel
Label for a group of items.
Autocomplete.Arrow
Arrow pointing to the trigger.
Autocomplete.Backdrop
Backdrop element shown when modal={true}.
Autocomplete.Value
Displays the current value (useful for custom rendering).
Autocompletion Modes
List Mode (Default)
Items filter as you type, input shows what you typed:
<Autocomplete.Root items={items} mode="list">
{/* ... */}
</Autocomplete.Root>
Inline Mode
Static items, input autocompletes to highlighted item:
<Autocomplete.Root items={items} mode="inline">
{/* ... */}
</Autocomplete.Root>
Both Mode
Items filter AND input autocompletes:
<Autocomplete.Root items={items} mode="both">
{/* ... */}
</Autocomplete.Root>
None Mode
Static items, no autocompletion:
<Autocomplete.Root items={items} mode="none">
{/* ... */}
</Autocomplete.Root>
Grouped Items
const groupedItems = [
{
label: 'Fruits',
items: ['Apple', 'Banana', 'Orange'],
},
{
label: 'Vegetables',
items: ['Carrot', 'Broccoli', 'Spinach'],
},
];
<Autocomplete.Root items={groupedItems}>
<Autocomplete.Input placeholder="Search food..." />
<Autocomplete.Portal>
<Autocomplete.Positioner>
<Autocomplete.Popup>
<Autocomplete.List>
<Autocomplete.Collection>
{(item, index) => (
<Autocomplete.Item key={index} value={item}>
{item}
</Autocomplete.Item>
)}
</Autocomplete.Collection>
</Autocomplete.List>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>
Custom Filtering
import { Autocomplete } from '@base-ui/react/Autocomplete';
function customFilter(item: string, query: string) {
return item.toLowerCase().startsWith(query.toLowerCase());
}
<Autocomplete.Root items={items} filter={customFilter}>
{/* ... */}
</Autocomplete.Root>
Object Items
const users = [
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com' },
{ id: 2, name: 'Bob Smith', email: 'bob@example.com' },
{ id: 3, name: 'Carol White', email: 'carol@example.com' },
];
function itemToString(user: typeof users[number]) {
return user.name;
}
<Autocomplete.Root
items={users}
itemToStringValue={itemToString}
>
<Autocomplete.Input placeholder="Search users..." />
<Autocomplete.Portal>
<Autocomplete.Positioner>
<Autocomplete.Popup>
<Autocomplete.List>
{users.map((user) => (
<Autocomplete.Item key={user.id} value={user}>
<div>
<div>{user.name}</div>
<div className="email">{user.email}</div>
</div>
</Autocomplete.Item>
))}
</Autocomplete.List>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>
Styling
.Autocomplete-trigger {
display: flex;
align-items: center;
gap: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 0.5rem;
padding: 0.5rem;
}
.Autocomplete-input {
flex: 1;
border: none;
outline: none;
font-size: 1rem;
}
.Autocomplete-clear {
background: none;
border: none;
cursor: pointer;
font-size: 1.25rem;
color: #6b7280;
}
.Autocomplete-popup {
background: white;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
max-height: 300px;
overflow: auto;
}
.Autocomplete-item {
padding: 0.75rem 1rem;
cursor: pointer;
}
.Autocomplete-item[data-highlighted] {
background-color: #eff6ff;
}
.Autocomplete-item[data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.Autocomplete-empty {
padding: 1rem;
text-align: center;
color: #6b7280;
}
Form Integration
import { Form } from '@base-ui/react/Form';
import * as Field from '@base-ui/react/Field';
import * as Autocomplete from '@base-ui/react/Autocomplete';
function JobApplicationForm() {
const skills = ['JavaScript', 'TypeScript', 'React', 'Node.js', 'Python'];
return (
<Form onFormSubmit={(values) => console.log(values)}>
<Field.Root name="skill">
<Field.Label>Primary Skill</Field.Label>
<Autocomplete.Root items={skills}>
<Autocomplete.Input />
<Autocomplete.Portal>
<Autocomplete.Positioner>
<Autocomplete.Popup>
<Autocomplete.List>
{skills.map((skill) => (
<Autocomplete.Item key={skill} value={skill}>
{skill}
</Autocomplete.Item>
))}
</Autocomplete.List>
</Autocomplete.Popup>
</Autocomplete.Positioner>
</Autocomplete.Portal>
</Autocomplete.Root>
<Field.Error match="valueMissing">Skill is required</Field.Error>
</Field.Root>
<button type="submit">Submit</button>
</Form>
);
}