Select

Opens a list and returns the single option the user picks.

import { Select } from "@usefragments/ui";Source

Preview

<Field>
  <Field.Label>Team</Field.Label>
  <Select placeholder="Choose a team">
    <Select.Trigger />
    <Select.Content>
      <Select.Item value="design">Design</Select.Item>

Usage

Use when

  • Picking one value from a known list
  • More than 4-5 options — radios would crowd the form
  • Tight forms where the list should stay collapsed

Avoid when

  • Two or three options (use RadioGroup)
  • Users may type their own value (use Combobox)
  • Multiple selections (use a Checkbox group)
  • Actions rather than values (use Menu)

Implementation notes

  • Placeholder names the decision, e.g. "Choose a team"
  • Wrap in a Field: Field.Label names it, Field.Description guides, Field.Error gives the reason
  • Set invalid with a Field.Error; colour is never the only signal
  • Group related options with Select.Group
  • Keep option text short
  • Order options predictably: alphabetical, by frequency, or by category

Do not use Select for a list of actions.

Don’t

<Select>Delete</Select>

Do

<Field>
  <Field.Label>Team</Field.Label>
  <Select options={[{ value: "design", label: "Design" }]} />
</Field>

Installation

pnpm add @usefragments/ui

Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Anatomy

Import Select once, then compose its parts with dot notation.

  • Select.Trigger
  • Select.Content
  • Select.Item
  • Select.Group
  • Select.GroupLabel

A Field label, a placeholder, three options.

<Field>
  <Field.Label>Team</Field.Label>
  <Select placeholder="Choose a team">
    <Select.Trigger />
    <Select.Content>
      <Select.Item value="design">Design</Select.Item>
      <Select.Item value="engineering">Engineering</Select.Item>
      <Select.Item value="product">Product</Select.Item>
    </Select.Content>
  </Select>
</Field>

Examples

With Groups

Headed sections separate related options.

<Select placeholder="Choose a country">
  <Select.Trigger />
  <Select.Content>
    <Select.Group>
      <Select.GroupLabel>Americas</Select.GroupLabel>
      <Select.Item value="us">United States</Select.Item>

With Label and Helper Text

A Field description explains what the choice affects.

<Field>
  <Field.Label>Timezone</Field.Label>
  <Select>
    <Select.Trigger placeholder="Select a timezone" />
    <Select.Content>
      <Select.Item value="pt">Pacific Time</Select.Item>

Error State

The danger edge, with the reason in a Field.Error beside an icon.

<Field invalid>
  <Field.Label>Team</Field.Label>
  <Select placeholder="Choose a team" invalid>
    <Select.Trigger />
    <Select.Content>
      <Select.Item value="design">Design</Select.Item>

With Disabled Options

Unavailable options stay visible but cannot be picked.

<Select placeholder="Select a plan">
  <Select.Trigger />
  <Select.Content>
    <Select.Item value="free">Free</Select.Item>
    <Select.Item value="pro">Pro</Select.Item>
    <Select.Item value="enterprise" disabled>

Scrollable List

Caps at four rows and half-shows the fifth as a scroll hint.

<Select placeholder="Select a timezone">
  <Select.Trigger />
  <Select.Content maxVisibleItems={4}>
    <Select.Item value="utc-8">Pacific Time (UTC-8)</Select.Item>
    <Select.Item value="utc-7">Mountain Time (UTC-7)</Select.Item>
    <Select.Item value="utc-6">Central Time (UTC-6)</Select.Item>

Custom Max Visible Items

maxVisibleItems raises the cap to six rows.

<Select placeholder="Select a color">
  <Select.Trigger />
  <Select.Content maxVisibleItems={6}>
    <Select.Item value="red">Red</Select.Item>
    <Select.Item value="orange">Orange</Select.Item>
    <Select.Item value="yellow">Yellow</Select.Item>

Read Only

A dashed edge and no caret: it opens to show the choices but cannot change.

<Select readOnly defaultValue="engineering">
  <Select.Trigger aria-label="Team" />
  <Select.Content>
    <Select.Item value="design">Design</Select.Item>
    <Select.Item value="engineering">Engineering</Select.Item>
  </Select.Content>

Disabled

Dimmed and cannot be opened.

<Select disabled placeholder="Select an option">
  <Select.Trigger />
  <Select.Content>
    <Select.Item value="one">Option 1</Select.Item>
  </Select.Content>
</Select>

Options Prop

The options array replaces hand-written Select.Item children.

<Select
  placeholder="Select a team"
  options={[
    { value: "engineering", label: "Engineering" },
    { value: "design", label: "Design" },
    { value: "product", label: "Product" },

Long Localized Option

The trigger grows to fit a long label instead of clipping it.

<Field>
  <Field.Label>Workspace region</Field.Label>
  <Select placeholder="Choose a workspace region">
    <Select.Trigger />
    <Select.Content>
      <Select.Item value="eu-central">

API reference

Component props
Prop
Type
Default
Description
autoCompletestring | undefinedNot setBrowser autofill hint for the hidden input
childrenReact.ReactNodeNot set—
Content.align"center" | "start" | "end" | undefinedcenterstartendNot set—
Content.childrenReact.ReactNodeNot setOmit to render the items the root's `options` prop describes.
Content.maxVisibleItemsnumber | undefinedNot setMaximum number of visible options before scrolling. Shows half of the next item as a scroll hint.
Content.sideOffsetnumber | undefinedNot set—
defaultOpenboolean | undefinedNot setDefault open state
defaultValuestring | undefinedNot setDefault value for uncontrolled usage
disabledboolean | undefinedNot setWhether the select is disabled
formstring | undefinedNot setID of the form that owns the hidden input
Group.childrenRequiredReact.ReactNodeNot set—
GroupLabel.childrenRequiredReact.ReactNodeNot set—
inputRefReact.Ref<HTMLInputElement> | undefinedNot setRef to the hidden input element
invalidboolean | undefinedfalseMarks the selection invalid: the danger edge and `aria-invalid` on the trigger. Say why in a Field.Error; inside a Field, its `invalid` does the same.
Item.childrenRequiredReact.ReactNodeNot set—
Item.disabledboolean | undefinedNot set—
Item.valueRequiredstringNot set—
namestring | undefinedNot setForm field name
onOpenChange((open: boolean) => void) | undefinedNot setCalled when open state changes
onValueChange((value: SelectValue | null) => void) | undefinedNot setCalled when the selection changes
openboolean | undefinedNot setControlled open state
optionsSelectOption[] | undefinedNot setConvenience API for simple selects (renders Select.Item entries when children are omitted)
placeholderstring | undefinedNot setPlaceholder text when no value is selected
readOnlyboolean | undefinedNot setWhether the user cannot choose a different option
requiredboolean | undefinedNot setWhether a selection is required
sizeSelectSize | undefinedxssmmdlg"md"Trigger height on the shared control track: 24, 28, 32 or 40.
Trigger.childrenReact.ReactNodeNot set—
Trigger.iconReact.ReactNodeNot setLeading adornment shown before the value — usually says what the choice is about, so the visible text can be the choice itself. Ignored when you pass your own `children`.
Trigger.placeholderstring | undefinedNot set—
valuestring | null | undefinedNot setControlled selected value

Accessibility

  • Full keyboard navigation
  • Type-ahead jumps to matching options
  • Trigger and list carry the right ARIA roles
  • MenualternativeUse Menu for action-based dropdowns
  • InputsiblingUse Input for free-form text entry
  • CheckboxalternativeUse Checkbox group for multiple selections

Next steps