Autocomplete

Autocomplete user input with any list of options
Import

Usage

import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<Autocomplete
label="Your favorite framework/library"
placeholder="Pick one"
data={['React', 'Angular', 'Svelte', 'Vue']}
/>
);
}

Controlled

import { useState } from 'react';
import { Autocomplete } from '@mantine/core';
function Demo() {
const [value, setValue] = useState('');
return <Autocomplete value={value} onChange={setValue} data={[]} />;
}

Data prop

Autocomplete support two different data formats:

  1. An array of strings
  2. An array of objects with required value property and any other additional properties
import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<>
{/* Data as an array of strings */}
<Autocomplete data={['React', 'Angular', 'Svelte', 'Vue']} />
{/* Data as an array of objects: Minimal example (same as first example above) */}
<Autocomplete
data={[{ value: 'React' }, { value: 'Angular' }, { value: 'Svelte' }, { value: 'Vue' }]}
/>
{/* Additional data properties for custom item component (see documentation below) */}
<Autocomplete
// Your custom item component with data properties
itemComponent={({ value, color, email, name }) => <div />}
data={[
{
value: 'bob@handsome.inc',
color: 'red',
email: 'bob@handsome.inc',
name: 'Bob Handsome',
},
{
value: 'bill@outlook.com',
color: 'teal',
email: 'bill@outlook.com',
name: 'Bill Gates',
},
{ value: 'amy@wong.cn', color: 'blue', email: 'amy@wong.cn', name: 'Amy Wong' },
]}
/>
</>
);
}

Dynamic data

import { useState } from 'react';
import { Autocomplete } from '@mantine/core';
function Demo() {
const [value, setValue] = useState('');
const data =
value.trim().length > 0 && !value.includes('@')
? ['gmail.com', 'outlook.com', 'yahoo.com'].map((provider) => `${value}@${provider}`)
: [];
return (
<Autocomplete
value={value}
onChange={setValue}
label="Email"
placeholder="Start typing to see options"
data={data}
/>
);
}

Group options

import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<Autocomplete
label="Your favorite Rick and Morty character"
placeholder="Pick one"
data={[
{ value: 'Rick', group: 'Used to be a pickle' },
{ value: 'Morty', group: 'Never was a pickle' },
{ value: 'Beth', group: 'Never was a pickle' },
{ value: 'Summer', group: 'Never was a pickle' },
]}
/>
);
}

Custom item component

Autocomplete item component and filtering logic can be changed. To do so:

  • Add extra props to data objects
  • Create filter function which determines whether item should be added to the search results
  • Provide itemComponent which will consume data objects
import { forwardRef } from 'react';
import { Group, Avatar, Text, MantineColor, SelectItemProps, Autocomplete } from '@mantine/core';
const charactersList = [
{
image: 'https://img.icons8.com/clouds/256/000000/futurama-bender.png',
label: 'Bender Bending Rodríguez',
description: 'Fascinated with cooking, though has no sense of taste',
},
{
image: 'https://img.icons8.com/clouds/256/000000/futurama-mom.png',
label: 'Carol Miller',
description: 'One of the richest people on Earth',
},
{
image: 'https://img.icons8.com/clouds/256/000000/homer-simpson.png',
label: 'Homer Simpson',
description: 'Overweight, lazy, and often ignorant',
},
{
image: 'https://img.icons8.com/clouds/256/000000/spongebob-squarepants.png',
label: 'Spongebob Squarepants',
description: 'Not just a sponge',
},
];
const data = charactersList.map((item) => ({ ...item, value: item.label }));
interface ItemProps extends SelectItemProps {
color: MantineColor;
description: string;
image: string;
}
const AutoCompleteItem = forwardRef<HTMLDivElement, ItemProps>(
({ description, value, image, ...others }: ItemProps, ref) => (
<div ref={ref} {...others}>
<Group noWrap>
<Avatar src={image} />
<div>
<Text>{value}</Text>
<Text size="xs" color="dimmed">
{description}
</Text>
</div>
</Group>
</div>
)
);
function Demo() {
return (
<Autocomplete
label="Choose employee of the month"
placeholder="Pick one"
itemComponent={AutoCompleteItem}
data={data}
filter={(value, item) =>
item.value.toLowerCase().includes(value.toLowerCase().trim()) ||
item.description.toLowerCase().includes(value.toLowerCase().trim())
}
/>
);
}

Limit amount of options

By default, Autocomplete will render 5 items at a time, to change that set limit prop:

import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<Autocomplete
label="Only 2 options at a time"
placeholder="Your favorite framework"
limit={2}
data={['React', 'Angular', 'Svelte', 'Vue']}
/>
);
}

Dropdown position

By default, dropdown is placed below the input and when there is not enough space, it flips to be above the input. To change this behavior, set dropdownPosition prop:

DropdownPosition
import { Autocomplete } from '@mantine/core';
function Demo() {
return <Autocomplete />;
}

Animations

By default, dropdown animations are turned off to increase responsiveness. To enable animations set the following optional props:

  • transition – premade transition name or custom transition styles object, see Transition component for all available options
  • transitionDuration – transition duration in ms, defaults to 0
  • transitionTimingFunction – defaults to theme.transitionTimingFunction
import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<Autocomplete
transition="pop-top-left"
transitionDuration={80}
transitionTimingFunction="ease"
/>
);
}

With icon

import { Autocomplete } from '@mantine/core';
import { Hash } from 'tabler-icons-react';
function Demo() {
return <Autocomplete icon={<Hash />} />;
}

Invalid state and error

Field is required
import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<>
{/* Error as boolean – red border color */}
<Autocomplete error />
{/* Error as React node – red border color and message below input */}
<Autocomplete error="Field is required" />
</>
);
}

Disabled state

import { Autocomplete } from '@mantine/core';
function Demo() {
return <Autocomplete disabled />;
}

Input props

Radius
xs
sm
md
lg
xl
Size
xs
sm
md
lg
xl
import { Autocomplete } from '@mantine/core';
function Demo() {
return (
<Autocomplete
placeholder="Pick one"
label="Your favorite framework/library"
required
data={['React', 'Angular', 'Svelte', 'Vue']}
/>
);
}

Get input ref

import { useRef } from 'react';
import { Autocomplete } from '@mantine/core';
function Demo() {
const ref = useRef<HTMLInputElement>();
return <Autocomplete ref={ref} data={[]} />;
}

Accessibility

Provide aria-label in case component does not have a label for screen reader support:

<Autocomplete /> // -> not ok, input is not labeled
<Autocomplete label="My input" /> // -> ok, input and label is connected
<Autocomplete aria-label="My input" /> // -> ok, label is not visible but will be announced by screen reader