Skip to main content

Overview

Select provides a dropdown menu for selecting a value from a list of options. It’s similar to a native <select> element but with enhanced customization, keyboard navigation, and accessibility features.

Features

  • Full keyboard navigation
  • Can be controlled or uncontrolled
  • Supports custom placeholder
  • Supports grouping of items
  • Supports labels and separators
  • Focus automatically managed
  • Typeahead support
  • Works inside forms
  • Customizable positioning and collision detection
  • Scrollable content area with scroll buttons

Installation

npm install @radix-ui/react-select

Anatomy

import * as Select from '@radix-ui/react-select';

export default () => (
  <Select.Root>
    <Select.Trigger>
      <Select.Value />
      <Select.Icon />
    </Select.Trigger>
    <Select.Portal>
      <Select.Content>
        <Select.ScrollUpButton />
        <Select.Viewport>
          <Select.Item>
            <Select.ItemText />
            <Select.ItemIndicator />
          </Select.Item>

          <Select.Group>
            <Select.Label />
            <Select.Item>
              <Select.ItemText />
              <Select.ItemIndicator />
            </Select.Item>
          </Select.Group>

          <Select.Separator />
        </Select.Viewport>
        <Select.ScrollDownButton />
        <Select.Arrow />
      </Select.Content>
    </Select.Portal>
  </Select.Root>
);

API Reference

Root

Contains all the select component parts.
value
string
The controlled value of the select.
defaultValue
string
The value of the select when initially rendered (uncontrolled).
onValueChange
(value: string) => void
Event handler called when the value changes.
open
boolean
The controlled open state of the select.
defaultOpen
boolean
The open state when initially rendered (uncontrolled).
onOpenChange
(open: boolean) => void
Event handler called when the open state changes.
dir
'ltr' | 'rtl'
The reading direction. If omitted, inherits from the parent.
name
string
The name of the select. Submitted with its owning form as part of a name/value pair.
disabled
boolean
When true, prevents the user from interacting with the select.
required
boolean
When true, indicates that the user must select a value before the form can be submitted.

Trigger

The button that toggles the select.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Value

The part that reflects the selected value. By default it will render the selected item’s text. Use the placeholder prop for when there is no value.
placeholder
React.ReactNode
The content that will be rendered when no value is selected.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Icon

A small icon often displayed next to the value as a visual affordance for the fact it can be opened.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Portal

When used, portals the content part into the body.
container
HTMLElement
Specify a container element to portal the content into.

Content

The component that pops out when the select is open.
onCloseAutoFocus
(event: Event) => void
Event handler called when focus moves back after closing.
onEscapeKeyDown
(event: KeyboardEvent) => void
Event handler called when the escape key is down.
onPointerDownOutside
(event: PointerDownOutsideEvent) => void
Event handler called when a pointer event occurs outside the bounds of the component.
position
'item-aligned' | 'popper'
default:"'item-aligned'"
The positioning mode to use.
  • item-aligned: Positions content aligned with the selected item
  • popper: Positions content using a positioning engine
side
'top' | 'right' | 'bottom' | 'left'
default:"'bottom'"
The preferred side of the trigger to render against when open (only available when position is set to popper).
sideOffset
number
default:"0"
The distance in pixels from the trigger (only available when position is set to popper).
align
'start' | 'center' | 'end'
default:"'start'"
The preferred alignment against the trigger (only available when position is set to popper).
alignOffset
number
default:"0"
An offset in pixels from the “start” or “end” alignment options (only available when position is set to popper).
avoidCollisions
boolean
default:"true"
When true, overrides the side and align preferences to prevent collisions (only available when position is set to popper).
collisionBoundary
Element | Element[]
default:"[]"
The element(s) used as collision boundary (only available when position is set to popper).
collisionPadding
number | Partial<Record<Side, number>>
default:"0"
The distance in pixels from the boundary edges (only available when position is set to popper).
arrowPadding
number
default:"0"
The padding between the arrow and the edges of the content (only available when position is set to popper).
sticky
'partial' | 'always'
default:"'partial'"
The sticky behavior on the align axis (only available when position is set to popper).
hideWhenDetached
boolean
default:"false"
Whether to hide the content when the trigger becomes fully occluded (only available when position is set to popper).

