Overview
Dropdown is a form component that displays a menu of options when triggered. It supports single and multiple selection modes, search functionality, custom headers, and action buttons.
Basic Usage
import { Dropdown } from 'grauity';
import { useState } from 'react';
function MyForm() {
const [value, setValue] = useState(null);
return (
<Dropdown
name="country"
label="Select Country"
placeholder="Choose a country"
items={[
{ type: 'option', label: 'United States', value: 'us' },
{ type: 'option', label: 'Canada', value: 'ca' },
{ type: 'option', label: 'United Kingdom', value: 'uk' },
{ type: 'option', label: 'Australia', value: 'au' },
]}
value={value}
onChange={setValue}
/>
);
}
Single Selection
import { Dropdown } from 'grauity';
import { useState } from 'react';
function SingleSelect() {
const [profession, setProfession] = useState(null);
return (
<Dropdown
name="profession"
label="Select Profession"
placeholder="Choose your profession"
multiple={false}
searchable
items={[
{ type: 'option', label: 'Developer', value: 'developer' },
{ type: 'option', label: 'Designer', value: 'designer' },
{ type: 'option', label: 'Manager', value: 'manager' },
{ type: 'option', label: 'Tester', value: 'tester' },
]}
value={profession}
onChange={setProfession}
/>
);
}
Multiple Selection
import { Dropdown } from 'grauity';
import { useState } from 'react';
function MultipleSelect() {
const [hobbies, setHobbies] = useState([]);
return (
<Dropdown
name="hobbies"
label="Select Hobbies"
placeholder="Choose your hobbies"
multiple
searchable
showActionButtons
items={[
{ type: 'option', label: 'Reading', value: 'reading' },
{ type: 'option', label: 'Writing', value: 'writing' },
{ type: 'option', label: 'Gaming', value: 'gaming' },
{ type: 'option', label: 'Cooking', value: 'cooking' },
{ type: 'option', label: 'Photography', value: 'photography' },
]}
value={hobbies}
onChange={setHobbies}
/>
);
}
In multiple selection mode, the value is an array of selected items. Use showActionButtons to require explicit confirmation.
With Sections and Dividers
import { Dropdown } from 'grauity';
function GroupedDropdown() {
const [value, setValue] = useState(null);
return (
<Dropdown
name="difficulty"
label="Difficulty Level"
items={[
{ type: 'subheader', title: 'BEGINNER' },
{ type: 'option', label: 'Easy', value: 'easy', description: 'Good for starters' },
{ type: 'option', label: 'Medium', value: 'medium', description: 'Some experience needed' },
{ type: 'divider' },
{ type: 'subheader', title: 'ADVANCED' },
{ type: 'option', label: 'Hard', value: 'hard', description: 'Challenging' },
{ type: 'option', label: 'Expert', value: 'expert', description: 'Very difficult', disabled: true },
]}
value={value}
onChange={setValue}
/>
);
}
With Icons
import { Dropdown } from 'grauity';
function IconDropdown() {
const [status, setStatus] = useState(null);
return (
<Dropdown
name="status"
label="Status"
items={[
{
type: 'option',
label: 'Active',
value: 'active',
leftIcon: 'check-circle',
rightIcon: 'arrow-right',
},
{
type: 'option',
label: 'Pending',
value: 'pending',
leftIcon: 'clock',
},
{
type: 'option',
label: 'Inactive',
value: 'inactive',
leftIcon: 'close-circle',
},
]}
value={status}
onChange={setStatus}
/>
);
}
Custom Trigger
import { Dropdown, Button } from 'grauity';
import { useState } from 'react';
function CustomTriggerDropdown() {
const [value, setValue] = useState(null);
return (
<Dropdown
name="actions"
trigger={<Button>Open Menu</Button>}
menuProps={{ width: '300px', fullWidth: false }}
items={[
{ type: 'option', label: 'Edit', value: 'edit' },
{ type: 'option', label: 'Delete', value: 'delete' },
{ type: 'option', label: 'Share', value: 'share' },
]}
value={value}
onChange={setValue}
/>
);
}
With Validation
import { Dropdown } from 'grauity';
import { useState } from 'react';
function ValidatedDropdown() {
const [value, setValue] = useState(null);
const [error, setError] = useState('');
const handleChange = (newValue) => {
setValue(newValue);
if (newValue) {
setError('');
}
};
const handleSubmit = () => {
if (!value) {
setError('Please select an option');
}
};
return (
<Dropdown
name="required"
label="Required Field"
placeholder="Select an option"
isRequired
errorMessage={error}
helpMessage="This field is required"
items={[
{ type: 'option', label: 'Option 1', value: '1' },
{ type: 'option', label: 'Option 2', value: '2' },
]}
value={value}
onChange={handleChange}
/>
);
}
Props
Trigger Props
The name of the dropdown field for form submission.
The label displayed above the dropdown.
Placeholder text shown when no option is selected.
Whether the dropdown field is required.
Whether the dropdown is disabled.
Helper text displayed below the dropdown.
Error message displayed below the dropdown.
Color theme for the dropdown. Options: 'brand' | 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info'
showSelectedValueOnTrigger
Whether to show the selected value on the trigger button.
- If
false, placeholder is always shown
- In single select: shows label
- In multi select: shows “n selected”
Custom trigger element to display instead of default trigger.
Callback fired when the dropdown menu is closed.(value: BaseItemOptionProps | BaseItemOptionProps[]) => void
Array of menu items to display. Each item can be:
{ type: 'option', label: string, value: string | number, description?: string, leftIcon?: string, rightIcon?: string, disabled?: boolean }
{ type: 'subheader', title: string }
{ type: 'divider' }
value
BaseItemOptionProps | BaseItemOptionProps[]
Currently selected value(s).
- Single select: single object or
null
- Multiple select: array of objects
Whether multiple items can be selected.
Whether the dropdown menu includes a search field.
Whether to show the dropdown menu header.
Title text for the dropdown menu header.
Subtext displayed in the dropdown menu header.
Whether to show Apply and Clear All buttons. When true, onChange is called only on Apply button click.
Callback fired when selection changes.(value: BaseItemOptionProps | BaseItemOptionProps[]) => void
Configuration for the dropdown menu positioning:
width: Menu width (default: '300px')
fullWidth: Whether menu matches trigger width (default: true)
TypeScript
import { DropdownProps, BaseItemOptionProps } from 'grauity';
enum BaseItemType {
OPTION = 'option',
SUBHEADER = 'subheader',
DIVIDER = 'divider',
}
type BaseItemOptionProps = {
type: 'option';
label: string;
value: string | number;
description?: string;
leftIcon?: string;
rightIcon?: string;
disabled?: boolean;
};
Accessibility
- Keyboard navigation with arrow keys, Enter, and Escape
- Focus management for overlay and menu items
- ARIA attributes for screen readers
- Disabled items are not focusable
- Selected items are announced
When using showActionButtons={true}, the onChange callback will only fire when the user clicks “Apply”, not when individual options are selected.
Related Components
- Combobox - Dropdown with searchable input field
- RadioButton - For fewer, always-visible options
- useForm - For form validation and state management
Source
View the source code on GitHub: