combobox-wc
Autocomplete combobox with filtering, keyboard navigation, and native form association. Supports single-select and multi-select tag modes.
Overview
An autocomplete combobox following the W3C ARIA combobox pattern. Users type to filter a list of options, navigate with arrow keys, and select with Enter or click. The selected value participates in native form submission via ElementInternals.
Add data-multiple to enable multi-select tag mode, where users can select multiple items as tag chips.
Usage
Place an <input> and a <ul> inside <combobox-wc>. Each <li> needs a data-value attribute for the form value. The visible text content becomes the label.
Inside a Form
Use the standard name attribute to set the form field name. The selected data-value is submitted as the form value. Add data-required to enable required validation.
Filter Modes
By default, typing filters options by substring match (contains). Set data-filter="startsWith" to only match from the beginning of each option.
Multi-Select Mode
Add data-multiple to switch to multi-select tag mode. Users select multiple items which appear as removable tag chips. Selected options are hidden from the dropdown to prevent duplicates.
Multi-Select Options
In multi mode, use data-max to limit the number of selections and data-allow-custom to let users type custom entries (press Enter or comma to add). Each selected tag is submitted as a separate FormData entry (like multiple checkboxes with the same name).
Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
name | string | — | Form field name (standard HTML attribute) |
data-required | boolean | — | Require a selection for form validation |
data-filter | "contains", "startsWith" | "contains" | How typing filters the options |
data-value | string | — | Get/set selected value (reflected, single mode) |
data-placeholder | string | — | Input placeholder text |
data-open | boolean | — | Reflected when the listbox is open |
data-multiple | boolean | — | Enable multi-select tag mode |
data-max | number | — | Maximum number of tags (multi mode) |
data-allow-custom | boolean | — | Allow typed entries via Enter/comma (multi mode) |
Events
| Event | Detail | Description |
|---|---|---|
combobox-change | { value, label } | Fired when an option is selected (single mode). |
combobox-change | { values: string[], labels: string[] } | Fired when tags are added or removed (multi mode). |
combobox-open | — | Fired when the listbox opens. |
combobox-close | — | Fired when the listbox closes. |
Single Mode
Multi Mode
JavaScript API
| Property | Type | Mode | Description |
|---|---|---|---|
element.value | string | Single | Current selected value (read/write) |
element.label | string | Single | Current selected label (read-only) |
element.values | string[] | Multi | Array of selected tag values (read-only) |
element.labels | string[] | Multi | Array of selected tag labels (read-only) |
Single Mode
Multi Mode
Keyboard Navigation
| Key | Action |
|---|---|
| ArrowDown | Open listbox / move to next option |
| ArrowUp | Open listbox / move to previous option |
| Home | Jump to first option |
| End | Jump to last option |
| Enter | Select option (single) or add tag (multi). With data-allow-custom: add typed text. |
| Escape | Close listbox |
| Tab | Close listbox and move focus |
| Backspace | Remove last tag when input is empty (multi mode) |
| , (comma) | Add custom tag (multi mode with data-allow-custom) |
Accessibility
ARIA Pattern
Implements the W3C ARIA Combobox pattern:
- Input has
role="combobox",aria-expanded,aria-autocomplete="list", andaria-controls - List has
role="listbox"with an auto-generated ID - Options have
role="option"andaria-selected - Active option announced via
aria-activedescendant - Multi mode adds
aria-multiselectable="true"and anaria-liveregion for tag add/remove announcements
Form Validation
Uses ElementInternals.setValidity() so screen readers can announce validation errors. Works with :user-valid and :user-invalid CSS pseudo-classes.
Form Association
This component is a Form-Associated Custom Element. It uses ElementInternals to:
- Submit the selected
data-valueviaFormData(single mode: one value; multi mode: one entry per tag) - Validate with
setValidity()for required fields - Reset on form reset via
formResetCallback() - Restore state from browser history via
formStateRestoreCallback()(single mode)
No hidden inputs needed. The component name is set via the standard name attribute.
Styling
The component uses @scope (combobox-wc) for shared CSS encapsulation and @scope (combobox-wc[data-multiple]) for tag-specific styles. Override option states and tag chip appearance using standard selectors:
Progressive Enhancement
Without JavaScript, <combobox-wc> renders as a plain text input above a visible, scrollable list. Users can still see all options and type into the input. Once JS loads, the component adds filtering, keyboard navigation, and form association.
Related
- Form-Associated Custom Elements — Guide to the pattern
<rating-wc>— Another form-associated component<dropdown-wc>— Action menu (non-form)<datalist>— Native autocomplete