• CMSnpm version

    • Overview
    • ContentBuilder
    • InviteUserForm
    • LoginForm
    • RenewPasswordForm
  • UInpm version

    • Overview
    • Accordion
    • AlertBubble
    • AnnouncementBar
    • Avatar
    • AvatarFileInput
    • Badge
    • Button
    • ButtonGroup
    • ButtonList
    • Calendar
    • Checkbox
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • Chip
    • ColorRadio
    • ColorRadioGroup
    • Combobox
    • DatePicker
    • DatePickerInput
    • DateRangePicker
    • DateRangePickerInput
    • DatetimePicker
    • DatetimePickerInput
    • Dialog
    • Dropdown
    • Dropzone
    • ErrorMessage
    • FileInput
    • FlashMessages
    • FormComponent
    • Icon
    • IconButton
    • ImageGallery
    • InfoBox
    • Input
    • Label
    • Layout
    • Lightbox
    • ListItem
    • Loader
    • Lozenge
    • Menu
    • Message
    • Modal
    • ✅ ModalDialog
    • ✅ ModalHeader
    • MultiCombobox
    • MultiSelect
    • Pagination
    • Paper
    • Popover
    • Radio
    • RadioGroup
    • RasterImage
    • Select
    • ✅ Tabs
    • TextInput
    • TextLink
    • Textarea
    • TimePicker
    • TimePickerInput
    • Toggle
    • Tooltip
    • Typography
  • Formnpm version

    • Overview
    • AvatarFileInput
    • CheckboxButton
    • CheckboxInput
    • CheckboxList
    • ColorRadioGroup
    • Combobox
    • DatePickerInput
    • DateRangePickerInput
    • DatetimePickerInput
    • Dropzone
    • FileInput
    • Form
    • FormRenderer
    • GpsInput
    • MoneyInput
    • MultiCombobox
    • MultiSelect
    • NumberInput
    • PasswordInput
    • RadioGroup
    • Select
    • TextInput
    • Textarea
    • TimePickerInput
    • Toggle
  • DataGridnpm version

    • Overview
    • DataGrid
    • DataGridCustomExample
    • ExportButton
    • FilterList
    • Filters
    • FiltersButton
    • FulltextInput
    • HiddenColumns
    • HiddenColumnsButton
    • Pagination
    • RowCounts
    • RowsPerPageSelect
    • SelectedRowsToolbar
    • TableV2
    • ToolbarControl
    • ToolbarCustoms
    • ToolbarTabs
  • Wysiwygnpm version

    • Overview
  • Resizernpm version

    • Overview
  • Routernpm version

    • Overview
  • Corenpm version

    • Overview
  • Core-Reactnpm version

    • Overview
  • Stylesnpm version

    • Overview
  • Localizenpm version

    • Overview
  • Analyticsnpm version

    • Overview
  • Datepickernpm version

    • Overview
  • Icons-generatornpm version

    • Overview
  • Smart-addressnpm version

    • Overview
  • E2Enpm version

    • Overview
  • E2E-Playwrightnpm version

    • Overview
View source on GitLab

Combobox

Single-value picker with a searchable text input, built on Headless UI Combobox. As the user types, the option list is filtered (accent-insensitive); options can also be loaded asynchronously.

When to use

Reach for Combobox when the user picks one value from a list and should be able to filter by typing (or the options come from a server).

  • Don't need search? Use Select.
  • Need to pick multiple values? Use MultiCombobox.

Use @uxf/ui/combobox for a controlled combobox outside a form. Inside a @uxf/form form, use @uxf/form/combobox instead — it registers the field with react-hook-form and derives isInvalid / helperText from validation. This @uxf/ui component is the controlled primitive the form twin wraps.

Usage

import { Combobox, ComboboxOption, ComboboxValue } from "@uxf/ui/combobox";
import { useState } from "react";

const options: ComboboxOption[] = [
    { id: "one", label: "Option one" },
    { id: "two", label: "Option two", disabled: true },
    { id: "three", label: "Option three" },
];

