InputsReact
A common form control for choosing a predefined value in a dropdown.
Rendered by React 19.3.1
Loading React…Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<Select.Root>
<Select.Label />
<Select.Trigger>
<Select.Value />
<Select.Icon />
</Select.Trigger>
<Select.Portal>
<Select.Positioner>
<Select.Popup>
<Select.ScrollUpArrow />
<Select.List>
<Select.Item>
<Select.ItemIndicator />
<Select.ItemText />
</Select.Item>
</Select.List>
<Select.ScrollDownArrow />
</Select.Popup>
</Select.Positioner>
</Select.Portal>
</Select.Root>
// Not in this example: Select.Arrow, Select.Backdrop, Select.Group, Select.GroupLabel, Select.SeparatorExamples
Multiple
multiple keeps several values.
Object Values
Items use objects as values; Value renders the chosen object's label.
Grouped
Group and GroupLabel add headings inside the popup.
API reference
56 props across 19 parts, in React syntax. className, style, render are listed once, under Shared props.
ArrowSelect.Arrow
Displays an element positioned against the select popup anchor. Renders a <div>.
| Data attribute | Description |
|---|---|
data-open | Present when the select popup is open. |
data-closed | Present when the select popup is closed. |
data-side | Indicates which side the popup is positioned relative to the trigger. |
data-align | Indicates how the popup is aligned relative to specified side. |
data-uncentered | Present when the select arrow is uncentered. |
BackdropSelect.Backdrop
An overlay displayed beneath the select popup. Renders a <div>.
| Data attribute | Description |
|---|---|
data-open | Present when the select is open. |
data-closed | Present when the select is closed. |
data-starting-style | Present when the select begins animating in. |
data-ending-style | Present when the select is animating out. |
GroupSelect.Group
Groups related select items with the corresponding label. Renders a <div>.
GroupLabelSelect.GroupLabel
An accessible label that is automatically associated with its parent group. Renders a <div>.
IconSelect.Icon
An icon that indicates that the trigger button opens a select popup. Renders a <span>.
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding popup is open. |
ItemSelect.Item
An individual option in the select popup. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
labelSpecifies the text label to use when the item is matched during keyboard text navigation. | string | — |
valueA unique value that identifies this select item. | any | null |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
children | React.ReactNode | — |
| Data attribute | Description |
|---|---|
data-selected | Present when the select item is selected. |
data-highlighted | Present when the select item is highlighted. |
data-disabled | Present when the select item is disabled. |
ItemIndicatorSelect.ItemIndicator
Indicates whether the select item is selected. Renders a <span>.
| Prop | Type | Default |
|---|---|---|
children | React.ReactNode | — |
keepMountedWhether to keep the HTML element in the DOM when the item is not selected. | boolean | — |
| Data attribute | Description |
|---|---|
data-starting-style | Present when the indicator begins animating in. |
data-ending-style | Present when the indicator is animating out. |
ItemTextSelect.ItemText
A text label of the select item. Renders a <div>.
LabelSelect.Label
An accessible label that is automatically associated with the select trigger. Renders a <div>.
ListSelect.List
A container for the select items. Renders a <div>.
PopupSelect.Popup
A container for the select list. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
finalFocusDetermines the element to focus when the select popup is closed. | boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null) | — |
children | React.ReactNode | — |
| Data attribute | Description |
|---|---|
data-open | Present when the select is open. |
data-closed | Present when the select is closed. |
data-starting-style | Present when the select begins animating in. |
data-ending-style | Present when the select is animating out. |
data-side | Indicates which side the popup is positioned relative to the trigger. |
data-align | Indicates how the popup is aligned relative to specified side. |
PortalSelect.Portal
A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to <body>. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
containerA parent element to render the portal element into. | HTMLElement | ShadowRoot | React.RefObject<HTMLElement | ShadowRoot | null> | null | — |
PositionerSelect.Positioner
Positions the select popup. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
alignItemWithTriggerWhether the positioner overlaps the trigger so the selected item's text is aligned with the trigger's value text. | boolean | true |
disableAnchorTrackingWhether to disable the popup from tracking any layout shift of its positioning anchor. | boolean | false |
alignHow to align the popup relative to the specified side. | Align | 'center' |
alignOffsetAdditional offset along the alignment axis in pixels. | number | OffsetFunction | 0 |
sideWhich side of the anchor element to align the popup against. | Side | 'bottom' |
sideOffsetDistance between the anchor and the popup in pixels. | number | OffsetFunction | 0 |
arrowPaddingMinimum distance to maintain between the arrow and the edges of the popup. | number | 5 |
anchorAn element to position the popup against. | Element | VirtualElement | React.RefObject<Element | null> | (() => Element | VirtualElement | null) | null | — |
collisionAvoidanceDetermines how to handle collisions when positioning the popup. | CollisionAvoidance | — |
collisionBoundaryAn element or a rectangle that delimits the area that the popup is confined to. | Boundary | 'clipping-ancestors' |
collisionPaddingAdditional space to maintain from the edge of the collision boundary. | Padding | 5 |
stickyWhether to maintain the popup in the viewport after | boolean | false |
positionMethodDetermines which CSS position property to use. | "absolute" | "fixed" | 'absolute' |
| Data attribute | Description |
|---|---|
data-open | Present when the select popup is open. |
data-closed | Present when the select popup is closed. |
data-anchor-hidden | Present when the anchor is hidden. |
data-side | Indicates which side the popup is positioned relative to the trigger. |
data-align | Indicates how the popup is aligned relative to specified side. |
| CSS variable | Description |
|---|---|
--available-width | The available width between the trigger and the edge of the viewport. |
--available-height | The available height between the trigger and the edge of the viewport. |
--anchor-width | The anchor's width. |
--anchor-height | The anchor's height. |
--transform-origin | The coordinates that this element is anchored to. Used for animations and transitions. |
RootSelect.Root
Groups all parts of the select. Doesn’t render its own element.
| Prop | Type | Default |
|---|---|---|
nameIdentifies the field when a form is submitted. | string | — |
defaultValueThe uncontrolled value of the select when it's initially rendered. | SelectInputValue<Value, Multiple> | null | — |
valueThe value of the select. | SelectInputValue<Value, Multiple> | null | — |
onValueChangeEvent handler called when the value of the select changes. | ((value: SelectOutputValue<Value, Multiple> | (Multiple extends true ? never : null), eventDetails: SelectRootChangeEventDetails) => void) | — |
defaultOpenWhether the select popup is initially open. | boolean | false |
openWhether the select popup is currently open. | boolean | — |
onOpenChangeEvent handler called when the select popup is opened or closed. | ((open: boolean, eventDetails: SelectRootOpenChangeEventDetails) => void) | — |
highlightItemOnHoverWhether moving the pointer over items should highlight them. | boolean | true |
actionsRefA ref to imperative actions. | React.RefObject<SelectRootActions | null> | — |
autoCompleteProvides a hint to the browser for autofill. | string | — |
formIdentifies the form that owns the hidden input. | string | — |
isItemEqualToValueCustom comparison logic used to determine if a select item value matches the current selected value. | ((itemValue: Value, value: Value) => boolean) | — |
itemToStringLabelWhen the item values are objects (<Select.Item value={object}>), this function converts the object value to a string representation for display in the trigger. | ((itemValue: Value) => string) | — |
itemToStringValueWhen the item values are objects (<Select.Item value={object}>), this function converts the object value to a string representation for form submission. | ((itemValue: Value) => string) | — |
itemsData structure of the items rendered in the select popup. | readonly Group<any>[] | Record<string, React.ReactNode> | readonly { label: React.ReactNode; value: any; }[] | — |
modalDetermines if the select enters a modal state when open. | boolean | true |
multipleWhether multiple items can be selected. | Multiple | false |
onOpenChangeCompleteEvent handler called after any animations complete when the select popup is opened or closed. | ((open: boolean) => void) | — |
disabledWhether the component should ignore user interaction. | boolean | false |
readOnlyWhether the user should be unable to choose a different option from the select popup. | boolean | false |
requiredWhether the user must choose a value before submitting a form. | boolean | false |
inputRefA ref to access the hidden input element. | React.Ref<HTMLInputElement> | — |
idThe id of the Select. | string | — |
children | React.ReactNode | — |
isItemDisabledWhether the item at index is disabled, for items that are not mounted (a virtualized list). | ((itemValue: Value, index: number) => boolean) | — |
ScrollDownArrowSelect.ScrollDownArrow
An element that scrolls the select popup down when hovered. Does not render when using touch input. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
keepMountedWhether to keep the HTML element in the DOM while the select popup is not scrollable. | boolean | false |
| Data attribute | Description |
|---|---|
data-starting-style | Present when the scroll arrow begins animating in. |
data-ending-style | Present when the scroll arrow is animating out. |
data-direction | Indicates the direction of the scroll arrow. |
data-visible | Present when the scroll arrow is visible. |
data-side | Indicates which side the popup is positioned relative to the trigger. |
ScrollUpArrowSelect.ScrollUpArrow
An element that scrolls the select popup up when hovered. Does not render when using touch input. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
keepMountedWhether to keep the HTML element in the DOM while the select popup is not scrollable. | boolean | false |
| Data attribute | Description |
|---|---|
data-starting-style | Present when the scroll arrow begins animating in. |
data-ending-style | Present when the scroll arrow is animating out. |
data-direction | Indicates the direction of the scroll arrow. |
data-visible | Present when the scroll arrow is visible. |
data-side | Indicates which side the popup is positioned relative to the trigger. |
SeparatorSelect.Separator
A visual separator between items or groups. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
orientationThe orientation of the separator. | Orientation | 'horizontal' |
| Data attribute | Description |
|---|---|
data-orientation | Indicates the orientation of the separator. |
TriggerSelect.Trigger
A button that opens the select popup. Renders a <button>.
| Prop | Type | Default |
|---|---|---|
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | true |
disabledWhether the component should ignore user interaction. | boolean | — |
children | React.ReactNode | — |
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding select is open. |
data-pressed | Present when the trigger is pressed. |
data-disabled | Present when the select is disabled. |
data-readonly | Present when the select is readonly. |
data-popup-side | Indicates which side the corresponding popup is positioned relative to its anchor. |
data-required | Present when the select is required. |
data-valid | Present when the select is in a valid state (when wrapped in Field.Root). |
data-invalid | Present when the select is in an invalid state (when wrapped in Field.Root). |
data-touched | Present when the select has been touched (when wrapped in Field.Root). |
data-dirty | Present when the select's value has changed (when wrapped in Field.Root). |
data-filled | Present when the select has a value (when wrapped in Field.Root). |
data-focused | Present when the select trigger is focused (when wrapped in Field.Root). |
data-placeholder | Present when the select doesn't have a value. |
ValueSelect.Value
A text label of the currently selected item. Renders a <span>.
| Prop | Type | Default |
|---|---|---|
placeholderThe placeholder value to display when no value is selected. | React.ReactNode | — |
childrenAccepts a function that returns a ReactNode to format the selected value. | React.ReactNode | ((value: any) => React.ReactNode) | — |
| Data attribute | Description |
|---|---|
data-placeholder | Present when the select doesn't have a value. |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS 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> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| ArrowDownEnterSpace | Opens the popup | Trigger |
| On the closed trigger, selects the next item whose text starts with what was typed | Trigger | |
| ArrowDownArrowUp | Moves the highlight one item at a time and stops at the ends | List |
| HomeEnd | Moves the highlight to the first or last item | List |
| In the open popup, highlights the next item whose text starts with what was typed | List | |
| Enter | Selects the highlighted item and closes the popup | Item |
| Escape | Closes the popup without changing the value and keeps focus on the trigger | Popup |
| Tab | Closes the popup without changing the value and moves on | Popup |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Trigger | role="combobox", aria-haspopup="listbox", aria-expanded, aria-controls | a screen reader says the button picks from a list and whether it is open |
| Trigger | aria-labelledby to Label, aria-readonly, aria-required | the control is read with its name and constraints |
| List | role="listbox", aria-multiselectable with multiple | the items are announced as options, and whether several can be chosen |
| Item | role="option", aria-selected | each option is read with its selected state |
| Group | role="group", aria-labelledby to its GroupLabel | grouped options are read under their heading |
| Icon | aria-hidden="true" | the decorative chevron is not read |
| ScrollUpArrow | aria-hidden="true" | the scroll arrows are pointer aids only |
| ScrollDownArrow | aria-hidden="true" | the scroll arrows are pointer aids only |
| Backdrop | role="presentation" | the overlay is not read |
Focus order
- Trigger is the tab stop.
- Opening moves focus to the selected item; arrow keys move it.
Escapereturns focus to Trigger;Tabcloses the popup and moves on.