# Native Select

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";
---

<NativeSelect class="w-[240px]">
  <NativeSelectOption value="" disabled>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>
```
  </div>
  <div slot="react">
```tsx
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";

export function Example() {
  return (
    <>
      <NativeSelect className="w-[240px]">
            <NativeSelectOption value="" disabled>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>
    </>
  );
}
```
  </div>
</FrameworkCodeSwitcher>

> **Info:** Native Select follows Astro and HTML option-selection semantics. Omitting a value selects the
first option naturally; the legacy React-style `defaultValue` prop is no longer used.

> **Info:** For a styled select component, see the [Select](/docs/components/select/) component.

## Installation

```bash
npx starwind@latest add native-select
```

## Usage

### Groups

Use `NativeSelectOptGroup` to organize options into categories.

```astro
---
import { NativeSelect, NativeSelectOptGroup, NativeSelectOption } from "@/components/starwind/native-select";
---

<NativeSelect class="w-[260px]">
  <NativeSelectOption value="" disabled>Select an option</NativeSelectOption>
  <NativeSelectOptGroup label="Fruits">
    <NativeSelectOption value="apple">Apple</NativeSelectOption>
    <NativeSelectOption value="banana">Banana</NativeSelectOption>
  </NativeSelectOptGroup>
  <NativeSelectOptGroup label="Vegetables">
    <NativeSelectOption value="carrot">Carrot</NativeSelectOption>
    <NativeSelectOption value="spinach">Spinach</NativeSelectOption>
  </NativeSelectOptGroup>
</NativeSelect>
```

> **Info:** The grouped example now relies on the first native option for its initial selection instead of
passing the legacy `defaultValue` prop.

### Disabled

Add the `disabled` prop to disable the entire select, or disable specific options.

```astro
---
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";
---

<NativeSelect class="w-[220px]" disabled>
  <NativeSelectOption value="" disabled>Select framework</NativeSelectOption>
  <NativeSelectOption value="astro">Astro</NativeSelectOption>
  <NativeSelectOption value="next">Next.js</NativeSelectOption>
</NativeSelect>

<NativeSelect class="w-[220px]">
  <NativeSelectOption value="astro" selected>Astro</NativeSelectOption>
  <NativeSelectOption value="next" disabled>Next.js (Disabled)</NativeSelectOption>
  <NativeSelectOption value="svelte">SvelteKit</NativeSelectOption>
</NativeSelect>
```

> **Info:** Set an initial native selection with `selected` on `NativeSelectOption`. This replaces the
React-style `defaultValue` previously passed to `NativeSelect`.

### Invalid

Use `aria-invalid` for assistive technology and `data-error-visible` to opt into the visible error
state after validation has run.

```astro
---
import { Label } from "@/components/starwind/label";
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";
---

<div class="grid w-full max-w-sm gap-2">
  <Label for="native-select-invalid">Framework</Label>
  <NativeSelect
    id="native-select-invalid"
    class="w-full"
    aria-invalid
    data-error-visible
  >
    <NativeSelectOption value="" disabled>Select a framework</NativeSelectOption>
    <NativeSelectOption value="astro">Astro</NativeSelectOption>
    <NativeSelectOption value="next">Next.js</NativeSelectOption>
    <NativeSelectOption value="svelte">SvelteKit</NativeSelectOption>
  </NativeSelect>
  <p class="text-error text-sm">Please select a framework.</p>
</div>
```

> **Info:** The example now uses native option-selection semantics. Visible validation styling follows the
shared `data-error-visible` contract; keep `aria-invalid` as well so the invalid state remains
available to assistive technology.

### Size

Use the `size` prop to render compact or larger controls.

```astro
---
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";
---

<NativeSelect size="sm" class="w-[180px]">
  <NativeSelectOption value="" disabled>Small</NativeSelectOption>
  <NativeSelectOption value="one">Option 1</NativeSelectOption>
  <NativeSelectOption value="two">Option 2</NativeSelectOption>
</NativeSelect>

<NativeSelect size="md" class="w-[180px]">
  <NativeSelectOption value="" disabled>Medium</NativeSelectOption>
  <NativeSelectOption value="one">Option 1</NativeSelectOption>
  <NativeSelectOption value="two">Option 2</NativeSelectOption>
</NativeSelect>

<NativeSelect size="lg" class="w-[180px]">
  <NativeSelectOption value="" disabled>Large</NativeSelectOption>
  <NativeSelectOption value="one">Option 1</NativeSelectOption>
  <NativeSelectOption value="two">Option 2</NativeSelectOption>
</NativeSelect>
```

> **Info:** Each size example now lets its first native option provide the initial selection rather than
using the legacy `defaultValue` prop.

### Native Select vs Select

Use [Native Select](/docs/components/native-select/) for simple forms when you want browser-native behavior and mobile pickers. Use [Select](/docs/components/select/) when you need custom popover behavior, search, and advanced interaction patterns.

> **Tip:** Prefer `NativeSelect` for straightforward form controls and mobile-first flows where native platform
pickers are beneficial. Choose [Select](/docs/components/select/) when you need richer UI features
like searchable options, custom popover positioning, and advanced interactions.

### RTL

Set `dir="rtl"` to support right-to-left languages.

```astro
---
import { NativeSelect, NativeSelectOption } from "@/components/starwind/native-select";
---

<div dir="rtl">
  <NativeSelect class="w-[240px]">
    <NativeSelectOption value="" disabled>Select a fruit</NativeSelectOption>
    <NativeSelectOption value="apple">Apple</NativeSelectOption>
    <NativeSelectOption value="banana">Banana</NativeSelectOption>
    <NativeSelectOption value="grape">Grape</NativeSelectOption>
  </NativeSelect>
</div>
```

> **Info:** The RTL example now uses native option-selection semantics and no longer passes the legacy
`defaultValue` prop.

## Framework Availability
Native Select is available for Astro and React.
Astro available; React available
| Framework | Status | Notes |
| --- | --- | --- |
| Astro | available | - |
| React | available | - |
## API Reference
### NativeSelect
| Prop | Type | Required | Default | Kind | Description |
| --- | --- | --- | --- | --- | --- |
| `size` | `"sm" \| "md" \| "lg"` | No | `"md"` | Styled variant | Selects the component's visual size. |
- Inherits select attributes. Omits `size`.

### NativeSelectOption
- Inherits option attributes.

### NativeSelectOptGroup
- Inherits optgroup attributes.

## Changelog

### v1.1.0

- Added contract-generated Astro and React implementations while preserving the component's existing public API and styling.

### v1.0.1

- Refactor tailwind variants functions into separate `variants.ts` file

### v1.0.0

- Initial release with starwind v1.16.0