@biem/ui

Combobox

An input with a list of options that users filter by typing and select from.

A combobox joins a text input with a list of options that opens in a popup. Users type to narrow the list to the options that match and then select one, so they find an option in a long list, such as the stores of a chain, without scrolling. Users can select only options of the list, never free text. ComboboxList receives a function that renders each option, so the file that contains the combobox starts with "use client".

Usage

combobox-default.tsx
"use client";

import {
	Combobox,
	ComboboxContent,
	ComboboxEmpty,
	ComboboxInput,
	ComboboxItem,
	ComboboxList,
} from "@biem/ui/components/ui/combobox";

const stores = [
	"Basel",
	"Bern",
	"Geneva",
	"Lausanne",
	"Lucerne",
	"St. Gallen",
	"Winterthur",
	"Zurich",
];

export function ComboboxDefault() {
	return (
		<Combobox items={stores}>
			<ComboboxInput aria-label="Store" placeholder="Select a store"/>
			<ComboboxContent>
				<ComboboxEmpty>No store found.</ComboboxEmpty>
				<ComboboxList>
					{(store: string) => (
						<ComboboxItem key={store} value={store}>{store}</ComboboxItem>
					)}
				</ComboboxList>
			</ComboboxContent>
		</Combobox>
	);
}

Examples

With Clear Button

A filter often applies only for a while, such as a report narrowed to one supplier. Through showClear, the input offers a button that empties the selection and the text in a single press, so users return to the full view without deleting the text letter by letter. That button appears only while an option is selected.

Without Trigger

Experienced users rarely browse a list, because they already know the first letters of what they need. Set to false, showTrigger leaves out the button that opens the list, and the input takes over its task: the list opens as soon as users click the input or start typing.

With Icon

Among many fields in a form, an icon tells users at a glance what a field is for, before they read a word. Passed to the input as children, an InputGroupAddon becomes part of the field, and a click on its icon places the cursor in the input.

With Groups

Long lists become easier to search when their options follow familiar categories, such as products by department. When items holds groups, the combobox filters the options within each group, so users still see to which category a match belongs. Any group without a match disappears together with its heading.

Multiple

Some decisions cover more than one option, such as a promotion that runs in several regions. With multiple, the combobox keeps every option users select, and a second press on a selected option removes it again. Each selected option remains visible as a chip, so users review the selection without opening the list.

Chips without Remove Button

A selection that users build with care, such as the warehouses behind a replenishment order, should not lose an entry through a stray click. Once showRemove is false on each chip, users remove an option deliberately: Backspace in the empty input takes away the last one, and a second press in the list removes any other.

Input in Popup

Where a selection changes only now and then, such as the warehouse a report refers to, the current choice matters more than the search. Here the trigger shows the selected option through ComboboxValue, and ComboboxInput moves into the popup. Focus enters that input as soon as the popup opens and returns to the trigger when it closes, so keyboard users continue where they left off.

Auto Highlight

Users who enter data at speed, such as during a goods receipt, type a few letters and expect to confirm at once. Because autoHighlight marks the first match while they type, Enter selects it without a detour over the arrow keys.

Default Value

Many forms start from the choice users make most often, such as their own location. Through defaultValue, that option is already selected when the form appears, and the combobox tracks every later change itself, so users act only when the suggestion does not fit.

Controlled

Sometimes the selection drives other parts of the screen, such as the figures that load for the chosen location or a reset that returns every filter to its start. With value and onValueChange, the application holds the selection, so the combobox and the rest of the interface always agree on the current choice.

Disabled Item

An option can exist and still be unavailable for now, such as a supplier during a delivery stop. Marked as disabled, it keeps its place in the list and stays reachable with the arrow keys, while users cannot select it and assistive technology announces it as unavailable.

Disabled

Some fields depend on an earlier step, such as a supplier that users can choose only once a product category is set. Until then, disabled on the input locks the text field together with its buttons, so users can neither type nor open the list, and assistive technology reports the field as unavailable.

Disabled with Chips

While a transfer is in progress, the warehouses it draws from must stay as they are. Set on the combobox itself, disabled locks the input, the chips and their remove buttons, so users still read the selection but can neither change it nor open the list.

Read-Only

