Dropdown
Dropdowns allow users to select a single option from a list. They support search, floating labels, and six leading item types — icons, avatars, brand logos, country flags, images, and plain text.
Dropdown Playground
Dropdown Playground
Preview
Code
Quick Access
Select an option
Controls
Size:
Small
Default
Large
Type:
Default
Prefixed
Inline
Leading Item:
None
Icon
Avatar
Brand
Image
Country
Search:
Floating Label:
Disabled:
Installation
You can add the dropdown component to your project manually:
1
Install the following dependencies:
npm
pnpm
yarn
bun
npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @floating-ui/react @react-aria/focus @react-aria/button @react-aria/interactions2
Copy and paste the following code into your project.
Dropdown.tsx
DropdownInput.tsx
Menu.tsx
MenuItem.tsx
SearchBar.tsx
Material.tsx
Checkbox.tsx
CompactIconButton.tsx
Avatar.tsx
cn.ts
Loading source code...
3
Update the import paths to match your project setup.
Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.
Basic Usage
import { Dropdown } from '@versaui/ui/components/Dropdown';
const options = [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' },
{ value: 'cherry', label: 'Cherry' },
];
<Dropdown
options={options}
placeholder="Select fruit"
onChange={(value, option) => console.log(option.label)}
/>Dropdown Types
Three layout types are available:
// Default — floating label with full input
<Dropdown options={options} label="Category" />
// Prefixed Label — label shown as prefix
<Dropdown type="prefixedLabel" label="Country" options={countries} />
// Inline — compact inline style
<Dropdown type="inline" options={options} />Size Variants
<Dropdown size="small" options={options} />
<Dropdown size="default" options={options} />
<Dropdown size="large" options={options} />Leading Item Types
Options can include various leading item types for richer selection UIs:
// Icons
const options = [
{ value: 'settings', label: 'Settings', leadingType: 'icon', leadingItem: <GearIcon /> },
];
// Avatars
const options = [
{ value: 'user1', label: 'Adam Smith', leadingType: 'avatar', leadingItem: <Avatar size="xxs" type="image" person="adam-smith" /> },
];
// Country Flags
const options = [
{ value: 'us', label: 'United States', leadingType: 'country', leadingItem: <CountryFlag country="us" size="medium" /> },
];
// Brand Icons
const options = [
{ value: 'github', label: 'GitHub', leadingType: 'brand', leadingItem: <BrandIcon platform="github" size={16} /> },
];Controlled Usage
const [selected, setSelected] = useState<string>();
<Dropdown
options={options}
value={selected}
onChange={(value) => setSelected(value)}
/>DropdownOption Interface
interface DropdownOption {
value: string; // Unique option value
label: string; // Display label
leadingType?: 'none' | 'icon' | 'avatar' | 'brand' | 'country' | 'image';
leadingItem?: ReactNode; // Leading element (icon, avatar, etc.)
disabled?: boolean; // Disabled state
}Accessibility
- Uses
role="listbox"with properaria-expandedandaria-activedescendant - Keyboard navigation: arrow keys, Enter to select, Escape to close
- Search input is automatically focused when opened
- Selected option announced to screen readers
Dropdown Props
| Prop | Type | Default | Description |
|---|---|---|---|
options | DropdownOption[] | — | Required. Array of selectable options. |
size | 'small' | 'default' | 'large' | 'default' | Dropdown size variant. |
type | 'default' | 'prefixedLabel' | 'inline' | 'default' | Visual layout type. |
value | string | — | Controlled selected value. |
defaultValue | string | — | Initial value for uncontrolled usage. |
placeholder | string | 'Select...' | Placeholder text. |
label | string | 'Label' | Label text (visible in default and prefixedLabel types). |
disabled | boolean | false | Prevents interaction. |
showSearch | boolean | true | Show search input in menu. |
searchPlaceholder | string | 'Search' | Placeholder for the search input. |
floatingLabel | boolean | true | Use floating label animation. |
fullWidth | boolean | false | Expand to fill container width. |
menuMaxHeight | number | string | 300 | Maximum height of the dropdown menu. |
onChange | (value: string, option: DropdownOption) => void | — | Called when selection changes. |
className | string | '' | Additional CSS classes. |
DropdownInput Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | DropdownInputSize | 'default' | Input size. |
type | DropdownInputType | 'default' | Input layout type. |
label | string | 'Label' | Label text. |
placeholder | string | 'Select' | Placeholder text. |
value | string | — | Display value. |
isOpen | boolean | — | Whether dropdown is open. |
disabled | boolean | — | Disabled state. |
floatingLabel | boolean | true | Use floating label. |
Menu Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | MenuSize | 'default' | Menu size. |
showSearch | boolean | true | Show search input. |
searchPlaceholder | string | 'Search' | Search placeholder text. |
maxHeight | number | string | — | Maximum menu height. |
MenuItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
size | MenuItemSize | 'default' | Item size. |
leadingItem | MenuItemLeadingType | 'none' | Leading item type (icon, avatar, etc.). |
selected | boolean | — | Selected state. |
disabled | boolean | — | Disabled state. |