← All components
forms / stable

ComboBox

Text input with a filtered option list, same rows as Select, an empty state and an async mode.

LIVE PREVIEW
Loading preview…

When to use

  • Picking one record from a long or searchable list (clients, people, projects).

Consider an alternative

  • Short fixed lists — use Select.
  • Free text — use TextField.
  • Filtering a table — use SearchField.

Import

import { ComboBox } from '@revido-llc/kit';

Keyboard interaction

  • Type — filter
  • ↓ / ↑ — move
  • Enter — select
  • Escape — close / revert

Props

Props documented by the Kit. Refer to the TypeScript types for the complete interface, including inherited props.

items (required)SelectItems—Options and/or sections (same shape as Select).
classNamestring—Classes for the root (label + input + help).
controlClassNamestring—Classes for the bordered control.
defaultSelectedKeyKey—The initially selected option id (uncontrolled).
descriptionReactNode—One short sentence of help under the control.
emptyStateReactNode"No results"Shown in the popover when nothing matches.
errorMessagestring | ((validation: ValidationResult) => string)—Error text shown while the field is invalid (or a function of the validation result).
filter"contains" | "startsWith" | "none""contains"`"contains"` (default) / `"startsWith"` filter `items` as the user types. `"none"` shows `items` as given — filter them yourself (e.g. server-side from `onInputChange`) for async search.
isLoadingbooleanfalseShows a spinner in the input while async results load.
labelReactNode—Visible label. Omit only when an `aria-label` names the field.
onSelectionChange((key: Key) => void)—Called with the newly selected id (`null` when cleared).
placeholderstring—
selectedKeyKey—The selected option id (controlled).
sizeFieldSize"md"`md` 32px (default) or `compact` 28px.
allowsEmptyCollectionboolean—Whether the combo box allows the menu to be open when the collection is empty.
autoFocusboolean—Whether the element should receive focus on render.
disabledKeysIterable<Key>—The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.
formstring—The `<form>` element to associate the input with. The value of this attribute must be the id of a `<form>` in the same document. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#form).
isDisabledboolean—Whether the input is disabled.
isInvalidboolean—Whether the input value is invalid.
isReadOnlyboolean—Whether the input can be selected but not changed by the user.
isRequiredboolean—Whether user input is required on the input before form submission.
namestring—The name of the input element, used when submitting an HTML form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefname).
renderDOMRenderFunction<"div", ComboBoxRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if `<button>` is expected, you cannot render an `<a>`). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
shouldFocusWrapboolean—Whether keyboard navigation is circular.
validate((value: ComboBoxValidationValue<"single">) => ValidationError | true)—A function that returns an error message if a given value is invalid. Validation errors are displayed to the user when the form is submitted if `validationBehavior="native"`. For realtime validation, use the `isInvalid` prop instead.
validationBehavior"native" | "aria"'native'Whether to use native HTML form validation to prevent form submission when the value is missing or invalid, or mark the field as required or invalid via ARIA.

Examples

Filtering

<ComboBox label="Client" items={clients} selectedKey={clientId} onSelectionChange={setClientId} />

Async search

`filter="none"` + `onInputChange`: you fetch and pass the matching `items`; set `isLoading` while waiting.

<ComboBox label="Client" filter="none" items={results} inputValue={query}
  onInputChange={setQuery} isLoading={isFetching} emptyState="No clients match" />

Error

<ComboBox label="Owner" items={people} isRequired errorMessage="Pick an owner." />

Literal anatomy

Static component anatomy; bind events in the consuming app.

<ComboBox label="Owner" items={[{ id: "ada", label: "Ada" }, { id: "grace", label: "Grace" }]} />

Related components