Autocomplete renders a TextField and a list of suggested values using the Autocomplete.Item compound components. The list is shown when the user focuses on the field and is hidden once they select a value or there are no items to render.
Autocomplete supports all TextField properties as well as additional onInput, onBackspace and onItemSelect handlers. Since Autocomplete is a form element, name is a required property for it to work. Here is a basic example that always renders the same passed items and autocompletes the field on selecting one of them:
function Component() {
const [value, setValue] = React.useState("");
const options = ["Pizza", "Pie", "Ice-cream"];
const handleChange: AutocompleteProps["onChange"] = (args) =>
setValue(args.value);
return (
<Autocomplete
name="fruit"
placeholder="Pick your food"
value={value}
onChange={handleChange}
>
{options.map((option) => (
<Autocomplete.Item key={option} value={option}>
{option}
</Autocomplete.Item>
))}
</Autocomplete>
);
Autocomplete gives you full control over item rendering and filtering. You can remove any items based on user input or control asynchronous data loading.
function Component() {
const [value, setValue] = React.useState("");
const options = ["Pizza", "Pie", "Ice-cream"];
const handleChange: AutocompleteProps["onChange"] = (args) =>
setValue(args.value);
return (
<Autocomplete
name="fruit"
placeholder="Pick your food"
value={value}
onChange={handleChange}
>
{options.map((option) => {
if (!option.toLowerCase().includes(value.toLowerCase())) return;
return (
<Autocomplete.Item key={option} value={option}>
{option}
</Autocomplete.Item>
);
})}
</Autocomplete>
);
You can fully customize the composition of the dropdown content. Autocomplete.Item supports the same properties as MenuItem, making each item's layout very flexible and allowing custom wrappers around the items. Use onItemSelect when you want to render something in the field only when an item is selected, not on every value change.
const options = [
{
title: "Paul Farell",
role: "Designer",
photo: "/img/examples/avatar-3.png",
},
{
title: "Esther Naomi",
role: "Developer",
photo: "/img/examples/avatar-2.png",
},
{
title: "Whitney Raynolds",
role: "Developer",
photo: "/img/examples/avatar-1.png",
},
];
function Component() {
const [value, setValue] = React.useState("");
const [selectedItem, setSelectedItem] = React.useState("");
const handleChange: AutocompleteProps["onChange"] = (args) =>
setValue(args.value);
const handleItemSelect: AutocompleteProps["onItemSelect"] = (args) => {
setSelectedItem(args.value);
setValue("");
};
return (
<Autocomplete
name="people"
placeholder="Pick assignee"
value={value}
onChange={handleChange}
onItemSelect={handleItemSelect}
startSlot={selectedItem && <Badge>{selectedItem}</Badge>}
>
{options.map((option) => {
const valueMatch = value.toLowerCase();
const optionValue = option.title.toLowerCase();
if (!optionValue.includes(valueMatch) || valueMatch === optionValue)
return;
return (
<Autocomplete.Item
key={option.title}
value={option.title}
startSlot={<Avatar src={option.photo} size={7} />}
endSlot={<Badge>{option.role}</Badge>}
>
{option.title}
</Autocomplete.Item>
);
})}
</Autocomplete>
);
If you're using the start slot to display selected values, apply the multiline flag to make the selected values wrap onto the next line.
function Component() {
const options = ["Salad", "Quinoa", "Beans"];
return (
<View width="280px">
<Autocomplete
name="food"
placeholder="Pick your favorite food"
startSlot={[
<Badge size="small">Cinnamon bun</Badge>,
<Badge size="small">Pasta</Badge>,
<Badge size="small">Ice-cream</Badge>,
<Badge size="small">Pizza</Badge>,
]}
defaultValue="Pineapple"
multiline
>
{options.map((option) => {
return (
<Autocomplete.Item key={option} value={option}>
{option}
</Autocomplete.Item>
);
})}
</Autocomplete>
</View>
);
When working with custom data structures, you can pass any data value to the Autocomplete.Item and later use it inside the onItemSelect:
const options = [ { name: "Pizza", id: 1 }, { name: "Pie", id: 2 }, { name: "Ice-cream", id: 3 }, ]; const [selectedItem, setSelectedItem] = useState(null); const handleItemSelect = (args) => setSelectedItem(args.data); return ( <Autocomplete name="food" placeholder="Pick your food" value={value}> {options.map((option) => ( <Autocomplete.Item key={option.id} value={option.name} data={option}> {option.name} </Autocomplete.Item> ))} </Autocomplete> );
To let the user know what data you expect them to type in, add labels or status messages to your fields with the help of the FormControl utility. In case you're using xlarge TextField size, you can also combine it with the large FormControl size for better visual alignment. Don't use placeholders as labels for the fields as users won't see the placeholder when input contains a value.
function Component() {
const [value, setValue] = React.useState("");
const options = ["Pizza", "Pie", "Ice-cream"];
const handleChange: AutocompleteProps["onChange"] = (args) =>
setValue(args.value);
return (
<FormControl>
<FormControl.Label>Favorite food</FormControl.Label>
<Autocomplete
name="fruit"
placeholder="Pick your option"
value={value}
onChange={handleChange}
>
{options.map((option) => (
<Autocomplete.Item key={option} value={option}>
{option}
</Autocomplete.Item>
))}
</Autocomplete>
</FormControl>
);
Autocomplete supports responsive syntax for the size property. Use object syntax to control its value based on the viewport size. Responsive properties are mobile-first, so selecting a value for a viewport will also apply it to all wider viewports.
<Autocomplete size={{ s: "medium", l: "large" }} />