Native Select

The browser’s own select, styled to match.

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

export default function NativeSelectDemo() {
  return (
    <NativeSelect defaultValue="" aria-label="Status" className="w-[200px]">
      <NativeSelectOption value="" disabled>
        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://kagadmodyaa.vercel.app/r/native-select.json

Needs a React + Tailwind project set up with shadcn. Copies the component source straight into your project, so you can edit it.

Native Select imports cn() from lib/utils.ts — add it too if you don't have it yet:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Usage

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

<NativeSelect defaultValue="todo" name="status">
  <NativeSelectOption value="todo">Todo</NativeSelectOption>
  <NativeSelectOption value="done">Done</NativeSelectOption>
</NativeSelect>

Examples

Groups and states

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

export default function NativeSelectGroups() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-4">
      <NativeSelect defaultValue="paris" aria-label="City" className="w-[200px]">
        <NativeSelectOptGroup label="Europe">
          <NativeSelectOption value="paris">Paris</NativeSelectOption>
          <NativeSelectOption value="berlin">Berlin</NativeSelectOption>
        </NativeSelectOptGroup>
        <NativeSelectOptGroup label="Asia">
          <NativeSelectOption value="tokyo">Tokyo</NativeSelectOption>
          <NativeSelectOption value="seoul">Seoul</NativeSelectOption>
        </NativeSelectOptGroup>
      </NativeSelect>

      <NativeSelect disabled aria-label="Disabled" className="w-[200px]">
        <NativeSelectOption>Disabled</NativeSelectOption>
      </NativeSelect>

      <NativeSelect aria-invalid="true" aria-label="Invalid" className="w-[200px]">
        <NativeSelectOption>Invalid</NativeSelectOption>
      </NativeSelect>
    </div>
  )
}

API Reference

NameTypeDefaultDescription
NativeSelectselect props—A real <select>: native pickers on mobile, type-ahead and form submission for free. Accepts every select attribute; className goes on the <select>.
NativeSelect wrapperClassNamestring—Classes for the wrapper that holds the chevron.
NativeSelectOption / NativeSelectOptGroupoption / optgroup props—Styled <option> and <optgroup>.