Dropdown
Simple select dropdown supporting both custom styled popup panel and native HTML <select> mobile rendering.
// Plain markup
import { Dropdown } from "@shavin/ui";Variants
Two rendering modes via the variant prop. Both share the same value / onChange / options API.
Default — styled panel
const OPTIONS = [
{ value: "a", label: "Option A" },
{ value: "b", label: "Option B" },
{ value: "c", label: "Option C" },
];
const [value, setValue] = useState("a");
<Dropdown value={value} onChange={setValue} options={OPTIONS} />Native — OS picker
{/* Renders a real <select> — best for simple, mobile-first forms */}
<Dropdown variant="native" value={value} onChange={setValue} options={OPTIONS} />Appearance
Ghost — no chrome until hover (inline/toolbar filters)
<Dropdown appearance="ghost" size="sm" value={value} onChange={setValue} options={OPTIONS} />States
Disabled
<Dropdown value={value} onChange={setValue} options={OPTIONS} disabled />Select vs Dropdown
Use Dropdown (variant="native") for simple, mobile-first forms — it renders a real <select> and gets the OS picker for free. The default variant is a styled panel for desktop-first UIs. Reach for Select when you also need type-ahead and larger, fully-custom option rows.
Props
| Prop | Type | Default |
|---|---|---|
| value* | string | — |
| onChange* | (v: string) => void | — |
| options* | DropdownOption[] | — |
| disabled | boolean | — |
| variant | "native" | "default" | — |
| ariaLabel | string | — |
| className | string | — |
| size | "sm" | "md" | "md" |
| appearance | "default" | "focus" | "ghost" | "hover" | "default" |
* required