Embossed UI

Search documentation

Search for a page or component.

Native Select

A styled native HTML select element with consistent design system integration.

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

export function NativeSelectDemo() {
  return (
    <NativeSelect aria-label="Status">
      <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

pnpm dlx shadcn@latest add https://ui.ikramhasan.com/r/native-select.json

Usage

import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@/components/ui/native-select"
<NativeSelect>
  <NativeSelectOption value="">Select a fruit</NativeSelectOption>
  <NativeSelectOption value="apple">Apple</NativeSelectOption>
  <NativeSelectOption value="banana">Banana</NativeSelectOption>
</NativeSelect>

Examples

Groups

Use NativeSelectOptGroup to organize options into categories.

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

export function NativeSelectGroups() {
  return (
    <NativeSelect aria-label="Department">
      <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>
      </NativeSelectOptGroup>
      <NativeSelectOptGroup label="Operations">
        <NativeSelectOption value="support">
          Customer support
        </NativeSelectOption>
        <NativeSelectOption value="ops-manager">
          Operations manager
        </NativeSelectOption>
      </NativeSelectOptGroup>
    </NativeSelect>
  )
}

Sizes

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

export function NativeSelectSizes() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <NativeSelect size="sm" aria-label="Fruit (small)">
        <NativeSelectOption value="apple">Apple</NativeSelectOption>
        <NativeSelectOption value="banana">Banana</NativeSelectOption>
      </NativeSelect>
      <NativeSelect aria-label="Fruit">
        <NativeSelectOption value="apple">Apple</NativeSelectOption>
        <NativeSelectOption value="banana">Banana</NativeSelectOption>
      </NativeSelect>
    </div>
  )
}

Invalid

Use aria-invalid to show an error state.

import { Field, FieldError, FieldLabel } from "@/components/ui/field"
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"

export function NativeSelectInvalid() {
  return (
    <Field data-invalid className="w-fit">
      <FieldLabel htmlFor="native-select-country">Country</FieldLabel>
      <NativeSelect id="native-select-country" aria-invalid="true">
        <NativeSelectOption value="">Select a country</NativeSelectOption>
        <NativeSelectOption value="bd">Bangladesh</NativeSelectOption>
        <NativeSelectOption value="de">Germany</NativeSelectOption>
        <NativeSelectOption value="us">United States</NativeSelectOption>
      </NativeSelect>
      <FieldError>Choose the country you ship from.</FieldError>
    </Field>
  )
}

Disabled

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

export function NativeSelectDisabled() {
  return (
    <NativeSelect disabled aria-label="Fruit">
      <NativeSelectOption value="">Disabled</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 pickers.
  • Use Select for custom styling of the options, animations, or complex interactions.

The trigger looks the same as SelectTrigger; the open list is the browser's own.

API Reference

PartProps / notes
NativeSelectEvery <select> prop, plus size: default · sm (default default). className goes on the wrapper.
NativeSelectOptionEvery <option> prop.
NativeSelectOptGroupEvery <optgroup> prop.