Select
A compact choice field with a keyboard friendly menu.
fieldform
Preview
Select preview
Live · keyboard ready
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
Live · keyboard ready
Delivered Monday morning.
report-schedule-a-native-feeling-select-with-a-disabled-option-and-helper-text-.tsxtsx
"use client";
import { useState } from "react";
import { Select } from "@/components/manicat/select/select";
const frequencies = [
{ value: "daily", label: "Daily" },
{ value: "weekly", label: "Weekly" },
{ value: "monthly", label: "Monthly" },
{ value: "never", label: "Never", disabled: true },
];
export function SelectScheduleExample() {
const [frequency, setFrequency] = useState("weekly");
return (
<div className="grid w-full max-w-xs gap-2">
<Select label="Send usage report" options={frequencies} value={frequency} onValueChange={setFrequency} description="Delivered Monday morning." />
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Enter / Space / ArrowDown | Opens the list from the trigger. |
| ArrowUp / ArrowDown | Moves between enabled items. |
| Enter / Space | Selects the highlighted item and closes. |
| Escape | Closes without changing the value. |
| Type a letter | Jumps 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.