JGuang

ContextMenu

ContextMenu · Astryx

Preview
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

ContextMenu

A right-click context menu that appears at the cursor position. Use to provide contextual actions for specific elements or regions without cluttering the UI with visible buttons.

Installation

npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

Requires React 19+, base CSS and a Theme provider. See Setup.

Context Menu

A right-click context menu that appears at the cursor position. Use to provide contextual actions for specific elements or regions without cluttering the UI with visible buttons.

PropTypeDefaultDescription
children *ReactNodeThe trigger area: right-click on this content to open the menu.
items *ContextMenuOption[]Array of menu entries. Each entry is one of: an action item {label, onClick?, icon?, isDisabled?, variant?, items?} (nested items open a flyout in popover presentation and drill into a new view in bottom-sheet presentation; variant "destructive" renders it in the error color), a divider {type: "divider"}, or a section {type: "section", title?, items: [...action items]}.
menuContentReactNodeCustom JSX menu content for compound mode. Use instead of items for dynamic or stateful menus.
menuWidthnumber | string'160px'Custom menu width.
size'sm' | 'md' | 'lg''md'Size of menu items: controls padding density.
labelstring'Context menu'Accessible name for the menu surface, announced when it opens.
onOpenChange(isOpen: boolean) => voidCallback fired when the menu opens or closes.
presentation'popover' | 'bottom-sheet' | 'adaptive''popover'Presentation policy. popover opens at the pointer position, bottom-sheet always uses an action sheet, and adaptive uses the BottomSheet at 768px and below when the primary pointer is coarse.
isDisabledbooleanfalseWhen true, right-click shows the native browser context menu instead.
triggerXstyleStyleXStyles | StyleXStyles[]Styles applied to the trigger wrapper. Accepts stylex.create() values, not inline style objects.
triggerAs'div' | 'span''div'The element the trigger wrapper renders as. 'div' is a block; 'span' an inline wrapper, so a reference inside prose can own a context menu without breaking the text flow.

Usage guidance

  • Keep menu items concise and action-oriented; users expect quick access to contextual actions.
  • Use sections and dividers to group related actions when the menu has many items.
  • Use presentation="adaptive" when right-click should remain cursor-positioned on desktop while long-press opens a reachable BottomSheet on compact touch devices.
  • Ensure all context menu actions are also accessible via other UI elements for keyboard-only users.
  • Keep a visible MoreMenu or equivalent trigger for important mobile actions; long-press must not be the only route.
  • Avoid: Use a ContextMenu as the only way to access important actions; not all users know to right-click.
  • Avoid: Place more than 10–12 items in a single menu without grouping them into sections.

Theming API

{
  "targets": [
    {
      "className": "astryx-context-menu"
    }
  ],
  "vars": [
    {
      "name": "--_dropdown-menu-radius",
      "description": "Border radius of the menu popup",
      "default": "var(--radius-container)",
      "private": true
    },
    {
      "name": "--_dropdown-menu-padding",
      "description": "Inner padding of the menu popup",
      "default": "var(--spacing-1)",
      "private": true
    }
  ],
  "derived": [
    {
      "property": "borderRadius",
      "vars": [
        "--_dropdown-menu-radius"
      ]
    },
    {
      "property": "padding",
      "vars": [
        "--_dropdown-menu-padding"
      ]
    }
  ]
}

ContextMenuItem

Anatomy

  • Trigger area: Caller-provided region that accepts right-click, keyboard context-menu, and long-press input.
  • Pointer menu surface: Cursor-positioned menu panel used by the pointer presentation.
  • Pointer action row: DropdownMenu-owned action, selectable option, or submenu row in the pointer presentation.
  • Touch sheet frame: BottomSheet panel, content area, handle, and optional scrim that host touch actions.
  • Touch menu surface: ContextMenu-owned content panel rendered inside the touch sheet frame.
  • Touch action list: Spacious List that groups data-driven touch actions.
  • Touch action row: ListItem button used for a data-driven action or drill-in entry in the touch presentation.

Context Menu Item

Menu item component for compound mode. Re-exported from DropdownMenuItem for discoverability.

PropTypeDefaultDescription
iconIconTypeIcon to display before the label.
labelReactNodePrimary label text.
descriptionReactNodeSecondary description text displayed below the label.
endContentReactNodeAdditional content rendered after the label and description.
xstyleStyleXStylesStyleX styles for layout customization.

Examples

  • Context Menu Item: Context menu with custom-rendered items using ContextMenuItem for icons and descriptions.
  • Context Menu: An adaptive context area that supports long-press on compact touch screens and right-click elsewhere.
  • ContextMenu — Basic: An adaptive context area: long-press opens a BottomSheet on compact touch screens, while right-click opens a cursor-positioned menu elsewhere.
  • ContextMenu — Bottom Sheet: A ContextMenu using the explicit BottomSheet presentation. Long-press the target on touch devices or right-click it with a pointer. Keep a visible menu trigger for important mobile actions.
  • ContextMenuItem — Basic: Context menu items with labels and secondary descriptions. Use ContextMenuItem to render custom menu entries with consistent styling.

Complete example dependencies

Some examples import optional icons. The per-example install command in the examples list identifies exactly what that example needs. For all examples on this page:

npm install @heroicons/react@2.2.0