Skip to content

ComboBox

Introduction

The ComboBox component is an advanced autocomplete input for selecting items from a list, supporting search, filtering, custom display/value fields, async API loading, validation states, and full reactivity via Pulse signals. It is ideal for forms, search/filter interfaces, and any scenario requiring a searchable dropdown.

Import

tsx
import { ComboBox } from '@odyssee/components';

LiveCodeEditor Examples

Basic ComboBox

Code Éditable
Résultat

ComboBox with Label and Reactive Value

Code Éditable
Résultat

Custom Display & Value Fields

Code Éditable
Résultat

Features: Close Button, Min Search Length, Max Height

Code Éditable
Résultat

Sizes

Code Éditable
Résultat

States: Error, Disabled, Readonly, Required, Hint

Code Éditable
Résultat

Props Table

PropTypeDefaultDescription
optionsComboBox.Option[][]Array of options to display in the dropdown.
valuestring | Signal<string>Selected value (can be reactive signal).
placeholderstring"Search..."Placeholder text for the input field.
disabledbooleanfalseDisables the ComboBox input.
readonlybooleanfalseMakes the ComboBox input read-only.
requiredbooleanfalseMarks the ComboBox as required.
labelstringLabel displayed above the input.
hintstringOptional hint text below the input.
errorstringError message displayed below the input.
size"xs" | "sm" | "md" | "lg" | "xl""md"Size of the input field.
displayFieldstring"name"Field name to display for each option.
valueFieldstring"id"Field name to use as the value for each option.
searchFieldsstring[][displayField]Fields to search/filter in the options.
minSearchLengthnumber0Minimum number of characters required to trigger search/filter.
showCloseButtonbooleanfalseShows a close/clear button in the input.
maxHeightstring"max-h-72"Maximum height for the dropdown list.
apiUrlstringAPI endpoint for async option loading.
apiSearchQuerystring"search"Query parameter name for API search requests.
onChange(item: ComboBox.Option | null) => voidCallback fired when the selected item changes.
onSearch(search: string) => voidCallback fired when the search input changes.
onFocus(event: Event) => voidCallback fired when the input gains focus.
onBlur(event: Event) => voidCallback fired when the input loses focus.
dropdownClassNamestringAdditional CSS classes for the dropdown container.
namestringName attribute for form integration.
renderItem(item: ComboBox.Option) => Pulse.JSX.ElementCustom renderer for dropdown items.
classNamestringAdditional CSS classes for the root element.
idstringauto-genUnique ID for the ComboBox input.
...restanyOther props are spread to the root element.

Implementation Notes

  • Fully reactive: supports Pulse signals for value and option updates.
  • Options can be filtered locally or loaded asynchronously via API.
  • Customizable display and value fields for flexible data structures.
  • Keyboard navigation: arrow keys, enter, escape supported.
  • Validation states (error, required, disabled, readonly) affect styling and accessibility.
  • Dropdown supports custom max height and scrollable content.
  • Optionally renders a close/clear button for quick reset.
  • Custom item rendering via renderItem prop.

Accessibility

  • Uses native <input type="text"> with role="combobox", aria-expanded, and aria-autocomplete.
  • Dropdown uses role="listbox" and each option uses role="option".
  • Label is linked via for and id attributes.
  • Supports required, disabled, and readonly attributes.
  • Error and hint messages are announced via text.
  • Keyboard navigation and focus management are fully supported.

Best Practices

  • Use displayField, valueField, and searchFields to adapt ComboBox to your data model.
  • For async loading, provide a fast API and set minSearchLength to reduce requests.
  • Always provide a clear label and placeholder for context.
  • Use validation states to guide user input and improve UX.
  • Use renderItem for custom dropdown item layouts (e.g., avatars, icons).
  • Avoid excessive dropdown height; set maxHeight for usability.

Released under the MIT License.