Skip to content

Combobox <l-combobox>

A text input paired with a filterable list of options — type to narrow the list, then pick a match.

HTML tag<l-combobox>
Native
Progressive
Plain
Shadow-DOM
Shadow-DOM Custom Element
html
<l-combobox
  label="Country"
  name="country"
  placeholder="Search a country…"
>
  <datalist>
    <option value="us">United States</option>
    <option value="fr">France</option>
    <option value="de">Germany</option>
  </datalist>
</l-combobox>

Options are authored as a native <datalist> of <option> — the same authoring surface as <select>.

Options

Basic

Author the choices as <option> inside a <datalist>. label names the input; name submits the chosen value.

Code
html
<div class="w-72">
  <l-combobox
    label="Country"
    name="country"
    placeholder="Search a country…"
  >
    <datalist>
      <option value="us">United States</option>
      <option value="fr">France</option>
      <option value="de">Germany</option>
      <option value="es">Spain</option>
      <option value="it">Italy</option>
      <option value="jp">Japan</option>
    </datalist>
  </l-combobox>
</div>

Clearable

Add with-clear for a button that resets the value.

Code
html
<div class="w-72">
  <l-combobox
    label="Country"
    value="fr"
    with-clear
  >
    <datalist>
      <option value="us">United States</option>
      <option value="fr">France</option>
      <option value="de">Germany</option>
      <option value="es">Spain</option>
    </datalist>
  </l-combobox>
</div>

Custom values

Add allow-custom to accept a typed value that matches no option.

Code
html
<div class="w-72">
  <l-combobox
    label="Tag"
    placeholder="Pick or type a tag…"
    allow-custom
  >
    <datalist>
      <option value="bug">Bug</option>
      <option value="feature">Feature</option>
      <option value="docs">Documentation</option>
    </datalist>
  </l-combobox>
</div>

Rich options

Put markup inside each <option> — the same .l-select-item-media / .l-select-item-text / .l-select-item-title / .l-select-item-description classes as <select>. Set a label (or .l-select-item-title) so filtering and the input display use the title.

Code
html
<div class="w-72">
  <l-combobox
    label="Country"
    placeholder="Search a country…"
  >
    <datalist>
      <option
        value="us"
        label="United States"
      >
        <span class="l-select-item-media"><l-icon name="circle-flags:us"></l-icon></span>
        <span class="l-select-item-text">
          <span class="l-select-item-title">United States</span>
          <span class="l-select-item-description">North America</span>
        </span>
      </option>
      <option
        value="fr"
        label="France"
      >
        <span class="l-select-item-media"><l-icon name="circle-flags:fr"></l-icon></span>
        <span class="l-select-item-text">
          <span class="l-select-item-title">France</span>
          <span class="l-select-item-description">Europe</span>
        </span>
      </option>
      <option
        value="jp"
        label="Japan"
      >
        <span class="l-select-item-media"><l-icon name="circle-flags:jp"></l-icon></span>
        <span class="l-select-item-text">
          <span class="l-select-item-title">Japan</span>
          <span class="l-select-item-description">Asia</span>
        </span>
      </option>
    </datalist>
  </l-combobox>
</div>

Disabled

Native disabled attribute.

Code
html
<div class="w-72">
  <l-combobox
    label="Country"
    value="fr"
    disabled
  >
    <datalist>
      <option value="fr">France</option>
      <option value="de">Germany</option>
    </datalist>
  </l-combobox>
</div>

Custom filter

By default options are matched case- and accent-insensitively (every space-separated keyword must appear). Override the filter property — (item, query) => boolean — for startsWith, fuzzy, or remote-driven filtering.

Accessibility

Criteria

Role

The input is a role="combobox" with aria-expanded / aria-controls / aria-activedescendant; options are role="option" in a role="listbox"

WCAG4.1.2
RGAA11.1
Accessible name

Set label (or wrap with <l-form-field>)

WCAG1.3.1
RGAA11.1
Focus

Focus stays on the input; the active option is tracked via aria-activedescendant

WCAG2.4.7
RGAA10.7

Keyboard interactions

Down / Up
Opens the list, then moves the active option
Home / End
Jumps to the first / last option
Enter
Selects the active option
Escape
Closes the list, or clears the value when already closed
Tab
Selects the active option (if any) and moves focus on

API reference

Importing

js
import 'luxen-ui/combobox';

Attributes & Properties

valuestringProperty
Selected value (the chosen option's value).
placeholderstringProperty
Placeholder text in the input.
labelstringProperty
Accessible label for the input.
sizeComboboxSizedefault:'md'Property
Control size.
with-clearbooleandefault:falseProperty
Show a button to clear the value.
allow-custombooleandefault:falseProperty
Accept a typed value that matches no option.
highlightbooleandefault:trueProperty
Wrap the matching substring of each option in <mark>.
placementPlacementdefault:'bottom-start'Property
Panel placement relative to the control.
filterComboboxFilterdefault:defaultFilterProperty
Override the option filter. (item, query) => boolean.

Events

changeEvent
Fired when an option is selected. Bubbles. Not cancelable. Properties: value: string.
inputEvent
Fired as the user types. Bubbles. Not cancelable. Properties: value: string (the query).
showcancelableEvent
Fired before the list opens. Cancelable.
hidecancelableEvent
Fired before the list closes. Cancelable.

CSS parts

basePart
The host wrapper.
controlPart
The input control row (input + clear + chevron).
inputPart
The text input.
panelPart
The floating popover panel.
listboxPart
The options container.
optionPart
Each option row.
emptyPart
The "no results" message.

CSS custom properties

--heightCustom property
Control height. Defaults to the form-control height.
--border-radiusCustom property
Control + panel radius.
--backgroundCustom property
Panel background.