Viewport

The scrolling viewport that contains all of the items.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Item

The component that contains the select items.
value
string
required
The value given as data when submitted with a name.
disabled
boolean
When true, prevents the user from interacting with the item.
textValue
string
Optional text used for typeahead purposes. By default the typeahead behavior will use the text content.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

ItemText

The textual part of the item. It should only contain the text you want to announce to assistive technology when the item is selected.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

ItemIndicator

Renders when the item is selected. You can style this element directly, or you can use it as a wrapper to put an icon into.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

ScrollUpButton

An optional button used to indicate when the viewport can be scrolled up.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

ScrollDownButton

An optional button used to indicate when the viewport can be scrolled down.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Group

Used to group multiple items. Use in conjunction with Label to ensure good accessibility via automatic labelling.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Label

Used to render the label of a group. It won’t be focusable using arrow keys.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Separator

Used to visually separate items in the select.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Arrow

An optional arrow element to render alongside the content.
width
number
default:"10"
The width of the arrow in pixels.
height
number
default:"5"
The height of the arrow in pixels.
asChild
boolean
default:"false"
Change the default rendered element for the one passed as a child.

Example

import * as Select from '@radix-ui/react-select';
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons';
import './styles.css';

export default () => (
  <Select.Root>
    <Select.Trigger className="SelectTrigger" aria-label="Food">
      <Select.Value placeholder="Select a fruit…" />
      <Select.Icon className="SelectIcon">
        <ChevronDownIcon />
      </Select.Icon>
    </Select.Trigger>
    <Select.Portal>
      <Select.Content className="SelectContent">
        <Select.ScrollUpButton className="SelectScrollButton">
          <ChevronUpIcon />
        </Select.ScrollUpButton>
        <Select.Viewport className="SelectViewport">
          <Select.Group>
            <Select.Label className="SelectLabel">Fruits</Select.Label>
            <Select.Item value="apple" className="SelectItem">
              <Select.ItemText>Apple</Select.ItemText>
              <Select.ItemIndicator className="SelectItemIndicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
            <Select.Item value="banana" className="SelectItem">
              <Select.ItemText>Banana</Select.ItemText>
              <Select.ItemIndicator className="SelectItemIndicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
            <Select.Item value="blueberry" className="SelectItem">
              <Select.ItemText>Blueberry</Select.ItemText>
              <Select.ItemIndicator className="SelectItemIndicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
          </Select.Group>

          <Select.Separator className="SelectSeparator" />

          <Select.Group>
            <Select.Label className="SelectLabel">Vegetables</Select.Label>
            <Select.Item value="carrot" className="SelectItem">
              <Select.ItemText>Carrot</Select.ItemText>
              <Select.ItemIndicator className="SelectItemIndicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
            <Select.Item value="potato" className="SelectItem">
              <Select.ItemText>Potato</Select.ItemText>
              <Select.ItemIndicator className="SelectItemIndicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
          </Select.Group>
        </Select.Viewport>
        <Select.ScrollDownButton className="SelectScrollButton">
          <ChevronDownIcon />
        </Select.ScrollDownButton>
      </Select.Content>
    </Select.Portal>
  </Select.Root>
);

Accessibility

Keyboard Interactions

  • Space - When focus is on the trigger, opens the select and focuses the selected item.
  • Enter - When focus is on the trigger, opens the select and focuses the first item.
  • ArrowDown - When focus is on the trigger, opens the select. When focus is on an item, moves focus to the next item.
  • ArrowUp - When focus is on the trigger, opens the select. When focus is on an item, moves focus to the previous item.
  • Esc - Closes the select and moves focus to the trigger.
  • A-Z - When focus is on the trigger or an item, opens the select (if closed) and focuses the first item starting with that letter.

Build docs developers (and LLMs) love