Stable in React
Combobox
An input combined with a list of predefined items to select.
Install#
One package per framework. Combobox's parts come from it; the anatomy tab at the top shows how they nest.
bun add @▢▢▢▢/react26 parts. The example uses 14 of them; the data does not say which are required.
Combobox.RootGroups all parts of the combobox.Combobox.InputGroupA wrapper for the input and its associated controls.Combobox.InputA text input to search for items in the list.Combobox.ClearClears the value when clicked.Combobox.TriggerA button that opens the popup.Combobox.IconAn icon that indicates that the trigger button opens the popup.Combobox.PortalA portal element that moves the popup to a different part of the DOM.Combobox.PositionerPositions the popup against the trigger.Combobox.PopupA container for the list.Combobox.EmptyRenders its children only when the list is empty.Combobox.ListA list container for the items.Combobox.CollectionRenders filtered list items.Combobox.ItemAn individual item in the list.Combobox.ItemIndicatorIndicates whether the item is selected.Combobox.ArrowDisplays an element positioned against the anchor. Not in the example.Combobox.BackdropAn overlay displayed beneath the popup. Not in the example.Combobox.ChipAn individual chip that represents a value in a multiselectable input. Not in the example.Combobox.ChipRemoveA button to remove a chip. Not in the example.Combobox.ChipsA container for the chips in a multiselectable input. Not in the example.Combobox.GroupGroups related items with the corresponding label. Not in the example.Combobox.GroupLabelAn accessible label that is automatically associated with its parent group. Not in the example.Combobox.LabelAn accessible label that is automatically associated with the combobox trigger. Not in the example.Combobox.RowDisplays a single row of items in a grid list. Not in the example.Combobox.SeparatorA visual separator between items or groups. Not in the example.Combobox.StatusDisplays a status message whose content changes are announced politely to screen readers. Not in the example.Combobox.ValueThe current value of the combobox. Not in the example.
Examples#
Common ways to put it to work. Each one runs live.
createItems derives each item's value and label when the app stores ids.
ComboboxCreateItems.tsxStyling and accessibility#
The parts ship no styles. Style their states with these attributes; the CSS tab at the top has a sheet. The same CSS works in all five frameworks.
[data-popup-open]Present when the corresponding popup is open. On InputGroup, Input, Clear, Trigger.[data-pressed]Present when the input group is pressed. On InputGroup, Input, Trigger.[data-disabled]Present when the component is disabled. On InputGroup, Input, Clear, Trigger, Item.[data-readonly]Present when the component is readonly. On InputGroup, Input, Trigger.[data-popup-side]Indicates which side the corresponding popup is positioned relative to its anchor. On InputGroup, Input, Trigger.[data-valid]Present when the component is in a valid state (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-invalid]Present when the component is in an invalid state (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-touched]Present when the component has been touched (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-dirty]Present when the component's value has changed (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-filled]Present when the component has a value (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-focused]Present when the component is focused (when wrapped in Field.Root). On InputGroup, Input, Trigger.[data-list-empty]Present when the corresponding items list is empty. On InputGroup, Input, Trigger.[data-placeholder]Present when the combobox doesn't have a value. On InputGroup, Trigger.[data-required]Present when the component is required. On Input, Trigger.[data-visible]Present when the clear button is visible. On Clear.[data-starting-style]Present when the button begins animating in. On Clear, Popup, ItemIndicator, Backdrop.[data-ending-style]Present when the button is animating out. On Clear, Popup, ItemIndicator, Backdrop.[data-open]Present when the popup is open. On Positioner, Popup, Arrow, Backdrop.[data-closed]Present when the popup is closed. On Positioner, Popup, Arrow, Backdrop.[data-anchor-hidden]Present when the anchor is hidden. On Positioner, Popup.[data-side]Indicates which side the popup is positioned relative to the trigger. On Positioner, Popup, Arrow.[data-align]Indicates how the popup is aligned relative to specified side. On Positioner, Popup, Arrow.[data-empty]Present when the items list is empty. On Positioner, Popup.--available-widthThe available width between the trigger and the edge of the viewport. On Positioner.--available-heightThe available height between the trigger and the edge of the viewport. On Positioner.--anchor-widthThe anchor's width. On Positioner.--anchor-heightThe anchor's height. On Positioner.--transform-originThe coordinates that this element is anchored to. Used for animations and transitions. On Positioner.[data-selected]Present when the item is selected. On Item.[data-highlighted]Present when the item is highlighted. On Item.[data-uncentered]Present when the arrow is uncentered. On Arrow.[data-orientation]Indicates the orientation of the separator. On Separator.
Keyboard
- ArrowDownArrowUpOpens the list and highlights the first or the last item On Input.
- ArrowDownArrowUpMoves the highlight and wraps at the ends while
loopFocusis on On List. - ArrowDownArrowUpArrowLeftArrowRightWith
grid, moves across rows and columns On Row. - EnterSelects the highlighted item On Item.
- EscapeCloses the list without changing the value On Input.
- EscapeWith the list closed and
multipleon, clears the selected values On Input. - TabCloses the list without changing the value and moves focus on On Input.
- BackspaceIn an empty input, removes the last chip On Input.
- ArrowLeftArrowRightMoves between chips and back to the input On Chip.
- DeleteRemoves the focused chip On Chip.
- ArrowDownArrowUpOpens the list from the trigger On Trigger.
Set for you
a screen reader says the input picks from a list and whether it is shownInputrole="combobox",aria-expanded,aria-haspopup,aria-controlsto the list while openthe highlight is read while focus stays in the inputInputaria-autocomplete,aria-activedescendantto the highlighted itemthe button says what it opensTriggeraria-haspopup("listbox", or"dialog"when the input is inside the popup),aria-expandedthe items are announced as options, and whether several can be chosenListrole="listbox"(role="grid"withgrid),aria-multiselectablewithmultipleeach item is read with its selected stateItemrole="option"(role="gridcell"in a Row),aria-selectedgrid rows are announced as rowsRowrole="row"the chips are one group the arrow keys move throughChipsrole="toolbar"a group of items is read with its headingGrouparia-labelledbyto its GroupLabelloading and result counts are announced without moving focusStatusrole="status",aria-live="polite""no results" is announced as it appearsEmptyrole="status",aria-live="polite"the decorative icon is not readIconaria-hidden="true"
API reference#
75 props across 26 parts, in React syntax, and className, style, render once for every part. Open a row to try it.
Combobox · all partsclassNameCSS class applied to the element, or a function that
returns a class based on the component's state.string | ((state: State) => string | undefined)styleStyle applied to the element, or a function that
returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>Use it in React#
What differs from the React API. Switch the framework at the top of the page.
@▢▢▢▢/react is the React 19 package. Its parts, props, data attributes and error messages are upstream Base UI's, and upstream's own tests run against it.
- Parts
Each component is its own entry point and exports one namespace named after it.
import { Switch } from '@base-ui-next/react/switch' export function Example() { return ( <Switch.Root> <Switch.Thumb /> </Switch.Root> ) }A part renders the element its API reference names, such as a
<span>forSwitch.Root. - Props and events
Props and callbacks have upstream's names and signatures:
onCheckedChange(checked, details),onOpenChange(open, details),onValueChange(value, details).detailscarriesreason,event,cancel()andallowPropagation(). Native handlers are React's (onClick,onKeyDown), andevent.preventBaseUIHandler()stops a part's own handler. - Styling
classNametakes a string or a function(state) => string;styletakes an object or a function(state) => object. The state'sdata-*attributes are on the element for CSS. renderrendertakes an element (render={<a href="/docs" />}) or a function(props, state) => elementthat spreadspropson what it returns.- Refs
refreaches the part's element. Imperative handles are ref props, as upstream:inputRef, andactionsRef({ validate }on Field and Form,{ unmount, close }on Dialog). - Binding
A part is controlled when its value prop (
checked,open,value) is set, and uncontrolled with thedefaultform (defaultChecked,defaultOpen,defaultValue). React has no two-way binding: pair the value with its change callback. - From @base-ui/reactChange the import from
@base-ui/react/<component>to@▢▢▢▢/react/<component>. - From @base-ui/reactNothing else changes: props, parts, data attributes and errors are the same.