Skip to main content

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

PropTypeDefaultDescription
triggerReactNodeRequired. Usually a Button or IconButton
items(MenuItem | typeof MENU_SEPARATOR)[]Required
align"left" | "right""left"Which edge the menu aligns to
onSelect(id: string) => voidFires 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_SEPARATOR between groups. Put destructive items last, below a separator, marked danger.
  • Escape closes; so does a click outside.
  • shortcut is a display hint only — it renders the text, it doesn't bind the key. Register the real shortcut yourself.
  • Align right when the trigger sits at the right edge, or the menu will overflow.