Select

A dropdown component that allows users to choose from a list of options.

Overview

The Select component provides a dropdown interface for choosing from a list of options, with support for grouping, clearing, custom indicators, and advanced rendering. Built on Base UI primitives, it offers full keyboard navigation and accessibility features out of the box.

Usage

import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
  SelectGroup,
  SelectLabel,
  SelectSeparator,
  SelectClear,
  SelectIndicator,
} from "@tilt-legal/cubitt-components/primitives";
// Basic select
const fruitItems = [
  { label: "Apple", value: "apple" },
  { label: "Banana", value: "banana" },
  { label: "Cherry", value: "cherry" },
];

<Select items={fruitItems}>
  <SelectTrigger>
    <SelectValue placeholder="Select a fruit" />
  </SelectTrigger>
  <SelectContent>
    {fruitItems.map((item) => (
      <SelectItem key={item.value} value={item.value}>
        {item.label}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

Pass items whenever you rely on the default <SelectValue /> output. Without that label map, the trigger can only fall back to raw values.

Examples

Indicator Position

Move the selection indicator to the left side.

With Clear Button

Add a clear button to reset the selection.

With Groups

Organize related options into labeled groups with separators.

Destructive Item

Use the destructive variant when one option represents a dangerous choice inside an otherwise standard select list.

Multiple Selection

Enable multi-select mode. Labels are automatically rendered from the items prop.

Size Variants

The select trigger supports three size variants: sm, md (default), and lg.

Disabled States

Disable the entire select or specific items.

With Status Indicators

Display items with colored status dots.

With Icons

Display items with custom icons.

With Descriptions

Display items with labels and descriptions, plus custom indicators.

With Avatars

Display items with user avatars.

With Badges

Display items as badge components for statuses.

Scrollable Content

Handle long lists with scrollable content.

URL State (Single Select)

Sync a single selection with the URL. Try selecting a category and refreshing the page.

URL State (Multi-Select)

Sync multiple selections with the URL using comma-separated values.

API Reference

Select

The root component that provides context for all child components.

PropTypeDefaultDescription
items{ label: ReactNode, value: string }[]Label/value pairs used by the trigger display. Pass this whenever you want the default SelectValue to render labels instead of raw values.
valuestring | string[] | nullThe controlled value of the select.
defaultValuestring | string[] | nullThe default value when uncontrolled.
onValueChange(value: string | string[] | null) => voidCallback when the selection changes.
multiplebooleanfalseEnable multi-select mode. When true, value/defaultValue should be arrays.
disabledbooleanfalseDisable the select component.
readOnlybooleanfalseMake the select read-only (user cannot change selection).
openbooleanControl the open state of the dropdown.
defaultOpenbooleanfalseThe default open state when uncontrolled.
onOpenChange(open: boolean) => voidCallback when the open state changes.
namestringThe name for form submission.
requiredbooleanfalseWhether the select is required in forms.
indicatorPosition"left" | "right""right"Position of the selection indicator within items.
indicatorVisibilitybooleantrueWhether to show the selection indicator.
indicatorReactNodeCustom indicator component to replace the default checkmark.
iconReactNodeCustom icon for the trigger button (replaces default chevron).
invalidbooleanfalseApplies invalid styling and sets aria-invalid on the trigger.
aria-invalidAriaAttributes['aria-invalid']Forwarded to the trigger; values true, "grammar", or "spelling" are treated as invalid.
aria-describedbystringForwarded to the trigger (useful for error message ids).
classNamestringAdditional CSS classes for the select root.

URL State Props

When provided with a paramName, the select will sync its value with URL parameters via TanStack Router search params.

PropTypeDefaultDescription
paramNamestringURL parameter name for syncing state with URL. Enables URL state management.
onUrlValueChange(value: string | string[] | null) => voidCallback when URL parameter value changes.
paramClearOnDefaultbooleantrueRemove URL param when value equals default.
paramThrottlenumberThrottle URL updates in milliseconds.
paramDebouncenumberDebounce URL updates in milliseconds.

SelectTrigger

The button that toggles the select dropdown.

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"The size variant of the trigger.
classNamestringAdditional CSS classes for the trigger.
idstringID for linking with labels.

SelectValue

Displays the selected value or placeholder text. When the items prop is provided on the Select root, labels are automatically rendered. For complex displays (icons, avatars, badges), provide a render function as children.

PropTypeDefaultDescription
placeholderstringText to display when no value is selected.
classNamestringAdditional CSS classes for the value.
childrenReactNode | ((value: string | string[] | null) => ReactNode)Custom render function for complex displays. Receives the current value and should return React elements.

SelectContent

The dropdown panel that contains the select options.

PropTypeDescription
classNamestringAdditional CSS classes for the content.

SelectItem

An individual option within the select dropdown.

PropTypeDescription
valuestringThe value this item represents.
disabledbooleanWhether the item is disabled.
classNamestringAdditional CSS classes for the item.

SelectGroup

Groups related select items together.

PropTypeDescription
classNamestringAdditional CSS classes for the group.

SelectLabel

A label for a group of select items.

PropTypeDescription
classNamestringAdditional CSS classes for the label.

SelectSeparator

A visual separator between groups or items.

PropTypeDescription
classNamestringAdditional CSS classes for the separator.

SelectClear

A button to clear the current selection. Must be positioned within the trigger.

PropTypeDescription
onClick() => voidHandler for clearing the selection.
classNamestringAdditional CSS classes for the clear button.

SelectIndicator

Custom indicator component to replace the default checkmark.

PropTypeDescription
classNamestringAdditional CSS classes for the indicator.
childrenReactNodeCustom indicator content.

On this page