Head office often assigns a setting that users may see but not change, such as the supplier of a product. With readOnly, the list still opens so that users can compare the options, while the selection stays as it is. Unlike a disabled combobox, it still submits its value with the form.

Invalid

A form can find a field incomplete, for instance when users submit an order without a delivery location. Through aria-invalid on the input, the field marks the error for users and for assistive technology, so they find at once where a correction is needed.

Invalid with Chips

Several options together can break a rule as well, such as a limit on how many categories a single price campaign may cover. Placed on ComboboxChipsInput, aria-invalid marks the entire field, so users recognize that the selection as a whole needs a correction, and assistive technology announces the error on the input.

API Reference

Combobox

Propitems
Typereadonly any[] | readonly Group<any>[] | ComboboxItemCollection<Item, Value>
Default–
DescriptionSets the options of the list. It takes an array of options, an array of groups that each hold their options in items, or a collection created with Combobox.createItems() from @base-ui/react/combobox. The combobox filters these options by the text in the input, and ComboboxList, ComboboxCollection and ComboboxEmpty work with the result.
Propvalue
TypeValue | Value[] | null
Default–
DescriptionSets the selected option and makes the combobox controlled. Update it in onValueChange. With multiple, it is an array of options.
PropdefaultValue
TypeValue | Value[] | null
Default–
DescriptionSets the option that is selected at first render. The combobox then tracks the selection itself. With multiple, it is an array of options.
ProponValueChange
Type(value: Value | Value[] | null, eventDetails: ComboboxRootChangeEventDetails) => void
Default–
DescriptionRuns when users select, deselect or clear an option. It receives the selection that follows: the option or null, and with multiple the array of selected options.
Propmultiple
Typeboolean
Defaultfalse
DescriptionLets users select several options. The value is then an array, and a press on a selected option removes it from the selection.
PropinputValue
Typestring | number | readonly string[]
Default–
DescriptionSets the text in the input and makes it controlled. Update it in onInputValueChange.
PropdefaultInputValue
Typestring | number | readonly string[]
Default–
DescriptionSets the text in the input at first render. The combobox then tracks the text itself.
ProponInputValueChange
Type(inputValue: string, eventDetails: ComboboxRootChangeEventDetails) => void
Default–
DescriptionRuns when the text in the input changes, whether users type or the combobox changes the text after a selection.
Propopen
Typeboolean
Default–
DescriptionSets whether the popup is open and makes it controlled. Update it in onOpenChange.
PropdefaultOpen
Typeboolean
Defaultfalse
DescriptionOpens the popup at first render. The combobox then tracks its open state itself.
ProponOpenChange
Type(open: boolean, eventDetails: ComboboxRootChangeEventDetails) => void
Default–
DescriptionRuns when users open or close the popup. It receives the open state that follows.
ProponOpenChangeComplete
Type(open: boolean) => void
Default–
DescriptionRuns after the popup has opened or closed and its animations have finished.
PropopenOnInputClick
Typeboolean
Defaulttrue
DescriptionOpens the popup when users click the input. With false, a click on the input no longer opens the popup.
PropautoHighlight
Typeboolean
Defaultfalse
DescriptionHighlights the first option that matches while users type, so that Enter selects it.
ProphighlightItemOnHover
Typeboolean
Defaulttrue
DescriptionHighlights an option when the pointer moves over it. With false, CSS can style a hovered option with :hover apart from the highlighted one.
ProploopFocus
Typeboolean
Defaulttrue
DescriptionMoves the highlight from the last option back to the input, and from there to the first option, when users keep pressing the arrow keys. With false, the highlight stops at the first and at the last option.
Propfilter
Type((item: Item, query: string, itemToString?: (item: Item) => string) => boolean) | null
Default–
DescriptionReplaces the function that decides whether an option matches the text in the input. null turns the filter off, so the list shows all options.
PropfilteredItems
Typereadonly Item[] | readonly Group<Item>[]
Default–
DescriptionSets the options that the list shows, in place of the options that the combobox filters from items itself. Use it to filter outside of the combobox. Together with items, it keeps the flat or grouped structure of items.
Proplimit
Typenumber
Default-1
DescriptionSets the largest number of options that the list shows. -1 shows all options.
Proplocale
TypeIntl.LocalesArgument
Default–
DescriptionSets the locale that the filter compares text with. Without it, the filter uses the locale of the user's runtime.
PropitemToStringLabel
Type(itemValue: Value) => string
Default–
DescriptionConverts an option that is an object to the text that the input shows. An object with the properties value and label doesn't need it, because the combobox reads label itself.
PropitemToStringValue
Type(itemValue: Value) => string
Default–
DescriptionConverts an option that is an object to the text that the form submits. An object with the properties value and label doesn't need it, because the combobox reads value itself.
PropisItemEqualToValue
Type(itemValue: Value, value: Value) => boolean
Default–
DescriptionDecides whether an option equals the selected value. Set it when options are objects that aren't the same instances as the value. Without it, the combobox compares with Object.is.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from opening the popup and changing the selection, and leaves the value out of the submitted form. It disables the trigger button, the chips and ComboboxChipsInput. The input of ComboboxInput stays editable, so set disabled on ComboboxInput as well.
PropreadOnly
Typeboolean
Defaultfalse
DescriptionPrevents users from changing the selection. The popup still opens, so users can read the options, and the value is submitted with the form.
Proprequired
Typeboolean
Defaultfalse
DescriptionRequires users to select an option before they can submit the form.
Propname
Typestring
Default–
DescriptionIdentifies the combobox when the form is submitted.
Propform
Typestring
Default–
DescriptionSets the ID of the form that the combobox belongs to. Set it when the combobox is rendered outside of that form.
PropautoComplete
Typestring
Default–
DescriptionGives the browser a hint for autofill, as the HTML attribute autocomplete does.
Propid
Typestring
Default–
DescriptionSets the ID of the input, so that a label can refer to the combobox with htmlFor. When the input sits in the popup, the ID goes to the trigger instead.
PropinputRef
TypeRef<HTMLInputElement>
Default–
DescriptionReceives the hidden input element that carries the value of the combobox in a form.
Propmodal
Typeboolean
Defaultfalse
DescriptionLocks the scroll position of the page and disables pointer interaction with elements outside of the popup while the popup is open.
Propinline
Typeboolean
Defaultfalse
DescriptionDeclares that the list is rendered in the page, without the popup of ComboboxContent. Set open together with it, so that the list counts as visible.
Propgrid
Typeboolean
Defaultfalse
DescriptionPresents the options in a grid, where the arrow keys move across rows and columns. The rows are Combobox.Row parts from @base-ui/react/combobox.
Propvirtualized
Typeboolean
Defaultfalse
DescriptionDeclares that a virtualization library renders the options, so that only a part of them is in the DOM.
ProponItemHighlighted
Type(highlightedValue: Value | undefined, eventDetails: ComboboxRootHighlightEventDetails) => void
Default–
DescriptionRuns when an option gets or loses the highlight. It receives the highlighted option, or undefined when none is highlighted. eventDetails.reason says whether the keyboard, the pointer or code moved the highlight.
PropactionsRef
TypeRefObject<ComboboxRootActions | null>
Default–
DescriptionReceives the function unmount, which removes the popup from the DOM after a closing animation that the code controls itself.

