Amplify UI

Autocomplete

Autocomplete is a SearchField enhanced by a list of suggested options.

Demo

Usage

Import the Autocomplete, provide options for autocomplete and a label for accessibility/usability.

import { Autocomplete } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const DefaultAutocompleteExample = () => (
  <Autocomplete label="Default autocomplete" options={options} />
);

Accessibility / Label behavior

Controlled component

import { Autocomplete } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteControlledExample = () => {
  const [value, setValue] = React.useState('');

  const onChange = (event) => {
    setValue(event.target.value);
  };

  // It is your responsibility to set up onSelect
  const onSelect = (option) => {
    const { label } = option;
    setValue(label);
  };

  // It is your responsibility to set up onClear
  const onClear = () => {
    setValue('');
  };

  return (
    <Autocomplete
      label="Controlled autocomplete"
      options={options}
      value={value}
      onChange={onChange}
      onClear={onClear}
      onSelect={onSelect}
    />
  );
};

Note: When using Autocomplete in controlled way, you are also responsible to set up onClear and onSelect event handlers in addition to onChange since the input value is under your control.

Placeholder

Text that appears in Autocomplete when it has no value set.

import { Autocomplete } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompletePlaceholderExample = () => (
  <Autocomplete
    label="Autocomplete placeholder example"
    options={options}
    placeholder="Search for fruit..."
  />
);

Sizes

Use the size prop to change Autocomplete size. Available options are small, large, and none (default).

import { Autocomplete, Flex } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteSizeExample = () => (
  <Flex direction="column">
    <Autocomplete
      label="Autocomplete size example"
      options={options}
      size="small"
    />
    <Autocomplete label="Autocomplete size example" options={options} />
    <Autocomplete
      label="Autocomplete size example"
      options={options}
      size="large"
    />
  </Flex>
);

Variations

There are two variation styles available: default and quiet.

import { Autocomplete, Flex } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteVariationExample = () => (
  <Flex direction="column">
    <Autocomplete label="Autocomplete variation example" options={options} />
    <Autocomplete
      label="Autocomplete variation example"
      options={options}
      variation="quiet"
    />
  </Flex>
);

Loading state

By setting isLoading to true, Autocomplete will be in loading state.

import { Autocomplete } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [];

export const AutocompleteLoadingStateExample = () => {
  return (
    <Autocomplete
      label="Autocomplete in loading state"
      options={options}
      isLoading
    />
  );
};

Custom filtering

By default, Autocomplete will filter against option label. You can customize the filtering behavior by providing filteringOptions.

import { Autocomplete, HighlightMatch } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  {
    id: 'apple',
    label: 'apple',
    description: 'An apple is an edible fruit produced by an apple tree.',
  },
  {
    id: 'banana',
    label: 'banana',
    description:
      'A banana is an elongated, edible fruit produced by several kinds of large herbaceous flowering plants.',
  },
  {
    id: 'cherry',
    label: 'cherry',
    description:
      'A cherry is the fruit of many plants of the genus Prunus, and is a fleshy drupe.',
  },
  {
    id: 'grape',
    label: 'grape',
    description:
      'A grape is a fruit, botanically a berry, of the deciduous woody vines of the flowering plant genus Vitis.',
  },
  {
    id: 'kiwis',
    label: 'kiwis',
    description:
      'Kiwifruit or Chinese gooseberry is the edible berry of several species of woody vines in the genus Actinidia.',
  },
  {
    id: 'lemon',
    label: 'lemon',
    description:
      'The lemon is a species of small evergreen trees in the flowering plant family Rutaceae.',
  },
  {
    id: 'mango',
    label: 'mango',
    description:
      'A mango is an edible stone fruit produced by the tropical tree Mangifera indica.',
  },
  {
    id: 'orange',
    label: 'orange',
    description:
      'An orange is a fruit of various citrus species in the family Rutaceae.',
  },
  {
    id: 'strawberry',
    label: 'strawberry',
    description:
      'The garden strawberry is a widely grown hybrid species of the genus Fragaria, collectively known as the strawberries.',
  },
];

