Skip to Content

Combobox

Package: @tesserix/web

Searchable select input with full keyboard support, controlled/uncontrolled modes, icons, descriptions, custom search terms, and custom option rendering.

Import

import { Combobox } from '@tesserix/web' import type { ComboboxOption, ComboboxProps } from '@tesserix/web'

Source

  • Component: packages/web/src/components/combobox/combobox.tsx
  • Story: packages/web/src/components/combobox/combobox.stories.tsx
  • Test: packages/web/src/components/combobox/combobox.test.tsx

Status

  • Component implementation file: Present
  • Story file: Present
  • Test file: Present

Usage

Basic

const options = [ { value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }, { value: 'svelte', label: 'Svelte' }, ] <Combobox options={options} placeholder="Choose framework" searchPlaceholder="Search framework..." />

Controlled

const [value, setValue] = useState('react') <Combobox options={options} value={value} onValueChange={setValue} placeholder="Choose framework" />

With Default Value (Uncontrolled)

<Combobox options={options} defaultValue="vue" />

With Description and Search Terms

Options can include description for secondary text and searchTerms for additional search keywords.

const currencies = [ { value: 'USD', label: '$ USD', description: 'United States Dollar', searchTerms: ['dollar', 'america'] }, { value: 'EUR', label: '€ EUR', description: 'Euro', searchTerms: ['europe'] }, { value: 'GBP', label: '£ GBP', description: 'British Pound Sterling', searchTerms: ['uk', 'pound'] }, ] <Combobox options={currencies} placeholder="Select currency" searchPlaceholder="Search by name or code..." />

With Icons

const countries = [ { value: 'US', label: '+1', icon: <span>🇺🇸</span> }, { value: 'GB', label: '+44', icon: <span>🇬🇧</span> }, { value: 'IN', label: '+91', icon: <span>🇮🇳</span> }, ] <Combobox options={countries} placeholder="Code" />

Custom Option Rendering

Use renderOption for full control over how each option is displayed.

<Combobox options={options} renderOption={(option, { selected, highlighted }) => ( <div className="flex items-center gap-2"> <span>{option.label}</span> {selected && <CheckIcon />} </div> )} />

Disabled Options

const options = [ { value: 'react', label: 'React' }, { value: 'legacy', label: 'Legacy Framework', disabled: true }, { value: 'vue', label: 'Vue' }, ] <Combobox options={options} />

Error State

<Combobox options={options} error placeholder="Please select a framework" />

Loading State

<Combobox options={[]} loading placeholder="Loading..." />

Disabled

<Combobox options={options} disabled placeholder="Unavailable" />

Keyboard Navigation

KeyAction
ArrowDownOpen dropdown / move to next option
ArrowUpOpen dropdown / move to previous option (wraps)
EnterSelect highlighted option
EscapeClose dropdown and reset query
TypeFilter options by label, value, description, or search terms

API

ComboboxOption

PropTypeDescription
valuestringUnique option value
labelstringDisplay text
descriptionstringSecondary description text
iconReactNodeIcon rendered before the label
searchTermsstring[]Additional terms for search filtering
disabledbooleanPrevents selection of this option

ComboboxProps

PropTypeDefaultDescription
optionsComboboxOption[]Array of options
valuestringControlled selected value
defaultValuestringInitial value (uncontrolled)
onValueChange(value: string) => voidCalled when selection changes
placeholderstring"Select an option..."Input placeholder when closed
searchPlaceholderstring"Search..."Input placeholder when open
emptyTextstring"No results found."Text shown when no options match
disabledbooleanfalseDisables the combobox
errorbooleanfalseShows error styling and sets aria-invalid
loadingbooleanfalseShows loading spinner in dropdown
renderOption(option, state) => ReactNodeCustom option renderer
aria-labelstring"Combobox input"Accessible label

Accessibility

  • role="combobox" on input with aria-expanded, aria-controls, aria-activedescendant
  • role="listbox" on the dropdown with role="option" on each item
  • aria-selected marks the currently selected option
  • aria-invalid set when error is true
  • Disabled options have disabled attribute and reduced opacity
  • Full keyboard navigation with arrow keys, Enter, and Escape