Skip to content

ComboBox

A text input that offers options as the user types, on react-aria-components, for a search answered elsewhere: the caller supplies items for the current inputValue. The input is an input control, so it sizes with the rest of the form. Compose options with ComboBoxItem.

import { ComboBox } from "@evolve-storefront/ui/combo-box";

Preview

DefaultOpen in Storybook ↗

Usage

Options follow what is typed, and choosing one hands over its id.

<ComboBox
label={t("search")}
items={suggestions}
inputValue={query}
onInputValueChange={setQuery}
onValueChange={choose}
emptyState={t("nothingFound")}
>
{(item) => <ComboBoxItem id={item.id} textValue={item.label}>{item.label}</ComboBoxItem>}
</ComboBox>;

Props

PropTypeDescription
childrenReactNode | ((item: { id: string; }) => ReactNode)

Renders one option of items, a ComboBoxItem. Without items, the options themselves: ComboBoxItems, or ComboBoxSections holding them.

label?ReactNode

Visible label, rendered inside so the input and listbox are named by it.

description?ReactNode
placeholder?string
items?Iterable<{ id: string; }>

The options for what is typed. The caller filters; nothing is filtered here, children included.

name?string

Submits what is typed as this form field, so the form works before hydration.

menuTrigger?"input" | "focus"

"focus" opens the options when the field is entered, before anything is typed.

inputValue?string
onInputValueChange?((value: string) => void)
onValueChange?((id: string) => void)

Hands over the chosen option's id.

emptyState?ReactNode

Shown in the open listbox when there are no options. Without it, the listbox stays closed.

popoverClassName?string

Classes for the portalled panel, such as a taller max-h-*.

disabled?boolean
invalid?boolean
placement?SelectPlacement

Any other props go to the root element, like on a plain HTML element.

Change the layout

Pass children to ComboBox to arrange its parts yourself. Every part is exported from @evolve-storefront/ui/combo-box.

<ComboBox label={t("search")} inputValue={query} onInputValueChange={setQuery}>
<ComboBoxSection id="cities" title={t("cities")}>
{cities.map((city) => <ComboBoxItem key={city.id} id={city.id} textValue={city.label}>{city.label}</ComboBoxItem>)}
</ComboBoxSection>
</ComboBox>;
ComboBoxItemA single option inside ComboBox.
PropTypeDescription
idstring

The value reported by onValueChange when this option is chosen.

textValuestring

What the input shows once chosen, and what is announced.

href?string

Makes the option a link: choosing it navigates instead of filling the input.

disabled?boolean

Any other props go to the root element, like on a plain HTML element.

ComboBoxSectionA named group of ComboBoxItems, for a ComboBox without items.
PropTypeDescription
idstring
title?ReactNode

The group's visible heading, which also names it; without one, pass an aria-label.

Any other props go to the root element, like on a plain HTML element.