Morphos
Inputs

Combobox

A searchable select that filters options as the user types.

Interactive example

Open in Storybook

Installation

npm install @morphos/inputs
pnpm add @morphos/inputs
yarn add @morphos/inputs
bun add @morphos/inputs

Import

import { Combobox } from '@morphos/inputs'

Usage

@Component()
class MyComponent extends StatefulComponent {
  @State() value = ''

  render() {
    return (
      <Combobox
        class="morphos-combobox"
        options={[
          { value: 'react', label: 'React' },
          { value: 'vue', label: 'Vue' },
          { value: 'svelte', label: 'Svelte' },
        ]}
        placeholder="Select a framework…"
        onValueChange={(v) => { this.value = v }}
      />
    )
  }
}

Props

PropTypeDefaultDescription
options{ value: string; label: string; disabled?: boolean }[][]List of selectable options
valuestring—Controlled selected value
defaultValuestring—Initial value in uncontrolled mode
placeholderstring—Text shown when nothing is selected
disabledbooleanfalseDisables the entire combobox
requiredbooleanfalseMarks the field as required
namestring—Form field name; renders a hidden <input type="hidden"> that mirrors the selected value
filterFn(option: ComboboxOption, query: string) => booleancase-insensitive substringCustom filter function
onValueChange(value: string) => void—Called when a value is selected (also called with "" when the query is cleared)
onQueryChange(query: string) => void—Called as the user types in the input
classstring—CSS class on the root element
idstring—id on the rendered text <input>, so a <label for> can target it (falls back to an auto-generated id)
aria-labelstring—Accessible label
aria-labelledbystring—ID of an element that labels the input
aria-describedbystring—ID of an element that describes the input

data-* attributes

AttributeElementWhen present
data-openRootListbox is open
data-disabledRootdisabled is true
data-activeOption <li>Option is keyboard-focused
data-selectedOption <li>Option is selected
data-disabledOption <li>Option is disabled

Keyboard navigation

KeyAction
ArrowDownOpens the listbox if closed; otherwise moves focus to the next option (wraps to the first)
ArrowUpOpens the listbox if closed (focusing the last option); otherwise moves focus to the previous option (wraps to the last)
EnterSelects the focused option
EscapeCloses the listbox and resets the query to the current selection's label
TabCloses the listbox

Custom filter

Replace the default case-insensitive substring match:

<Combobox
  class="morphos-combobox"
  options={countries}
  filterFn={(option, query) => option.label.toLowerCase().startsWith(query.toLowerCase())}
  placeholder="Select country…"
/>

Controlled mode

@Component()
class MyComponent extends StatefulComponent {
  @State() value = 'react'

  render() {
    return (
      <Combobox
        class="morphos-combobox"
        options={frameworks}
        value={this.value}
        onValueChange={(v) => { this.value = v }}
      />
    )
  }
}

Combobox is a constrained select — the user must choose from the provided options list. For free-text input with optional suggestions, see Autocomplete.

Styling example

.morphos-combobox > ul[role="listbox"] > li[role="option"][data-active] {
  background: var(--morphos-color-bg-hover);
}

.morphos-combobox > ul[role="listbox"] > li[role="option"][data-selected] {
  background: var(--morphos-color-accent);
  color: var(--morphos-color-accent-text);
}

.morphos-combobox[data-disabled] > input {
  opacity: 0.5;
  cursor: not-allowed;
}

On this page