const renderOptions = (option, value) => {
  return <HighlightMatch query={value}>{option?.description}</HighlightMatch>;
};

export const AutocompleteCustomFilteringExample = () => {
  const [value, setValue] = React.useState('');

  // Create your own filtering
  const optionFilter = (option, value) => {
    // filter options against description
    return option?.description?.includes(value);
  };

  return (
    <Autocomplete
      label="Autocomplete with custom filtering"
      optionFilter={optionFilter}
      options={options}
      value={value}
      onChange={(event) => setValue(event.target.value)}
      onClear={() => setValue('')}
      onSelect={(option) => {
        setValue(option?.description);
      }}
      renderOption={renderOptions}
    />
  );
};

Note: When you create your own filtering logic, match highlighting will be disabled. If you want to enable it, you can build a custom option and wrap the label with HighlightMatch. See custom option example.

Custom option

You can create a custom option by providing renderOption.

import {
  Autocomplete,
  Flex,
  HighlightMatch,
  Image,
} from '@aws-amplify/ui-react';
import * as React from 'react';

// When you run the code locally, you need to update the url with yours.
const options = [
  { id: 'cat-1', label: 'cat-1', url: '/cats/1.jpg' },
  { id: 'cat-2', label: 'cat-2', url: '/cats/2.jpg' },
  { id: 'cat-3', label: 'cat-3', url: '/cats/3.jpg' },
  { id: 'cat-4', label: 'cat-4', url: '/cats/4.jpg' },
  { id: 'cat-5', label: 'cat-5', url: '/cats/5.jpg' },
];

export const AutocompleteCustomOptionExample = () => {
  const renderOption = (option, value) => {
    const { label, url } = option;
    return (
      <Flex alignItems="center">
        <Image src={url} alt={label} width="100px" height="100px" />
        <HighlightMatch query={value}>{label}</HighlightMatch>
      </Flex>
    );
  };

  return (
    <Autocomplete
      label="Autocomplete with custom options"
      options={options}
      renderOption={renderOption}
    />
  );
};

Custom menu

You can customize the option menu by setting menu. The available slots accept a ReactNode.

Custom header

import { Autocomplete, Divider, View } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteCustomHeaderExample = () => (
  <Autocomplete
    label="Autocomplete custom header example"
    options={options}
    menuSlots={{
      Header: (
        <View padding="xxxs">
          <View>Search results:</View>
          <Divider />
        </View>
      ),
    }}
  />
);
import { Autocomplete, Divider, Link, View } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteCustomFooterExample = () => (
  <Autocomplete
    label="Autocomplete custom footer example"
    options={options}
    menuSlots={{
      Footer: (
        <View padding="xxxs">
          <Divider />
          <View>
            <Link>See more results...</Link>
          </View>
        </View>
      ),
    }}
  />
);

Custom empty

import { Autocomplete, View } from '@aws-amplify/ui-react';
import * as React from 'react';