function Example() {
    const [value, setValue] = useState<ComboboxValue | null>(null);

    return (
        <Combobox
            isClearable
            label="Choose an option"
            name="example"
            onChange={setValue}
            options={options}
            placeholder="Search..."
            value={value}
        />
    );
}

Async options — pass loadOptions instead of (or alongside) options; the returned promise supplies the list and local filtering is skipped:

<Combobox
    label="Country"
    loadOptions={(query) => fetchCountries(query)}
    name="country"
    onChange={setValue}
    placeholder="Search country..."
    value={value}
/>

value is the selected option object (ComboboxValue, i.e. { id, label }) or null, and onChange receives that whole object — not just the id.

Exports: Combobox and the types ComboboxProps, ComboboxOption, ComboboxValue, ComboboxValueId, ComboboxTypeRef.

Props

ComboboxProps<Id = ComboboxValueId, Option = ComboboxOption<Id>, Value = Option> extends FormControlProps<Value | null> and Clearable. ComboboxValueId is number | string; ComboboxValue is { id: Id; label: string }; ComboboxOption adds disabled?: boolean.

Prop Type Default Description
label ReactNode — Required. Field label.
name string — Required. Field name (also set as data-name).
value Value | null — Required. Selected option object, or null.
onChange (value: Value | null) => void — Required. Called with the selected option object (or null).
options Option[] — Static option list. Optional; omit when using loadOptions.
loadOptions (query: string) => Promise<Option[]> — Async option loader. When set, the component is async and skips local filtering.
placeholder string — Placeholder for the text input.
helperText ReactNode — Text under the control; styled as an error when isInvalid.
isClearable boolean false Show a clear button that resets the value to null.
isDisabled boolean false Disable the control.
isReadOnly boolean false Prevent changes while staying focusable.
isInvalid boolean false Invalid styling; sets aria-invalid and styles helperText as an error.
isRequired boolean false Mark the field required (adds the label indicator).
hiddenLabel boolean false Visually hide the label (kept for assistive tech).
renderOption (option: Option, isSelected: boolean) => ReactNode option.label Custom renderer for each dropdown option.
keyExtractor (option: Option) => string | number option.id Custom React key for options.
noQueryMessage string localized "Start typing to see options" Shown when the query is empty.
noOptionsMessage string localized "No items found" Shown when there are no options.
notFoundMessage string "Nic nenalezeno" Shown when a non-empty query matches nothing.
iconName IconName arrow icon Icon for the dropdown arrow.
size InputGroupSize "default" "small", "default", or "large".
variant InputGroupVariant "default" Input group variant.
id string auto (useId) Root id; the error-message id derives from it.
onBlur / onFocus FocusEventHandler<HTMLInputElement> — Focus handlers.

Layout, dropdown, and ref props: className, style, form, leftAddon, rightAddon, leftElement, rightElement, inputArrow, dropdownClassName, dropdownMatchesInputWidth (default true), dropdownMaxHeight (default 240), dropdownPlacement (default "bottom"), dropdownStrategy, inputRef, inputGroupRef, inputWrapperRef.

Variants & states

  • Search: typing filters options locally by label (accent-insensitive via slugify). With loadOptions, filtering is delegated to the loader (debounced ~200 ms).
  • Sizes: small, default, large (via size).
  • Invalid: set isInvalid; combine with helperText to show an error message.
  • Disabled / read-only: isDisabled blocks interaction; isReadOnly keeps focus but prevents changes.
  • Clearable: with isClearable, a remove button appears once a value is selected (unless disabled/read-only).
  • Empty states: distinct messages for empty query, no options, and no match (see props above).

Requirements

The component composes the input, label, dropdown, form-component, and icon primitives, so import all of their stylesheets once in your global CSS:

@import url("@uxf/ui/css/icon.css");
@import url("@uxf/ui/css/dropdown.css");
@import url("@uxf/ui/css/label.css");
@import url("@uxf/ui/css/form-component.css");
@import url("@uxf/ui/css/input-basic.css");
@import url("@uxf/ui/css/input.css");
@import url("@uxf/ui/css/combobox.css");

Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.

AsynchronousOptions
Open in new tab
OnlyForE2ETests
Open in new tab
SynchronousOptions
Open in new tab