---
title: "Select"
description: "An option list with built-in label, description and error. The popup is non-modal by default and Base UI handles the keyboard."
kind: component
id: C-009
registry: "select"
docs: "https://koten.codehive.com.co/components/select"
markdown: "https://koten.codehive.com.co/md/components/select.md"
install: "npx shadcn@latest add https://koten.codehive.com.co/r/select.json"
language: en
---

# Select · 選択

> Component C-009 in the Koten UI catalog.

An option list with built-in label, description and error. The popup is non-modal by default and Base UI handles the keyboard.

> Japanese labels in this page are documentation metadata. Keep the consumer UI in the product's language and do not add Japanese decoration unless the user asks (R-031).

## Install

Install `koten-theme` first when the project does not have Koten tokens yet. Use the runner of your project.

```bash
# Node
npx shadcn@latest add https://koten.codehive.com.co/r/select.json

# Bun
bunx shadcn@latest add https://koten.codehive.com.co/r/select.json
```

## Files

- `@/components/ui/select.tsx`
- `@/lib/koten/cn.ts`
- `@/lib/koten/format.ts`
- `@/lib/koten/intl.ts`
- `@/lib/koten/labels.ts`
- `@/lib/koten/provider.tsx`

## Reference

- Upstream primitive: https://base-ui.com/react/components/select

## Examples

### Options and states

Each item declares value, label and an optional disabled; description sits under the trigger.

```tsx
<Select
  label="Source warehouse"
  items={warehouses}
  defaultValue="tokyo"
  description="Stock and lead time come from this warehouse."
/>
<Select label="Locked warehouse" items={warehouses} defaultValue="osaka" disabled />
```

### Controlled selection

value and onValueChange let the choice be reflected outside the control.

```tsx
const [warehouse, setWarehouse] = useState<string | null>("tokyo");
const selected = warehouses.find((item) => item.value === warehouse)?.label;

<Select
  label="Source warehouse"
  items={warehouses}
  value={warehouse ?? undefined}
  onValueChange={setWarehouse}
  description="Stock and lead time come from this warehouse."
/>
<p className="text-2xs text-muted">
  Selected: <span className="font-semibold text-ink">{selected ?? "none"}</span>
</p>
```

### Use inside a form

A minimal form: the field requires an active warehouse, shows help and error in their own slots, and ends with a submit button.

```tsx
<form
  className="grid w-full max-w-sm gap-[var(--koten-gap)]"
  onSubmit={(event) => event.preventDefault()}
>
  <Select
    label="Source warehouse"
    items={warehouses}
    placeholder="Select a warehouse…"
    required
    description="Lead time and shipping cost are calculated from this warehouse."
    error="Choose an active warehouse before saving."
  />
  <div className="flex justify-end">
    <Button type="submit" variant="primary">Save order</Button>
  </div>
</form>
```

## Props

| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `label` | `string` | `—` | Visible label and accessible name of the trigger; required. |
| `items` | `readonly SelectItem[]` | `—` | Each item declares value, label and an optional disabled. |
| `value / defaultValue` | `string` | `—` | Controlled or uncontrolled; without a value the placeholder shows. |
| `onValueChange` | `(value: string \| null) => void` | `—` | Returns the chosen value, or null when the selection is cleared. |
| `placeholder` | `string` | `Seleccionar…` | Trigger text shown when nothing is selected. |
| `description / error` | `string` | `—` | description is wired through aria-describedby; error adds aria-invalid and role=alert. |
| `modal` | `boolean` | `false` | When true it locks scroll and interaction outside the popup; Koten defaults to false. |
| `disabled / required` | `boolean` | `false` | disabled blocks the control; required adds the asterisk and aria-required. |

## Accessibility

- The trigger takes its accessible name from label; the popup is announced as a listbox and each option as an option.
- Arrow keys move the focus, Enter or Space selects, and Escape closes without submitting the form.
- description and error are wired through aria-describedby; the error is announced with role=alert.

## Sources

- Catalog page: https://koten.codehive.com.co/components/select
- Markdown: https://koten.codehive.com.co/md/components/select.md
- Repository: https://github.com/codehive-colombia/koten
