Dropdown
React dropdown field with single and multiple selection, in-panel search, grouped options, and full field wiring. Built on cmdk for fast filtering in Arabic and English.
Dropdown is a select field composed from DropdownItem children. Add multiple for multi-select or searchable for an in-panel filter.
When to use
Use Dropdown when a select needs search, multiple values, or grouped options: choosing several services, filtering by many cities, or picking from a long reference list. Use Select for a plain single choice and Chip for a visible set of filters.
Provide emptyMessage so a search with no results still explains itself.
Examples
Props
Props declared by Dropdown. Native attributes of the underlying element pass through.
<Dropdown>
| Prop | Type | Default | Description |
|---|---|---|---|
size | "md" | "lg" | ||
variant | "default" | "filled-lighter" | "filled-darker" | ||
open | boolean | ||
defaultOpen | boolean | ||
onOpenChange | (open: boolean) => void | ||
label | react.ReactNode | Visible label above the trigger. | |
helperText | react.ReactNode | Hint shown below the trigger when there's no error. | |
errorMessage | react.ReactNode | Message shown below the trigger when error is true. | |
error | boolean | Marks the field invalid - sets aria-invalid and the error border. | |
required | boolean | Adds the required asterisk + aria-required. | |
disabled | boolean | Disables the trigger entirely. | |
readOnly | boolean | Shows the value but blocks opening (SDGA Read-only). | |
placeholder | react.ReactNode | Placeholder shown when nothing is selected. | |
searchable | boolean | Render the in-panel filter input (combobox behavior). Off by default - the plain SDGA dropdown. A hidden focusable input is kept either way for cmdk's keyboard model. | |
searchPlaceholder | string | Placeholder for the filter input when searchable. | |
emptyMessage | react.ReactNode | Shown when a filter matches nothing. | |
getLabel | (value: string) => ReactNode | Override the trigger label resolver (e.g. async-loaded options). | |
id | string | ||
className | string | ||
aria-label | string | ||
aria-labelledby | string | ||
childrenrequired | react.ReactNode | <DropdownItem> (+ optional DropdownGroup / DropdownSeparator). | |
multiple | false | ||
value | string | ||
defaultValue | string | ||
onValueChange | (value: string) => void |
<DropdownItem>
| Prop | Type | Default | Description |
|---|---|---|---|
valuerequired | string | Stable value for filtering + selection. | |
keywords | string[] | Extra search terms cmdk matches against the filter input. | |
disabled | boolean | Whether this item is currently disabled. | |
onSelect | (value: string) => void | Fires alongside the root's onValueChange. | |
children | ReactNode | ||
asChild | boolean | ||
forceMount | boolean | Whether this item is forcibly rendered regardless of filtering. |
<DropdownGroup>
| Prop | Type | Default | Description |
|---|---|---|---|
heading | react.ReactNode | Optional heading to render for this group. | |
children | ReactNode | ||
asChild | boolean | ||
value | string | If no heading is provided, you must provide a value that is unique for this group. | |
forceMount | boolean | Whether this group is forcibly rendered regardless of filtering. |
<DropdownSeparator>
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | ||
alwaysRender | boolean | Whether this separator should always be rendered. Useful if you disable automatic filtering. |
Accessibility
The trigger reports aria-haspopup, and the field label, helper text, and error use the same wiring as TextInput. Inside the panel, the search input and option list follow the combobox pattern from cmdk. Arrow keys move through options, Enter toggles the highlighted one, and Escape closes.
Selected values are announced, and in multiple mode each selection stays visible in the trigger.