The m3e-autocomplete component enhances an input field with a panel of suggested
options.
npm i @m3e/autocomplete
This section outlines usage examples and configuration guidance for the components in this package.
Begin by declaring the m3e-autocomplete panel and populating it with a set of
m3e-option elements. Each option represents a selectable value. When a user selects an option, its
textual content becomes the value of the associated text input. Alternatively, you may specify a distinct value
using the value attribute.
To bind the autocomplete panel to an input, use the for attribute on m3e-autocomplete,
setting it to match the id of the target input element.
The following example illustrates use of a m3e-autocomplete in conjunction with the
m3e-form-field. See Form Field for more information.
<m3e-form-field> <label slot="label" for="fruit">Choose your favorite fruit</label> <input id="fruit" /> </m3e-form-field> <m3e-autocomplete for="fruit"> <m3e-option>Apples</m3e-option> <m3e-option>Oranges</m3e-option> <m3e-option>Bananas</m3e-option> <m3e-option>Grapes</m3e-option> </m3e-autocomplete>
By default, m3e-autocomplete accepts any value typed into the input field, regardless of whether it
matches a listed option. To enforce selection from the available options, use the
required attribute.
When required is set, the autocomplete behaves as follows:
<m3e-form-field> <label slot="label" for="fruit">Choose your favorite fruit</label> <input id="fruit" value="Apple" /> </m3e-form-field> <m3e-autocomplete for="fruit" required> <!-- Options omitted for brevity --> </m3e-autocomplete>
Use the auto-activate attribute to control whether the first option will automatically be
activated.
<m3e-form-field> <label slot="label" for="fruit">Choose your favorite fruit</label> <input id="fruit" /> </m3e-form-field> <m3e-autocomplete for="fruit" auto-activate> <!-- Options omitted for brevity --> </m3e-autocomplete>
The m3e-autocomplete component follows the ARIA combobox interaction pattern. The
associated text input receives role="combobox", while the dropdown panel applies
role="listbox" to convey its structure to assistive technologies.
Options are given ARIA role="option", indicating that each item represents a selectable choice
within a listbox context. This role enables assistive technologies to interpret and announce the options
appropriately, supporting accessible navigation and selection behavior.
The aria-selected attribute reflects whether an option is currently selected. When an option is
selected, aria-selected="true" is exposed to assistive technologies; otherwise, it is
"false".
When disabled using the disabled attribute, aria-disabled="true" is used to convey to
assistive technologies that an option is disabled.
The aria-activedescendant attribute is applied to the input element to indicate which
option is currently active within the listbox. Instead of moving DOM focus to each option, the select retains
focus while updating aria-activedescendant to reference the id of the focused
m3e-option. This approach preserves focus management and enables assistive technologies to announce
the active option during keyboard navigation, ensuring accessible and predictable interaction.
The aria-owns and aria-controls attributes are applied to the
input element to establish an explicit relationship with the listbox popup. Both attributes
reference the id of the listbox container, ensuring assistive technologies recognize the connection
between the trigger and the controlled content. While aria-controls indicates that the select
governs the visibility and behavior of the listbox, aria-owns asserts DOM ownership when the
listbox is rendered outside the input's subtree.
The aria-expanded attribute reflects the current state of the listbox popup. When the listbox is
open, aria-expanded="true" is set on the input element; when collapsed, it is set to
false. This dynamic state enables screen readers to announce whether the listbox is expanded or
collapsed, supporting accessible navigation and interaction.
Because listbox is designed for single-item selection, you should avoid placing additional
interactive elements—such as buttons, checkboxes, or toggles—inside m3e-option. Nesting interactive
controls within options disrupts expected navigation and interferes with screen reader behavior.
This package uses JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.
<script type="module" src="/node_modules/@m3e/autocomplete/dist/index.js"></script>
You also need a module script for @m3e/option due to it being a dependency.
<script type="module" src="/node_modules/@m3e/option/dist/index.js"></script>
In addition, you must use an import map to include additional dependencies.
<script type="importmap">
{
"imports": {
"lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
"@m3e/core": "/node_modules/@m3e/core/dist/index.js",
"@m3e/core/a11y": "/node_modules/@m3e/core/dist/a11y.js",
"@m3e/core/anchoring": "/node_modules/@m3e/core/dist/anchoring.js",
"@m3e/core/bidi": "/node_modules/@m3e/core/dist/bidi.js"
}
}
</script>
For production, use index.min.js, a11y.min.js, anchoring.min.js, and bidi.min.js for faster load times.
This package includes a Custom Elements Manifest (custom-elements.json), which
documents the properties, attributes, slots, events and CSS custom properties of each component.
You can explore the API below, or integrate the manifest into your own tooling.