---
type: doc
title: Native Select
description: A styled native HTML select element with consistent design system integration.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/native-select/native-select-demo.astro"
---
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"
---

<NativeSelect>
  <NativeSelectOption value="">Select status</NativeSelectOption>
  <NativeSelectOption value="todo">Todo</NativeSelectOption>
  <NativeSelectOption value="in-progress">In Progress</NativeSelectOption>
  <NativeSelectOption value="done">Done</NativeSelectOption>
  <NativeSelectOption value="cancelled">Cancelled</NativeSelectOption>
</NativeSelect>
```

## Installation

```bash
npx shadcn@latest add @fulldev/native-select
```

## Usage

```ts
import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@/components/ui/native-select"
```

```astro
<NativeSelect>
  <NativeSelectOption value="">Select a fruit</NativeSelectOption>
  <NativeSelectOption value="apple">Apple</NativeSelectOption>
  <NativeSelectOption value="banana">Banana</NativeSelectOption>
  <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
  <NativeSelectOption value="pineapple">Pineapple</NativeSelectOption>
</NativeSelect>
```

`NativeSelect` renders a real `select` inside a wrapper `div`. `class` goes to
the wrapper; all other attributes, such as `name`, `required`, `disabled` and
`dir`, go to the `select`, so it submits with a native form.

## Composition

```text
NativeSelect
├── NativeSelectOption
└── NativeSelectOptGroup
    ├── NativeSelectOption
    └── NativeSelectOption
```

## Groups

Use `NativeSelectOptGroup` to organize options into categories.

```astro title="src/components/examples/native-select/native-select-groups.astro"
---
import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@/components/ui/native-select"
---

<NativeSelect>
  <NativeSelectOption value="">Select department</NativeSelectOption>
  <NativeSelectOptGroup label="Engineering">
    <NativeSelectOption value="frontend">Frontend</NativeSelectOption>
    <NativeSelectOption value="backend">Backend</NativeSelectOption>
    <NativeSelectOption value="devops">DevOps</NativeSelectOption>
  </NativeSelectOptGroup>
  <NativeSelectOptGroup label="Sales">
    <NativeSelectOption value="sales-rep">Sales Rep</NativeSelectOption>
    <NativeSelectOption value="account-manager">
      Account Manager
    </NativeSelectOption>
    <NativeSelectOption value="sales-director">
      Sales Director
    </NativeSelectOption>
  </NativeSelectOptGroup>
  <NativeSelectOptGroup label="Operations">
    <NativeSelectOption value="support">Customer Support</NativeSelectOption>
    <NativeSelectOption value="product-manager">
      Product Manager
    </NativeSelectOption>
    <NativeSelectOption value="ops-manager">
      Operations Manager
    </NativeSelectOption>
  </NativeSelectOptGroup>
</NativeSelect>
```

## Disabled

Add the `disabled` prop to `NativeSelect` to disable the select.

```astro title="src/components/examples/native-select/native-select-disabled.astro"
---
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"
---

<NativeSelect disabled>
  <NativeSelectOption value="">Disabled</NativeSelectOption>
  <NativeSelectOption value="apple">Apple</NativeSelectOption>
  <NativeSelectOption value="banana">Banana</NativeSelectOption>
  <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
</NativeSelect>
```

## Invalid

Use `aria-invalid` to show validation errors, and `data-invalid` on a
surrounding `Field` for its styling.

```astro title="src/components/examples/native-select/native-select-invalid.astro"
---
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"
---

<NativeSelect aria-invalid="true">
  <NativeSelectOption value="">Error state</NativeSelectOption>
  <NativeSelectOption value="apple">Apple</NativeSelectOption>
  <NativeSelectOption value="banana">Banana</NativeSelectOption>
  <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
</NativeSelect>
```

## Native Select vs Select

Use `NativeSelect` for native browser behavior, better performance, or
mobile-optimized dropdowns. Use `Select` for custom styling of the open list.

## RTL

```astro title="src/components/examples/native-select/native-select-rtl.astro"
---
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"

const translations = {
  en: {
    dir: "ltr",
    values: {
      placeholder: "Select status",
      todo: "Todo",
      inProgress: "In Progress",
      done: "Done",
      cancelled: "Cancelled",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      placeholder: "اختر الحالة",
      todo: "مهام",
      inProgress: "قيد التنفيذ",
      done: "منجز",
      cancelled: "ملغي",
    },
  },
  he: {
    dir: "rtl",
    values: {
      placeholder: "בחר סטטוס",
      todo: "לעשות",
      inProgress: "בתהליך",
      done: "הושלם",
      cancelled: "בוטל",
    },
  },
}

const { dir, values: t } = translations.ar
---

<NativeSelect dir={dir}>
  <NativeSelectOption value="">{t.placeholder}</NativeSelectOption>
  <NativeSelectOption value="todo">{t.todo}</NativeSelectOption>
  <NativeSelectOption value="in-progress">{t.inProgress}</NativeSelectOption>
  <NativeSelectOption value="done">{t.done}</NativeSelectOption>
  <NativeSelectOption value="cancelled">{t.cancelled}</NativeSelectOption>
</NativeSelect>
```

## Accessibility

- It keeps all native `select` keyboard and screen reader behavior.
- The chevron icon has `aria-hidden="true"`.
- Give the select a label, with `Label for`, `aria-label` or `aria-labelledby`.

## API Reference

Source: [`src/components/ui/native-select`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/native-select)

### NativeSelect

| Prop       | Type                | Default     |
| ---------- | ------------------- | ----------- |
| `size`     | `"sm" \| "default"` | `"default"` |
| `multiple` | `boolean`           | `false`     |
| `disabled` | `boolean`           | `false`     |

### NativeSelectOption

| Prop       | Type      | Default |
| ---------- | --------- | ------- |
| `value`    | `string`  |         |
| `disabled` | `boolean` | `false` |

### NativeSelectOptGroup

| Prop       | Type      | Default |
| ---------- | --------- | ------- |
| `label`    | `string`  |         |
| `disabled` | `boolean` | `false` |

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/native-select-examples
```
