ComboboxForm-associated
4.66 KB gzip4.1 KB brotli4.86 KB zstd
Depends on <sv-flyout /> and <sv-anchor />
sv-combobox combines an editable text field with a listbox. Use sv-select when users should choose without typing: a combobox keeps focus in its text field, while a select moves focus through its options.
Usage
<label for="color">Color</label><sv-combobox id="color" name="color" placeholder="Search colors"> <sv-flyout> <button type="button" value="red">Red</button> <button type="button" value="green">Green</button> <button type="button" value="blue">Blue</button> <p data-combobox-no-results>No matching color</p> </sv-flyout></sv-combobox>A button becomes an option only when it carries a value attribute, and every value has to be unique. Add data-combobox-ignore to a button that should stay out of the list.
A disabled option stays visible and keeps taking part in filtering.
Options are found at any depth inside the flyout, but only its direct children are watched for changes. Call refresh() after adding or removing an option nested deeper than that.
Name the control with <label for>, aria-label, or aria-labelledby.
Filtering
The built-in filters compare the query with the option’s text, ignoring case.
An element with data-combobox-no-results inside the flyout is shown only while a query matches nothing.
Without that element, a list with nothing to show closes and keeps the query. It reopens once a later query or a newly added option matches, so asynchronously loaded options need no open-state handling.
Selection
Typing only filters the list. The value always comes from an option, so free text is never accepted as a value.
A single selection puts its option’s label in the text field. Multiple selections become chips in selection order, and a chip falls back to its raw value until its option exists.
Declare an initial multiple selection on the options instead of the single-value value attribute:
<sv-combobox multiple> <sv-flyout> <button type="button" value="red" aria-selected="true">Red</button> <button type="button" value="blue" aria-selected="true">Blue</button> </sv-flyout></sv-combobox>Selecting an option closes the list in single-selection mode. In multiple-selection mode the list stays open and the query clears.
Pointer interaction never moves focus out of the text field. Focusing the field selects its text and opens the list, so typing replaces the current label.
The arrow button opens and closes the list without disturbing the query.
Keyboard and accessibility
The component follows the WAI-ARIA combobox pattern with a listbox popup. Focus stays in a native text field while aria-activedescendant identifies the active option.
| Key | Behavior |
|---|---|
| Printable character | Filters the options and opens the list |
ArrowDown | Opens the list, or moves to the next option |
ArrowUp | Opens the list, or moves to the previous option |
PageDown | Five options forward |
PageUp | Five options backward |
Alt + ArrowDown | Opens the list |
Alt + ArrowUp | Closes the list |
Enter | Selects the active option, or the first match for the query; submits the form while closed |
Escape | Closes the list, clears the query, and restores the selection |
Backspace | Removes the last chip while a multiple-selection field is empty |
Tab | Closes the list |
Home, End | Native text-caret behavior |
The whole combobox is a single tab stop.
Form behavior
A single selection submits one entry, and a multiple selection submits one entry per value, all under the same name:
// <sv-combobox name="color" multiple> with red and blue selectednew FormData(form).getAll("color"); // ["red", "blue"]Resetting the form goes back to the selection written in the HTML: the value attribute for a single selection, or the options that started out with aria-selected="true".
Styling options
Option buttons are given role="option". data-combobox-active marks the option that keyboard navigation is currently on, and aria-selected="true" marks the chosen ones.
Options that are direct children of the flyout come with default styling, which your own rules override without needing extra specificity.
[role="option"] { padding: 0.75em 1em; border-radius: var(--sv-bdr-rad-md);}
[role="option"][data-combobox-active] { background-color: var(--sv-gray-5);}
[role="option"][aria-selected="true"] { background-color: var(--sv-accent);}Nested options get no default styling.
API References
Methods
refresh()
Rescans option buttons after nested content changes that do not produce a slot change.
open()
Opens the list unless effectively disabled, skipping the animation when isInstant is true.
close()
Closes the list and clears the query, skipping the animation when isInstant is true.
Properties
filter
How the typed query is matched against the options.
Use "none" to keep every option visible and drive the list yourself, which is required for asynchronous option sources. The property additionally accepts a function that receives each option and the trimmed, case-preserved query, then returns whether the option should remain visible.
required
Whether at least one value is required for constraint validation.
multiple
Whether option clicks toggle multiple values instead of replacing a single value.
value
The selected value, or a copy of the selected values when multiple is enabled.
Assigning an array removes duplicate values. Single-selection mode retains only its first value.
opened
The supplied flyout’s requested open state.
Assigning this property uses the normal animated transition. Use open(true) or close(true) for an instant transition.
disabled
Whether the combobox’s own disabled attribute is present.
Effective disabledness can also be inherited from an ancestor fieldset.
name
The form field name used for submission.
placeholder
The hint text shown by the text field while it is empty.
Attributes
"filter"
Matching the query anywhere in the option’s text, only at its start, or not filtering at all.
"disabled"
Whether the combobox itself is disabled.
"opened"
The supplied flyout’s requested open state.
Assigning this property uses the normal animated transition. Use open(true) or close(true) for an instant transition.
"value"
The selected value, or a copy of the selected values when multiple is enabled.
Assigning an array removes duplicate values. Single-selection mode retains only its first value.
"required"
Whether at least one value is required for constraint validation.
"multiple"
Whether option clicks toggle multiple values instead of replacing a single value.
"placeholder"
The hint text shown by the text field while it is empty.
Events
valuechange
Fired when a connected combobox’s value changes through assignment, its attribute, or option interaction.
optionclick
Fired when an enabled option receives a click.
filterchange
Fired after the typed query changed and the options were filtered.
Slots
| Name | Description |
|---|---|
clear-icon | Use this slot to replace the clear button’s default icon. |
arrow | Use this slot to replace the default dropdown arrow. A slotted arrow keeps the positioning and the open-state rotation. |
Default | The default slot where the sv-flyout should be rendered. |
CSS Properties
| Name | Description |
|---|---|
--sv-anim-dur | Duration of the border color, chip, and arrow transitions. |
--sv-anim-ease | Easing function of the border color, chip, and arrow transitions. |
--sv-gray-6 | Background color of the built-in trigger. |
--sv-gray-0 | Text color of the built-in trigger’s text field and the selection chips. Fill color of a chip’s remove glyph, the clear button’s glyph, and the arrow button’s glyph while hovered. |
--sv-gray-3 | Fill color of the dropdown arrow, the chips’ remove glyph, and the clear button’s glyph. |
--sv-gray-5 | Border color of the built-in trigger while it does not hold the focus, and background color of the selection chips. |
--sv-accent | Border color of the built-in trigger while it holds the focus. |
--sv-bdr-sz-sm | Border thickness of the built-in trigger. |
--sv-bdr-rad-md | Border radius of the built-in trigger, the selection chips, the clear button, and the arrow button. |
--sv-bdr-rad-sm | The border radius of the chips. |
CSS Parts
| Name | Description |
|---|---|
::part(trigger) | The built-in trigger’s container. |
::part(input) | The built-in trigger’s text field. |
::part(chips) | The container holding the selection chips while multiple is enabled. |
::part(clear-button) | The built-in trigger’s clear button, shown while there is a query or a selection to clear; set display: none on it to remove the button. |
::part(clear-icon) | The clear button’s glyph. |
::part(arrow-button) | The built-in trigger’s arrow button, which opens and closes the list; set display: none on it to remove the button. |
::part(arrow) | The built-in trigger’s dropdown arrow. |
::part(chip) | A selection chip; clicking it deselects its value. |
::part(chip-label) | A chip’s text label. |
::part(chip-remove) | A chip’s remove glyph. |
CSS States
| Name | Description |
|---|---|
:state(--no-results) | When a filter query is active and no option matches it. |
:state(--open) | When the supplied flyout’s requested open state is open. |