EQTY Lab Equality

Dropdown Menu

A menu of actions or options triggered by a button

View as Markdown

Overview

A dropdown menu displays a list of actions or options in a floating panel anchored to a trigger. Use it for contextual actions, account menus, view options, and settings. It supports labels, separators, checkboxes, radio groups, keyboard shortcuts, grouping, and nested submenus, and is fully keyboard navigable.

Usage

Import the components:

ts
import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
} from "@eqtylab/equality";

Basic usage:

jsx
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button size="sm" variant="tertiary">
      Open Menu
    </Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent align="start">
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Settings</DropdownMenuItem>
    <DropdownMenuItem variant="danger">Logout</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Variants

With Separators and Labels

Use DropdownMenuLabel to title a section and DropdownMenuSeparator to divide groups of items. Items accept icons as children alongside a <span> label.

jsx
<DropdownMenuContent align="start">
  <DropdownMenuLabel>My Account</DropdownMenuLabel>
  <DropdownMenuSeparator />
  <DropdownMenuItem>
    <User />
    <span>Profile</span>
  </DropdownMenuItem>
  <DropdownMenuItem>
    <Settings />
    <span>Settings</span>
  </DropdownMenuItem>
  <DropdownMenuSeparator />
  <DropdownMenuItem>
    <LogOut />
    <span>Logout</span>
  </DropdownMenuItem>
</DropdownMenuContent>

With Checkboxes

Use DropdownMenuCheckboxItem for options that toggle on and off independently. Control each item with checked and onCheckedChange.

jsx
const [showStatusBar, setShowStatusBar] = useState(true);

<DropdownMenuCheckboxItem
  checked={showStatusBar}
  onCheckedChange={setShowStatusBar}
>
  Status Bar
</DropdownMenuCheckboxItem>;

With Radio Items

Use DropdownMenuRadioGroup with DropdownMenuRadioItem to select a single option from a set. The group is controlled with value and onValueChange.

jsx
const [position, setPosition] = useState("bottom");

<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
  <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
  <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
  <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>;

With Shortcuts

Use DropdownMenuShortcut to display a keyboard shortcut hint aligned to the end of an item.

jsx
<DropdownMenuItem>
  <span>New Tab</span>
  <DropdownMenuShortcut>⌘T</DropdownMenuShortcut>
</DropdownMenuItem>

With Submenu

Use DropdownMenuSub, DropdownMenuSubTrigger, and DropdownMenuSubContent to nest a menu inside an item. The submenu opens on hover or keyboard focus.

jsx
<DropdownMenuSub>
  <DropdownMenuSubTrigger>
    <span>More Tools</span>
  </DropdownMenuSubTrigger>
  <DropdownMenuSubContent>
    <DropdownMenuItem>Save Page As...</DropdownMenuItem>
    <DropdownMenuItem>Create Shortcut...</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Developer Tools</DropdownMenuItem>
  </DropdownMenuSubContent>
</DropdownMenuSub>

With Groups

Wrap related items in DropdownMenuGroup to associate a label with its items for assistive technology.

jsx
<DropdownMenuGroup>
  <DropdownMenuLabel>File</DropdownMenuLabel>
  <DropdownMenuItem>
    <span>New File</span>
    <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
  </DropdownMenuItem>
  <DropdownMenuItem>
    <span>Open File</span>
    <DropdownMenuShortcut>⌘O</DropdownMenuShortcut>
  </DropdownMenuItem>
</DropdownMenuGroup>

Slots

NameDescription
DropdownMenuRoot component, manages open state
DropdownMenuTriggerElement that opens the menu on click
DropdownMenuContentFloating panel containing the menu items
DropdownMenuItemA single actionable menu item
DropdownMenuCheckboxItemA toggleable item with a checkmark indicator
DropdownMenuRadioGroupGroups radio items into a single-select set
DropdownMenuRadioItemA single-select item within a radio group
DropdownMenuLabelNon-interactive section title
DropdownMenuSeparatorDivider between groups of items
DropdownMenuShortcutKeyboard shortcut hint aligned to the item’s end
DropdownMenuGroupGroups related items for assistive technology
DropdownMenuSubRoot for a nested submenu
DropdownMenuSubTriggerItem that opens a nested submenu
DropdownMenuSubContentFloating panel for a nested submenu

Props

NameDescriptionTypeDefaultRequired
openControls the open stateboolean-
defaultOpenOpen state when initially renderedboolean-
onOpenChangeCalled when the open state changes(open: boolean) => void-
NameDescriptionTypeDefaultRequired
asChildMerge props onto the child instead of rendering a buttonbooleanfalse
NameDescriptionTypeDefaultRequired
alignAlignment against the triggerstart, center, endcenter
sideSide of the trigger to render ontop, right, bottom, leftbottom
sideOffsetDistance in pixels from the triggernumber4
NameDescriptionTypeDefaultRequired
variantVisual style; danger marks a destructive actionneutral, dangerneutral
insetAdds left padding to align with items that have iconsbooleanfalse
disabledPrevents interaction and dims the itembooleanfalse
onSelectCalled when the item is selected() => void-
NameDescriptionTypeDefaultRequired
checkedWhether the item is checkedboolean-
onCheckedChangeCalled when the checked state changes(checked: boolean) => void-
disabledPrevents interaction and dims the itembooleanfalse
NameDescriptionTypeDefaultRequired
valueThe value of the selected itemstring-
onValueChangeCalled when the selected value changes(value: string) => void-
NameDescriptionTypeDefaultRequired
valueThe unique value of the itemstring-
disabledPrevents interaction and dims the itembooleanfalse
NameDescriptionTypeDefaultRequired
insetAdds left padding to align with items that have iconsbooleanfalse