InputsReact
An input combined with a list of predefined items to select.
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:
<Combobox.Root>
<Combobox.InputGroup>
<Combobox.Input />
<Combobox.Clear />
<Combobox.Trigger>
<Combobox.Icon />
</Combobox.Trigger>
</Combobox.InputGroup>
<Combobox.Portal>
<Combobox.Positioner>
<Combobox.Popup>
<Combobox.Empty />
<Combobox.List>
<Combobox.Collection>
<Combobox.Item>
<Combobox.ItemIndicator />
</Combobox.Item>
</Combobox.Collection>
</Combobox.List>
</Combobox.Popup>
</Combobox.Positioner>
</Combobox.Portal>
</Combobox.Root>
// Not in this example: Combobox.Arrow, Combobox.Backdrop, Combobox.Chip, Combobox.ChipRemove, Combobox.Chips, Combobox.Group, Combobox.GroupLabel, Combobox.Label, Combobox.Row, Combobox.Separator, Combobox.Status, Combobox.ValueExamples
Create Items
createItems derives each item's value and label when the app stores ids.
Multiple
multiple keeps several values, shown as chips in the input.
Input Inside Popup
The input sits in the popup; Label names the trigger that opens it.
Grouped
Group and GroupLabel add headings inside the popup.
Async Single
Items load from a remote source as the person types.
Async Multiple
Remote items with multiple; chosen items stay in the list.
Virtualized
A virtualization library renders only the visible items of a long list.
API reference
76 props across 26 parts, in React syntax. className, style, render are listed once, under Shared props.
ArrowCombobox.Arrow
Displays an element positioned against the anchor. Renders a <div>.
| Data attribute | Description |
|---|---|
data-open | Present when the popup is open. |
data-closed | Present when the 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 arrow is uncentered. |
BackdropCombobox.Backdrop
An overlay displayed beneath the popup. Renders a <div>.
| Data attribute | Description |
|---|---|
data-open | Present when the popup is open. |
data-closed | Present when the popup is closed. |
data-starting-style | Present when the popup begins animating in. |
data-ending-style | Present when the popup is animating out. |
ChipCombobox.Chip
An individual chip that represents a value in a multiselectable input. Renders a <div>.
ChipRemoveCombobox.ChipRemove
A button to remove a chip. Renders a <button>.
| Prop | Type | Default |
|---|---|---|
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | true |
ChipsCombobox.Chips
A container for the chips in a multiselectable input. Renders a <div>.
ClearCombobox.Clear
Clears the value when clicked. 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 | false |
keepMountedWhether the component should remain mounted in the DOM when not visible. | boolean | false |
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding popup is open. |
data-disabled | Present when the button is disabled. |
data-visible | Present when the clear button is visible. |
data-starting-style | Present when the button begins animating in. |
data-ending-style | Present when the button is animating out. |
CollectionCombobox.Collection
Renders filtered list items. If rendering a flat list, pass a function child to the List component instead, which implicitly wraps it. Doesn’t render its own element.
| Prop | Type | Default |
|---|---|---|
childrenrequired | (item: any, index: number) => React.ReactNode | — |
EmptyCombobox.Empty
Renders its children only when the list is empty. Requires the items prop on the root component. Announces changes politely to screen readers. This component's root element must remain mounted in the DOM to announce changes consistently across screen readers. Avoid hiding or removing the component itself with display: none, hidden, aria-hidden, or conditional rendering. Prefer updating or conditionally rendering its children instead. Renders a <div>.
GroupCombobox.Group
Groups related items with the corresponding label. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
itemsItems to be rendered within this group. | readonly any[] | — |
GroupLabelCombobox.GroupLabel
An accessible label that is automatically associated with its parent group. Renders a <div>.
IconCombobox.Icon
An icon that indicates that the trigger button opens the popup. Renders a <span>.
InputCombobox.Input
A text input to search for items in the list. Renders an <input>.
| Prop | Type | Default |
|---|---|---|
disabledWhether the component should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding popup is open. |
data-pressed | Present when the input is pressed. |
data-disabled | Present when the component is disabled. |
data-readonly | Present when the component is readonly. |
data-popup-side | Indicates which side the corresponding popup is positioned relative to its anchor. |
data-required | Present when the component is required. |
data-valid | Present when the component is in a valid state (when wrapped in Field.Root). |
data-invalid | Present when the component is in an invalid state (when wrapped in Field.Root). |
data-touched | Present when the component has been touched (when wrapped in Field.Root). |
data-dirty | Present when the component's value has changed (when wrapped in Field.Root). |
data-filled | Present when the component has a value (when wrapped in Field.Root). |
data-focused | Present when the input is focused (when wrapped in Field.Root). |
data-list-empty | Present when the corresponding items list is empty. |
InputGroupCombobox.InputGroup
A wrapper for the input and its associated controls. Renders a <div>.
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding popup is open. |
data-pressed | Present when the input group is pressed. |
data-disabled | Present when the component is disabled. |
data-readonly | Present when the component is readonly. |
data-popup-side | Indicates which side the corresponding popup is positioned relative to its anchor. |
data-valid | Present when the component is in a valid state (when wrapped in Field.Root). |
data-invalid | Present when the component is in an invalid state (when wrapped in Field.Root). |
data-touched | Present when the component has been touched (when wrapped in Field.Root). |
data-dirty | Present when the component's value has changed (when wrapped in Field.Root). |
data-filled | Present when the component has a value (when wrapped in Field.Root). |
data-focused | Present when the component is focused (when wrapped in Field.Root). |
data-list-empty | Present when the corresponding items list is empty. |
data-placeholder | Present when the combobox doesn't have a value. |
ItemCombobox.Item
An individual item in the list. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
valueA unique value that identifies this item. | any | null |
onClickAn optional click handler for the item when selected. | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | — |
indexThe index of the item in the list. | number | — |
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 item is selected. |
data-highlighted | Present when the item is highlighted. |
data-disabled | Present when the item is disabled. |
ItemIndicatorCombobox.ItemIndicator
Indicates whether the 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 | false |
| Data attribute | Description |
|---|---|
data-starting-style | Present when the indicator begins animating in. |
data-ending-style | Present when the indicator is animating out. |
LabelCombobox.Label
An accessible label that is automatically associated with the combobox trigger. Renders a <div>.
ListCombobox.List
A list container for the items. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
children | React.ReactNode | ((item: any, index: number) => React.ReactNode) | — |
PopupCombobox.Popup
A container for the list. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
initialFocusDetermines the element to focus when the popup is opened. | boolean | React.RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | void | HTMLElement | null) | — |
finalFocusDetermines the element to focus when the popup is closed. | boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null) | — |
| Data attribute | Description |
|---|---|
data-open | Present when the popup is open. |
data-closed | Present when the popup is closed. |
data-starting-style | Present when the popup begins animating in. |
data-ending-style | Present when the popup 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. |
data-anchor-hidden | Present when the anchor is hidden. |
data-empty | Present when the items list is empty. |
PortalCombobox.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 | — |
keepMountedWhether to keep the portal mounted in the DOM while the popup is hidden. | boolean | false |
PositionerCombobox.Positioner
Positions the popup against the trigger. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
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 popup is open. |
data-closed | Present when the 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. |
data-empty | Present when the items list is empty. |
| 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. |
RootCombobox.Root
Groups all parts of the combobox. Doesn’t render its own element.
| Prop | Type | Default |
|---|---|---|
nameIdentifies the field when a form is submitted. | string | — |
defaultValueThe uncontrolled selected value of the combobox when it's initially rendered. | ComboboxInputValue<Value, Multiple> | null | — |
valueThe selected value of the combobox. | ComboboxInputValue<Value, Multiple> | null | — |
onValueChangeEvent handler called when the selected value of the combobox changes. | ((value: ComboboxOutputValue<Value, Multiple> | (Multiple extends true ? never : null), eventDetails: AriaCombobox.ChangeEventDetails) => void) | — |
defaultInputValueThe uncontrolled input value when initially rendered. | string | number | readonly string[] | — |
inputValueThe input value of the combobox. | string | number | readonly string[] | — |
onInputValueChangeEvent handler called when the input value changes. | ((inputValue: string, eventDetails: AriaCombobox.ChangeEventDetails) => void) | — |
defaultOpenWhether the popup is initially open. | boolean | false |
openWhether the popup is currently open. | boolean | — |
onOpenChangeEvent handler called when the popup is opened or closed. | ((open: boolean, eventDetails: AriaCombobox.OpenChangeEventDetails) => void) | — |
autoHighlightWhether the first matching item is highlighted automatically while filtering. | boolean | false |
highlightItemOnHoverWhether moving the pointer over items should highlight them. | boolean | true |
actionsRefA ref to imperative actions. | React.RefObject<AriaCombobox.Actions | null> | — |
autoCompleteProvides a hint to the browser for autofill. | string | — |
filterFilter function used to match items vs input query. | ((item: Item, query: string, itemToString?: ((item: Item) => string) | undefined) => boolean) | null | — |
filteredItemsFiltered items to display in the list. | readonly Item[] | readonly Group<Item>[] | — |
formIdentifies the form that owns the internal input. | string | — |
gridWhether list items are presented in a grid layout. | boolean | false |
inlineWhether the list is rendered inline without using the component's own popup. | boolean | false |
isItemEqualToValueCustom comparison logic used to determine if a combobox item value matches the current selected value. | ((itemValue: Value, value: Value) => boolean) | — |
itemToStringLabelWhen the item values are objects (<Combobox.Item value={object}>), this function converts the object value to a string representation for display in the input. | ((itemValue: Value) => string) | — |
itemToStringValueWhen the item values are objects (<Combobox.Item value={object}>), this function converts the object value to a string representation for form submission. | ((itemValue: Value) => string) | — |
itemsThe items to be displayed in the list. | readonly any[] | readonly Group<any>[] | ComboboxItemCollection<Item, Value> | — |
limitThe maximum number of items to display in the list. | number | -1 |
localeThe locale to use for string comparison. | Intl.LocalesArgument | — |
loopFocusWhether to loop keyboard focus back to the input when the end of the list is reached while using the arrow keys. | boolean | true |
modalDetermines if the popup enters a modal state when open. | boolean | false |
multipleWhether multiple items can be selected. | Multiple | false |
onItemHighlightedCallback fired when an item is highlighted or unhighlighted. | ((highlightedValue: Value | undefined, eventDetails: AriaCombobox.HighlightEventDetails) => void) | — |
onOpenChangeCompleteEvent handler called after any animations complete when the popup is opened or closed. | ((open: boolean) => void) | — |
openOnInputClickWhether the popup opens when clicking the input. | boolean | true |
virtualizedWhether the items are being externally virtualized. | boolean | false |
disabledWhether the component should ignore user interaction. | boolean | false |
readOnlyWhether the user should be unable to choose a different option from the popup. | boolean | false |
requiredWhether the user must choose a value before submitting a form. | boolean | false |
inputRefA ref to the hidden input element. | React.Ref<HTMLInputElement> | — |
idThe id of the component. | 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) | — |
RowCombobox.Row
Displays a single row of items in a grid list. Enable grid on the root component to turn the listbox into a grid. Renders a <div>.
SeparatorCombobox.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. |
StatusCombobox.Status
Displays a status message whose content changes are announced politely to screen readers. Useful for conveying the status of an asynchronously loaded list. This component's root element must remain mounted in the DOM to announce changes consistently across screen readers. Avoid hiding or removing the component itself with display: none, hidden, aria-hidden, or conditional rendering. Prefer updating or conditionally rendering its children instead. Renders a <div>.
TriggerCombobox.Trigger
A button that opens the 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 | false |
| Data attribute | Description |
|---|---|
data-popup-open | Present when the corresponding popup is open. |
data-pressed | Present when the trigger is pressed. |
data-disabled | Present when the component is disabled. |
data-readonly | Present when the component is readonly. |
data-popup-side | Indicates which side the corresponding popup is positioned relative to its anchor. |
data-required | Present when the component is required. |
data-valid | Present when the component is in a valid state (when wrapped in Field.Root). |
data-invalid | Present when the component is in an invalid state (when wrapped in Field.Root). |
data-touched | Present when the component has been touched (when wrapped in Field.Root). |
data-dirty | Present when the component's value has changed (when wrapped in Field.Root). |
data-filled | Present when the component has a value (when wrapped in Field.Root). |
data-focused | Present when the trigger is focused (when wrapped in Field.Root). |
data-list-empty | Present when the corresponding items list is empty. |
data-placeholder | Present when the combobox doesn't have a value. |
ValueCombobox.Value
The current value of the combobox. Doesn’t render its own element.
| 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 | ((selectedValue: any) => React.ReactNode) | — |
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 |
|---|---|---|
| ArrowDownArrowUp | Opens the list and highlights the first or the last item | Input |
| ArrowDownArrowUp | Moves the highlight and wraps at the ends while loopFocus is on | List |
| ArrowDownArrowUpArrowLeftArrowRight | With grid, moves across rows and columns | Row |
| Enter | Selects the highlighted item | Item |
| Escape | Closes the list without changing the value | Input |
| Escape | With the list closed and multiple on, clears the selected values | Input |
| Tab | Closes the list without changing the value and moves focus on | Input |
| Backspace | In an empty input, removes the last chip | Input |
| ArrowLeftArrowRight | Moves between chips and back to the input | Chip |
| Delete | Removes the focused chip | Chip |
| ArrowDownArrowUp | Opens the list from the trigger | Trigger |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Input | role="combobox", aria-expanded, aria-haspopup, aria-controls to the list while open | a screen reader says the input picks from a list and whether it is shown |
| Input | aria-autocomplete, aria-activedescendant to the highlighted item | the highlight is read while focus stays in the input |
| Trigger | aria-haspopup ("listbox", or "dialog" when the input is inside the popup), aria-expanded | the button says what it opens |
| List | role="listbox" (role="grid" with grid), aria-multiselectable with multiple | the items are announced as options, and whether several can be chosen |
| Item | role="option" (role="gridcell" in a Row), aria-selected | each item is read with its selected state |
| Row | role="row" | grid rows are announced as rows |
| Chips | role="toolbar" | the chips are one group the arrow keys move through |
| Group | aria-labelledby to its GroupLabel | a group of items is read with its heading |
| Status | role="status", aria-live="polite" | loading and result counts are announced without moving focus |
| Empty | role="status", aria-live="polite" | "no results" is announced as it appears |
| Icon | aria-hidden="true" | the decorative icon is not read |
Focus order
- Input is the tab stop; arrow keys move a highlight in the list, not focus.
- Trigger, Clear and ChipRemove are not tab stops while the input is outside the popup; chips are reached with
ArrowLeftfrom the input. - With the input inside the popup, Trigger is the tab stop and opening moves focus to the input.
Tabcloses the list and moves on.