DropdownMenu
Interactive
See DropdownMenu in Storybook for every variant, with live controls.
A menu of actions hanging off a trigger.
import { DropdownMenu, MENU_SEPARATOR, IconButton } from "@kairosis/eidos";
<DropdownMenu
align="right"
trigger={<IconButton icon="ellipsis" label="More actions" />}
items={[
{ id: "rerun", label: "Re-run", icon: "refresh-cw", shortcut: "⌘R" },
{ id: "logs", label: "View logs", icon: "scroll-text" },
MENU_SEPARATOR,
{ id: "delete", label: "Delete run", icon: "trash-2", danger: true },
]}
onSelect={handle}
/>;
Props
| Prop | Type | Default | Description |
|---|---|---|---|
trigger | ReactNode | — | Required. Usually a Button or IconButton |
items | (MenuItem | typeof MENU_SEPARATOR)[] | — | Required |
align | "left" | "right" | "left" | Which edge the menu aligns to |
onSelect | (id: string) => void | — | Fires for any item |
MenuItem is { id, label, icon?, shortcut?, danger?, onClick? }. Both onSelect and the item's own onClick fire, so you can handle centrally or per item.
Keyboard
Opening moves focus to the first item. ↑/↓ move between items (skipping separators) and wrap at both ends; Home/End jump to the first and last. Escape closes and returns focus to the trigger.
The trigger element itself is decorated with aria-haspopup, aria-expanded and aria-controls — the component clones your node rather than wrapping it, so the ARIA lands on the real button.
Guidelines
- Insert
MENU_SEPARATORbetween groups. Put destructive items last, below a separator, markeddanger. - Escape closes; so does a click outside.
shortcutis a display hint only — it renders the text, it doesn't bind the key. Register the real shortcut yourself.- Align
rightwhen the trigger sits at the right edge, or the menu will overflow.