Anchor Design System
Form

Autocomplete4.0

Autocomplete description

WORK IN PROGRESS: This component has not gone through final testing and a11y validation. It may see breaking changes in the near future based on the feedback from testing.

Installation

npm i @tryg/ui-library

Usage

The Autocomplete component allows users to search through a list of options and select a value. It supports keyboard navigation, custom filtering, and rich options with labels and descriptions.

Individual only imports the desired component, and only needs to be included once within the application. Which is beneficial to keep the application size small.

Webcomponent
<script type="module">
  import { defineCustomElement } from '@tryg/ui-library/dist/components/anchor-autocomplete';
  defineCustomElement();

  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" placeholder="Start typing to search..."></anchor-autocomplete>

Global only needs to be defined once in the application, but it will import all components even the ones that are not in use.

Webcomponent
<script type="module">
  import { defineCustomElements } from '@tryg/ui-library/dist/loader';
  defineCustomElements();

  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" placeholder="Start typing to search..."></anchor-autocomplete>

Rich Options

Options can be passed as an array of OptionValue objects with value, label, and optional description properties. Options display labels but submit values on selection.

Options with Descriptions

Options can include a description field that provides additional context in the dropdown.

Disabled

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" placeholder="Cannot interact with this field" disabled></anchor-autocomplete>

Read Only

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" placeholder="This field is read-only" readonly></anchor-autocomplete>

Required

If you pass the required property to the component, the field will be required for form validation.

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" required></anchor-autocomplete>

Help Text

You can add helpful text to the component by passing the help-text property.

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" help-text="Enter a country name to see suggestions"></anchor-autocomplete>

With Error Message

When show-error is true (default), typing a value that is not selected from the dropdown will display an error message on blur. Customize the message with error-text.

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));
</script>
<anchor-autocomplete label="Search Countries" error-text="Please select a valid country"></anchor-autocomplete>

Filter Options

Filter Condition

Control how the default filter matches options using the filter-condition property. The default is contains.

Available filter conditions:

  • contains — Shows options that contain the input text anywhere (default)
  • startsWith — Shows options that start with the input text
  • endsWith — Shows options that end with the input text

Custom Filter Function

For full control over filtering, pass a custom filter function via the custom-filter attribute.

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));

  const autocomplete = document.querySelector('anchor-autocomplete');
  autocomplete.customFilter = (options, input, condition) => {
    const trimmed = input?.toLowerCase().trim();
    if (!trimmed) return options;
    return options.filter(opt =>
      (opt.label || opt.value).toLowerCase().startsWith(trimmed)
    );
  };
</script>
<anchor-autocomplete label="Search Countries"></anchor-autocomplete>

Expand Behavior

Expand on Click

The dropdown expands when the user clicks the input (default behavior).

Expand on Character Limit

The dropdown expands only after the user types a minimum number of characters.

Backend Filtering

When filtering on your backend (e.g., querying an API for each keystroke), listen to the inputchange event and update the options prop with the server response. Combine with loading to show a loading indicator while fetching.

Webcomponent
<script type="module">
  const autocomplete = document.querySelector('anchor-autocomplete');
  let abortController = null;

  autocomplete.addEventListener('inputchange', async (e) => {
    const searchTerm = e.detail.value;

    // Abort previous in-flight request to avoid stale results
    if (abortController) abortController.abort();
    abortController = new AbortController();

    // Show loading indicator
    autocomplete.loading = true;

    try {
      const response = await fetch(`/api/countries?q=${encodeURIComponent(searchTerm)}`, {
        signal: abortController.signal
      });
      const data = await response.json();

      // Feed server-filtered results back into options
      autocomplete.loading = false;
      autocomplete.options = data.map(c => ({
        value: c.id,
        label: c.name
      }));
    } catch (err) {
      if (err.name !== 'AbortError') {
        autocomplete.loading = false;
      }
    }
  });
</script>
<anchor-autocomplete label="Search Countries" placeholder="Search..." load-text="Searching countries..."></anchor-autocomplete>

The inputchange event fires on every keystroke. The component's internal watcher picks up the new options automatically — no manual filter function is needed since the backend has already done the filtering.

Loading State

Set loading to display a loading indicator while options are being fetched asynchronously.

Search Icon

Show a search icon in the input using the show-icon property. The icon is visible when the dropdown is collapsed and no option is selected.

Events

The Autocomplete component emits several custom events that can be listened to for reactive behavior.

