{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "context-menu",
  "title": "Context Menu",
  "description": "An animated context menu for React and shadcn, opened by right-click or long-press, with submenus.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "https://eased.dev/r/eased-tokens.json",
    "https://eased.dev/r/eased-floating.json",
    "https://eased.dev/r/eased-overlay-core.json",
    "https://eased.dev/r/dropdown-menu.json"
  ],
  "files": [
    {
      "path": "src/registry/eased/context-menu/context-menu.tsx",
      "content": "\"use client\";\n\nimport { ContextMenu as BaseContextMenu } from \"@base-ui/react/context-menu\";\nimport type { ComponentProps } from \"react\";\nimport { FloatingLayer } from \"../_primitives/floating/floating\";\nimport { HighlightGroup, menuSurface, OVERLAY_ROLES } from \"../_primitives/overlay-core/overlay-core\";\nimport {\n  DropdownMenuCheckboxItem,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuLinkItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  MenuFlashContext,\n  useMenuFlash,\n  type DropdownMenuContentProps,\n} from \"../dropdown-menu/dropdown-menu\";\n\n/**\n * A context menu on Base UI's ContextMenu. It appears at the pointer on right click, or on a\n * 500ms long press on touch, with no enter animation (rule 84: a right-click is high-frequency)\n * and its transform-origin at the cursor; it fades out in 100ms. Rows are Dropdown Menu's:\n * Base UI's ContextMenu re-exports Menu's parts, so every row, the gliding highlight and the\n * selection blink are shared, not copied.\n */\n\nexport type ContextMenuProps = ComponentProps<typeof BaseContextMenu.Root>;\n\n/**\n * Groups a context menu's parts and owns its open state (`open` / `defaultOpen` / `onOpenChange`).\n * Lets rows blink before it closes; `actionsRef` still reaches Base UI's `close` and `unmount`.\n */\nexport function ContextMenu({ actionsRef, children, ...props }: ContextMenuProps) {\n  const { ref, flash } = useMenuFlash(actionsRef);\n  return (\n    <MenuFlashContext value={flash}>\n      <BaseContextMenu.Root {...props} actionsRef={ref}>\n        {children}\n      </BaseContextMenu.Root>\n    </MenuFlashContext>\n  );\n}\n\nexport type ContextMenuTriggerProps = Omit<ComponentProps<typeof BaseContextMenu.Trigger>, \"className\"> & {\n  /** The region's classes. It renders a `<div>`; pass `render` for another element. */\n  className?: string;\n};\n\n/**\n * The region that opens the menu on right click and on a 500ms long press on touch (moving more\n * than 10px cancels it, so scrolling still works). Base UI suppresses the iOS callout; text in\n * the region is unselectable on coarse pointers so a long press opens the menu instead of a selection.\n */\nexport function ContextMenuTrigger({ className = \"\", ...props }: ContextMenuTriggerProps) {\n  return <BaseContextMenu.Trigger {...props} className={`pointer-coarse:select-none ${className}`} />;\n}\n\n/*\n * Base UI places a context menu just right of and above the pointer (align start, 2px along,\n * −5px on the side axis) so the pointer lands on the first row. FloatingLayer always passes a\n * side, which turns off that default, so the same numbers are set here.\n */\nconst AT_CURSOR = { sideOffset: -5, alignOffset: 2 } as const;\n\nexport type ContextMenuContentProps = Pick<\n  DropdownMenuContentProps,\n  \"finalFocus\" | \"container\" | \"zIndex\" | \"width\" | \"className\" | \"children\"\n>;\n\n/** The menu popup at the pointer: Dropdown Menu's surface and tracks, appearing at once and fading out in 100ms. */\nexport function ContextMenuContent({ finalFocus, container, zIndex, width, className = \"\", children }: ContextMenuContentProps) {\n  return (\n    <FloatingLayer\n      parts={BaseContextMenu}\n      motion={OVERLAY_ROLES.context}\n      side={OVERLAY_ROLES.context.side}\n      align=\"start\"\n      sideOffset={AT_CURSOR.sideOffset}\n      alignOffset={AT_CURSOR.alignOffset}\n      container={container}\n      zIndex={zIndex}\n      popupProps={{ finalFocus }}\n      style={width ? { width } : undefined}\n      className={`${menuSurface} ${className}`}\n    >\n      <HighlightGroup>{children}</HighlightGroup>\n    </FloatingLayer>\n  );\n}\n\n/** A command row; blinks, then closes the menu. See `DropdownMenuItem`. */\nexport const ContextMenuItem = DropdownMenuItem;\n/** A row that navigates. See `DropdownMenuLinkItem`. */\nexport const ContextMenuLinkItem = DropdownMenuLinkItem;\n/** A toggle row; the menu stays open. See `DropdownMenuCheckboxItem`. */\nexport const ContextMenuCheckboxItem = DropdownMenuCheckboxItem;\n/** One choice among its radio items. See `DropdownMenuRadioGroup`. */\nexport const ContextMenuRadioGroup = DropdownMenuRadioGroup;\n/** One option of a radio group. See `DropdownMenuRadioItem`. */\nexport const ContextMenuRadioItem = DropdownMenuRadioItem;\n/** A nested menu. See `DropdownMenuSub`. */\nexport const ContextMenuSub = DropdownMenuSub;\n/** The row that opens a submenu. See `DropdownMenuSubTrigger`. */\nexport const ContextMenuSubTrigger = DropdownMenuSubTrigger;\n/** The submenu popup beside its row. See `DropdownMenuSubContent`. */\nexport const ContextMenuSubContent = DropdownMenuSubContent;\n/** Related rows under a label. See `DropdownMenuGroup`. */\nexport const ContextMenuGroup = DropdownMenuGroup;\n/** A group's heading. See `DropdownMenuLabel`. */\nexport const ContextMenuLabel = DropdownMenuLabel;\n/** A full-bleed rule between groups. See `DropdownMenuSeparator`. */\nexport const ContextMenuSeparator = DropdownMenuSeparator;\n\nexport type {\n  DropdownMenuCheckboxItemProps as ContextMenuCheckboxItemProps,\n  DropdownMenuGroupProps as ContextMenuGroupProps,\n  DropdownMenuItemProps as ContextMenuItemProps,\n  DropdownMenuLabelProps as ContextMenuLabelProps,\n  DropdownMenuLinkItemProps as ContextMenuLinkItemProps,\n  DropdownMenuRadioGroupProps as ContextMenuRadioGroupProps,\n  DropdownMenuRadioItemProps as ContextMenuRadioItemProps,\n  DropdownMenuSubContentProps as ContextMenuSubContentProps,\n  DropdownMenuSubTriggerProps as ContextMenuSubTriggerProps,\n} from \"../dropdown-menu/dropdown-menu\";\n",
      "type": "registry:ui",
      "target": "@components/eased/context-menu/context-menu.tsx"
    }
  ],
  "meta": {
    "details": "A right-click and long-press menu that appears at the cursor with no enter animation and fades out in 100ms. Its rows are Dropdown Menu's: gliding highlight, blink on select, submenus.",
    "industries": [
      "devtools",
      "media",
      "saas"
    ],
    "releaseAt": "2026-10-21"
  },
  "type": "registry:ui"
}