Autocomplete

Import
import { Autocomplete } from "reshaped";
import type { AutocompleteProps } from "reshaped";
Related components

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 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 DemoBasic() {
  const [value, setValue] = React.useState("");
  const options = ["Pizza", "Pie", "Ice-cream"];

  const handleChange = (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 DemoFiltering() {
  const [value, setValue] = React.useState("");
  const options = ["Pizza", "Pie", "Ice-cream"];

  const handleChange = (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.

function DemoComposition() {
  const [value, setValue] = React.useState("");
  const [selectedItem, setSelectedItem] = React.useState("");
  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",
    },
  ];

  const handleChange = (args) => setValue(args.value);
  const handleItemSelect = (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>
  );
}

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 DemoBasic() {
  const [value, setValue] = React.useState("");
  const options = ["Pizza", "Pie", "Ice-cream"];

  const handleChange = (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" }} />
  • ArrowDown - open the dropdown while the text field is focused and at least one value is available
  • Esc - close the dropdown
  • ArrowUp / ArrowDown - navigate the autocomplete items
  • Enter - select the focused autocomplete item
  • Tab - close the dropdown and move the focus to the next element after the text field
  • Shift + Tab - close the dropdown and keep the focus on the text field
  • When using Autocomplete without a label, provide a text description by passing inputAttributes={{ 'aria-label': 'Your label' }} to the component.