Skip to main content

select

Displays a list of options for the user to pick from -- triggered by a button.

Philosophy

Native selects are accessible but difficult to style consistently. This select builds on @gentleduck/primitives/select which provides full keyboard navigation, ARIA semantics, scroll management, and typeahead search. The wrapper adds design-system styling while the primitive handles all interaction logic.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add select

npx @gentleduck/cli add select

Usage

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
<Select>
  <SelectTrigger className="w-[180px]">
    <SelectValue placeholder="Theme" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">Light</SelectItem>
    <SelectItem value="dark">Dark</SelectItem>
    <SelectItem value="system">System</SelectItem>
  </SelectContent>
</Select>
<Select>
  <SelectTrigger className="w-[180px]">
    <SelectValue placeholder="Theme" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="light">Light</SelectItem>
    <SelectItem value="dark">Dark</SelectItem>
    <SelectItem value="system">System</SelectItem>
  </SelectContent>
</Select>

Examples

Scrollable

Form

Component Composition

Loading diagram...

API Reference

Select

The root component that manages open/closed state, value state, and provides context.

PropTypeDefaultDescription
valuestring--Controlled selected value
defaultValuestring--Initial value (uncontrolled)
onValueChange(value: string) => void--Callback fired when the selected value changes
openboolean--Controlled open state
defaultOpenbooleanfalseInitial open state (uncontrolled)
onOpenChange(open: boolean) => void--Callback fired when dropdown open state changes
dir'ltr' | 'rtl'--Text direction. Resolved by primitives useDirection (dir prop -> DirectionProvider -> 'ltr').
namestring--Name attribute for native form submission
disabledboolean--Disables the entire select
requiredboolean--Marks the select as required for form validation
formstring--Associates the select with a form element by ID
autoCompletestring--Hint for browser autofill

SelectTrigger

Button that toggles the dropdown. Renders a styled <button> with a chevron icon.

PropTypeDefaultDescription
classNamestring--Additional CSS class names
disabledboolean--Disables the trigger

Sets role="combobox", aria-expanded, aria-controls, aria-autocomplete="none", and data-state automatically.

SelectValue

Renders the selected value text, or a placeholder when nothing is selected.

PropTypeDefaultDescription
placeholderReact.ReactNode''Text shown when no value is selected

SelectContent

The dropdown content area. Handles positioning, focus management, keyboard navigation, and dismiss behavior.

PropTypeDefaultDescription
position'item-aligned' | 'popper''popper'Positioning strategy. item-aligned aligns selected item with trigger. popper uses floating positioning.
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side (popper position only)
sideOffsetnumber--Offset from trigger on the main axis
align'start' | 'center' | 'end''start'Alignment on the cross axis
alignOffsetnumber--Offset on the cross axis
avoidCollisionsbooleantrueWhether to flip to avoid viewport overflow
collisionPaddingnumber10Padding from viewport edges
classNamestring--Additional CSS class names

Exposes data-state="open" / data-state="closed" and data-side for CSS animation.

SelectGroup

Groups related items together. Renders a <div> with role="group".

PropTypeDefaultDescription
classNamestring--Additional CSS class names

SelectLabel

Label for a SelectGroup. Renders a <div> linked to its group via aria-labelledby.

PropTypeDefaultDescription
classNamestring--Additional CSS class names

SelectItem

An individual selectable item. Renders a <div> with role="option".

PropTypeDefaultDescription
valuestring(required)The value representing this item. Must not be empty string.
disabledbooleanfalseWhether the item is disabled
textValuestring--Optional text override for typeahead search
classNamestring--Additional CSS class names

Exposes data-state="checked" / data-state="unchecked", data-highlighted, and data-disabled.

SelectSeparator

Visual separator between items. Renders a styled <div>.

PropTypeDefaultDescription
classNamestring--Additional CSS class names

SelectScrollUpButton / SelectScrollDownButton

Scroll navigation buttons that appear when content overflows the viewport.

PropTypeDefaultDescription
classNamestring--Additional CSS class names

RTL Support

Set dir="rtl" on Select for a local override, or set DirectionProvider once at app/root level for global direction.