RRezi UI

Select

Input-styled select with an overlay list and the check at the end, built on Radix Select.

The trigger looks like Input, so selects and inputs read as one set in a form. The list opens below it on the same surface as the Dropdown Menu, with the check at the end so option text lines up with the value in the trigger.

Installation

npx shadcn@latest add @reziui/select

Usage

app/page.tsx
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";

export function Example() {
  return (
    <div className="grid gap-1.5">
      <Label htmlFor="framework">Framework</Label>
      <Select>
        <SelectTrigger id="framework">
          <SelectValue placeholder="Select a framework" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="next">Next.js</SelectItem>
          <SelectItem value="astro">Astro</SelectItem>
        </SelectContent>
      </Select>
    </div>
  );
}

Examples

Invalid and disabled

Choose a region to continue.

aria-invalid on the trigger switches its ring to the destructive color; connect the message with aria-describedby.

Keyboard

KeyAction
Enter Space ↓Open the list.
↑ ↓Move between options, skipping disabled ones.
TypingJump to the option starting with those letters.
EnterChoose the highlighted option and close.
EscClose without changing the value.

API reference

ComponentNotes
SelectRadix Select.Root: value, defaultValue, onValueChange, disabled, name, required.
SelectTrigger36px, full width; pass a width class to size it. Takes id for a Label.
SelectValueplaceholder, shown muted until a value is chosen.
SelectContentOpens below the trigger (position="popper"), at least as wide; position="item-aligned" lays it over the trigger instead.
SelectItemvalue, disabled.
SelectGroup · SelectLabel · SelectSeparatorStructure.