Autocomplete

View on Github

The autocomplete component is an input field that provides selectable options as a user types into it. It allows users to quickly search through and select from large collections of options.

How to use Autocomplete

The Autocomplete requires 3 props to work:

  • items: It’s an array containing the items that will be shown as selectable options when the user types something in the TextInput.
  • onInputValueChange: This function will be called every time the user types something in the input. The component will pass the item, which the filter method is currently iterating over, and the inputValue prop of the TextInput component.
  • onSelectItem: This function is called when the user selects one of the options of the list. The component will pass the selected item as an argument to the function.

An Autocomplete with a list of fruits will look like this:

Best practices

  • Autocomplete should have a clear label so user understands what type of action is possible
  • Consider using autocomplete over selects if a user will be choosing from a very long list, for example a country list.

Code examples

Using objects as items

On the example in the "How to use Autocomplete" section, we showed how to create an Autocomplete with an array of string but it’s also possible to use other types of data as items. A very common way of using the Autocomplete is with objects and for that, with a few changes to the Fruit’s example this can be done:

Both itemToString and renderItem are necessary when passing objects as items and they both will receive an "item" as an argument.

If you are using Typescript, you can tell the Autocomplete what is the type of your items to make these functions strongly typed. You can do that by writing the component like this <Autocomplete<ItemType> {...props}/>

Highlighting an item with getStringMatch

A common use case for Autocomplete components is to highlight in each suggestion what is typed in the input. Using the previous example, if a user types "ana" we want to show a list of suggestions where only "ana" is bold. This is possible by using the renderItem prop and the getStringMatch utility function:

// We need to import the function from the `f36-utils` package
import { getStringMatch } from '@contentful/f36-utils';
import { Autocomplete } from '@contentful/f36-autocomplete';
// Everything stays the same, besides the `renderItem` prop
<Autocomplete
items={filteredItems}
onInputValueChange={handleInputValueChange}
onSelectItem={handleSelectItem}
itemToString={(item) => item.name}
// Two arguments are provided to the `renderItem` prop: the item and the inputValue
renderItem={(item, inputValue) => {
// we pass `item.name` and the inputValue to getStringMatch and the util will return an object
// for our example, for the "Banana" item this will return { before: 'B' , match: 'ana', after: 'na' }
const { before, match, after } = getStringMatch(item.name, inputValue);
// Finally, we return a ReactNode
// this will return `<>B<b>ana</b>na 🍌</>` (the "ana" will be bold)
return (
<>
{before}
<b>{match}</b>
{after} {item.emoji}
</>
);
}}
/>;

Filling in a list of items

Using grouped objects as items

As an extension of "Use objects as items" section, you are also able to use a nested object to group your entries. The most important part of making this work is the shape of the grouped object. The options themselves work exactly as in the object example and require the itemToString and renderItem functions. Besides the correct shape of the object the Autocomplete component needs to receive the prop isGrouped

Error validation with FormControl

Fetching async data

Content guidelines

  • Autocomplete label should be short, contain 1 to 3 words
  • Label should be written in a sentence case (the first word capitalized, the rest lowercase)

Accessibility

  • dismisses the dropdown when selecting with the enter key

Props

  • Name

    items(required)

    Description

    It’s an array of data to be used as "options" by the autocomplete component. This can either be a plain list of items or a list of groups of items.

    T[]
    GenericGroupType<T>[]
  • Name

    onSelectItem(required)

    Description

    This is the function that will be called when the user selects one of the "options" in the list. It receives the selected item as an argument and it needs to return a string that will be set as the value of `TextInput`.

    (item: T) => void
  • Name

    className

    Description

    CSS class to be appended to the root element

    string
  • Name

    clearAfterSelect

    Description

    If this is set to `true` the text input will be cleared after an item is selected

    false
    true
  • Name

    defaultValue

    Description

    Set's default value for text input

    string
  • Name

    id

    Description

    Sets the id of the input

    string
  • Name

    inputRef

    Description

    Use this prop to get a ref to the input element of the component

    (instance: HTMLInputElement) => void
    RefObject<HTMLInputElement>
  • Name

    isDisabled

    Description

    Applies disabled styles

    false
    true
  • Name

    isGrouped

    Description

    Tells if the item is a object with groups

    false
    true
  • Name

    isInvalid

    Description

    Applies invalid styles

    false
    true
  • Name

    isLoading

    Description

    Sets the list to show its loading state

    false
    true
  • Name

    isReadOnly

    Description

    Applies read-only styles

    false
    true
  • Name

    isRequired

    Description

    Validate the input

    false
    true
  • Name

    itemToString

    Description

    When using objects as `items`, we recommend passing a function that tells Downshift how to extract a string from those objetcs to be used as inputValue

    (item: T) => string
  • Name

    listMaxHeight

    Description

    It sets the max-height, in pixels, of the list The default value is the height of 5 single line items

    number
  • Name

    listRef

    Description

    Use this prop to get a ref to the list of items of the component

    (instance: HTMLUListElement) => void
    RefObject<HTMLUListElement>
  • Name

    listWidth

    Description

    It sets the width of the list

    "auto"
    "full"
  • Name

    noMatchesMessage

    Description

    A message that will be shown when it is not possible to find any option that matches the input value

    string
  • Name

    onInputValueChange

    Description

    Function called whenever the input value changes

    (value: string) => void
  • Name

    placeholder

    Description

    This is the value will be passed to the `placeholder` prop of the input.

    string
  • Name

    renderItem

    Description

    This is the function that will be called for each "item" passed in the `items` prop. It receives the "item" and "inputValue" as arguments and returns a ReactNode. The inputValue is passed in case you want to highlight the match on the render.

    (item: T, inputValue: string) => ReactNode
  • Name

    testId

    Description

    A [data-test-id] attribute used for testing purposes

    string
  • Name

    toggleRef

    Description

    Use this prop to get a ref to the toggle button of the component

    (instance: HTMLButtonElement) => void
    RefObject<HTMLButtonElement>
  • Name

    usePortal

    Description

    Boolean to control whether or not to render the suggestions box in a React Portal. Rendering content inside a Portal allows the suggestions box to escape the bounds of its parent while still being positioned correctly. Defaults to `false`

    false
    true