Native Select

The browser's own select, dressed as Koala's Select trigger. The list that opens is the operating system's: the wheel on iOS, the sheet on Android. Closed, it is indistinguishable from a Select of the same size.

Used for your reports and reminders.

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add native-select

Usage#

usage.tsxTSX
import { NativeSelect, NativeSelectOption } from "@/components/ui/native-select"export function Example() {  return (    <NativeSelect name="role" defaultValue="editor">      <NativeSelectOption value="admin">Admin</NativeSelectOption>      <NativeSelectOption value="editor">Editor</NativeSelectOption>      <NativeSelectOption value="viewer">Viewer</NativeSelectOption>    </NativeSelect>  )}

Beside a Select#

The closed control is the Select trigger, token for token: the same frame and --surface ground, the same caret, and the same brand border and halo once it has focus. Heights come from size, the scale every control shares (sm 32 · md 36 · lg 40px), so the two sit in a row without anyone noticing which one is native. Native on the left, Select on the right.

Placeholder#

Make the first option the empty one (value=""), and disabled so it can't be chosen back. While it is the selected option the control reads in the muted placeholder ink at normal weight, like an empty Select; the rows in the open list keep the foreground.

In a form#

Where a native picker is the better one: a card expiry is two short fixed lists, and on a phone the OS wheel beats any custom menu. Form imposes its lg size on every control inside it, the native selects included, so the row lines up with the security code beside it. The values post with the form, with no JavaScript required.

Error and disabled#

Inside a Field, hasError turns the frame red and points aria-describedby at the hint, which becomes the message; disabled on the Field reaches the select too. Both need no wiring on the control itself.

Pick a plan to continue.

Fixed while a payment is pending.

API reference#

NativeSelect

A <select> in a positioned frame with the caret. Props: size (sm · md · lg, defaulting from the nearest Form or density), density, and every <select> prop except multiple: name, value, defaultValue, onChange, required, ref. className goes on the frame, so a width moves the caret with it.

NativeSelectOption · NativeSelectOptGroup

The native <option> and <optgroup>, with their data-slots. The operating system draws them, so they take text only.

FAQ#

Native Select where the OS picker is the better one: forms used on phones, long fixed lists (years, timezones), and forms that must post without JavaScript. Select where the options need icons, flags, descriptions, a search, or the same look on every platform.