Components
Dropdown
A floating container positioned relative to an anchor element. The low-level primitive underlying ActionsDropdown — use when you need custom dropdown content.
Overview
Dropdown extends Popper with a visual shell: a white rounded container with a shadow, an optional title header, optional search slot, and a Scrollable content area. Use it directly when you need a fully custom dropdown body. For standard action lists, use ActionsDropdown.
Import
import { Dropdown } from '@unflow/ui/components/Dropdown';Props
| Prop | Type | Default | Description |
|---|---|---|---|
anchorEl | Element | VirtualElement | required | Anchor for positioning |
open | boolean | false | Visibility |
placement | Placement | 'bottom-start' | Position relative to anchor |
offset | number | 4 | Gap from anchor in px |
keepMounted | boolean | false | Keep DOM node when closed |
onClickAway | () => void | — | Called on outside click |
clickAwayIgnore | Element | — | Element excluded from click-away |
title | string | — | Section title above content |
Slots
| Slot | Type | Position |
|---|---|---|
header | ReactNode | Fixed area above the scrollable list |
search | ReactNode | Search input below the header title |
option | () => ReactNode | Custom option renderer (factory function) |
Examples
Basic custom dropdown
<Dropdown
anchorEl={buttonRef.current}
open={isOpen}
onClickAway={() => setOpen(false)}
clickAwayIgnore={buttonRef.current ?? undefined}
>
<div className="p-2">
<p>Custom content goes here</p>
</div>
</Dropdown>With title and search
<Dropdown
anchorEl={anchor}
open={isOpen}
title="Assign to"
onClickAway={() => setOpen(false)}
slots={{ search: <SearchInput value={query} onChange={setQuery} /> }}
>
{filteredUsers.map(user => (
<UserOption key={user.id} user={user} />
))}
</Dropdown>keepMounted for stateful content
<Dropdown
anchorEl={anchor}
open={isOpen}
keepMounted
onClickAway={() => setOpen(false)}
>
<FilterForm /> {/* retains state between open/close */}
</Dropdown>Anatomy
Popper
└── container (rounded, shadowed div)
├── headerRoot
│ ├── title (if provided)
│ └── search slot (if provided)
└── Scrollable
├── header slot (custom header content)
└── children / option slotCustomization (slotProps)
| Slot | Type | Controls |
|---|---|---|
headerRoot | HTMLDivElement props | The header wrapper div |
scrollable | IScrollable | The scrollable content area |
popper | Partial IPopper | The underlying Popper |
<Dropdown
anchorEl={anchor}
open={isOpen}
slotProps={{
scrollable: { height: 320 },
popper: { placement: 'top-start' },
}}
>
{content}
</Dropdown>Accessibility
Dropdown renders as a plain <div>. For a navigation menu, add role="menu" (or use ActionsDropdown which handles this). For a selection list, add role="listbox".