export const AutocompleteCustomEmptyExample = () => (
  <Autocomplete
    label="Autocomplete custom empty example"
    options={[]}
    menuSlots={{
      Empty: <View>No results found :(</View>,
    }}
  />
);

Custom loading

import { Autocomplete, Flex, Loader } from '@aws-amplify/ui-react';
import * as React from 'react';

export const AutocompleteCustomLoadingExample = () => (
  <Autocomplete
    label="Autocomplete custom loading example"
    options={[]}
    menuSlots={{
      LoadingIndicator: (
        <Flex alignItems="center" gap="0.25rem">
          <Loader />
          Loading more cats...
        </Flex>
      ),
    }}
    isLoading={true}
  />
);

Styling

Theme

You can customize the appearance of all Autocomplete components in your application with a Theme.

Autocomplete Theme Source

import { Autocomplete, ThemeProvider, Theme } from '@aws-amplify/ui-react';
import * as React from 'react';

const theme: Theme = {
  name: 'autocomplete-theme',
  tokens: {
    components: {
      autocomplete: {
        menu: {
          option: {
            _active: {
              backgroundColor: {
                value: '{colors.secondary.80}',
              },
            },
          },
        },
      },
    },
  },
};

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteThemeExample = () => {
  return (
    <ThemeProvider theme={theme} colorMode="light">
      <Autocomplete label="Autocomplete theme example" options={options} />
    </ThemeProvider>
  );
};

Target classes

ClassDescription
amplify-autocompleteTop level element that wraps the Autocomplete primitive
amplify-autocomplete__menuTop level element that wraps the dropdown menu
amplify-autocomplete__menu--emptyClass applied to the no options slot of menu
amplify-autocomplete__menu__footerClass applied to menu footer
amplify-autocomplete__menu__headerClass applied to menu header
amplify-autocomplete__menu--loadingClass applied to the loading slot of menu
amplify-autocomplete__menu__optionClass applied to each li option
amplify-autocomplete__menu__optionsClass applied to ul container element
  • --amplify-components-autocomplete-menu-background-color
  • --amplify-components-autocomplete-menu-border-color
  • --amplify-components-autocomplete-menu-border-radius
  • --amplify-components-autocomplete-menu-border-style
  • --amplify-components-autocomplete-menu-border-width
  • --amplify-components-autocomplete-menu-empty-display
  • --amplify-components-autocomplete-menu-loading-align-items
  • --amplify-components-autocomplete-menu-loading-display
  • --amplify-components-autocomplete-menu-loading-gap
  • --amplify-components-autocomplete-menu-margin-block-start
  • --amplify-components-autocomplete-menu-option-active-background-color
  • --amplify-components-autocomplete-menu-option-active-color
  • --amplify-components-autocomplete-menu-option-background-color
  • --amplify-components-autocomplete-menu-option-color
  • --amplify-components-autocomplete-menu-option-cursor
  • --amplify-components-autocomplete-menu-option-transition-duration
  • --amplify-components-autocomplete-menu-option-transition-property
  • --amplify-components-autocomplete-menu-option-transition-timing-function
  • --amplify-components-autocomplete-menu-options-display
  • --amplify-components-autocomplete-menu-options-flex-direction
  • --amplify-components-autocomplete-menu-options-max-height
  • --amplify-components-autocomplete-menu-space-shared-padding-block
  • --amplify-components-autocomplete-menu-space-shared-padding-inline
  • --amplify-components-autocomplete-menu-width

Global styling

To override styling on all Autocompletes, you can set the Amplify CSS variables with the built-in .amplify-autocomplete class.

/* styles.css */
.amplify-autocomplete {
  --amplify-components-autocomplete-menu-option-active-background-color: var(--amplify-colors-secondary-80);
}

Local styling

To override styling on a specific Autocomplete, you can use (in order of increasing specificity): a class selector and style props.

Using a class selector:

/* styles.css */
.my-autocomplete {
  --amplify-components-autocomplete-menu-option-active-background-color: var(--amplify-colors-secondary-80);
}

Using style props:

import { Autocomplete } from '@aws-amplify/ui-react';
import * as React from 'react';

const options = [
  { id: 'apple', label: 'apple' },
  { id: 'banana', label: 'banana' },
  { id: 'cherry', label: 'cherry' },
  { id: 'grape', label: 'grape' },
  { id: 'kiwis', label: 'kiwis' },
  { id: 'lemon', label: 'lemon' },
  { id: 'mango', label: 'mango' },
  { id: 'orange', label: 'orange' },
  { id: 'strawberry', label: 'strawberry' },
];

export const AutocompleteStylePropsExample = () => (
  <Autocomplete
    label="Autocomplete style props example"
    options={options}
    borderRadius="10px"
  />
);

Amplify open source software, documentation and community are supported by Amazon Web Services.

© 2024 Amazon Web Services, Inc. and its affiliates. All rights reserved. View the site terms and privacy policy.

Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.