ComboboxInput

PropshowTrigger
Typeboolean
Defaulttrue
DescriptionShows the button with the chevron that opens and closes the popup. While the clear button is visible, it takes the place of this button.
PropshowClear
Typeboolean
Defaultfalse
DescriptionShows a button that clears the selection and the text in the input. The button is visible only while an option is selected.
Propdisabled
Typeboolean
Defaultfalse
DescriptionDisables the input, the trigger button and the clear button, and exposes the disabled state to assistive technology.
Propchildren
TypeReactNode
Default–
DescriptionAdds content to the group around the input, such as an InputGroupAddon with an icon.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the input inside the group or composes it with another component. disabled then no longer reaches the input.

ComboboxTrigger

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the trigger with another component, such as a Button.
PropnativeButton
Typeboolean
Defaulttrue
DescriptionDeclares whether the rendered element is a native button. Set it to false when render returns a different element.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from opening the popup with this trigger. A disabled combobox disables the trigger as well.

ComboboxValue

Propchildren
TypeReactNode | ((selectedValue: any) => ReactNode)
Default–
DescriptionReplaces the label of the selected option, which the part shows without it. A function receives the selected option, or with multiple the array of selected options, and returns the content, such as the chips.
Propplaceholder
TypeReactNode
Default–
DescriptionSets the content that the part shows while no option is selected. children takes precedence over it.

