Components / Actions

DropdownMenu

A focused list of actions anchored to a trigger.

Install

npx shadcn@latest add https://irisui.dev/r/dropdown-menu.json
import { DropdownMenu } from "@/components/iris/dropdown-menu/dropdown-menu";
Registry item dropdown-menuBrings in foundationRegistry JSON

Preview

DropdownMenu

A focused list of actions anchored to a labelled trigger, with one highlight that glides between items for the pointer and jumps for the keyboard.

When to use

  • Sort, filter and "more" menus in headers and toolbars, where the trigger label shows the current choice ("Newest first").
  • A handful of actions with icons, an optional separator and a destructive item at the end.
  • For a default action plus alternatives, use SplitButton. For actions on right-click of an object, use ContextMenu. For an account menu behind an avatar, use UserMenu.

Usage

import { DropdownMenu } from "@/components/iris/dropdown-menu/dropdown-menu";

<DropdownMenu
  label={sort}
  icon={<SortIcon size={15} />}
  items={[
    { label: "Newest first", onSelect: () => setSort("Newest first") },
    { label: "Largest first", onSelect: () => setSort("Largest first") },
    { label: "Show archived", separatorBefore: true, disabled: true },
    { label: "Clear all filters", destructive: true, onSelect: clearFilters },
  ]}
/>;

Props

Prop Type Default Description
label string — Trigger text (required). When it changes, the new label rises in and the trigger width springs to fit.
items DropdownItem[] — Required: { label, onSelect?, disabled?, icon?, destructive?, separatorBefore? }. label is also the React key, so keep labels unique.
icon ReactNode — Optional icon before the trigger label.

Notes

  • Built on Radix DropdownMenu: opens on press or Enter/Space/ArrowDown, arrow keys loop through items, typeahead works, Escape closes and returns focus to the trigger. The menu is modal while open.
  • The menu portals to <body>, aligns to the trigger's end edge with a 6px offset and keeps 12px from the viewport edges.
  • There is no open/defaultOpen prop; the open state is internal.
  • Destructive items and their highlight use --red. Reduced motion removes the label morph and the gliding highlight.