{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "b-context-menu",
  "type": "registry:ui",
  "registryDependencies": [],
  "dependencies": ["@base-ui/react", "motion", "lucide-react"],
  "devDependencies": [],
  "files": [
    {
      "path": "b-context-menu.tsx",
      "content": "\"use client\";\n\nimport { ContextMenu as ContextMenuPrimitive } from \"@base-ui/react/context-menu\";\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui/react/scroll-area\";\nimport { Check, ChevronRight } from \"lucide-react\";\nimport { MotionConfig, motion, useReducedMotion } from \"motion/react\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst controlCornerClassName =\n  \"rounded-lg supports-[corner-shape:squircle]:corner-squircle supports-[corner-shape:squircle]:rounded-[11px]\";\n\nconst controlCornerInheritClassName =\n  \"rounded-[inherit] supports-[corner-shape:squircle]:[corner-shape:inherit]\";\n\nconst contextMenuThemeClassName =\n  \"[--cm-surface:var(--popover,#ffffff)] [--cm-foreground:var(--popover-foreground,#111111)] [--cm-border:var(--border,#e3e7ec)] [--cm-muted-foreground:var(--muted-foreground,#6d7480)] [--cm-accent:var(--accent,#f3f5f8)] [--color-accent:var(--cm-accent)] [--color-accent-foreground:var(--cm-accent-foreground)] [--cm-accent-foreground:var(--accent-foreground,#111111)] [--cm-destructive:var(--destructive,#dc2626)] [--cm-ring:var(--ring,rgba(17,17,17,0.16))] dark:[--cm-surface:var(--popover,#111111)] dark:[--cm-foreground:var(--popover-foreground,#f6f3ec)] dark:[--cm-border:var(--border,#2b2a25)] dark:[--cm-muted-foreground:var(--muted-foreground,#9a958a)] dark:[--cm-accent:var(--accent,#1a1a18)] dark:[--cm-accent-foreground:var(--accent-foreground,#f6f3ec)] dark:[--cm-destructive:var(--destructive,#f87171)] dark:[--cm-ring:var(--ring,rgba(246,243,236,0.18))]\";\n\nconst ITEM_HEIGHT = 44;\n\nconst contextMenuPanelChromeClassName = cn(\n  controlCornerClassName,\n  \"z-50 min-w-[232px] overflow-hidden border border-[color:color-mix(in_oklch,var(--cm-border),transparent_40%)] bg-[color:var(--cm-surface)] text-[color:var(--cm-foreground)] shadow-lg\"\n);\n\nconst contextMenuPanelScrollbarClassName =\n  \"z-10 my-1.5 mr-0.5 w-1 shrink-0 touch-none select-none opacity-0 transition-opacity duration-150 before:absolute before:left-1/2 before:h-full before:w-5 before:-translate-x-1/2 before:content-[''] data-hovering:pointer-events-auto data-hovering:opacity-100 data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-0\";\n\nconst contextMenuPanelThumbClassName =\n  \"relative rounded-full bg-[color:color-mix(in_oklch,var(--cm-muted-foreground),transparent_35%)]\";\n\nexport const contextMenuTriggerClassName =\n  \"select-none outline-none focus-visible:ring-2 focus-visible:ring-[color:color-mix(in_oklch,var(--cm-ring),transparent_50%)] focus-visible:ring-offset-2 focus-visible:ring-offset-[color:var(--cm-surface)]\";\n\nconst contextMenuItemHighlightClassName = cn(\n  controlCornerInheritClassName,\n  \"absolute inset-0 bg-[color:var(--cm-accent)]\"\n);\n\nconst contextMenuItemClassName = cn(\n  controlCornerClassName,\n  \"group/context-menu-item relative flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-left font-medium text-sm outline-none transition-colors\"\n);\n\nconst contextMenuSubTriggerClassName = cn(\n  controlCornerClassName,\n  \"group/context-menu-item relative flex w-full cursor-pointer items-center gap-2.5 px-3 py-2.5 text-left font-medium text-sm outline-none transition-colors\"\n);\n\nconst contextMenuIndicatorItemClassName = cn(\n  controlCornerClassName,\n  \"group/context-menu-item relative flex w-full cursor-pointer items-center gap-2.5 py-2.5 pr-8 pl-3 text-left font-medium text-sm outline-none transition-colors\"\n);\n\nconst contextMenuItemDefaultClassName =\n  \"text-[color:color-mix(in_oklch,var(--cm-foreground),transparent_15%)]\";\n\nconst contextMenuItemDestructiveClassName =\n  \"text-[color:var(--cm-destructive)]\";\n\nconst contextMenuItemDisabledClassName =\n  \"pointer-events-none cursor-not-allowed text-[color:var(--cm-muted-foreground)] opacity-50 data-popup-open:bg-transparent data-popup-open:text-[color:var(--cm-muted-foreground)] [&_svg]:text-[color:var(--cm-muted-foreground)] [&_svg]:opacity-70\";\n\nconst contextMenuSubTriggerOpenClassName =\n  \"data-popup-open:bg-[color:var(--cm-accent)] data-popup-open:text-[color:var(--cm-accent-foreground)]\";\n\nconst contextMenuShortcutClassName =\n  \"relative z-10 ml-auto text-[color:color-mix(in_oklch,var(--cm-muted-foreground),transparent_30%)] text-xs tracking-widest opacity-70 transition-opacity group-focus-visible/context-menu-item:opacity-100 group-hover/context-menu-item:opacity-100 group-data-[disabled]/context-menu-item:text-[color:var(--cm-muted-foreground)] group-data-[disabled]/context-menu-item:opacity-50\";\n\ntype DivRenderProps = React.HTMLAttributes<HTMLDivElement> & {\n  children?: React.ReactNode;\n  className?: string;\n  ref?: React.Ref<HTMLDivElement>;\n  style?: React.CSSProperties;\n};\n\ntype ButtonRenderProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n  children?: React.ReactNode;\n  className?: string;\n  ref?: React.Ref<HTMLButtonElement>;\n  style?: React.CSSProperties;\n};\n\ntype TriggerElementProps = React.HTMLAttributes<HTMLElement> & {\n  className?: string;\n};\n\ntype TriggerChildElement = React.ReactElement<\n  TriggerElementProps & React.RefAttributes<HTMLElement>\n>;\n\ntype ContextMenuContextValue = {\n  actionsRef: React.RefObject<ContextMenuPrimitive.Root.Actions | null>;\n  open: boolean;\n};\n\ntype PanelContextValue = {\n  activeItemId: string | undefined;\n  panelId: string;\n  setActiveItemId: React.Dispatch<React.SetStateAction<string | undefined>>;\n};\n\nconst ContextMenuContext = React.createContext<ContextMenuContextValue | null>(\n  null\n);\n\nconst PanelContext = React.createContext<PanelContextValue | null>(null);\n\nfunction useContextMenu(componentName: string) {\n  const context = React.useContext(ContextMenuContext);\n\n  if (!context) {\n    throw new Error(`${componentName} must be used within ContextMenu.`);\n  }\n\n  return context;\n}\n\nfunction useContextMenuPanel(componentName: string) {\n  const context = React.useContext(PanelContext);\n\n  if (!context) {\n    throw new Error(`${componentName} must be used within ContextMenuContent.`);\n  }\n\n  return context;\n}\n\nfunction isContextMenuKeyboardShortcut(\n  event: React.KeyboardEvent<HTMLElement>\n) {\n  return event.key === \"ContextMenu\" || (event.shiftKey && event.key === \"F10\");\n}\n\nfunction dispatchContextMenuFromKeyboard(target: HTMLElement) {\n  const rect = target.getBoundingClientRect();\n\n  target.dispatchEvent(\n    new MouseEvent(\"contextmenu\", {\n      bubbles: true,\n      cancelable: true,\n      clientX: rect.left + Math.min(rect.width / 2, 24),\n      clientY: rect.bottom,\n    })\n  );\n}\n\nfunction setRef<T>(ref: React.Ref<T> | undefined, value: T) {\n  if (typeof ref === \"function\") {\n    ref(value);\n    return;\n  }\n\n  if (ref) {\n    (ref as React.MutableRefObject<T>).current = value;\n  }\n}\n\nfunction composeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n  return (value: T) => {\n    for (const ref of refs) {\n      setRef(ref, value);\n    }\n  };\n}\n\nfunction composeEventHandlers<Event extends React.SyntheticEvent>(\n  originalEventHandler: ((event: Event) => void) | undefined,\n  eventHandler: (event: Event) => void\n) {\n  return (event: Event) => {\n    originalEventHandler?.(event);\n    eventHandler(event);\n  };\n}\n\nfunction getElementRef<T>(element: React.ReactElement) {\n  return (\n    (\n      element as React.ReactElement & {\n        ref?: React.Ref<T>;\n        props: { ref?: React.Ref<T> };\n      }\n    ).ref ??\n    (\n      element as React.ReactElement & {\n        ref?: React.Ref<T>;\n        props: { ref?: React.Ref<T> };\n      }\n    ).props.ref\n  );\n}\n\nfunction resolvePopupProps(popupProps: DivRenderProps) {\n  const {\n    children: _popupChildren,\n    className: popupClassName,\n    onAnimationEnd: _onAnimationEnd,\n    onAnimationIteration: _onAnimationIteration,\n    onAnimationStart: _onAnimationStart,\n    onDrag: _onDrag,\n    onDragEnd: _onDragEnd,\n    onDragEnter: _onDragEnter,\n    onDragExit: _onDragExit,\n    onDragLeave: _onDragLeave,\n    onDragOver: _onDragOver,\n    onDragStart: _onDragStart,\n    onDrop: _onDrop,\n    ref: popupRef,\n    style: popupStyle,\n    ...resolvedPopupProps\n  } = popupProps;\n\n  return {\n    popupClassName,\n    popupRef,\n    popupStyle,\n    resolvedPopupProps,\n  };\n}\n\nfunction resolveItemProps(itemProps: ButtonRenderProps) {\n  const {\n    children: _itemChildren,\n    className: itemClassName,\n    onAnimationEnd: _onAnimationEnd,\n    onAnimationIteration: _onAnimationIteration,\n    onAnimationStart: _onAnimationStart,\n    onDrag: _onDrag,\n    onDragEnd: _onDragEnd,\n    onDragEnter: _onDragEnter,\n    onDragExit: _onDragExit,\n    onDragLeave: _onDragLeave,\n    onDragOver: _onDragOver,\n    onDragStart: _onDragStart,\n    onDrop: _onDrop,\n    ref: itemRef,\n    style: itemStyle,\n    ...resolvedItemProps\n  } = itemProps;\n\n  return {\n    itemClassName,\n    itemRef,\n    itemStyle,\n    resolvedItemProps,\n  };\n}\n\nfunction resolveStateClassName<State>(\n  className: string | ((state: State) => string | undefined) | undefined,\n  state: State\n) {\n  return typeof className === \"function\" ? className(state) : className;\n}\n\nconst activeHighlightTransition = {\n  type: \"spring\" as const,\n  stiffness: 600,\n  damping: 38,\n};\n\nconst panelMotionVariants = {\n  closed: { opacity: 0, scale: 0.96, y: -2 },\n  open: { opacity: 1, scale: 1, y: 0 },\n};\n\nconst reducedPanelMotionVariants = {\n  closed: { opacity: 0 },\n  open: { opacity: 1 },\n};\n\nfunction getItemEntranceTransition(reduceMotion: boolean) {\n  if (reduceMotion) {\n    return { duration: 0 };\n  }\n\n  return {\n    duration: 0.12,\n    ease: [0.16, 1, 0.3, 1] as const,\n  };\n}\n\nfunction getPanelMotionTransition(reduceMotion: boolean) {\n  if (reduceMotion) {\n    return { duration: 0 };\n  }\n\n  return {\n    duration: 0.14,\n    ease: [0.16, 1, 0.3, 1] as const,\n  };\n}\n\nfunction ContextMenuPanelProvider({ children }: { children: React.ReactNode }) {\n  const panelId = React.useId();\n  const [activeItemId, setActiveItemId] = React.useState<string | undefined>();\n\n  return (\n    <PanelContext.Provider value={{ activeItemId, panelId, setActiveItemId }}>\n      {children}\n    </PanelContext.Provider>\n  );\n}\n\nfunction ContextMenuPanelScroll({ children }: { children: React.ReactNode }) {\n  return (\n    <ScrollAreaPrimitive.Root\n      className=\"relative overflow-hidden\"\n      style={{ maxHeight: \"calc(100vh - 32px)\" }}\n    >\n      <ScrollAreaPrimitive.Viewport className=\"max-h-[inherit] min-h-0 overscroll-contain outline-none\">\n        <motion.div className=\"relative overflow-x-hidden p-1.5\" layoutRoot>\n          {children}\n        </motion.div>\n      </ScrollAreaPrimitive.Viewport>\n      <ScrollAreaPrimitive.Scrollbar\n        className={contextMenuPanelScrollbarClassName}\n        orientation=\"vertical\"\n      >\n        <ScrollAreaPrimitive.Thumb className={contextMenuPanelThumbClassName} />\n      </ScrollAreaPrimitive.Scrollbar>\n    </ScrollAreaPrimitive.Root>\n  );\n}\n\nfunction renderContextMenuItemButton({\n  activeItemId,\n  baseClassName,\n  children,\n  className,\n  disabled,\n  dataVariant,\n  highlighted,\n  inset,\n  itemClassName,\n  itemId,\n  itemRef,\n  itemStyle,\n  panelId,\n  reduceMotion,\n  ref,\n  resolvedItemProps,\n  setActiveItemId,\n  slot,\n  trailing,\n  variantClassName,\n}: {\n  activeItemId: string | undefined;\n  baseClassName: string;\n  children: React.ReactNode;\n  className?: string;\n  disabled?: boolean;\n  dataVariant?: string;\n  highlighted: boolean;\n  inset?: boolean;\n  itemClassName?: string;\n  itemId: string;\n  itemRef?: React.Ref<HTMLButtonElement>;\n  itemStyle?: React.CSSProperties;\n  panelId: string;\n  reduceMotion: boolean;\n  ref?: React.Ref<HTMLButtonElement>;\n  resolvedItemProps: Omit<\n    ButtonRenderProps,\n    \"children\" | \"className\" | \"ref\" | \"style\"\n  >;\n  setActiveItemId: React.Dispatch<React.SetStateAction<string | undefined>>;\n  slot: string;\n  trailing?: React.ReactNode;\n  variantClassName?: string;\n}) {\n  const showHighlight = !disabled && (highlighted || activeItemId === itemId);\n\n  const activateItem = () => {\n    if (!disabled) {\n      setActiveItemId(itemId);\n    }\n  };\n\n  return (\n    <motion.button\n      {...(resolvedItemProps as React.ComponentPropsWithoutRef<\n        typeof motion.button\n      >)}\n      animate={reduceMotion ? undefined : { opacity: 1, x: 0 }}\n      aria-disabled={disabled}\n      className={cn(\n        baseClassName,\n        variantClassName ?? contextMenuItemDefaultClassName,\n        inset && \"pl-7\",\n        itemClassName,\n        className,\n        disabled && contextMenuItemDisabledClassName\n      )}\n      data-disabled={disabled ? \"\" : undefined}\n      data-inset={inset ? \"\" : undefined}\n      data-slot={slot}\n      data-variant={dataVariant}\n      initial={reduceMotion ? false : { opacity: 0, x: -4 }}\n      onFocus={composeEventHandlers(resolvedItemProps.onFocus, activateItem)}\n      onMouseEnter={composeEventHandlers(\n        resolvedItemProps.onMouseEnter,\n        activateItem\n      )}\n      onPointerMove={composeEventHandlers(\n        resolvedItemProps.onPointerMove,\n        activateItem\n      )}\n      ref={composeRefs(itemRef, ref)}\n      style={{\n        ...itemStyle,\n        minHeight: ITEM_HEIGHT,\n      }}\n      transition={getItemEntranceTransition(reduceMotion)}\n      type=\"button\"\n    >\n      {showHighlight ? (\n        <motion.div\n          className={contextMenuItemHighlightClassName}\n          initial={false}\n          layoutId={`${panelId}-context-menu-active`}\n          transition={\n            reduceMotion ? { duration: 0 } : activeHighlightTransition\n          }\n        />\n      ) : null}\n      <span className=\"relative z-10 flex flex-1 items-center gap-2.5\">\n        {children}\n      </span>\n      {trailing}\n    </motion.button>\n  );\n}\n\nfunction renderMotionPanel({\n  actionsRef,\n  children,\n  className,\n  popupClassName,\n  popupRef,\n  popupState,\n  popupStyle,\n  reduceMotion,\n  resolvedPopupProps,\n  unmountOnClose = true,\n}: {\n  actionsRef?: React.RefObject<ContextMenuPrimitive.Root.Actions | null>;\n  children: React.ReactNode;\n  className?: string;\n  popupClassName?: string;\n  popupRef?: React.Ref<HTMLDivElement>;\n  popupState: { open: boolean; transitionStatus?: string };\n  popupStyle?: React.CSSProperties;\n  reduceMotion: boolean;\n  resolvedPopupProps: Omit<\n    DivRenderProps,\n    \"children\" | \"className\" | \"ref\" | \"style\"\n  >;\n  unmountOnClose?: boolean;\n}) {\n  const panelVariants = reduceMotion\n    ? reducedPanelMotionVariants\n    : panelMotionVariants;\n\n  return (\n    <motion.div\n      {...(resolvedPopupProps as React.ComponentPropsWithoutRef<\n        typeof motion.div\n      >)}\n      animate={popupState.open ? \"open\" : \"closed\"}\n      className={cn(\n        contextMenuThemeClassName,\n        contextMenuPanelChromeClassName,\n        className,\n        popupClassName\n      )}\n      initial={\n        popupState.transitionStatus === \"starting\" && !reduceMotion\n          ? \"closed\"\n          : false\n      }\n      onAnimationComplete={() => {\n        if (!popupState.open && unmountOnClose && actionsRef) {\n          actionsRef.current?.unmount();\n        }\n      }}\n      ref={(node) => {\n        setRef(popupRef, node);\n      }}\n      style={{\n        ...popupStyle,\n        maxHeight: \"calc(100vh - 16px)\",\n        overscrollBehavior: \"contain\",\n        pointerEvents: popupState.open ? undefined : \"none\",\n        transformOrigin: \"var(--transform-origin)\",\n      }}\n      transition={getPanelMotionTransition(reduceMotion)}\n      variants={panelVariants}\n    >\n      <ContextMenuPanelProvider>\n        <ContextMenuPanelScroll>{children}</ContextMenuPanelScroll>\n      </ContextMenuPanelProvider>\n    </motion.div>\n  );\n}\n\ntype ContextMenuProps = Omit<\n  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Root>,\n  \"children\" | \"defaultOpen\" | \"onOpenChange\" | \"open\"\n> & {\n  children?: React.ReactNode;\n  defaultOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  open?: boolean;\n};\n\nfunction ContextMenu({\n  children,\n  defaultOpen = false,\n  onOpenChange,\n  open: openProp,\n  ...props\n}: ContextMenuProps) {\n  const actionsRef = React.useRef<ContextMenuPrimitive.Root.Actions | null>(\n    null\n  );\n  const isControlled = openProp !== undefined;\n  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n  const open = isControlled ? openProp : uncontrolledOpen;\n\n  const handleOpenChange = React.useCallback(\n    (nextOpen: boolean) => {\n      if (!isControlled) {\n        setUncontrolledOpen(nextOpen);\n      }\n\n      onOpenChange?.(nextOpen);\n    },\n    [isControlled, onOpenChange]\n  );\n\n  return (\n    <ContextMenuContext.Provider\n      value={{\n        actionsRef,\n        open,\n      }}\n    >\n      <ContextMenuPrimitive.Root\n        {...props}\n        actionsRef={actionsRef}\n        onOpenChange={handleOpenChange}\n        open={open}\n      >\n        {children}\n      </ContextMenuPrimitive.Root>\n    </ContextMenuContext.Provider>\n  );\n}\nContextMenu.displayName = \"ContextMenu\";\n\ntype ContextMenuTriggerProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.Trigger\n> & {\n  asChild?: boolean;\n};\n\nconst ContextMenuTrigger = React.forwardRef<\n  HTMLDivElement,\n  ContextMenuTriggerProps\n>(({ asChild, children, className, onKeyDown, ...props }, ref) => {\n  const { open } = useContextMenu(\"ContextMenuTrigger\");\n\n  const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n    (onKeyDown as React.KeyboardEventHandler<HTMLDivElement> | undefined)?.(\n      event\n    );\n\n    if (event.defaultPrevented || !isContextMenuKeyboardShortcut(event)) {\n      return;\n    }\n\n    event.preventDefault();\n    dispatchContextMenuFromKeyboard(event.currentTarget);\n  };\n\n  return (\n    <ContextMenuPrimitive.Trigger\n      {...props}\n      className={className}\n      data-slot=\"context-menu-trigger\"\n      render={(triggerProps) => {\n        const { \"aria-expanded\": _ariaExpanded, ...resolvedTriggerProps } =\n          triggerProps;\n\n        const mergedClassName = cn(\n          contextMenuThemeClassName,\n          contextMenuTriggerClassName,\n          className,\n          resolvedTriggerProps.className\n        );\n\n        const mergedKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n          resolvedTriggerProps.onKeyDown?.(event);\n          handleKeyDown(event);\n        };\n\n        if (asChild) {\n          if (!React.isValidElement<TriggerElementProps>(children)) {\n            throw new Error(\n              \"ContextMenuTrigger with asChild expects a single React element child.\"\n            );\n          }\n\n          const child = React.Children.only(children) as TriggerChildElement;\n\n          return React.cloneElement(child, {\n            ...resolvedTriggerProps,\n            \"aria-haspopup\": \"menu\",\n            className: cn(mergedClassName, child.props.className),\n            \"data-state\": open ? \"open\" : \"closed\",\n            onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => {\n              child.props.onKeyDown?.(event);\n              mergedKeyDown(\n                event as unknown as React.KeyboardEvent<HTMLDivElement>\n              );\n            },\n            ref: composeRefs<HTMLElement>(\n              getElementRef(child),\n              resolvedTriggerProps.ref as React.Ref<HTMLElement>,\n              ref as React.Ref<HTMLElement>\n            ),\n            tabIndex:\n              child.props.tabIndex ?? resolvedTriggerProps.tabIndex ?? 0,\n          } as TriggerElementProps & React.RefAttributes<HTMLElement>);\n        }\n\n        return (\n          <div\n            {...resolvedTriggerProps}\n            aria-haspopup=\"menu\"\n            className={mergedClassName}\n            data-state={open ? \"open\" : \"closed\"}\n            onKeyDown={mergedKeyDown}\n            ref={composeRefs(\n              resolvedTriggerProps.ref as React.Ref<HTMLDivElement>,\n              ref\n            )}\n            tabIndex={resolvedTriggerProps.tabIndex ?? 0}\n          >\n            {children}\n          </div>\n        );\n      }}\n    />\n  );\n});\nContextMenuTrigger.displayName = \"ContextMenuTrigger\";\n\nfunction ContextMenuGroup({\n  ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n  return (\n    <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />\n  );\n}\nContextMenuGroup.displayName = \"ContextMenuGroup\";\n\nfunction ContextMenuPortal({\n  ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {\n  return (\n    <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />\n  );\n}\nContextMenuPortal.displayName = \"ContextMenuPortal\";\n\nfunction ContextMenuSub({\n  ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.SubmenuRoot>) {\n  return (\n    <ContextMenuPrimitive.SubmenuRoot data-slot=\"context-menu-sub\" {...props} />\n  );\n}\nContextMenuSub.displayName = \"ContextMenuSub\";\n\nfunction ContextMenuRadioGroup({\n  ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {\n  return (\n    <ContextMenuPrimitive.RadioGroup\n      data-slot=\"context-menu-radio-group\"\n      {...props}\n    />\n  );\n}\nContextMenuRadioGroup.displayName = \"ContextMenuRadioGroup\";\n\ntype PositionerProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.Positioner\n>;\n\ntype ContextMenuContentProps = Omit<\n  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Popup>,\n  \"children\" | \"className\" | \"render\"\n> & {\n  align?: PositionerProps[\"align\"];\n  alignOffset?: PositionerProps[\"alignOffset\"];\n  children?: React.ReactNode;\n  className?: string;\n  collisionPadding?: PositionerProps[\"collisionPadding\"];\n  side?: PositionerProps[\"side\"];\n  sideOffset?: PositionerProps[\"sideOffset\"];\n};\n\nconst ContextMenuContent = React.forwardRef<\n  HTMLDivElement,\n  ContextMenuContentProps\n>(\n  (\n    {\n      align,\n      alignOffset,\n      children,\n      className,\n      collisionPadding = 8,\n      side,\n      sideOffset,\n      ...popupProps\n    },\n    ref\n  ) => {\n    const { actionsRef } = useContextMenu(\"ContextMenuContent\");\n    const reduceMotion = useReducedMotion() === true;\n\n    return (\n      <MotionConfig reducedMotion={reduceMotion ? \"always\" : \"never\"}>\n        <ContextMenuPrimitive.Portal>\n          <ContextMenuPrimitive.Positioner\n            align={align}\n            alignOffset={alignOffset}\n            className=\"z-50 outline-none\"\n            collisionPadding={collisionPadding}\n            side={side}\n            sideOffset={sideOffset}\n          >\n            <ContextMenuPrimitive.Popup\n              {...popupProps}\n              finalFocus\n              render={(renderPopupProps, popupState) => {\n                const {\n                  popupClassName,\n                  popupRef,\n                  popupStyle,\n                  resolvedPopupProps,\n                } = resolvePopupProps(renderPopupProps);\n\n                return renderMotionPanel({\n                  actionsRef,\n                  children,\n                  className,\n                  popupClassName,\n                  popupRef: composeRefs(popupRef, ref),\n                  popupState,\n                  popupStyle,\n                  reduceMotion,\n                  resolvedPopupProps,\n                  unmountOnClose: false,\n                });\n              }}\n            />\n          </ContextMenuPrimitive.Positioner>\n        </ContextMenuPrimitive.Portal>\n      </MotionConfig>\n    );\n  }\n);\nContextMenuContent.displayName = \"ContextMenuContent\";\n\ntype ContextMenuItemProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.Item\n> & {\n  closeOnClick?: boolean;\n  inset?: boolean;\n  variant?: \"default\" | \"destructive\";\n};\n\nconst ContextMenuItem = React.forwardRef<\n  HTMLButtonElement,\n  ContextMenuItemProps\n>(\n  (\n    {\n      children,\n      className,\n      closeOnClick = true,\n      disabled,\n      inset,\n      variant = \"default\",\n      ...props\n    },\n    ref\n  ) => {\n    const { activeItemId, panelId, setActiveItemId } =\n      useContextMenuPanel(\"ContextMenuItem\");\n    const itemId = React.useId();\n    const isDestructive = variant === \"destructive\";\n    const reduceMotion = useReducedMotion() === true;\n\n    return (\n      <ContextMenuPrimitive.Item\n        {...props}\n        closeOnClick={closeOnClick}\n        disabled={disabled}\n        nativeButton\n        render={(itemProps, itemState) => {\n          const { itemClassName, itemRef, itemStyle, resolvedItemProps } =\n            resolveItemProps(itemProps as ButtonRenderProps);\n\n          return renderContextMenuItemButton({\n            activeItemId,\n            baseClassName: contextMenuItemClassName,\n            children,\n            className: resolveStateClassName(className, itemState),\n            disabled,\n            dataVariant: variant,\n            highlighted: itemState.highlighted,\n            inset,\n            itemClassName,\n            itemId,\n            itemRef,\n            itemStyle,\n            panelId,\n            reduceMotion,\n            ref,\n            resolvedItemProps,\n            setActiveItemId,\n            slot: \"context-menu-item\",\n            variantClassName: isDestructive\n              ? contextMenuItemDestructiveClassName\n              : undefined,\n          });\n        }}\n      />\n    );\n  }\n);\nContextMenuItem.displayName = \"ContextMenuItem\";\n\ntype ContextMenuSubTriggerProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.SubmenuTrigger\n> & {\n  inset?: boolean;\n};\n\nconst ContextMenuSubTrigger = React.forwardRef<\n  HTMLButtonElement,\n  ContextMenuSubTriggerProps\n>(\n  (\n    { children, className, closeDelay = 150, disabled, inset, ...props },\n    ref\n  ) => {\n    const { activeItemId, panelId, setActiveItemId } = useContextMenuPanel(\n      \"ContextMenuSubTrigger\"\n    );\n    const itemId = React.useId();\n    const reduceMotion = useReducedMotion() === true;\n\n    return (\n      <ContextMenuPrimitive.SubmenuTrigger\n        {...props}\n        closeDelay={closeDelay}\n        disabled={disabled}\n        nativeButton\n        render={(itemProps, itemState) => {\n          const { itemClassName, itemRef, itemStyle, resolvedItemProps } =\n            resolveItemProps(itemProps as ButtonRenderProps);\n\n          return renderContextMenuItemButton({\n            activeItemId,\n            baseClassName: cn(\n              contextMenuSubTriggerClassName,\n              contextMenuSubTriggerOpenClassName\n            ),\n            children,\n            className: resolveStateClassName(className, itemState),\n            disabled,\n            highlighted: itemState.highlighted,\n            inset,\n            itemClassName,\n            itemId,\n            itemRef,\n            itemStyle,\n            panelId,\n            reduceMotion,\n            ref,\n            resolvedItemProps,\n            setActiveItemId,\n            slot: \"context-menu-sub-trigger\",\n            trailing: (\n              <ChevronRight className=\"relative z-10 ml-auto size-4 opacity-70\" />\n            ),\n          });\n        }}\n      />\n    );\n  }\n);\nContextMenuSubTrigger.displayName = \"ContextMenuSubTrigger\";\n\ntype ContextMenuSubContentProps = {\n  align?: PositionerProps[\"align\"];\n  alignOffset?: PositionerProps[\"alignOffset\"];\n  children?: React.ReactNode;\n  className?: string;\n  collisionPadding?: PositionerProps[\"collisionPadding\"];\n  side?: PositionerProps[\"side\"];\n  sideOffset?: PositionerProps[\"sideOffset\"];\n};\n\nconst ContextMenuSubContent = React.forwardRef<\n  HTMLDivElement,\n  ContextMenuSubContentProps\n>(\n  (\n    {\n      align,\n      alignOffset,\n      children,\n      className,\n      collisionPadding = 8,\n      side,\n      sideOffset,\n    },\n    ref\n  ) => {\n    const reduceMotion = useReducedMotion() === true;\n\n    return (\n      <MotionConfig reducedMotion={reduceMotion ? \"always\" : \"never\"}>\n        <ContextMenuPrimitive.Portal>\n          <ContextMenuPrimitive.Positioner\n            align={align}\n            alignOffset={alignOffset}\n            className=\"z-50 outline-none\"\n            collisionPadding={collisionPadding}\n            side={side}\n            sideOffset={sideOffset}\n          >\n            <ContextMenuPrimitive.Popup\n              render={(renderPopupProps, popupState) => {\n                const {\n                  popupClassName,\n                  popupRef,\n                  popupStyle,\n                  resolvedPopupProps,\n                } = resolvePopupProps(renderPopupProps);\n\n                return renderMotionPanel({\n                  children,\n                  className,\n                  popupClassName,\n                  popupRef: composeRefs(popupRef, ref),\n                  popupState,\n                  popupStyle,\n                  reduceMotion,\n                  resolvedPopupProps,\n                  unmountOnClose: false,\n                });\n              }}\n            />\n          </ContextMenuPrimitive.Positioner>\n        </ContextMenuPrimitive.Portal>\n      </MotionConfig>\n    );\n  }\n);\nContextMenuSubContent.displayName = \"ContextMenuSubContent\";\n\ntype ContextMenuCheckboxItemProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.CheckboxItem\n> & {\n  inset?: boolean;\n};\n\nconst ContextMenuCheckboxItem = React.forwardRef<\n  HTMLButtonElement,\n  ContextMenuCheckboxItemProps\n>(({ checked, children, className, disabled, inset, ...props }, ref) => {\n  const { activeItemId, panelId, setActiveItemId } = useContextMenuPanel(\n    \"ContextMenuCheckboxItem\"\n  );\n  const itemId = React.useId();\n  const reduceMotion = useReducedMotion() === true;\n\n  return (\n    <ContextMenuPrimitive.CheckboxItem\n      {...props}\n      checked={checked}\n      disabled={disabled}\n      nativeButton\n      render={(itemProps, itemState) => {\n        const { itemClassName, itemRef, itemStyle, resolvedItemProps } =\n          resolveItemProps(itemProps as ButtonRenderProps);\n\n        return renderContextMenuItemButton({\n          activeItemId,\n          baseClassName: contextMenuIndicatorItemClassName,\n          children,\n          className: resolveStateClassName(className, itemState),\n          disabled,\n          highlighted: itemState.highlighted,\n          inset,\n          itemClassName,\n          itemId,\n          itemRef,\n          itemStyle,\n          panelId,\n          reduceMotion,\n          ref,\n          resolvedItemProps,\n          setActiveItemId,\n          slot: \"context-menu-checkbox-item\",\n          trailing: (\n            <span className=\"pointer-events-none absolute right-3 z-10\">\n              <ContextMenuPrimitive.CheckboxItemIndicator>\n                <Check className=\"size-4\" />\n              </ContextMenuPrimitive.CheckboxItemIndicator>\n            </span>\n          ),\n        });\n      }}\n    />\n  );\n});\nContextMenuCheckboxItem.displayName = \"ContextMenuCheckboxItem\";\n\ntype ContextMenuRadioItemProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.RadioItem\n> & {\n  inset?: boolean;\n};\n\nconst ContextMenuRadioItem = React.forwardRef<\n  HTMLButtonElement,\n  ContextMenuRadioItemProps\n>(({ children, className, disabled, inset, ...props }, ref) => {\n  const { activeItemId, panelId, setActiveItemId } = useContextMenuPanel(\n    \"ContextMenuRadioItem\"\n  );\n  const itemId = React.useId();\n  const reduceMotion = useReducedMotion() === true;\n\n  return (\n    <ContextMenuPrimitive.RadioItem\n      {...props}\n      disabled={disabled}\n      nativeButton\n      render={(itemProps, itemState) => {\n        const { itemClassName, itemRef, itemStyle, resolvedItemProps } =\n          resolveItemProps(itemProps as ButtonRenderProps);\n\n        return renderContextMenuItemButton({\n          activeItemId,\n          baseClassName: contextMenuIndicatorItemClassName,\n          children,\n          className: resolveStateClassName(className, itemState),\n          disabled,\n          highlighted: itemState.highlighted,\n          inset,\n          itemClassName,\n          itemId,\n          itemRef,\n          itemStyle,\n          panelId,\n          reduceMotion,\n          ref,\n          resolvedItemProps,\n          setActiveItemId,\n          slot: \"context-menu-radio-item\",\n          trailing: (\n            <span className=\"pointer-events-none absolute right-3 z-10\">\n              <ContextMenuPrimitive.RadioItemIndicator>\n                <Check className=\"size-4\" />\n              </ContextMenuPrimitive.RadioItemIndicator>\n            </span>\n          ),\n        });\n      }}\n    />\n  );\n});\nContextMenuRadioItem.displayName = \"ContextMenuRadioItem\";\n\ntype ContextMenuLabelProps = React.ComponentPropsWithoutRef<\n  typeof ContextMenuPrimitive.GroupLabel\n> & {\n  inset?: boolean;\n};\n\nfunction ContextMenuLabel({\n  className,\n  inset,\n  ...props\n}: ContextMenuLabelProps) {\n  return (\n    <ContextMenuPrimitive.GroupLabel\n      className={cn(\n        \"px-3 py-1 font-medium text-[color:var(--cm-muted-foreground)] text-xs\",\n        inset && \"pl-7\",\n        className\n      )}\n      data-inset={inset ? \"\" : undefined}\n      data-slot=\"context-menu-label\"\n      {...props}\n    />\n  );\n}\nContextMenuLabel.displayName = \"ContextMenuLabel\";\n\nfunction ContextMenuSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n  return (\n    <ContextMenuPrimitive.Separator\n      className={cn(\n        \"my-1 h-px bg-[color:color-mix(in_oklch,var(--cm-border),transparent_40%)]\",\n        className\n      )}\n      data-slot=\"context-menu-separator\"\n      {...props}\n    />\n  );\n}\nContextMenuSeparator.displayName = \"ContextMenuSeparator\";\n\nfunction ContextMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(contextMenuShortcutClassName, className)}\n      data-slot=\"context-menu-shortcut\"\n      {...props}\n    />\n  );\n}\nContextMenuShortcut.displayName = \"ContextMenuShortcut\";\n\nexport {\n  ContextMenu,\n  ContextMenuTrigger,\n  ContextMenuContent,\n  ContextMenuItem,\n  ContextMenuCheckboxItem,\n  ContextMenuRadioItem,\n  ContextMenuLabel,\n  ContextMenuSeparator,\n  ContextMenuShortcut,\n  ContextMenuGroup,\n  ContextMenuPortal,\n  ContextMenuSub,\n  ContextMenuSubContent,\n  ContextMenuSubTrigger,\n  ContextMenuRadioGroup,\n};\n",
      "type": "registry:ui"
    }
  ],
  "title": "Context Menu (Base UI)",
  "description": "Composable context menu layered over Base UI primitives, preserving the original panel spring, row entrance, active highlight, and shortcut layout."
}
