Select

A compact choice field with a keyboard friendly menu.

fieldform
Preview
Select preview
We send it in your timezone.

When to use

  • A short fixed list where typing is not needed, such as region or sort order.
  • Form fields that should submit natively through Radix's hidden select via name.

When not to use

  • Use combobox for long or searchable lists.
  • Use multi-select when several values can be chosen.
  • Use segmented-control for two to four choices that should stay visible.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "type": "registry:ui",
  "title": "Select",
  "description": "A compact choice field with a keyboard friendly menu.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "@radix-ui/react-select",
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/select/select.tsx",
      "type": "registry:component",
      "target": "@components/manicat/select/select.tsx"
    },
    {
      "path": "registry/components/select/select.module.css",
      "type": "registry:component",
      "target": "@components/manicat/select/select.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/select",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/select",
    "markdown": "https://uiarc.dev/components/select/markdown",
    "tags": [
      "field",
      "form"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { useState } from "react";
import { Select } from "@/components/manicat/select/select";

const selectOptions = [
  { value: "daily", label: "Daily" },
  { value: "weekly", label: "Weekly" },
  { value: "monthly", label: "Monthly" },
  { value: "never", label: "Never", disabled: true },
];

export function SelectExample() {
  const [value, setValue] = useState("weekly");

  return <Select label="Report frequency" options={selectOptions} value={value} onValueChange={setValue} description="We send it in your timezone." />;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Report schedule A native-feeling select with a disabled option and helper text.

Report schedule A native-feeling select with a disabled option and helper text. preview
Delivered Monday morning.

Keyboard interactions

KeysAction
Enter / Space / ArrowDownOpens the list from the trigger.
ArrowUp / ArrowDownMoves between enabled items.
Enter / SpaceSelects the highlighted item and closes.
EscapeCloses without changing the value.
Type a letterJumps to the next item starting with it (Radix typeahead).

Accessibility

  • Built on Radix Select, so the trigger, listbox, and options get the right roles and focus handling.
  • The real value renders in a visually hidden Radix Value; the animated copy is aria-hidden.
  • Label is linked with htmlFor, and description through aria-describedby.

Motion

  • A later option rises in from below and an earlier one drops from above, with a soft blur.
  • Reduced motion swaps the value with an instant crossfade.

Responsive behavior

  • The menu matches the trigger width, caps at min(24rem, 100vw minus 20px), and at 320px or the available height, then scrolls.
  • Long labels ellipsize in the trigger instead of widening it.
  • The trigger never scales on press, so Radix measures a stable anchor on touch.

Performance

  • The menu renders in a Radix portal only while open; items are not virtualized, so keep the list short.
  • The translucent menu drops its backdrop blur under prefers-reduced-transparency.

Notes for AI

  • Pick for a short fixed list where typing is not needed. Use combobox for long or searchable lists, multi-select for several values, and segmented-control for two to four visible choices.
  • Controlled with value and onValueChange, or uncontrolled with defaultValue; pass name to submit with a form.