Skip to content

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.

KeyBehavior
Printable characterFilters the options and opens the list
ArrowDownOpens the list, or moves to the next option
ArrowUpOpens the list, or moves to the previous option
PageDownFive options forward
PageUpFive options backward
Alt + ArrowDownOpens the list
Alt + ArrowUpCloses the list
EnterSelects the active option, or the first match for the query; submits the form while closed
EscapeCloses the list, clears the query, and restores the selection
BackspaceRemoves the last chip while a multiple-selection field is empty
TabCloses the list
Home, EndNative 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 selected
new 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

NameDescription
clear-iconUse this slot to replace the clear button’s default icon.
arrowUse this slot to replace the default dropdown arrow. A slotted arrow keeps the positioning and the open-state rotation.
DefaultThe default slot where the sv-flyout should be rendered.

CSS Properties

NameDescription
--sv-anim-durDuration of the border color, chip, and arrow transitions.
--sv-anim-easeEasing function of the border color, chip, and arrow transitions.
--sv-gray-6Background color of the built-in trigger.
--sv-gray-0Text 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-3Fill color of the dropdown arrow, the chips’ remove glyph, and the clear button’s glyph.
--sv-gray-5Border color of the built-in trigger while it does not hold the focus, and background color of the selection chips.
--sv-accentBorder color of the built-in trigger while it holds the focus.
--sv-bdr-sz-smBorder thickness of the built-in trigger.
--sv-bdr-rad-mdBorder radius of the built-in trigger, the selection chips, the clear button, and the arrow button.
--sv-bdr-rad-smThe border radius of the chips.

CSS Parts

NameDescription
::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

NameDescription
: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.