Webcomponent
<script type="module">
  const options = ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany'];
  document.querySelector('anchor-autocomplete').setAttribute('options', JSON.stringify(options));

  const autocomplete = document.querySelector('anchor-autocomplete');

  autocomplete.addEventListener('selectevent', e => {
    console.log('Selected:', e.detail);
    // { value: string, label: string }
  });

  autocomplete.addEventListener('inputchange', e => {
    console.log('Input changed:', e.detail);
    // { value: string }
  });

  autocomplete.addEventListener('expand', e => {
    console.log('Dropdown expanded:', e.detail);
    // { expanded: true, searchTerm: string }
  });

  autocomplete.addEventListener('collapse', e => {
    console.log('Dropdown collapsed:', e.detail);
    // { expanded: false, selected: boolean }
  });

  autocomplete.addEventListener('highlight', e => {
    console.log('Option highlighted:', e.detail);
    // { index: number, value: string, label: string }
  });

  autocomplete.addEventListener('focusevent', e => {
    console.log('Input focused:', e.detail);
    // { value: string }
  });

  autocomplete.addEventListener('blurevent', e => {
    console.log('Input blurred:', e.detail);
    // { value: string, selected: boolean, error: boolean }
  });
</script>
<anchor-autocomplete label="Search Countries" placeholder="Interact to see events in console"></anchor-autocomplete>

Accessibility

The Autocomplete component implements the ARIA combobox pattern:

  • The input uses role="combobox" with aria-expanded, aria-controls, and aria-activedescendant
  • The dropdown list uses role="listbox"
  • Options use role="option" with aria-selected state
  • Full keyboard navigation is supported:
    • Arrow Down — Open dropdown / move focus to next option
    • Arrow Up — Move focus to previous option
    • Enter / Space — Select the currently focused option
    • Escape — Close the dropdown

Accessibility Considerations

  1. Avoid very long option names to facilitate understanding and perception.
  2. Don't use the same word or phrase at the beginning of a set of options.
  3. If the autocomplete is a required field, include the required property and indicate that it is a required field.

Guidelines

Do use

  • Autocomplete can be used in:
    • Full pages
    • Forms
    • Modals
    • Side panels
  • Autocomplete components are used to select values from a large dataset.

Don't use

  • It's best practice not to use an autocomplete if there are only a limited number of options to choose from. In this case, use a select or radio group instead.

API

anchor-typeahead

WORK IN PROGRESS: This component is new

How to use the typeahead component

Basic typeahead

<anchor-typeahead options='["foo","bar","foobar"]' language="NO" texts='{"noResult":"The search yeilded no results"}'></anchor-typeahead>

Properties

PropertyAttributeDescriptionTypeDefault
charLimitchar-limitCharacter limit to expand on for Autocompletenumber1
disableddisabledDisable flag for Autocompletebooleanfalse
errTextPlacementerr-text-placementThis prop decides if the messages should render between the label of an input and the input field, or below the input field."below" | "inside"'inside'
errorTexterror-textError text for Autocompletestring"default error text"
expandOnexpand-onExpand condition for Autocomplete"charLimit" | "click"'click'
filterConditionfilter-conditionFilter condition to be used with default filter function for Autocomplete"contains" | "endsWith" | "startsWith"'contains'
filterFn--Custom Filter Function for Autocomplete(options: OptionValue[], input: string, condition?: string) => OptionValue[]filterOptions
helpTexthelp-textHelpful Text for Autocompletestringundefined
inputValueinput-valueValue inputedstringundefined
labellabelLabel for Autocompletestringundefined
loadTextload-textText to show when loading is truestring"Searching..."
loadingloadingTo set a loading state while options are recievedbooleanfalse
noOptionsErrorTextno-options-error-textNo options text for Autocompletestring"No Options found"
optionsoptionsOptions for Autocomplete(string | OptionValue)[] | stringundefined
placeholderplaceholderPlaceholder Text for Autocompletestringundefined
readonlyreadonlyReadOnly flag for Autocompletebooleanfalse
requiredrequiredMark the field as required for form validation.booleanfalse
showErrorshow-errorShow error on not selecting from dropdownbooleantrue
showIconshow-iconShow search icon for Autocompletebooleanfalse
uuiduuidThe unique id of the input fieldstringuuidv4()

Events

EventDescriptionType
blureventEvent emitted when the input loses focusCustomEvent<AutocompleteBlurEventDetail>
collapseEvent emitted when the dropdown collapsesCustomEvent<AutocompleteCollapseEventDetail>
expandEvent emitted when the dropdown expandsCustomEvent<AutocompleteExpandEventDetail>
focuseventEvent emitted when the input receives focusCustomEvent<AutocompleteFocusEventDetail>
highlightEvent emitted for a highlighted selection when a user uses arrow keys for navigating optionsCustomEvent<AutocompleteHighlightEventDetail>
inputchangeEvent emitted when input field is changedCustomEvent<AutocompleteInputEventDetail>
selecteventEvent emitted when a valid option has been selectedCustomEvent<AutocompleteSelectEventDetail>

Dependencies

Depends on

Graph

graph TD;
  anchor-autocomplete --> anchor-input
  anchor-autocomplete --> anchor-option
  anchor-input --> anchor-form-field
  anchor-input --> anchor-icon
  anchor-input --> anchor-tooltip
  anchor-form-field --> anchor-icon
  anchor-option --> anchor-icon
  style anchor-autocomplete fill:#f9f,stroke:#333,stroke-width:4px

Built with StencilJS

On this page