Select

A dropdown selection component that allows users to choose a single option from a list

Installation

pnpm add @wandercom/design-system-web

Usage

import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectSeparator,
  SelectTrigger,
  SelectValue,
} from '@wandercom/design-system-web/ui/select';

export function Example() {
  return (
    <Select>
      <SelectTrigger>
        <SelectValue placeholder="Select an option" />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="option-1">Option 1</SelectItem>
        <SelectItem value="option-2">Option 2</SelectItem>
        <SelectItem value="option-3">Option 3</SelectItem>
      </SelectContent>
    </Select>
  );
}

Examples

The default example shows both size variants (default and sm), the disabled state, and the invalid state using aria-invalid.

Loading example...
<Select>
  <SelectTrigger className="w-[200px]">
    <SelectValue placeholder="Choose an option" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="1">Option 1</SelectItem>
    <SelectItem value="2">Option 2</SelectItem>
    <SelectItem value="3">Option 3</SelectItem>
  </SelectContent>
</Select>

<Select>
  <SelectTrigger size="sm" className="w-[200px]">
    <SelectValue placeholder="Small select" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="1">Option 1</SelectItem>
    <SelectItem value="2">Option 2</SelectItem>
    <SelectItem value="3">Option 3</SelectItem>
  </SelectContent>
</Select>

<Select disabled>
  <SelectTrigger className="w-[200px]">
    <SelectValue placeholder="Disabled select" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="1">Option 1</SelectItem>
    <SelectItem value="2">Option 2</SelectItem>
    <SelectItem value="3">Option 3</SelectItem>
  </SelectContent>
</Select>

<Select defaultValue="invalid">
  <SelectTrigger aria-invalid="true" className="w-[200px]">
    <SelectValue />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="invalid">Invalid selection</SelectItem>
    <SelectItem value="1">Option 1</SelectItem>
    <SelectItem value="2">Option 2</SelectItem>
    <SelectItem value="3">Option 3</SelectItem>
  </SelectContent>
</Select>

With groups

Use SelectGroup, SelectLabel, and SelectSeparator to organize options into labeled sections.

Loading example...
<Select>
  <SelectTrigger className="w-[200px]">
    <SelectValue placeholder="Choose a city" />
  </SelectTrigger>
  <SelectContent>
    <SelectGroup>
      <SelectLabel>East Coast</SelectLabel>
      <SelectItem value="nyc">New York</SelectItem>
      <SelectItem value="bos">Boston</SelectItem>
      <SelectItem value="dc">Washington DC</SelectItem>
    </SelectGroup>
    <SelectSeparator />
    <SelectGroup>
      <SelectLabel>West Coast</SelectLabel>
      <SelectItem value="sf">San Francisco</SelectItem>
      <SelectItem value="la">Los Angeles</SelectItem>
      <SelectItem value="sea">Seattle</SelectItem>
    </SelectGroup>
  </SelectContent>
</Select>

Props

Select

defaultValue?:

string
The default selected value when the component is first rendered.

value?:

string
The controlled selected value.

onValueChange?:

(value: string) => void
Callback fired when the selected value changes.

disabled?:

boolean
Disables the select when true.

required?:

boolean
Makes the select required in forms.

name?:

string
The name of the select for form submission.

open?:

boolean
The controlled open state of the select.

onOpenChange?:

(open: boolean) => void
Callback fired when the open state changes.

SelectTrigger

size?:

'default' | 'sm'
Size variant for the trigger. Defaults to 'default'.

className?:

string
Additional CSS classes to apply.

SelectContent

position?:

'item-aligned' | 'popper'
Positioning strategy for the content. Defaults to 'popper'.

align?:

'start' | 'center' | 'end'
Alignment of the content relative to the trigger. Defaults to 'center'.

className?:

string
Additional CSS classes to apply.

SelectItem

value:

string
The unique value of this select item.

disabled?:

boolean
Disables this specific select item.

className?:

string
Additional CSS classes to apply.

SelectLabel

className?:

string
Additional CSS classes to apply to the label.

SelectValue

placeholder?:

string
Text to display when no value is selected.

SelectSeparator

className?:

string
Additional CSS classes to apply to the separator.

Accessibility

The Select component is built on the Radix UI Select primitive, which provides full WAI-ARIA compliance out of the box.

  • Renders with role="combobox" on the trigger and role="listbox" on the content, following the WAI-ARIA listbox pattern
  • Supports keyboard interaction: Space and Enter open the dropdown, arrow keys navigate options, and Escape closes it
  • Type-ahead support allows users to jump to options by typing characters
  • Focus is indicated with a visible border for keyboard navigation
  • Disabled selects apply aria-disabled and reduce interactivity to communicate their state visually
  • Set aria-invalid="true" on the trigger to indicate validation errors with a destructive border style
Select