Reference index

Components

Select

Select on Base UI: ink trigger, paper popup with a 1px rule, ink check on the chosen item; no shadow or radius.

Preview

Install

bash

npx shadcn add @eloquent/select

Usage

tsx

import {
  Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue,
} from "@/components/ui/select";

const sections = [
  { label: "World", value: "world" },
  { label: "Business", value: "business" },
];

<Select items={sections} defaultValue="business">
  <SelectTrigger aria-label="Section">
    <SelectValue placeholder="Choose a section" />
  </SelectTrigger>
  <SelectContent>
    <SelectGroup>
      <SelectLabel>Sections</SelectLabel>
      {sections.map((s) => <SelectItem key={s.value} value={s.value}>{s.label}</SelectItem>)}
    </SelectGroup>
  </SelectContent>
</Select>

Pass items to Select so the trigger shows the chosen label before the popup has opened. Give the trigger a name with aria-label, aria-labelledby or a Field.

States

Placeholder
Disabled
Choose an edition to continue.
StateTreatment
Default1px ink border, paper fill, ink chevron, 44px high; the placeholder is halftone
Press, opentint-1 fill. No hover effect
Focus2px ink outline, 2px offset
Invalid2px ink underline, with FieldError giving the ink icon and message
DisabledHalftone text and border, cursor-not-allowed
Item highlightedInk fill, paper text (it follows the keyboard and the pointer)
Item selectedInk check at the start of the row
Item disabledHalftone text, cursor-not-allowed

Keyboard

KeyAction
Tab / Shift+TabMove focus to and from the trigger (a disabled select is skipped)
Enter / Space / Arrow Down / Arrow UpOpen the popup
Arrow Up / DownMove the highlight
Home / EndHighlight the first or last item
LettersJump to the matching item (typeahead)
EnterChoose the highlighted item and close
EscClose without changing the value; focus returns to the trigger

Vietnamese

Ink adaptation

Upstream shadcn's radius, shadow, focus ring glow and muted hover fill are removed. The popup is paper with a 1px ink rule, and it opens below the trigger (alignItemWithTrigger is off by default, unlike Base UI). The trigger's size prop is dropped to keep a 44px hit target. Fades use opacity only and stop under prefers-reduced-motion. Built on Base UI Select.