Native Select
Every hand-drawn native select size and state.
Sizes
Grouped
Invalid
Disabled
Installation
Add Native Select with the shadcn CLI.
npx shadcn@latest add https://sketchcn.chuwii.com/r/native-select.json
Examples
Form fields and grouped, controlled native selects.
Form field
import {
  NativeSelect,
  NativeSelectOption,
} from "@/components/ui/native-select";

const PAPERS = {
  graph: "Graph paper",
  dotted: "Dotted",
  plain: "Plain",
};

export function PaperField() {
  const id = useId();

  return (
    <div className="flex flex-col gap-2">
      <label htmlFor={id} className="text-sm">
        Paper
      </label>
      <NativeSelect id={id} name="paper" className="w-52">
        {Object.entries(PAPERS).map(([value, label]) => (
          <NativeSelectOption key={value} value={value}>
            {label}
          </NativeSelectOption>
        ))}
      </NativeSelect>
    </div>
  );
}
Grouped
Drawing with marker
import {
  NativeSelect,
  NativeSelectOptGroup,
  NativeSelectOption,
} from "@/components/ui/native-select";

export function StrokePicker() {
  const [stroke, setStroke] = useState("marker");

  return (
    <div className="flex items-center gap-3">
      <NativeSelect
        className="w-52"
        value={stroke}
        onChange={(event) => setStroke(event.target.value)}
      >
        <NativeSelectOptGroup label="Wet ink">
          <NativeSelectOption value="marker">Marker</NativeSelectOption>
          <NativeSelectOption value="fineliner">Fineliner</NativeSelectOption>
        </NativeSelectOptGroup>
        <NativeSelectOptGroup label="Dry">
          <NativeSelectOption value="pencil">Pencil</NativeSelectOption>
          <NativeSelectOption value="charcoal">Charcoal</NativeSelectOption>
        </NativeSelectOptGroup>
      </NativeSelect>
      <span className="text-sm">Drawing with {stroke}</span>
    </div>
  );
}