Select
Displays a list of options for the user to pick from.
Anatomy
To set up the select correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
Examples
Learn how to use the Select component in your project. Let's take a look at the most basic example:
Example not foundExample not foundExample not foundExample not foundControlled Value
Use the value and onValueChange props to control the selected items.
Example not foundExample not foundExample not foundExample not foundGrouping
Grouping related options can be useful for organizing options into categories.
- Use the
groupByprop to configure the grouping of the items. - Use the
collection.group()method to get the grouped items. - Use the
Select.ItemGroupandSelect.ItemGroupLabelcomponents to render the grouped items.
Example not foundExample not foundExample not foundExample not foundMultiple Selection
To enable multiple item selection:
Example not foundExample not foundExample not foundExample not foundForm Library
Here's an example of integrating the Select component with a form library.
Example not foundExample not foundExample not foundExample not foundField Component
The Field component helps manage form-related state and accessibility attributes of a select. It includes handling
ARIA labels, helper text, and error text to ensure proper accessibility.
Example not foundExample not foundExample not foundExample not foundAsync Loading
Here's an example of how to load the items asynchronously when the select is opened.
Example not foundExample not foundExample not foundExample not foundRoot Provider
The RootProvider component provides a context for the select. It accepts the value of the useSelect hook. You can
leverage it to access the component state and methods from outside the select.
Example not foundExample not foundExample not foundExample not foundIf you're using the
RootProvidercomponent, you don't need to use theRootcomponent.
Select on Highlight
Here's an example of automatically selecting items when they are highlighted (hovered or navigated to with keyboard).
Example not foundExample not foundExample not foundExample not foundMaximum Selected Items
Here's an example of limiting the number of items that can be selected in a multiple select.
Example not foundExample not foundExample not foundExample not foundLazy Mount
The lazyMount and unmountOnExit props allow you to control when the select content is mounted and unmounted from the
DOM. This can improve performance by only rendering the content when needed.
Example not foundExample not foundExample not foundExample not foundGuides
Type-Safety
The Select.RootComponent type enables you to create closed, strongly typed wrapper components that maintain full type
safety for collection items.
This is particularly useful when building reusable select components with custom props and consistent styling.
import { Select as ArkSelect, type CollectionItem } from '@ark-ui/react/select'
import { createListCollection } from '@ark-ui/react/collection'
interface SelectProps<T extends CollectionItem> extends ArkSelect.RootProps<T> {}
const Select: ArkSelect.RootComponent = (props) => {
return <ArkSelect.Root {...props}>{/* ... */}</ArkSelect.Root>
}
Then, you can use the Select component as follows:
const App = () => {
const collection = createListCollection({
initialItems: [
{ label: 'React', value: 'react' },
{ label: 'Vue', value: 'vue' },
{ label: 'Svelte', value: 'svelte' },
],
})
return (
<Select
collection={collection}
onValueChange={(e) => {
// this will be strongly typed Array<{ label: string, value: string }>
console.log(e.items)
}}
>
{/* ... */}
</Select>
)
}
Usage in Popover or Dialog
When using the Select component within a Popover or Dialog, avoid rendering its content within a Portal or
Teleport.
This ensures the Select's content stays within the Popover/Dialog's DOM hierarchy rather than being portalled to the document body, maintaining proper interaction and accessibility behavior.
Hidden Select
The Select.HiddenSelect component renders a native HTML <select> element that's visually hidden but remains in the
DOM. This component is essential for:
- Form submission: Native form submission and serialization work seamlessly since the actual
<select>element exists in the DOM - Browser auto-fill: Browsers can properly auto-fill the select based on previously submitted form data
- Progressive enhancement: Forms remain functional even if JavaScript fails to load
<Select.Root>
<Select.HiddenSelect />
{/* Other Select components */}
</Select.Root>
The hidden select automatically syncs with the Select component's value, ensuring form data is always up-to-date.
Empty State
You can create an empty state component that displays when there are no items in the collection. Use the
useSelectContext hook to check the collection size:
const SelectEmpty = (props: React.ComponentProps<'div'>) => {
const select = useSelectContext()
if (select.collection.size === 0) {
return <div {...props} role="presentation" />
}
return null
}
Then use it within your Select content:
<Select.Content>
<SelectEmpty>No items to display</SelectEmpty>
{/* Your items */}
</Select.Content>
Available height and width
The following css variables are exposed to the Select.Positioner which you can use to style the Select.Content
/* width of the select trigger */
--reference-width: <pixel-value>;
/* width of the available viewport */
--available-width: <pixel-value>;
/* height of the available viewport */
--available-height: <pixel-value>;
For example, if you want to make sure the maximum height doesn't exceed the available height, you can use the following:
[data-scope='select'][data-part='content'] {
max-height: calc(var(--available-height) - 100px);
}
API Reference
Props
Root
| Prop | Default | Type |
|---|---|---|
collection | ListCollection<T>The collection of items | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
closeOnSelect | true | booleanWhether the select should close after an item is selected |
composite | true | booleanWhether the select is a composed with other composite widgets like tabs or combobox |
defaultHighlightedValue | stringThe initial value of the highlighted item when opened. Use when you don't need to control the highlighted value of the select. | |
defaultOpen | booleanWhether the select's open state is controlled by the user | |
defaultValue | string[]The initial default value of the select when rendered. Use when you don't need to control the value of the select. | |
deselectable | booleanWhether the value can be cleared by clicking the selected item. **Note:** this is only applicable for single selection | |
disabled | booleanWhether the select is disabled | |
form | stringThe associate form of the underlying select. | |
highlightedValue | stringThe controlled key of the highlighted item | |
id | stringThe unique identifier of the machine. | |
ids | Partial<{
root: string
content: string
control: string
trigger: string
clearTrigger: string
label: string
hiddenSelect: string
positioner: string
item: (id: string | number) => string
itemGroup: (id: string | number) => string
itemGroupLabel: (id: string | number) => string
}>The ids of the elements in the select. Useful for composition. | |
immediate | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
invalid | booleanWhether the select is invalid | |
lazyMount | false | booleanWhether to enable lazy mounting |
loopFocus | false | booleanWhether to loop the keyboard navigation through the options |
multiple | booleanWhether to allow multiple selection | |
name | stringThe `name` attribute of the underlying select. | |
onExitComplete | VoidFunctionFunction called when the animation ends in the closed state | |
onFocusOutside | (event: FocusOutsideEvent) => voidFunction called when the focus is moved outside the component | |
onHighlightChange | (details: HighlightChangeDetails<T>) => voidThe callback fired when the highlighted item changes. | |
onInteractOutside | (event: InteractOutsideEvent) => voidFunction called when an interaction happens outside the component | |
onOpenChange | (details: OpenChangeDetails) => voidFunction called when the popup is opened | |
onPointerDownOutside | (event: PointerDownOutsideEvent) => voidFunction called when the pointer is pressed down outside the component | |
onSelect | (details: SelectionDetails) => voidFunction called when an item is selected | |
onValueChange | (details: ValueChangeDetails<T>) => voidThe callback fired when the selected item changes. | |
open | booleanWhether the select menu is open | |
positioning | PositioningOptionsThe positioning options of the menu. | |
present | booleanWhether the node is present (controlled by the user) | |
readOnly | booleanWhether the select is read-only | |
required | booleanWhether the select is required | |
scrollToIndexFn | (details: ScrollToIndexDetails) => voidFunction to scroll to a specific index | |
skipAnimationOnMount | false | booleanWhether to allow the initial presence animation. |
unmountOnExit | false | booleanWhether to unmount on exit. |
value | string[]The controlled keys of the selected items |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | root |
[data-invalid] | Present when invalid |
[data-readonly] | Present when read-only |
ClearTrigger
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | clear-trigger |
[data-invalid] | Present when invalid |
Content
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| CSS Variable | Description |
|---|---|
--layer-index | The index of the dismissable in the layer stack |
--nested-layer-count | The number of nested selects |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | content |
[data-state] | "open" | "closed" |
[data-nested] | listbox |
[data-has-nested] | listbox |
[data-placement] | The placement of the content |
[data-activedescendant] | The id the active descendant of the content |
Control
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | control |
[data-state] | "open" | "closed" |
[data-focus] | Present when focused |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
HiddenSelect
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Indicator
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | indicator |
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-readonly] | Present when read-only |
ItemGroupLabel
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
ItemGroup
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | item-group |
[data-disabled] | Present when disabled |
ItemIndicator
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | item-indicator |
[data-state] | "checked" | "unchecked" |
Item
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
item | anyThe item to render | |
persistFocus | booleanWhether hovering outside should clear the highlighted state |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | item |
[data-value] | The value of the item |
[data-state] | "checked" | "unchecked" |
[data-highlighted] | Present when highlighted |
[data-disabled] | Present when disabled |
ItemText
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | item-text |
[data-state] | "checked" | "unchecked" |
[data-disabled] | Present when disabled |
[data-highlighted] | Present when highlighted |
Label
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | label |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-readonly] | Present when read-only |
[data-required] | Present when required |
List
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Positioner
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| CSS Variable | Description |
|---|---|
--reference-width | The width of the reference element |
--reference-height | The height of the root |
--available-width | The available width in viewport |
--available-height | The available height in viewport |
--x | The x position for transform |
--y | The y position for transform |
--z-index | The z-index value |
--transform-origin | The transform origin for animations |
RootProvider
| Prop | Default | Type |
|---|---|---|
value | UseSelectReturn<T> | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
immediate | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
lazyMount | false | booleanWhether to enable lazy mounting |
onExitComplete | VoidFunctionFunction called when the animation ends in the closed state | |
present | booleanWhether the node is present (controlled by the user) | |
skipAnimationOnMount | false | booleanWhether to allow the initial presence animation. |
unmountOnExit | false | booleanWhether to unmount on exit. |
Trigger
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | trigger |
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-readonly] | Present when read-only |
[data-placement] | The placement of the trigger |
[data-placeholder-shown] | Present when placeholder is shown |
ValueText
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
placeholder | stringText to display when no value is selected. |
| Data Attribute | Value |
|---|---|
[data-scope] | select |
[data-part] | value-text |
[data-disabled] | Present when disabled |
[data-invalid] | Present when invalid |
[data-focus] | Present when focused |
Context
These are the properties available when using Select.Context, useSelectContext hook or useSelect hook.
API
| Property | Type |
|---|---|
focused | booleanWhether the select is focused |
open | booleanWhether the select is open |
empty | booleanWhether the select value is empty |
highlightedValue | stringThe value of the highlighted item |
highlightedItem | VThe highlighted item |
setHighlightValue | (value: string) => voidFunction to highlight a value |
clearHighlightValue | VoidFunctionFunction to clear the highlighted value |
selectedItems | V[]The selected items |
hasSelectedItems | booleanWhether there's a selected option |
value | string[]The selected item keys |
valueAsString | stringThe string representation of the selected items |
selectValue | (value: string) => voidFunction to select a value |
selectAll | VoidFunctionFunction to select all values |
setValue | (value: string[]) => voidFunction to set the value of the select |
clearValue | (value?: string) => voidFunction to clear the value of the select. If a value is provided, it will only clear that value, otherwise, it will clear all values. |
focus | VoidFunctionFunction to focus on the select input |
getItemState | (props: ItemProps<any>) => ItemStateReturns the state of a select item |
setOpen | (open: boolean) => voidFunction to open or close the select |
collection | ListCollection<V>Function to toggle the select |
reposition | (options?: Partial<PositioningOptions>) => voidFunction to set the positioning options of the select |
multiple | booleanWhether the select allows multiple selections |
disabled | booleanWhether the select is disabled |
Accessibility
Complies with the Listbox WAI-ARIA design pattern.
Keyboard Support
| Key | Description |
|---|---|
Space | When focus is on trigger, opens the select and focuses the first selected item. When focus is on the content, selects the highlighted item. |
Enter | When focus is on trigger, opens the select and focuses the first selected item. When focus is on content, selects the focused item. |
ArrowDown | When focus is on trigger, opens the select. When focus is on content, moves focus to the next item. |
ArrowUp | When focus is on trigger, opens the select. When focus is on content, moves focus to the previous item. |
Esc | Closes the select and moves focus to trigger. |
A-Za-z | When focus is on trigger, selects the item whose label starts with the typed character. When focus is on the listbox, moves focus to the next item with a label that starts with the typed character. |