ComboboxContent

Propside
Type"top" | "bottom" | "left" | "right" | "inline-end" | "inline-start"
Default"bottom"
DescriptionSets the side of the anchor that the popup opens on. The popup moves to another side when it doesn't fit there.
PropsideOffset
Typenumber | OffsetFunction
Default6
DescriptionSets the distance between the anchor and the popup in pixels. A function receives the side, the alignment and the sizes of the anchor and the popup and returns the distance.
Propalign
Type"start" | "center" | "end"
Default"start"
DescriptionSets how the popup aligns with the anchor along the side.
PropalignOffset
Typenumber | OffsetFunction
Default0
DescriptionMoves the popup along the alignment axis by a number of pixels. A function receives the side, the alignment and the sizes of the anchor and the popup and returns the offset.
Propanchor
TypeElement | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null) | null
Default–
DescriptionSets the element that the popup is positioned against. Without it, the popup uses the input, or the trigger when the input sits in the popup. With chips, pass the ref of useComboboxAnchor.
PropinitialFocus
Typeboolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | HTMLElement | null | void)
Default–
DescriptionDetermines the element that receives focus when the popup opens. Without it, focus stays in the input, or moves to the input when it sits in the popup.
PropfinalFocus
Typeboolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void)
Default–
DescriptionDetermines the element that receives focus when the popup closes. Without it, focus stays in the input, or returns to the trigger when the input sits in the popup.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the content with another component.

ComboboxList

Propchildren
TypeReactNode | ((item: any, index: number) => ReactNode)
Default–
DescriptionHolds the options. A function receives each option that matches the text in the input, or each group when items holds groups, and returns its element. Elements that are passed directly are not filtered.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the list with another component.

ComboboxItem

Propvalue
Typeany
Defaultnull
DescriptionIdentifies the option. value, defaultValue and onValueChange of the combobox work with it. Pass the option that the function of the list receives.
Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from selecting the option.
Propindex
Typenumber
Default–
DescriptionSets the position of the option in the list. With it, the combobox doesn't read the position from the DOM, which makes long lists faster.
ProponClick
Type(event: BaseUIEvent<MouseEvent<HTMLDivElement>>) => void
Default–
DescriptionRuns when users select the option with a click, or with Enter while the option is highlighted.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the item with another component.
PropnativeButton
Typeboolean
Defaultfalse
DescriptionDeclares whether the rendered element is a native button. Set it to true when render returns a button.

ComboboxEmpty

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the empty message with another component.

ComboboxGroup

Propitems
Typereadonly any[]
Default–
DescriptionSets the options of the group. A ComboboxCollection inside the group then renders these options instead of the options of the whole list.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the group with another component.

ComboboxLabel

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the label with another component.

ComboboxCollection

Propchildren
Type(item: any, index: number) => ReactNode
Default–
DescriptionReceives each option of the group that the collection sits in, or each option that matches the text in the input, and returns its element. The part requires this prop.

ComboboxSeparator

Proporientation
Type"horizontal" | "vertical"
Default"horizontal"
DescriptionSets the orientation that the separator exposes to assistive technology. The separator draws a horizontal line with either value.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the separator with another component.

ComboboxChips

Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the chips container with another component.

ComboboxChip

PropshowRemove
Typeboolean
Defaulttrue
DescriptionShows a button in the chip that removes the option from the selection. Without it, users remove the option with Backspace or deselect it in the list.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the chip with another component.

ComboboxChipsInput

Propdisabled
Typeboolean
Defaultfalse
DescriptionPrevents users from typing in the input. A disabled combobox disables the input as well.
Proprender
TypeReactElement | render function
Default–
DescriptionReplaces the native element or composes the input with another component.

useComboboxAnchor

useComboboxAnchor returns a ref that connects ComboboxChips with the popup: pass it to ComboboxChips as ref and to ComboboxContent as anchor, so that the popup opens below the chips and takes their width. The hook renders no element and takes no arguments.