Skip to content

Import

import { Autocomplete } from '@dnb/eufemia'

Description

The Autocomplete component is a combination of an Input and a Dropdown, also called ComboBox. During typing, matching data items gets suggested in an option menu (listbox).

Typeahead and ComboBox

The Autocomplete component may also be known as Typeahead or ComboBox. But autocomplete describes the purpose more precisely and descriptive, therefore Eufemia is using this term.

When to use it:

Use it for both small autocomplete purposes and large (async) data set searches. The component supports two ways of showing ProgressIndicator.

You may check out the Dropdown component for more details on how to use it etc. They both share the same DrawerList.

Highlighting

Words found during typing are highlighted. The rules are:

  1. The two first words will match the beginning of a word
  2. The third word will match inside a word (can be changed with search_in_word_index)
  3. Case insensitive

Using Components inside content

It is not possible to wrap them inside React Components. The reason is that the Autocomplete component needs to know what data it wants to search for before your React Component has rendered. But also, the component can't update the HTML to make the bold highlighting – "after" your component has rendered.

That means you can't run a component that will render as soon as it is displayed.

If you need to format numbers, then do it before you send in the data content.

It is possible to wrap your content inside one HTML Element. Nested elements are not supported.

To wrap your content only visually, you can provide your wrappers inside an array:

Code Editor
<Autocomplete
  data={[
    {
      content: [
        <IconPrimary icon="bell" key="item-1" />,
        <span className="custom-selector-a" key="item-2">
          The Shawshank Redemption
        </span>,
        <span className="custom-selector-b" key="item-3">
          The Dark Knight
        </span>,
        // etc.
        <NumberFormat value={1234} key="item-4" />, // <-- Not searchable nor highlightable
      ],
    },
  ]}
  label="Label"
/>

or you can provide it inside a fragment:

Code Editor
<Autocomplete
  data={[
    {
      content: (
        <>
          <IconPrimary icon="bell" />
          <span className="custom-selector-a">
            The Shawshank Redemption
          </span>
          <span className="custom-selector-b">The Dark Knight</span>
        </>
      ),
    },
  ]}
  label="Label"
/>

and if you need to decouple the searchable content from what's displayed, then you can put your searchable content inside search_content:

Code Editor
<Autocomplete
  data={[
    {
      content: ['your visual content'],
      search_content: ['your search content'],
    },
  ]}
  label="Label"
/>

Re-render data

For performance optimization, you should ensure the data array/object is memorized (with useMemo, useState or useRef), so when the Autocomplete re-renders, it does not have to process the internal data unnecessary.

const MyComponent = () => {
const data = React.useMemo(() => ['Item 1', 'Item 2'], [])
return <Autocomplete data={data} />
}

Or keep it outside the component:

const data = ['Item 1', 'Item 2']
const MyComponent = () => {
return <Autocomplete data={data} />
}

Numbers

Numbers are often different than a word filter. You can use search_numbers={true} to enable a number specialized filtering. See example in the demos.

Now the user could search for e.g. bank account numbers by just entering 201, even if you format it like 2000 12 34567 (e.g. use format(20001234567, { ban: true }) from @dnb/eufemia/components/number-format/NumberUtils).

Screen reader support

To enhance screen reader usage, this component uses aria-live to announce the number of options found (aria_live_options).

Custom size

.dnb-autocomplete {
--autocomplete-width: 20rem; /* custom width */
}

You can also set the width directly, but then it has to be defined like so (including min-width):

/** Because of the included label/status etc. we target the "__shell" */
.dnb-autocomplete__shell {
width: 10rem;
}
/** In order to change only the drawer-list width */
.dnb-autocomplete .dnb-drawer-list__root {
width: 10rem;
}

Dynamically change data

You can manipulate the used data dynamically, either by changing the data property or during user events like on_type or on_focus. The following properties and methods are there to use:

Methods

  • updateData replace all data entries.
  • emptyData remove all data entries.
  • resetSelectedItem will invalidate the selected key.
  • revalidateSelectedItem will re-validate the internal selected key on the given value.
  • revalidateInputValue will re-validate the current input value and update it – based on the given value.
  • setInputValue update the input value.
  • clearInputValue will set the current input value to an empty string.
  • focusInput will set focus on the input element.
  • showIndicator shows a progress indicator instead of the icon (inside the input).
  • hideIndicator hides the progress indicator inside the input.
  • showIndicatorItem shows an item with a ProgressIndicator status as an data option item.
  • showNoOptionsItem shows the "no entries found" status as an data option item.
  • setVisible shows the DrawerList.
  • setHidden hides the DrawerList.
  • showAllItems shows all DrawerList items.
  • setMode switch the mode during runtime.
  • debounce a debounce method with a cancel invocation method on repeating calls. There is more documentation about this method.

Properties

  • dataList contains all the data entries.

Example

<Autocomplete
on_focus={({ updateData, showIndicator }) => {
showIndicator()
setTimeout(() => {
updateData(topMovies)
}, 1e3)
}}
on_type={({ value /* updateData, ... */ }) => {
console.log('on_type', value)
}}
/>