# Select

> A choice from a list that is never the browser's dropdown: the pill grows into its list and folds back as the label morphs.

Native selects ignore the theme and look different on every system; most custom ones pop a panel over the trigger. Here the pill itself grows into the list from the edge it lines up with, opens upward when there is no room, and folds back as its label morphs to the choice. It lives in a portal, so no card or scroller clips it.

## Install

```bash
npx shadcn@latest add https://hairlineui.com/r/select.json
```

Needs React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.

- npm: none
- Hairline UI components it needs (the CLI installs them too): `text-morph`
- Docs and live preview: https://hairlineui.com/ui/select
- Registry item (source): https://hairlineui.com/r/select.json

## Usage

```tsx
import { Select } from "@/components/ui/select";

<Select label="Timezone" defaultValue="europe-london" options={[
  { value: "europe-london", label: "London" },
  { value: "america-new-york", label: "New York" },
]} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` | `{ value, label, description? }[]` | – | The list. |
| `value / defaultValue` | `string \| null` | – | Chosen value. |
| `onValueChange` | `(value: string) => void` | – | Called on choice. |
| `label` | `string` | – | Shown above; accessible name. |
| `hideLabel` | `boolean` | `false` | Keep the name, hide the text. |
| `hint / error` | `ReactNode` | – | As in Input. |
| `placeholder / align / width / mono` | `…` | – | Passed to the pill. |

## States

- **closed**: A pill with the chosen label and a chevron.
- **open**: The pill grows into its list (420ms, size and corners), upward if there is no room.
- **pick**: The list folds back and the label morphs; the chosen option carries a drawn check.

## What it handles

A styled select has to handle typeahead, scrolling lists, collision with the viewport and clipping parents. This one does all four.

- **One surface**: The pill grows into the list and folds back; nothing pops over it.
- **Typeahead**: Typing a few letters finds an option; arrows glide a highlight.
- **Never clipped**: A portal on the body that carries the theme tokens with it.
- **Field like the rest**: Label, hint and error from field.tsx.

## Replaces

Radix Select, native <select>, portal and collision logic

## Where it fits

- **Forms**: Country, role or timezone with a label and hint.
- **Table toolbars**: Sort by and rows per page.
- **Settings**: Language and theme choices.
- **Mapping screens**: Picking a field for each column.

## Notes

- Escape folds it back; scrolling the page closes it.
- Reduced motion: it opens and closes in place.

License: MIT (https://hairlineui.com/license#components)
