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
Component Source
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
Component Source
{/* 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)
Component Source
<Dropdown appearance="ghost" size="sm" value={value} onChange={setValue} options={OPTIONS} />States
Disabled
Component Source
<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 | Description |
|---|---|---|---|
| value | string | — | Active selected option value string (controlled). Omit and use `defaultValue` for uncontrolled. |
| defaultValue | string | — | Initial selected value when uncontrolled. |
| onChange | (v: string) => void | — | Callback fired when selected option value changes. |
| onValueChange | (v: string) => void | — | Alias of `onChange`. |
| options* | DropdownOption[] | — | List of dropdown options ({ value, label }). |
| disabled | boolean | — | Whether control is disabled. |
| variant | "native" | "default" | (custom | Rendering variant: native (<select>) or default (custom popup). Default 'default'. |
| placement | "bottom" | "top" | bottom | Popup placement relative to trigger: 'bottom' or 'top'. Default 'bottom'. |
| align | "start" | "end" | start | Popup horizontal alignment relative to trigger: 'start' (left) or 'end' (right). Default 'start'. |
| ariaLabel | string | — | Accessible ARIA label. |
| className | string | — | Optional custom CSS class name. |
| size | "sm" | "md" | "md" | — |
| appearance | "default" | "ghost" | "default" | — |
* required