GitHub

Dropdown Menu

A menu of actions or options triggered by a button.

CMSPayload CMS Integration

Dropdown menus can display CMS-configured actions for content management, such as publishing options, export formats, or content operations.

CMS Demo

See how content editors configure dropdown menus in a CMS:

Loading...
CMS ConfigurationSimulates Payload CMS dropdown configuration

Basic Usage

Loading...
Dropdown MenuButton-triggered menu

Installation

pnpm add @corew500/ui

Usage

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
} from "@mordecai-design-system/ui"
<DropdownMenu>
  <DropdownMenuTrigger>Open</DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuItem>Edit</DropdownMenuItem>
    <DropdownMenuItem>Delete</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Examples

With Groups

<DropdownMenuContent>
  <DropdownMenuGroup>
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Settings</DropdownMenuItem>
  </DropdownMenuGroup>
  <DropdownMenuSeparator />
  <DropdownMenuItem>Logout</DropdownMenuItem>
</DropdownMenuContent>

With Submenus

<DropdownMenuContent>
  <DropdownMenuItem>New File</DropdownMenuItem>
  <DropdownMenuSub>
    <DropdownMenuSubTrigger>Share</DropdownMenuSubTrigger>
    <DropdownMenuSubContent>
      <DropdownMenuItem>Email</DropdownMenuItem>
      <DropdownMenuItem>Slack</DropdownMenuItem>
    </DropdownMenuSubContent>
  </DropdownMenuSub>
</DropdownMenuContent>

With Checkboxes

const [showPanel, setShowPanel] = useState(true)

<DropdownMenuCheckboxItem
  checked={showPanel}
  onCheckedChange={setShowPanel}
>
  Show Panel
</DropdownMenuCheckboxItem>

With Radio Items

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

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

Destructive Items

<DropdownMenuItem variant="destructive">
  Delete
</DropdownMenuItem>

With Shortcuts

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

Sub-components

| Component | Description | |-----------|-------------| | DropdownMenu | Root component | | DropdownMenuTrigger | Button that opens the menu | | DropdownMenuContent | The popup content | | DropdownMenuItem | Clickable menu item | | DropdownMenuCheckboxItem | Checkable menu item | | DropdownMenuRadioGroup | Group of radio items | | DropdownMenuRadioItem | Selectable radio item | | DropdownMenuLabel | Non-interactive label | | DropdownMenuSeparator | Visual divider | | DropdownMenuShortcut | Keyboard shortcut hint | | DropdownMenuGroup | Grouping container | | DropdownMenuSub | Submenu container | | DropdownMenuSubTrigger | Submenu trigger | | DropdownMenuSubContent | Submenu content |

Props

DropdownMenuItem

PropTypeDefaultDescription
onClickMouseEventHandler<HTMLElement>The click handler for the menu item.
disabledenumfalseWhether the component should ignore user interaction.
labelstringOverrides the text label to use when the item is matched during keyboard text navigation.
idstring@ignore
closeOnClickenumtrueWhether to close the menu when the item is clicked.
nativeButtonenumtrueWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (e.g. `<div>`).
styleenumStyle applied to the element, or a function that returns a style object based on the component’s state.
classNameenumCSS class applied to the element, or a function that returns a class based on the component’s state.
renderenumAllows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
insetenum
variantenumdefault

DropdownMenuContent

PropTypeDefaultDescription
idstring@ignore
finalFocusenumDetermines the element to focus when the menu is closed. - `false`: Do not move focus. - `true`: Move focus based on the default behavior (trigger or previously focused element). - `RefObject`: Move focus to the ref element. - `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`). Return an element to focus, `true` to use the default behavior, or `false`/`undefined` to do nothing.
styleenumStyle applied to the element, or a function that returns a style object based on the component’s state.
classNameenumCSS class applied to the element, or a function that returns a class based on the component’s state.
renderenumAllows you to replace the component’s HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render.
alignenumstartHow to align the popup relative to the specified side.
alignOffsetenum0Additional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner alignOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.width : anchor.height; }} /> ```
sideenumbottomWhich side of the anchor element to align the popup against. May automatically change to avoid collisions.
sideOffsetenum4Distance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment. The function takes a `data` object parameter with the following properties: - `data.anchor`: the dimensions of the anchor element with properties `width` and `height`. - `data.positioner`: the dimensions of the positioner element with properties `width` and `height`. - `data.side`: which side of the anchor element the positioner is aligned against. - `data.align`: how the positioner is aligned relative to the specified side. @example ```jsx <Positioner sideOffset={({ side, align, anchor, positioner }) => { return side === 'top' || side === 'bottom' ? anchor.height : anchor.width; }} /> ```

Keyboard Navigation

| Key | Action | |-----|--------| | | Navigate items | | Enter Space | Select item | | | Open submenu | | | Close submenu | | Esc | Close menu |