Prototype Library

Search select

Form-associated combobox with two modes, two trigger styles, multi-select chips, match highlighting, debounced search, and loading/empty/count states. A Lit Web Component migrated from the Angular esa-combobox.

Inheritedwcimport '@esa/ecology/esa-combobox';

Preview

<esa-combobox label="State" mode="select" placeholder="Pick a state"></esa-combobox>

Modes

select uses a button trigger with in-panel search; autocomplete uses an input trigger. The text trigger style swaps the bordered field for a link-like control.

<esa-combobox label="Select mode" mode="select" placeholder="Pick a state"></esa-combobox>
<esa-combobox label="Autocomplete mode" mode="autocomplete" placeholder="Type to search"></esa-combobox>
<esa-combobox mode="select" trigger-style="text" placeholder="Filter by state"></esa-combobox>

Sizes

<esa-combobox label="Extra small" size="xs"></esa-combobox>
<esa-combobox label="Small" size="sm"></esa-combobox>
<esa-combobox label="Medium" size="md"></esa-combobox>
<esa-combobox label="Large" size="lg"></esa-combobox>

States

Multi-select renders chips. Loading, results-count, error, and disabled states are attribute-driven.

<esa-combobox label="States visited" mode="select" multiple placeholder="Add states"></esa-combobox>
<esa-combobox label="With results count" mode="select" results-count="50" help-text="Shows 'Displaying X of Y results'"></esa-combobox>
<esa-combobox label="Loading" mode="select" loading></esa-combobox>
<esa-combobox label="Error" error-text="Selection required"></esa-combobox>
<esa-combobox label="Disabled" disabled></esa-combobox>

API

PropTypeDefaultDescription
mode'autocomplete' | 'select''select''select' = button trigger with in-panel search; 'autocomplete' = input trigger. Reflected.
trigger-style'field' | 'text''field''field' = bordered control; 'text' = link-like trigger.
options{ value, label, disabled? }[][]Selectable options. Set as a property.
multiplebooleanfalseAllow multiple selections with removable chips.
size'xs' | 'sm' | 'md' | 'lg''md'Control size (reflected attribute).
labelstring''Field label above the control.
placeholderstring'Select...'Placeholder for the trigger/input.
disabledbooleanfalseDisables interaction (reflected attribute).
requiredbooleanfalseMarks the field required.
help-textstring''Helper text below the control.
error-textstring''Error message; sets the error state when present.
loadingbooleanfalseShows a spinner and "Searching..." state.
debounce-msnumber300Debounce window for the search event.
results-countnumber | nullnullWhen set, renders "Displaying X of Y results".
valuestring | string[]—Property accessor. Single = string; multiple = string array.

Events

EventTypeDefaultDescription
changeCustomEvent<{ value: string | string[] }>—Fired on selection change. Composed and bubbles.
searchCustomEvent<{ term: string }>—Debounced search term (300ms default), de-duplicated. Composed and bubbles.

Accessibility

  • Autocomplete input carries role="combobox" with aria-expanded, aria-haspopup="listbox", and aria-autocomplete="list".
  • Panel is role="listbox"; options are role="option" with aria-selected.
  • Keyboard: ArrowUp/Down navigate, Enter selects, Escape/Tab close. Outside-click closes.
  • Matched substrings are wrapped in <mark> for visible highlight.
  • Form-associated via ElementInternals — value submits with the enclosing form.

Tokens

  • --color-background-field · --form-text-color · --form-border-color / --form-border-color-focus / --form-error-border-color
  • Sizing reads --spacing-* directly (the --form-height/padding/radius/font-size-* hooks were removed upstream, 2026-08)
  • --color-background-elevation-raised · --color-background-elevation-sunken · --color-background-overlay-active · --color-background-brand / --color-background-brand-hover
  • --color-background-utility-warning-subtle (highlight) · --focus-ring-color · --z-dropdown · --elevation-3 · --radius-full