<u-combobox>
<u-combobox>
extends <input>
with support for multiselect and separate label and programmatic value. While these features are not yet part of any official ARIA pattern or HTML element, <u-combobox>
adhere closely to HTML conventions.
IMPORTANT
u-combobox
is work in progress. Changes might apply and documentation is not complete.
Quick intro:
- Use
<data>
as direct child elements - these are the removable items - Use
<input>
and<u-datalist>
to allow adding and suggesting items - Use
data-multiple
to allow selecting multiple items - Use
data-creatable
to allow creating items not in the list - Use
data-*
attributes to translate screen reader announcements - Use
beforechange
,afterchange
andbeforematch
events to manipulate state - Add
<select>
as child forFormData
or form submittion compatibility - Use matching
id
on<input>
andfor
attribute on<label>
to connect - MDN Web Docs: <data> (HTMLDataElement) / <input> (HTMLInputElement) / <datalist> (HTMLDatalistElement) / <option> (HTMLOptionElement)
Example
<label for="my-input"> Choose flavor of ice cream </label> <u-combobox> <data>Coconut</data> <data>Banana</data> <data>Pineapple</data> <data>Orange</data> <input id="my-input" list="my-list" /> <u-datalist id="my-list" data-sr-singular="%d flavor" data-sr-plural="%d flavours"> <u-option>Coconut</u-option> <u-option>Strawberries</u-option> <u-option>Chocolate</u-option> <u-option>Vanilla</u-option> <u-option>Licorice</u-option> <u-option>Pistachios</u-option> <u-option>Mango</u-option> <u-option>Hazelnut</u-option> </u-datalist> </u-combobox> <style> /* Styling just for example: */ u-combobox { border: 1px solid; display: flex; flex-wrap: wrap; gap: .5em; padding: .5em; position: relative } u-option[selected] { font-weight: bold } u-datalist { position: absolute z-index: 9; inset: 100% -1px auto; border: 1px solid; background: white; padding: .5em } </style>
Install
bash
npm add -S @u-elements/u-combobox
bash
pnpm add -S @u-elements/u-combobox
bash
yarn add @u-elements/u-combobox
bash
bun add -S @u-elements/u-combobox
html
<script type="module" src="https://unpkg.com/@u-elements/u-combobox@latest/dist/u-combobox.js"></script>
Attributes and props
<u-combobox>
- Attributes: all global HTML attributes such as
id
,class
,data-
data-sr-added
prefixes announcements about additions. Defaults to"Added"
data-sr-removed
prefixes announcements about removals. Defaults to"Removed"
data-sr-remove
announces ability to remove. Defaults to"Press to remove"
data-sr-empty
announces no selected items. Defaults to"No selected"
data-sr-found
announces where to find amount of selected items. Defaults to"Navigate left to find %d selected"
data-sr-invalid
announces if trying to select invalid value. Defaults to"Invalid value""
data-sr-of
separates "number of total" in announcements. Defaults to"of"
- DOM interface:
UHTMLComboboxElement
extendsHTMLElement
UHTMLComboboxElement.control
returnsHTMLInputElement | null
UHTMLComboboxElement.items
returnsHTMLCollectionOf<HTMLDataElement>
UHTMLComboboxElement.list
returnsHTMLDataListElement | null
UHTMLComboboxElement.options
returnsHTMLCollectionOf<HTMLOptionElement> | undefined
<data>
- Attributes: all global HTML attributes such as
id
,class
,data-
value
optionally specify the machine-readable translation of the text content.
- DOM interface:
HTMLDataElement
HTMLDataElement.value
string reflecting thevalue
HTML attribute.
Events
In addition to the usual events supported by HTML elements, the <u-combobox>
elements dispatches custom events allowing you to affect state:
beforechange
js
myCombobox.addEventListener('beforechange', (event) => {
event.detail // HTMLDataElement to add or remove
event.detail.isConnnected // true if removing, false if adding
event.preventDefault() // Optionally prevent action
})
afterchange
js
myCombobox.addEventListener('afterchange', (event) => {
event.detail // HTMLDataElement added or removed
event.detail.isConnnected // false if removing, true if adding
})
beforematch
js
myCombobox.addEventListener('beforematch', (event) => {
event.detail // HTMLOptionElement | undefined match in option list
})
Styling
<u-combobox>
renders as display: block
, while <data>
renders as display: inline-block
with a ::after
element to render the removal ×
.
Example: Norwegian
<label for="my-norwegian-combobox"> Velg type iskrem </label> <u-combobox data-sr-added="La til" data-sr-remove="Trykk for å fjerne" data-sr-removed="Fjernet" data-sr-empty="Ingen valgte" data-sr-found="Naviger til venstre for å finne %d valgte" data-sr-of="av" id="my-norwegian-combobox" > <data>Kokkos</data> <data>Banan</data> <data>Ananas</data> <data>Appelsin</data> <input list="my-norwegian-list" /> <u-datalist id="my-norwegian-list" data-sr-singular="%d smak" data-sr-plural="%d smaker"> <u-option>Kokkos</u-option> <u-option>Jordbær</u-option> <u-option>Sjokolade</u-option> <u-option>Vanilje</u-option> <u-option>Lakris</u-option> <u-option>Pistasj</u-option> <u-option>Mango</u-option> <u-option>Hasselnøtt</u-option> </u-datalist> </u-combobox> <style> /* Styling just for example: */ u-combobox { border: 1px solid; display: flex; flex-wrap: wrap; gap: .5em; padding: .5em; position: relative } u-option[selected] { font-weight: bold } u-datalist { position: absolute; z-index: 9; inset: 100% -1px auto; border: 1px solid; background: white; padding: .5em } </style>
Accessibility
Screen reader | <u-combobox> |
---|---|
VoiceOver (Mac) + Chrome | ✅ |
VoiceOver (Mac) + Edge | ✅ |
VoiceOver (Mac) + Firefox | ✅ |
VoiceOver (Mac) + Safari | ✅ |
VoiceOver (iOS) + Safari | ✅ |
Jaws (PC) + Chrome | ✅ |
Jaws (PC) + Edge | ✅ |
Jaws (PC) + Firefox | ✅ |
NVDA (PC) + Chrome | ✅ |
NVDA (PC) + Edge | ✅ |
NVDA (PC) + Firefox | ✅ needs focus mode to announce item removal |
Narrator (PC) + Chrome | ✅ |
Narrator (PC) + Edge | ✅ |
Narrator (PC) + Firefox | ✅ |
TalkBack (Android) + Chrome | ✅ |
TalkBack (Android) + Firefox | ✅ |
TalkBack (Android) + Samsung Internet | ✅ |
Specifications
- DOM interface: HTMLElement
- HTML Standard: The <div> element
- DOM interface: HTMLDataElement
- HTML Standard: The <data> element
Changelog
- 0.0.4: Bugfix
- 0.0.3: Prevent add if
u-option
has empty value attribute - 0.0.2: Reset value when clicking option in multiple mode
- 0.0.1: Support async
u-option
initialization - 0.0.0: Beta release