Skip to content

Dropdown

The Dropdown component is a wrapper around PrimeReact’s Dropdown with automatic z-index management for proper overlay behavior.

Dropdown provides a select component that correctly appears above dialogs and other overlays without z-index conflicts.

  • Full PrimeReact Dropdown functionality
  • Automatic z-index management
  • Works inside dialogs
  • Appends to document body by default
  • All PrimeReact Dropdown props supported
import { Dropdown } from '@cratis/components/Dropdown';
function MyForm() {
const [selectedCity, setSelectedCity] = useState(null);
const cities = [
{ label: 'Oslo', value: 'oslo' },
{ label: 'Bergen', value: 'bergen' },
{ label: 'Trondheim', value: 'trondheim' }
];
return (
<Dropdown
value={selectedCity}
options={cities}
onChange={(e) => setSelectedCity(e.value)}
placeholder="Select a City"
/>
);
}

All PrimeReact Dropdown props are supported. See PrimeReact Dropdown Documentation for complete list.

interface DropdownProps {
value?: unknown;
options: Array<{ label: string; value: unknown }>;
onChange?: (e: { value: unknown }) => void;
placeholder?: string;
disabled?: boolean;
filter?: boolean;
filterPlaceholder?: string;
showClear?: boolean;
optionLabel?: string;
optionValue?: string;
// ... all other PrimeReact Dropdown props
}
const options = ['React', 'Angular', 'Vue', 'Svelte'];
<Dropdown
value={selectedFramework}
options={options}
onChange={(e) => setSelectedFramework(e.value)}
placeholder="Select Framework"
/>
const countries = [
{ name: 'Norway', code: 'NO' },
{ name: 'Sweden', code: 'SE' },
{ name: 'Denmark', code: 'DK' }
];
<Dropdown
value={selectedCountry}
options={countries}
onChange={(e) => setSelectedCountry(e.value)}
optionLabel="name"
placeholder="Select Country"
/>
<Dropdown
value={selected}
options={longListOfOptions}
onChange={(e) => setSelected(e.value)}
filter
filterPlaceholder="Search..."
placeholder="Select Option"
/>
<Dropdown
value={selected}
options={options}
onChange={(e) => setSelected(e.value)}
showClear
placeholder="Select (optional)"
/>
const groupedCities = [
{
label: 'Norway',
items: [
{ label: 'Oslo', value: 'oslo' },
{ label: 'Bergen', value: 'bergen' }
]
},
{
label: 'Sweden',
items: [
{ label: 'Stockholm', value: 'stockholm' },
{ label: 'Gothenburg', value: 'gothenburg' }
]
}
];
<Dropdown
value={selected}
options={groupedCities}
onChange={(e) => setSelected(e.value)}
optionLabel="label"
optionGroupLabel="label"
optionGroupChildren="items"
placeholder="Select City"
/>
const countryTemplate = (option: Country) => {
return (
<div className="flex align-items-center">
<img src={`/flags/${option.code}.png`} width="20" alt={option.name} />
<span className="ml-2">{option.name}</span>
</div>
);
};
<Dropdown
value={selectedCountry}
options={countries}
onChange={(e) => setSelectedCountry(e.value)}
itemTemplate={countryTemplate}
optionLabel="name"
placeholder="Select Country"
/>

Dropdown automatically works correctly inside dialogs:

<Dialog visible={visible} onHide={() => setVisible(false)}>
<div className="field">
<label>Category</label>
<Dropdown
value={category}
options={categories}
onChange={(e) => setCategory(e.value)}
placeholder="Select Category"
/>
</div>
</Dialog>

The dropdown panel will appear above the dialog without z-index issues.

The component uses useOverlayZIndex hook to ensure proper layering:

  • Dropdown panel automatically gets correct z-index
  • Works with multiple layered dialogs
  • Appends to document body by default
  • Prevents overlay conflicts
<Dropdown
value={selected}
options={options}
disabled={isLoading}
placeholder="Loading..."
/>

Integrate with form validation:

<div className="field">
<label htmlFor="status">Status</label>
<Dropdown
id="status"
value={formData.status}
options={statusOptions}
onChange={(e) => setFormData({ ...formData, status: e.value })}
className={errors.status ? 'p-invalid' : ''}
/>
{errors.status && <small className="p-error">{errors.status}</small>}
</div>
import { Dropdown } from '@cratis/components/Dropdown';
import { useState } from 'react';
interface FormData {
category: string;
priority: string;
assignee: string;
}
function IssueForm() {
const [formData, setFormData] = useState<FormData>({
category: '',
priority: '',
assignee: ''
});
const categories = [
{ label: 'Bug', value: 'bug' },
{ label: 'Feature', value: 'feature' },
{ label: 'Improvement', value: 'improvement' }
];
const priorities = [
{ label: 'Low', value: 'low' },
{ label: 'Medium', value: 'medium' },
{ label: 'High', value: 'high' },
{ label: 'Critical', value: 'critical' }
];
const assignees = [
{ label: 'Alice', value: 'alice' },
{ label: 'Bob', value: 'bob' },
{ label: 'Charlie', value: 'charlie' }
];
return (
<form>
<div className="field">
<label htmlFor="category">Category</label>
<Dropdown
id="category"
value={formData.category}
options={categories}
onChange={(e) => setFormData({ ...formData, category: e.value })}
placeholder="Select Category"
/>
</div>
<div className="field">
<label htmlFor="priority">Priority</label>
<Dropdown
id="priority"
value={formData.priority}
options={priorities}
onChange={(e) => setFormData({ ...formData, priority: e.value })}
placeholder="Select Priority"
/>
</div>
<div className="field">
<label htmlFor="assignee">Assignee</label>
<Dropdown
id="assignee"
value={formData.assignee}
options={assignees}
onChange={(e) => setFormData({ ...formData, assignee: e.value })}
placeholder="Assign to..."
showClear
filter
/>
</div>
</form>
);
}
  • Form fields: Select inputs in forms
  • Filters: Filtering data by category, status, etc.
  • Preferences: User settings selection
  • Navigation: Menu-style navigation options
  • Status selection: Workflow state transitions
  • Type selection: Choose item types in editors

This component extends PrimeReact Dropdown with:

  1. Automatic z-index management: Works correctly in dialogs without manual configuration
  2. Default appendTo: Automatically appends to document.body
  3. Consistent behavior: Same overlay behavior across all usage contexts

Otherwise, it’s identical to PrimeReact Dropdown.

  1. Provide clear labels: Always label dropdowns
  2. Use placeholders: Guide users with meaningful placeholders
  3. Enable filtering for long lists: Use filter prop for 10+ options
  4. Show clear button: Use showClear for optional selections
  5. Validate selections: Provide error feedback
  6. Disable when appropriate: Disable during loading or when unavailable
  7. Use object options: For complex data with multiple properties
  8. Group related options: Use grouped options for better organization
  9. Provide feedback: Show loading states, error states clearly

Inherits PrimeReact Dropdown accessibility features:

  • Keyboard navigation (Arrow keys, Enter, Escape)
  • ARIA labels and roles
  • Focus management
  • Screen reader support

Enhance with:

<label htmlFor="dropdown-id">
Selection Label
</label>
<Dropdown
id="dropdown-id"
aria-label="Selection Label"
// ... other props
/>

Style via className or custom CSS:

<Dropdown
className="w-full"
panelClassName="custom-dropdown-panel"
// ...
/>

Or global CSS:

.p-dropdown {
/* Custom dropdown styles */
}
.p-dropdown-panel {
/* Custom panel styles */
}