Select
A dropdown for choosing from a list of options.
Import
import { Select } from '@oztix/roadie-components/select'
Examples
Default
Pass string children to Select.Item for automatic ItemText + ItemIndicator
wrapping. Use Select.Content as a convenience wrapper for Portal + Positioner + Popup.
Emphasis
Sizes
States
The trigger uses is-interactive-field for state-based colour transitions:
neutral at rest, accent on focus/open, danger when invalid.
Composition
With Field
Wrap Select in Field for consistent layout, labels, and error handling. Field provides spacing, label wiring, and context flow automatically.
With Field and error
With standalone label
Select also has its own Select.Label for standalone usage without a Field
wrapper. Use showIndicator to show a required or optional indicator.
With groups
Guidelines
When to use Select
Use Select when the list of options is known, short, and fixed. The user picks from a closed set — they don't need to search or type a custom value.
- Country/state dropdowns (small set)
- Status or category pickers
- Sort-by controls
- Any list under ~15 items where scanning is faster than typing
When to use Combobox instead
If users are likely to search the list, the list is long (15+ items), or options load asynchronously, use Combobox.
| Question | Select | Combobox |
|---|---|---|
| Can the user type to filter? | No (typeahead only) | Yes |
| Is the list longer than ~15 items? | Avoid | Preferred |
| Are options loaded from an API? | No | Yes |
| Can the user enter a custom value? | No | Possible |
| Does the user know roughly what they want? | Maybe not — they browse | Yes — they search |
Keyboard behaviour
Select delegates all keyboard handling to Base UI:
- Arrow keys navigate the list
- Typeahead jumps to items by first letter(s)
- Enter / Space confirms the highlighted item
- Escape closes the popup
Accessibility
- Always pair with
Select.Labelor anaria-labelon the trigger. Select.ItemIndicatorprovides a visible check for the selected item — include it for clarity.- The popup locks scroll by default (
modal={true}). Setmodal={false}if the select appears in a non-blocking context like a toolbar.
API reference
Select
Base UIA ref to access the hidden input element.
Identifies the field when a form is submitted.
Provides a hint to the browser for autofill. @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/autocomplete
The id of the Select.
Whether the user must choose a value before submitting a form.
Defaults to false.
Whether the user should be unable to choose a different option from the select popup.
Defaults to false.
Whether the component should ignore user interaction.
Defaults to false.
Whether multiple items can be selected.
Defaults to false.
Whether moving the pointer over items should highlight them. Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state.
Defaults to true.
Whether the select popup is initially open. To render a controlled select popup, use the `open` prop instead.
Defaults to false.
Event handler called when the select popup is opened or closed.
Event handler called after any animations complete when the select popup is opened or closed.
Whether the select popup is currently open.
Determines if the select enters a modal state when open. - `true`: user interaction is limited to the select: document page scroll is locked and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed.
Defaults to true.
A ref to imperative actions. - `unmount`: When specified, the select will not be unmounted when closed. Instead, the `unmount` function must be called to unmount the select manually. Useful when the select's animation is controlled by an external library.
Data structure of the items rendered in the select popup. When specified, `<Select.Value>` renders the label of the selected item instead of the raw value. @example ```tsx const items = { sans: 'Sans-serif', serif: 'Serif', mono: 'Monospace', cursive: 'Cursive', }; <Select.Root items={items} /> ```
When the item values are objects (`<Select.Item value={object}>`), this function converts the object value to a string representation for display in the trigger. If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop.
When the item values are objects (`<Select.Item value={object}>`), this function converts the object value to a string representation for form submission. If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop.
Custom comparison logic used to determine if a select item value matches the current selected value. Useful when item values are objects without matching referentially. Defaults to `Object.is` comparison.
The uncontrolled value of the select when it’s initially rendered. To render a controlled select, use the `value` prop instead.
The value of the select. Use when controlled.
Event handler called when the value of the select changes.
Select.Content
Inherited from SelectPopupProps
Determines the element to focus when the select popup is closed. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (trigger or previously focused element). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing.
Select.ErrorText
No additional props — forwards all standard HTML attributes to the underlying element.
Select.Group
Base UINo additional props — forwards all standard HTML attributes to the underlying element.
Select.GroupLabel
Base UINo additional props — forwards all standard HTML attributes to the underlying element.
Select.HelperText
No additional props — forwards all standard HTML attributes to the underlying element.
Select.Icon
Base UINo additional props — forwards all standard HTML attributes to the underlying element.
Select.Item
Base UIInherited from SelectItemProps
A unique value that identifies this select item.
Defaults to null.
Whether the component should ignore user interaction.
Defaults to false.
Specifies the text label to use when the item is matched during keyboard text navigation. Defaults to the item text content if not provided.
Inherited from NonNativeButtonProps
Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.
Defaults to false.
Select.ItemIndicator
Base UIInherited from SelectItemIndicatorProps
Whether to keep the HTML element in the DOM when the item is not selected.
Select.ItemText
Base UINo additional props — forwards all standard HTML attributes to the underlying element.
Select.Label
Base UISelect.Popup
Base UIInherited from SelectPopupProps
Determines the element to focus when the select popup is closed. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (trigger or previously focused element). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing.
Select.Portal
Base UIInherited from Props
A parent element to render the portal element into.
Select.Positioner
Base UIInherited from SelectPositionerProps
Whether the positioner overlaps the trigger so the selected item's text is aligned with the trigger's value text. This only applies to mouse input and is automatically disabled if there is not enough space.
Defaults to true.
Inherited from UseAnchorPositioningSharedParameters
An element to position the popup against. By default, the popup will be positioned against the trigger.
Determines which CSS `position` property to use.
Defaults to 'absolute'.
Which side of the anchor element to align the popup against. May automatically change to avoid collisions.
Defaults to 'bottom'.
Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner sideOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.height : anchor.width; }} /> ```
Defaults to 0.
How to align the popup relative to the specified side.
Defaults to 'center'.
Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner alignOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.width : anchor.height; }} /> ```
Defaults to 0.
An element or a rectangle that delimits the area that the popup is confined to.
Defaults to 'clipping-ancestors'.
Additional space to maintain from the edge of the collision boundary.
Defaults to 5.
Whether to maintain the popup in the viewport after the anchor element was scrolled out of view.
Defaults to false.
Minimum distance to maintain between the arrow and the edges of the popup. Use it to prevent the arrow element from hanging out of the rounded corners of a popup.
Defaults to 5.
Whether to disable the popup from tracking any layout shift of its positioning anchor.
Defaults to false.
Determines how to handle collisions when positioning the popup. `side` controls overflow on the preferred placement axis (`top`/`bottom` or `left`/`right`): - `'flip'`: keep the requested side when it fits; otherwise try the opposite side (`top` and `bottom`, or `left` and `right`). - `'shift'`: never change side; keep the requested side and move the popup within the clipping boundary so it stays visible. - `'none'`: do not correct side-axis overflow. `align` controls overflow on the alignment axis (`start`/`center`/`end`): - `'flip'`: keep side, but swap `start` and `end` when the requested alignment overflows. - `'shift'`: keep side and requested alignment, then nudge the popup along the alignment axis to fit. - `'none'`: do not correct alignment-axis overflow. `fallbackAxisSide` controls fallback behavior on the perpendicular axis when the preferred axis cannot fit: - `'start'`: allow perpendicular fallback and try the logical start side first (`top` before `bottom`, or `left` before `right` in LTR). - `'end'`: allow perpendicular fallback and try the logical end side first (`bottom` before `top`, or `right` before `left` in LTR). - `'none'`: do not fallback to the perpendicular axis. When `side` is `'shift'`, explicitly setting `align` only supports `'shift'` or `'none'`. If `align` is omitted, it defaults to `'flip'`. @example ```jsx <Positioner collisionAvoidance={{ side: 'shift', align: 'shift', fallbackAxisSide: 'none', }} /> ```
Select.ScrollDownArrow
Base UIInherited from SelectScrollDownArrowProps
Whether to keep the HTML element in the DOM while the select popup is not scrollable.
Defaults to false.
Select.ScrollUpArrow
Base UIInherited from SelectScrollUpArrowProps
Whether to keep the HTML element in the DOM while the select popup is not scrollable.
Defaults to false.
Select.Trigger
Base UIInherited from SelectTriggerProps
Whether the component should ignore user interaction.
Inherited from NonNativeButtonProps
Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button.
Defaults to false.
Select.Value
Base UIInherited from SelectValueProps
Accepts a function that returns a `ReactNode` to format the selected value. @example ```tsx <Select.Value> {(value: string | null) => value ? labels[value] : 'No value'} </Select.Value> ```
The placeholder value to display when no value is selected. This is overridden by `children` if specified, or by a null item's label in `items`.