#Dropdown
Group additional actions in a menu.
#Action menu
basic.tsx
import type { DropdownItem } from '@ifhover/leaf-ui';
import { Button, Dropdown, useMessage } from '@ifhover/leaf-ui';
import { ChevronDown, Copy, Pencil, Trash2 } from 'lucide-react';
const items: DropdownItem[] = [
{ key: 'edit', label: 'Edit', icon: <Pencil size={15} /> },
{ key: 'copy', label: 'Copy', icon: <Copy size={15} /> },
{ key: 'archive', label: 'Archive', disabled: true },
{ key: 'divider', type: 'divider' },
{ key: 'delete', label: 'Delete', icon: <Trash2 size={15} />, danger: true },
];
export function DropdownBasic() {
const { message } = useMessage();
return (
<Dropdown items={items} onSelect={(key) => message.info(key)}>
<Button variant="outline" endIcon={<ChevronDown size={16} />}>
More actions
</Button>
</Dropdown>
);
}
#Extended features
extensions.tsx
import { Button, Dropdown } from '@ifhover/leaf-ui';
import { useState } from 'react';
export function ExtensionDemo() {
const [checked, setChecked] = useState(true);
const [view, setView] = useState('list');
return (
<Dropdown
items={[
{
key: 'group',
label: 'View',
type: 'group',
children: [
{
key: 'list',
label: 'List',
type: 'radio',
group: 'view',
checked: view === 'list',
onCheckedChange: () => setView('list'),
},
{
key: 'grid',
label: 'Grid',
type: 'radio',
group: 'view',
checked: view === 'grid',
onCheckedChange: () => setView('grid'),
},
],
},
{ key: 'line', type: 'divider' },
{
key: 'detail',
label: 'Show details',
type: 'checkbox',
checked,
onCheckedChange: setChecked,
},
{
key: 'more',
label: 'More actions',
children: [
{ key: 'copy', label: 'Copy' },
{ key: 'archive', label: 'Archive' },
],
},
]}
>
<Button variant="outline">Views and actions</Button>
</Dropdown>
);
}
#Hover and context menus
capabilities.tsx
import { Button, Dropdown, Space } from '@ifhover/leaf-ui';
const items = [
{ key: 'edit', label: 'Edit' },
{ key: 'more', label: 'More', children: [{ key: 'archive', label: 'Archive' }] },
];
export function Capabilities() {
return (
<Space>
<Dropdown trigger="hover" items={items}>
<Button variant="outline">{'Hover to open'}</Button>
</Dropdown>
<Dropdown trigger="contextMenu" items={items}>
<Button variant="outline">{'Right-click here'}</Button>
</Dropdown>
</Space>
);
}
#Dropdown API
| Property | Type | Default | Description |
|---|---|---|---|
popupPlacement | 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end' | — | Placement relative to the trigger. |
popupClassName | string | — | Custom class for the popup. |
popupStyle | CSSProperties | — | Custom popup styles. |
popupRender | (content: React.ReactNode) => React.ReactNode | — | Wrap or extend popup content; retain the supplied content to preserve interaction. |
getPopupContainer | () => Element | DocumentFragment | — | Return a popup container, including a ShadowRoot. |
items | readonly DropdownItem[] | Required | Required. Menu entries |
children | ReactElement< ButtonHTMLAttributes<HTMLButtonElement> & { ref?: Ref<HTMLButtonElement> } > | Required | Required. A single Leaf Button or native button |
disabled | boolean | false | Disable interaction. |
open | boolean | false | Controlled / initial open state |
defaultOpen | boolean | false | Controlled / initial open state |
onOpenChange | (open: boolean) => void | — | Open-state changes |
onSelect | (key: string) => void | — | Called when an enabled menu entry is selected |
placement | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'bottom-start' | Popup placement |
popupWidth | number | string | — | Popup width / maximum width |
popupMaxWidth | number | string | 420 | Popup width / maximum width |
trigger | 'click' | 'hover' | 'contextMenu' | readonly ('click' | 'hover' | 'contextMenu')[] | 'click' | Trigger mode; Dropdown supports click, hover and context menu. |
mouseEnterDelay | number | 100 | Configure mouse enter delay. |
mouseLeaveDelay | number | 150 | Configure mouse leave delay. |
itemRender | (item: DropdownItem) => ReactNode | — | Customize item content. |
#DropdownItem
| Property | Type | Default | Description |
|---|---|---|---|
key | string | Required | Required. Unique key |
label | ReactNode | — | Content and icon |
icon | ReactNode | — | Content and icon |
type | 'item' | 'divider' | 'group' | 'checkbox' | 'radio' | 'item' | Menu entry or divider |
children | readonly DropdownItem[] | — | Content, or child nodes for hierarchical records. |
disabled | boolean | false | Disable interaction. |
danger | boolean | false | Disabled / danger action |
checked | boolean | — | Configure checked. |
group | string | — | Group heading. |
closeOnSelect | boolean | — | Configure close on select. |
onCheckedChange | (checked: boolean) => void | — | Configure on checked change. |
href | string | — | Link destination. |
target | string | — | Target selector or element getter; omit to center the step. |
onClick | (event: MouseEvent<HTMLElement>) => void | — | Runs when the item is selected |
#Types
Import types when defining reusable component props or assembling options.
import type { DropdownProps, DropdownItem } from '@ifhover/leaf-ui';#Usage notes
Press Down / Up on the trigger to open. Use arrow keys, Home, End or the first letter to navigate, Enter to select, and Escape to close and restore focus. Disabled entries and dividers are skipped.