Forms

Select

Dropdown selection menu. Wraps Radix Select with tokenised styling.

Preview
01 Installation

Install

Pull Select from the barrel for everyday use, or the granular path when you want a tighter bundle.

tsxBarrel1 line
import { Select } from "@brika/clay";
tsxGranular1 line
import { Select } from "@brika/clay/components/select";
02 Usage

A minimal example

Drop this into a page. Native HTML attributes pass through to the underlying primitive.

tsxSelect.tsx27 lines
'use client';

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@brika/clay/components/select';
/** Basic single-value select for picking a timezone. */
export default function SelectDefaultDemo() {
  return (
    <Select>
      <SelectTrigger className="w-56">
        <SelectValue placeholder="Select a timezone" />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="utc">UTC</SelectItem>
        <SelectItem value="america-new_york">America / New York</SelectItem>
        <SelectItem value="america-los_angeles">America / Los Angeles</SelectItem>
        <SelectItem value="europe-london">Europe / London</SelectItem>
        <SelectItem value="europe-paris">Europe / Paris</SelectItem>
        <SelectItem value="asia-tokyo">Asia / Tokyo</SelectItem>
      </SelectContent>
    </Select>
  );
}
03 Examples

Select, every way

Controlled

Controlled select with an external state readout.

Disabled

The entire select is disabled, no interaction possible.

Disabled Option

A single option marked disabled, users can see it but not select it.

Grouped

Options grouped by region using SelectGroup and SelectLabel.

04 Accessibility

Accessibility

  • Trigger carries role="combobox" and aria-expanded, no extra markup needed.
  • Arrow keys navigate options; Home/End jump to first/last; typing ahead filters.
  • Selected item receives aria-selected="true" and a visible check mark.
  • Disabled items carry aria-disabled="true" and are skipped by arrow navigation.
05 Tokens 24 theme-overridable

Theme tokens

Every CSS variable Select reads, with its default and the dotted path you'd write in a ThemeConfig JSON to override it. Set any of these in your theme to retune Select without touching component code.

Select tokens

24 tokens
ColorFill, border, and text colors.9
  • --select-trigger-containercolorvar(--input-container)
    components.select.triggerContainer

    Background of the select trigger in its resting state.

  • --select-trigger-labelcolorvar(--input-label)
    components.select.triggerLabel

    Foreground color of the selected value rendered inside the trigger.

  • --select-trigger-bordercolorvar(--input-border)
    components.select.triggerBorder

    Border color of the select trigger in its resting state.

  • --select-trigger-placeholdercolorvar(--input-placeholder)
    components.select.triggerPlaceholder

    Foreground color of the placeholder shown when no value is selected.

  • --select-trigger-hover-containercolorvar(--accent)
    components.select.triggerHoverContainer

    Background color of the select trigger on hover (dark theme only by default).

  • --select-trigger-icon-colorcolorvar(--muted-foreground)
    components.select.triggerIconColor

    Default color of inline SVG icons inside the trigger (chevron, leading icon).

  • --select-focus-ringcolorvar(--ring)
    components.select.focusRing

    Color of the focus ring drawn around the trigger when focus-visible.

  • --select-invalid-ringcolorvar(--destructive)
    components.select.invalidRing

    Single color driving the invalid state: border uses it directly, ring uses it at 20% (light) / 40% (dark) opacity.

  • --select-label-colorcolorvar(--muted-foreground)
    components.select.labelColor

    Foreground color of the SelectLabel section header inside the listbox.

GeometrySizes, lengths, and corner radii.5
  • --select-radiusradiusvar(--radius-control)
    components.select.radius

    Select trigger corner radius.

  • --select-heightsize2.25rem
    components.select.height

    Default select height.

  • --select-padding-xsizecalc(var(--spacing) * 3)
    components.select.paddingX

    Inline padding inside the select.

  • --select-padding-ysizecalc(var(--spacing) * 2)
    components.select.paddingY

    Block padding inside the select.

  • --select-gapsizecalc(var(--spacing) * 2)
    components.select.gap

    Gap between adjacent children inside the select.

BorderBorder width and style.2
  • --select-border-widthborder-width1px
    components.select.borderWidth

    Border width on the select. Set non-zero for outline-style variants.

  • --select-border-styleborder-stylesolid
    components.select.borderStyle

    Border style on the select (`solid`, `dashed`, `double`, `none`).

TypographyTypeface, size, weight, spacing.6
  • --select-font-familyfont-familyvar(--font-sans)
    components.select.fontFamily

    Typeface for select.

  • --select-font-sizefont-sizevar(--text-body-md)
    components.select.fontSize

    Font size for select.

  • --select-font-weightfont-weight500
    components.select.fontWeight

    Font weight for select.

  • --select-line-heightline-height1.25
    components.select.lineHeight

    Line height for select.

  • --select-letter-spacingletter-spacing0
    components.select.letterSpacing

    Letter spacing for select. Useful for caps labels.

  • --select-text-transformtext-transformnone
    components.select.textTransform

    Text transform for select (`uppercase`, `lowercase`, `capitalize`, `none`).

MotionAnimation duration and easing.2
  • --select-durationdurationvar(--motion-standard-duration)
    components.select.duration

    Transition duration for select state changes.

  • --select-easingeasingvar(--motion-standard-easing)
    components.select.easing

    Transition easing for select state changes.

Override in a theme

Authoring a theme is plain JSON. Drop overrides under components.select, the names are camelCase versions of the variable suffix.

jsonmy-theme.json12 lines
{
  "id": "my-theme",
  "name": "My Theme",
  "description": "...",
  "accentSwatches": ["#000"],

  "components": {
    "select": {
      "paddingX": "calc(var(--spacing) * 3)"
    }
  }
}

Then apply with applyTheme(myTheme) (see the theming guide), scope it to a subtree with themeToCssVars(myTheme, mode), or consume any token directly in your own JSX with the matching Tailwind utility (e.g. bg-select-…) — see the chips on each token row.

06 API reference

API reference

Props specific to Select. Native HTML attributes pass through to the underlying primitive, see the component source on GitHub for the full type signature.

<Select />

3 props
  • string
    Initial selected value for uncontrolled mode.
  • (value: string) => void
    Called with the next value whenever the user selects an option.
  • string
    Controlled selected value; pair with onValueChange.

<SelectContent />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectGroup />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectItem />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectLabel />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectScrollDownButton />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectScrollUpButton />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectSeparator />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<SelectTrigger />

1 prop
  • sizedefault 'default'
    'sm' | 'default'
    Trigger size preset.

<SelectValue />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.