EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
DropdownMenu·component·@astryxdesign/core

Dropdown Menu

Action menu with a trigger button and anchored, bottom-sheet, or adaptive presentation.

Open in Playground @astryxdesign/core/DropdownMenu

Showcases and examples

7 documented examples

Dropdown Menu

A button that opens a dropdown menu with action items. The menu starts open for preview.

Preview loads on approachPreview loads on approach
Exact source · dropdown-menu-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {DropdownMenu} from '@astryxdesign/core/DropdownMenu';

export default function DropdownMenuShowcase() {
  return (
    <DropdownMenu
      button={{label: 'Actions'}}
      items={[
        {label: 'Edit', onClick: () => {}},
        {label: 'Duplicate', onClick: () => {}},
        {label: 'Delete', onClick: () => {}},
      ]}
    />
  );
}

Usage

A dropdown menu that displays a list of actionable items in a popup triggered by a button. Use to present action options as a next step in a process, or to offer contextual actions without cluttering the interface.

  • Keep menu items concise and action-oriented so users can scan options quickly.
  • Use sections and dividers to group related actions when the menu has many items.
  • For a short, flat action set, use presentation="bottom-sheet" when product policy calls for a modal touch surface.
  • Use presentation="adaptive" when the same short action set should remain anchored on pointer layouts and become a BottomSheet on compact coarse-pointer layouts.
  • For a hierarchy that cannot fit as adjacent flyouts on a compact touch surface, a product may explicitly use a drill-in interaction with a Back action.
  • Choose presentation explicitly in product code. A compact, coarse-pointer, hover-free media query is one useful policy, but DropdownMenu does not impose a universal device breakpoint.
  • When the content is no longer a short list of immediate actions, reevaluate the interaction and choose a component that matches the actual task; content traits alone do not determine the component.
  • Use a DropdownMenu for navigation; use a navigation component instead.
  • Place more than 10–12 items in a single menu without grouping them into sections.

Typed props

PropType and behavior
buttonDropdownMenuButtonProps · default { label: 'Menu' }
Props for the trigger button (Button props except onClick).
itemsDropdownMenuOption[] · required
Array of menu entries. Each entry is one of: an action item {label, onClick?, icon?, description?, endContent?, isDisabled?, variant?, hasCloseOnSelect?, id?} (variant "destructive" renders it in the error color; endContent holds trailing content such as a keyboard-shortcut hint; id is the row's stable React key, needed only when the array reorders or filters), a divider {type: "divider"}, or a section {type: "section", title?, id?, items: [...action items]}.
presentation'popover' | 'bottom-sheet' | 'adaptive' · default 'popover'
Presentation surface for data-driven items. 'popover' stays anchored, 'bottom-sheet' always renders the actions in a modal BottomSheet, and 'adaptive' uses a BottomSheet on compact coarse-pointer layouts while remaining anchored elsewhere. Compound children currently support popover only.
isMenuOpenboolean
Controlled open state for the menu. Mounting with true renders the menu open without moving focus into it; focus moves to the first item only when the menu opens after mount.
onOpenChange(isOpen: boolean) => void
Callback fired when the open state changes.
menuWidthnumber | string
Minimum width for the popover presentation. Length values may grow for content; intrinsic and CSS-wide keywords select the preferred inline size. Every form is capped to the available viewport space. Defaults to matching the trigger width up to that cap.
placement'above' | 'below' | 'start' | 'end' · default 'below'
Popover placement relative to the trigger. Ignored by the bottom-sheet presentation. Logical: start/end resolve against the menu's own inherited direction (RTL mirrors).
alignment'start' | 'center' | 'end' · default 'start'
Popover alignment along the placement axis. Ignored by the bottom-sheet presentation. Logical: start/end follow the menu's own inherited direction (RTL mirrors).
onClick() => void
Callback fired for accepted trigger activation. The trailing click from the same press that light-dismissed the menu is ignored.
hasChevronboolean · default true
Whether to show a chevron icon on the trigger button. Set to false for icon-only triggers.
childrenReactNode
Compound-mode menu content: DropdownMenuItem, DropdownMenuDivider, DropdownMenuSubMenu, and the selectable items. Mutually exclusive with items.

Anatomy

Trigger button · required

Button that opens and closes the selected menu presentation.

Trigger indicator icon · optional

Optional trailing chevron shown by a labeled trigger when hasChevron is enabled.

Pointer menu surface · optional

Anchored top-level or nested menu panel used by the pointer presentation.

Pointer action row · optional

Action, selectable option, or submenu trigger row in an anchored menu.

Icon-rendered item icon · optional

Optional semantic or component icon rendered through Icon at the start of an action row.

Caller-rendered item start content · optional

Optional arbitrary React content rendered directly at the start of an action row.

Checkbox indicator · optional

Decorative shared checkbox indicator for a checkbox action row.

Radio indicator · optional

Decorative shared radio indicator with an additional menu-owned target.

Pointer section heading · optional

Heading that labels a data-driven section in an anchored menu.

Pointer divider · optional

Divider between groups in an anchored menu.

Pointer submenu indicator icon · optional

Trailing chevron that identifies an action row as a nested flyout trigger.

Touch sheet frame · optional

BottomSheet panel, content area, handle, and optional scrim that host touch actions.

Touch menu surface · optional

Menu-owned content panel rendered inside the touch sheet frame.

Touch heading · optional

Current action-sheet title, updated when a nested action view is opened.

Touch action list · optional

Spacious List that groups actions in the touch presentation.

Touch action row · optional

ListItem button used for an action or drill-in entry in the touch presentation.

Touch divider · optional

Divider between action groups in the touch presentation.

Theming

Targets

astryx-dropdown-menu

Visual props: presentation

astryx-dropdown-menu-item

Visual props: size, variant

astryx-dropdown-menu-radio

Visual props: size

States: checked, disabled

astryx-dropdown-menu-section-heading
astryx-dropdown-menu-divider
astryx-dropdown-menu-indicator-icon

Variables

--_dropdown-menu-radius · private

Border radius of the menu popup

Default: var(--radius-element)

--_dropdown-menu-padding · private

Inner padding of the menu popup

Default: var(--spacing-1)

Derived properties

borderRadius

Uses --_dropdown-menu-radius.

padding

Uses --_dropdown-menu-padding.