• CMSnpm version

    • Overview
    • ContentBuilder
    • InviteUserForm
    • LoginForm
    • RenewPasswordForm
    • WysiwygInput
  • 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
    • Switch
    • ✅ 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
  • DnDnpm version

    • Overview
  • Page-Buildernpm version

    • Overview
  • Page-Builder-CMSnpm version

    • Overview
  • Page-Builder-Webnpm version

    • Overview
  • Sentrynpm 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 Base 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, { signal }) => fetchCountries(query, { signal })}
    name="country"
    onChange={setValue}
    placeholder="Search country..."
    value={value}
/>

Content below the options — dropdownEndContent, e.g. a button that adds an item the search did not find. The function form gets args.close(); static content leaves the dropdown open:

<Combobox
    dropdownEndContent={(args) => (
        <Button
            isFullWidth
            onClick={() => {
                args.close();
                openAddCountryModal();
            }}
            variant="text"
        >
            Add a new country
        </Button>
    )}
    label="Country"
    loadOptions={(query, { signal }) => fetchCountries(query, { signal })}
    name="country"
    onChange={setValue}
    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.

PropTypeDefaultDescription
labelReactNode—Required. Field label.
namestring—Required. Field name (also set as data-name).
valueValue | null—Required. Selected option object, or null.
onChange(value: Value | null) => void—Required. Called with the selected option object (or null).
optionsOption[]—Static option list. Optional; omit when using loadOptions.
loadOptions(query: string, { signal }) => Promise<Option[]>—Async option loader. When set, the component is async and skips local filtering. signal aborts when the result is no longer wanted (new query, unmount, the field paused, a new loadOptions); pass it to fetch.
placeholderstring—Placeholder for the text input.
helperTextReactNode—Text under the control; styled as an error when isInvalid.
isClearablebooleanfalseShow a clear button that resets the value to null.
isDisabledbooleanfalseDisable the control.
isReadOnlybooleanfalsePrevent changes while staying focusable.
isInvalidbooleanfalseInvalid styling; sets aria-invalid and styles helperText as an error.
isRequiredbooleanfalseMark the field required (adds the label indicator).
hiddenLabelbooleanfalseVisually hide the label (kept for assistive tech).
renderOption(option: Option, isSelected: boolean) => ReactNodeoption.labelCustom renderer for each dropdown option.
keyExtractor(option: Option) => string | numberoption.idCustom React key for options.
noQueryMessagestringlocalized "Start typing to see options"Shown when the query is empty.
noOptionsMessagestringlocalized "No items found"Shown when there are no options.
notFoundMessagestring"Nic nenalezeno"Shown when a non-empty query matches nothing.
iconNameIconNamearrow iconIcon for the dropdown arrow.
sizeInputGroupSize"default""small", "default", or "large".
variantInputGroupVariant"default"Input group variant.
idstringauto (useId)Root id; the error-message id derives from it.
onBlur / onFocusFocusEventHandler<HTMLInputElement>—Focus handlers.

Layout, dropdown, and ref props: className, style, form, leftAddon, rightAddon, leftElement, rightElement, inputArrow, dropdownClassName, dropdownEndContent, 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).
  • Content below the options: dropdownEndContent pins content (typically an "add a new item" button) below the options. It stays visible while the list scrolls and when nothing matches, fits inside dropdownMaxHeight together with the list, and is not part of the arrow-key navigation. Static content (ReactNode) leaves the dropdown open; the function form (args) => ReactNode gets args.close(), which closes the dropdown without changing the value.

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
DropdownEndContent
Open in new tab
OnlyForE2ETests
Open in new tab
Sizes
Open in new tab
States
Open in new tab
SynchronousOptions
Open in new tab