---
title: Select
description: Picks one value, or several, from a short fixed list.
---

```tsx
import { Select } from "@openperf/deft";

import { Preview } from "../../src/Preview";
import { OPTIONS } from "./data";

export default function SelectBasic() {
  return (
    <Preview overlay={true}>
      <Select.Root defaultValue="option-1" items={OPTIONS}>
        <Select.Trigger />
        <Select.Content>
          {OPTIONS.map((option) => (
            <Select.Item key={option.value} value={option.value}>
              {option.label}
            </Select.Item>
          ))}
        </Select.Content>
      </Select.Root>
    </Preview>
  );
}
```

- After selection, the trigger shows the current value. Before selection, use a specific `placeholder`, not a generic label like "Select…".
- Use [Combobox](/deft/components/combobox) for lists longer than ten items or lists that people need to search.
- Pass `multiple` to `Select.Root` for several values; a check marks the chosen ones.
- The trigger takes the variants and sizes of [Button](/deft/components/button). Inside a [List](/deft/components/list), use `variant="field"`.
- The list opens below the trigger, at least as wide as it, and scrolls when it runs out of room.

## Inline

```tsx
import { Select } from "@openperf/deft";

import { Preview } from "../../src/Preview";
import { OPTIONS } from "./data";

export default function SelectInline() {
  return (
    <Preview overlay={true}>
      <p>
        Text with{" "}
        <Select.Root defaultValue="option-1" items={OPTIONS}>
          <Select.Trigger size="inline" variant="ghost" />
          <Select.Content>
            {OPTIONS.map((option) => (
              <Select.Item key={option.value} value={option.value}>
                {option.label}
              </Select.Item>
            ))}
          </Select.Content>
        </Select.Root>{" "}
        in a sentence.
      </p>
    </Preview>
  );
}
```

`size="inline"` with `variant="ghost"` sits inside a line of text and follows its size.

## With pictures

```tsx
import { Select } from "@openperf/deft";
import { useState } from "react";

import { Preview } from "../../src/Preview";

const OPTIONS = [
  { value: "accent", label: "Accent", color: "var(--accent-emphasis)" },
  { value: "warning", label: "Warning", color: "var(--chart-warning)" },
  { value: "danger", label: "Danger", color: "var(--chart-danger)" },
];

export default function SelectMedia() {
  const [value, setValue] = useState<null | string>("accent");

  return (
    <Preview overlay={true}>
      <Select.Root items={OPTIONS} onValueChange={setValue} value={value}>
        <Select.Trigger
          media={
            <span
              className="size-3.5 rounded-xs"
              style={{ background: OPTIONS.find((option) => option.value === value)?.color }}
            />
          }
        />
        <Select.Content>
          {OPTIONS.map((option) => (
            <Select.Item
              key={option.value}
              media={<span className="size-3.5 rounded-xs" style={{ background: option.color }} />}
              value={option.value}
            >
              {option.label}
            </Select.Item>
          ))}
        </Select.Content>
      </Select.Root>
    </Preview>
  );
}
```

`media` on `Select.Item` puts a swatch or a thumbnail before the label. Pass the chosen item's picture to `Select.Trigger` with the same `media` prop so the trigger shows it too.

## API

| Prop | Type | Default | Description |
| - | - | - | - |
| `variant?` | `"default" \| "field" \| "primary" \| "ghost" \| "danger"` | `"default"` | On Trigger. |
| `size?` | `"inline" \| "xs" \| "sm" \| "md"` | `"md"` | On Trigger. |
| `placeholder?` | `ReactNode` | - | On Trigger. Shown before a value is picked. |
| `children?` | `ReactNode` | - | On Trigger. Shown before the value, such as an icon or a label. |
| `media?` | `ReactNode` | - | On Trigger and Item. A picture before the label, such as a swatch or a thumbnail. |
| `align?` | `"start" \| "center" \| "end"` | `"start"` | On Content. |
| `icon?` | `TablerIcon` | - | On Item. |

Parts: all parts of Base UI [Select](https://base-ui.com/react/components/select), such as `Root`, `Group` and `Value`, with Deft's `Content`, `GroupLabel`, `Item`, `Separator` and `Trigger` in place of the Base UI ones. `Content` renders the portal, positioner, popup and list.
