Morphos
Inputs

Combobox

A searchable select that filters options as the user types.

Interactive example

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
valuestringControlled selected value
defaultValuestringInitial value in uncontrolled mode
placeholderstringText shown when nothing is selected
disabledbooleanfalseDisables the entire combobox
requiredbooleanfalseMarks the field as required
namestringForm 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) => voidCalled when a value is selected (also called with "" when the query is cleared)
onQueryChange(query: string) => voidCalled as the user types in the input
classstringCSS class on the root element
idstringid on the rendered text <input>, so a <label for> can target it (falls back to an auto-generated id)
aria-labelstringAccessible label
aria-labelledbystringID of an element that labels the input
aria-describedbystringID 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