Stable in React
Select
A common form control for choosing a predefined value in a dropdown.
Install#
One package per framework. Select's parts come from it; the anatomy tab at the top shows how they nest.
bun add @▢▢▢▢/react19 parts. The example uses 14 of them; the data does not say which are required.
Select.RootGroups all parts of the select.Select.LabelAn accessible label that is automatically associated with the select trigger.Select.TriggerA button that opens the select popup.Select.ValueA text label of the currently selected item.Select.IconAn icon that indicates that the trigger button opens a select popup.Select.PortalA portal element that moves the popup to a different part of the DOM.Select.PositionerPositions the select popup.Select.PopupA container for the select list.Select.ScrollUpArrowAn element that scrolls the select popup up when hovered.Select.ListA container for the select items.Select.ItemAn individual option in the select popup.Select.ItemIndicatorIndicates whether the select item is selected.Select.ItemTextA text label of the select item.Select.ScrollDownArrowAn element that scrolls the select popup down when hovered.Select.ArrowDisplays an element positioned against the select popup anchor. Not in the example.Select.BackdropAn overlay displayed beneath the select popup. Not in the example.Select.GroupGroups related select items with the corresponding label. Not in the example.Select.GroupLabelAn accessible label that is automatically associated with its parent group. Not in the example.Select.SeparatorA visual separator between items or groups. Not in the example.
Examples#
Common ways to put it to work. Each one runs live.
multiple keeps several values.
SelectMultiple.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 select is open. On Trigger, Icon.[data-pressed]Present when the trigger is pressed. On Trigger.[data-disabled]Present when the select is disabled. On Trigger, Item.[data-readonly]Present when the select is readonly. On Trigger.[data-popup-side]Indicates which side the corresponding popup is positioned relative to its anchor. On Trigger.[data-required]Present when the select is required. On Trigger.[data-valid]Present when the select is in a valid state (when wrapped in Field.Root). On Trigger.[data-invalid]Present when the select is in an invalid state (when wrapped in Field.Root). On Trigger.[data-touched]Present when the select has been touched (when wrapped in Field.Root). On Trigger.[data-dirty]Present when the select's value has changed (when wrapped in Field.Root). On Trigger.[data-filled]Present when the select has a value (when wrapped in Field.Root). On Trigger.[data-focused]Present when the select trigger is focused (when wrapped in Field.Root). On Trigger.[data-placeholder]Present when the select doesn't have a value. On Trigger, Value.[data-open]Present when the select popup is open. On Positioner, Popup, Arrow, Backdrop.[data-closed]Present when the select popup is closed. On Positioner, Popup, Arrow, Backdrop.[data-anchor-hidden]Present when the anchor is hidden. On Positioner.[data-side]Indicates which side the popup is positioned relative to the trigger. On Positioner, Popup, ScrollUpArrow, ScrollDownArrow, Arrow.[data-align]Indicates how the popup is aligned relative to specified side. On Positioner, Popup, Arrow.--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-starting-style]Present when the select begins animating in. On Popup, ScrollUpArrow, ItemIndicator, ScrollDownArrow, Backdrop.[data-ending-style]Present when the select is animating out. On Popup, ScrollUpArrow, ItemIndicator, ScrollDownArrow, Backdrop.[data-direction]Indicates the direction of the scroll arrow. On ScrollUpArrow, ScrollDownArrow.[data-visible]Present when the scroll arrow is visible. On ScrollUpArrow, ScrollDownArrow.[data-selected]Present when the select item is selected. On Item.[data-highlighted]Present when the select item is highlighted. On Item.[data-uncentered]Present when the select arrow is uncentered. On Arrow.[data-orientation]Indicates the orientation of the separator. On Separator.
Keyboard
- ArrowDownEnterSpaceOpens the popup On Trigger.
- On the closed trigger, selects the next item whose text starts with what was typed On Trigger.
- ArrowDownArrowUpMoves the highlight one item at a time and stops at the ends On List.
- HomeEndMoves the highlight to the first or last item On List.
- In the open popup, highlights the next item whose text starts with what was typed On List.
- EnterSelects the highlighted item and closes the popup On Item.
- EscapeCloses the popup without changing the value and keeps focus on the trigger On Popup.
- TabCloses the popup without changing the value and moves on On Popup.
Set for you
a screen reader says the button picks from a list and whether it is openTriggerrole="combobox",aria-haspopup="listbox",aria-expanded,aria-controlsthe control is read with its name and constraintsTriggeraria-labelledbyto Label,aria-readonly,aria-requiredthe items are announced as options, and whether several can be chosenListrole="listbox",aria-multiselectablewithmultipleeach option is read with its selected stateItemrole="option",aria-selectedgrouped options are read under their headingGrouprole="group",aria-labelledbyto its GroupLabelthe decorative chevron is not readIconaria-hidden="true"the scroll arrows are pointer aids onlyScrollUpArrowaria-hidden="true"the scroll arrows are pointer aids onlyScrollDownArrowaria-hidden="true"the overlay is not readBackdroprole="presentation"
API reference#
55 props across 19 parts, in React syntax, and className, style, render once for every part. Open a row to try it.
Select · 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.