Form controls

Select
v0.7.2
Documentation Under Review

A dropdown component for selecting options from a list, built on Radix UI Select with Catalyst design tokens and CVA size variants. Supports Single Select (one option) and Multi-Select (multiple options via checkboxes and tags) patterns.

Prefer AI-assisted development?

This documentation is available via the Catalyst MCP Server. Learn how to connect →

Catalyst Select wraps Radix UI's Select primitive with built-in design tokens, CVA size variants (sm / md / lg), a danger state for validation feedback, and compound sub-components — giving you a fully accessible, production-ready dropdown with zero configuration.

Select supports two usage patterns:

  • Single Select — choose exactly one option from a list. The base Select primitive (SelectRoot, SelectTrigger, SelectValue, SelectItem, etc.) handles this out of the box.
  • Multi-Select — choose multiple options from a list. This is a composed pattern built on top of the Select primitive, combining SelectItem with checkboxes and tags to display and manage the selected values (see Multi-Select Default below).
Preview

Installation

npm install @pmi/catalyst-select
import {
  SelectRoot,
  SelectTrigger,
  SelectValue,
  SelectIcon,
  SelectContent,
  SelectViewport,
  SelectItem,
  SelectItemText,
  SelectItemIndicator,
  SelectLabel,
  SelectGroup,
  SelectSeparator,
  SelectScrollUpButton,
  SelectScrollDownButton,
  SelectPortal,
} from '@pmi/catalyst-select';

Variants

Danger

Apply the danger prop to SelectRoot to signal a validation error. The trigger, icon, and all items inherit the error color scheme.

Preview

Disabled

Apply the disabled prop to SelectRoot to prevent interaction. The trigger and icon reflect the disabled visual state.

Preview

Sizes

A single size prop on SelectRoot controls the height, padding, and typography of the trigger and all items simultaneously.

Preview

Common Patterns

With Label and Sub-Text

Pair the select with Label and SubText to build an accessible form field with helper text.

Preview
Sub-text here.

Scrollable Content

Use SelectScrollUpButton and SelectScrollDownButton around SelectViewport to add scroll affordance buttons when the option list overflows the available height.

Preview

Text Wrap

Add className="whitespace-normal" to SelectItemText to allow long option labels to wrap across multiple lines instead of truncating.

Preview

Multi-Select Default

A multi-select built on top of the Select primitive using checkboxes and tags to display selected items.

Preview

Multi-Select with Label

Multi-select composed with Label and SubText for an accessible form field.

Preview
Sub-text here.

Multi-Select with Avatars

Combine the select with Checkbox and Avatar to build a multi-select pattern for team-member assignment.

Preview

Multi-Select with Country Flags

Use flag icons inside select items for language or region selection.

Preview

API Reference

Select is a compound component built on Radix UI Select. The sections below summarize the API surface for each sub-component.

SelectRoot

The root container that manages open/closed state, controlled value, and propagates size, danger, and disabled to all sub-components via context.

Prop

Type

SelectTrigger

The button that opens the Select dropdown. Inherits danger and disabled from SelectRoot context.

Prop

Type

Accepts all standard Radix Select Trigger props and forwards ref to the underlying element.

SelectContent

The dropdown container. Controls positioning via position, side, sideOffset, and align.

Prop

Type

SelectItem

An individual selectable option inside SelectViewport. Inherits danger from SelectRoot context.

Prop

Type

SelectPortal

Portals dropdown content into document.body to prevent clipping from overflow: hidden ancestors.

Accepts all standard Radix Select Portal props. Pass className (e.g. z-[60]) when rendering inside Sheet or Dialog to override the stacking context.

SelectIcon

Wrapper for the chevron or custom icon inside SelectTrigger. Inherits danger and disabled color tokens from context.

Accepts all standard Radix Select Icon props plus unstyled.

SelectValue

Displays the current selected value or the placeholder. Accepts all standard Radix Select Value props.

SelectViewport

Scroll container for the option list. Accepts all standard Radix Select Viewport props plus unstyled.

SelectLabel

Group label rendered above a SelectGroup. Accepts all standard Radix Select Label props plus unstyled.

SelectGroup

Logical group for related options. Accepts all standard Radix Select Group props.

SelectSeparator

Visual divider between option groups. Accepts all standard Radix Select Separator props plus unstyled.

SelectItemText

The visible label for a SelectItem. Accepts all standard Radix Select ItemText props.

SelectItemIndicator

Rendered inside a SelectItem when that item is selected. Accepts all standard Radix Select ItemIndicator props plus unstyled.

SelectScrollUpButton

Scroll affordance button shown at the top of the dropdown when options overflow. Accepts all standard Radix Select ScrollUpButton props plus unstyled.

SelectScrollDownButton

Scroll affordance button shown at the bottom of the dropdown when options overflow. Accepts all standard Radix Select ScrollDownButton props plus unstyled.

Accessibility

Select is designed to meet WCAG 2.2 AA standards.

Keyboard Interactions

KeyAction
Space / Enter / Arrow DownOpens the dropdown
Arrow Down / Arrow UpNavigates between options when open
Home / EndJumps to the first or last option
EscapeCloses the dropdown and returns focus to the trigger
Tab / Shift+TabCloses the dropdown and moves focus to the next/previous focusable element
Printable characterTypeahead: jumps to the first option matching the typed character

ARIA

  • Radix UI provides the underlying role="listbox" / role="option" semantics, aria-expanded, aria-selected, and aria-disabled attributes automatically.
  • Catalyst adds the visual styling (focus rings, danger tokens, disabled opacity) on top of Radix's accessible foundation.
  • Consumer responsibility: always pair SelectTrigger with a visible Label connected via htmlFor / id so screen readers announce the field purpose. Use SelectValue's aria-label prop when building custom multi-select triggers whose visual display differs from the underlying value string.

See the Radix Select accessibility docs for full baseline behavior.

Choosing the Right Component

Use Select when users must choose exactly one option from a list of four or more items. Reach for a different primitive when:

If you need…Use instead
Searchable or filterable optionsCombobox
Multiple selections with checkboxesCombobox Multi
Mutually exclusive choices with all options always visible (3 or fewer)Radio Group
Yes / No or On / Off toggleCheckbox

On this page