Select
Listbox select that unfolds from its trigger with staggered options, full keyboard support and type-ahead.
- Category: Inputs
- Licence: Free, MIT
- Built with: React 19, Tailwind CSS 4, Motion
- Dependencies: motion, clsx, tailwind-merge
Examples
Select
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
options | { value: string; label: string; icon?: ReactNode }[] | — | |
value | string | — | Controlled value. |
defaultValue | string | — | Initial value when uncontrolled. |
onValueChange | (value: string) => void | — | |
placeholder | string | "Select…" | |
label | string | — | |
disabled | boolean | — |
About Select
Select is a listbox dropdown that unfolds from its trigger with options staggering in, and it behaves like a native select: arrow keys move, Enter picks, Escape closes, and typing a letter jumps to the first match.
Select is an input component for React 19, styled with Tailwind CSS 4 and animated with Motion. It drops into Next.js, Vite, Remix or Astro through the shadcn CLI as a single file you own.
When to use Select
- Form fields with a fixed list of choices.
- Country, language or timezone pickers.
- Sort and filter dropdowns.
- Settings with more options than a segmented control can hold.
How it works
It implements the listbox pattern with aria-activedescendant, so focus stays on the trigger while the highlight moves. The panel animates from the trigger's position, and type-ahead collects keystrokes for half a second to match multi-letter prefixes.
It is a real form control: it has an accessible name, works with the keyboard alone, shows a visible focus ring and announces its state to screen readers. With prefers-reduced-motion on, it holds still or settles instantly instead of animating.
Customizing Select
Every prop is documented in the API reference above with its type and default. The ones you will reach for first are listed here.
The Customize panel next to the preview lets you change label, placeholder, disabled live, and the Code tab updates to match, so the snippet you copy already carries your values.
- options.
- value (string): Controlled value.
- defaultValue (string): Initial value when uncontrolled.
- placeholder (string, default "Select…").
- label (string).
- disabled (boolean).
Goes well with Select
Select is already composed into 2 ready-made sections, so you can see it in context or install the whole block.
- Pricing Enterprise: Pricing section
- Product Grid: Commerce section
- Range Slider: Six animated React range sliders on one accessible core: inline, tick, fluid, wave, bubble and ruler
- Button: An animated React button with six variants, spring press feedback and a width-stable loading state
- Switch: An animated React toggle switch whose thumb stretches when pressed, like a real switch
- Checkbox: An animated React checkbox: the check draws itself in, the box pops, indeterminate morphs to a dash
- Radio Group: An animated React radio group with roving focus and a highlight that glides between card options
Install Select
npx shadcn@latest add https://charcoalui.com/r/select.jsonSelect is free and MIT licensed. The command copies select.tsx into components/ui and installs clsx, tailwind-merge; you can also copy the source from the Code tab by hand.
It pairs well with Morph Menu, a Pro piece: A button that stretches into its own menu surface, then shrinks back. Arrow keys and Escape work.
Frequently asked questions
- How do I install Select?
- Run npx shadcn@latest add https://charcoalui.com/r/select.json. The shadcn CLI copies select.tsx into components/ui and installs motion, clsx, tailwind-merge. You can also copy the source from this page by hand.
- Is Select free for commercial use?
- Yes. Select is MIT licensed: use it in any personal or commercial project and change it however you like.
- Does Select work with Next.js?
- Yes. It is a client component for React 19 styled with Tailwind CSS 4, so it works in the Next.js App Router and Pages Router, Vite, Remix and Astro.
- Can an AI coding agent install Select?
- Yes. Connect the Charcoal UI MCP server (https://charcoalui.com/mcp) to Claude Code, Cursor or any MCP client; get_component returns Select's props and source and get_install_command returns the exact command.