Autocomplete4.0
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-libraryUsage
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.
<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.
<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
<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
<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.
<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.
<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.
<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 textendsWith— 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.
<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.
<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.
<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"witharia-expanded,aria-controls, andaria-activedescendant - The dropdown list uses
role="listbox" - Options use
role="option"witharia-selectedstate - 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
- Avoid very long option names to facilitate understanding and perception.
- Don't use the same word or phrase at the beginning of a set of options.
- If the autocomplete is a required field, include the
requiredproperty 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
| Property | Attribute | Description | Type | Default |
|---|---|---|---|---|
charLimit | char-limit | Character limit to expand on for Autocomplete | number | 1 |
disabled | disabled | Disable flag for Autocomplete | boolean | false |
errTextPlacement | err-text-placement | This 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' |
errorText | error-text | Error text for Autocomplete | string | "default error text" |
expandOn | expand-on | Expand condition for Autocomplete | "charLimit" | "click" | 'click' |
filterCondition | filter-condition | Filter 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 |
helpText | help-text | Helpful Text for Autocomplete | string | undefined |
inputValue | input-value | Value inputed | string | undefined |
label | label | Label for Autocomplete | string | undefined |
loadText | load-text | Text to show when loading is true | string | "Searching..." |
loading | loading | To set a loading state while options are recieved | boolean | false |
noOptionsErrorText | no-options-error-text | No options text for Autocomplete | string | "No Options found" |
options | options | Options for Autocomplete | (string | OptionValue)[] | string | undefined |
placeholder | placeholder | Placeholder Text for Autocomplete | string | undefined |
readonly | readonly | ReadOnly flag for Autocomplete | boolean | false |
required | required | Mark the field as required for form validation. | boolean | false |
showError | show-error | Show error on not selecting from dropdown | boolean | true |
showIcon | show-icon | Show search icon for Autocomplete | boolean | false |
uuid | uuid | The unique id of the input field | string | uuidv4() |
Events
| Event | Description | Type |
|---|---|---|
blurevent | Event emitted when the input loses focus | CustomEvent<AutocompleteBlurEventDetail> |
collapse | Event emitted when the dropdown collapses | CustomEvent<AutocompleteCollapseEventDetail> |
expand | Event emitted when the dropdown expands | CustomEvent<AutocompleteExpandEventDetail> |
focusevent | Event emitted when the input receives focus | CustomEvent<AutocompleteFocusEventDetail> |
highlight | Event emitted for a highlighted selection when a user uses arrow keys for navigating options | CustomEvent<AutocompleteHighlightEventDetail> |
inputchange | Event emitted when input field is changed | CustomEvent<AutocompleteInputEventDetail> |
selectevent | Event emitted when a valid option has been selected | CustomEvent<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:4pxBuilt with StencilJS
