{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "context-menu",
  "title": "Context Menu",
  "description": "A menu that appears at the pointer on right click or long press.",
  "dependencies": [
    "@base-ui/react",
    "lucide-react",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "utils",
    "@lumi-ui/arrow-svg"
  ],
  "files": [
    {
      "path": "registry/ui/context-menu.tsx",
      "content": "\"use client\";\n\nimport { ContextMenu as BaseContextMenu } from \"@base-ui/react/context-menu\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"@/registry/lib/utils\";\nimport { ArrowSvg } from \"@/registry/ui/arrow-svg\";\n\nfunction ContextMenu(props: BaseContextMenu.Root.Props) {\n  return <BaseContextMenu.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger({\n  className,\n  ...props\n}: BaseContextMenu.Trigger.Props) {\n  return (\n    <BaseContextMenu.Trigger\n      className={className}\n      data-slot=\"context-menu-trigger\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuPortal({\n  className,\n  ...props\n}: BaseContextMenu.Portal.Props) {\n  return (\n    <BaseContextMenu.Portal\n      className={className}\n      data-slot=\"context-menu-portal\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuBackdrop({\n  className,\n  ...props\n}: BaseContextMenu.Backdrop.Props) {\n  return (\n    <BaseContextMenu.Backdrop\n      className={cn(\"fixed inset-0\", className)}\n      data-slot=\"context-menu-backdrop\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuPositioner({\n  className,\n  ...props\n}: BaseContextMenu.Positioner.Props) {\n  return (\n    <BaseContextMenu.Positioner\n      className={cn(\"relative\", className)}\n      data-slot=\"context-menu-positioner\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuPopup({\n  className,\n  ...props\n}: BaseContextMenu.Popup.Props) {\n  return (\n    <BaseContextMenu.Popup\n      className={cn(\"relative\", className)}\n      data-slot=\"context-menu-popup\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuArrow({\n  className,\n  ...props\n}: BaseContextMenu.Arrow.Props) {\n  return (\n    <BaseContextMenu.Arrow\n      className={cn(\n        \"data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180\",\n        className,\n      )}\n      data-slot=\"context-menu-arrow\"\n      {...props}\n    >\n      <ArrowSvg />\n    </BaseContextMenu.Arrow>\n  );\n}\n\nfunction ContextMenuGroup({\n  className,\n  ...props\n}: BaseContextMenu.Group.Props) {\n  return (\n    <BaseContextMenu.Group\n      className={className}\n      data-slot=\"context-menu-group\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuRadioGroup({\n  className,\n  ...props\n}: BaseContextMenu.RadioGroup.Props) {\n  return (\n    <BaseContextMenu.RadioGroup\n      className={className}\n      data-slot=\"context-menu-radio-group\"\n      {...props}\n    />\n  );\n}\n\nconst contextMenuItemVariants = cva(\n  [\n    \"flex items-center gap-2 py-1.5 px-3.5 text-sm\",\n    \"outline-none select-none cursor-default\",\n    \"highlight-on-active\",\n    \"data-disabled:opacity-50 data-disabled:pointer-events-none\",\n    \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground hover:[&_svg:not([class*='text-'])]:text-foreground\",\n  ],\n  {\n    defaultVariants: {\n      variant: \"default\",\n    },\n    variants: {\n      variant: {\n        default: \"\",\n        destructive: [\n          \"text-destructive *:[svg]:!text-destructive\",\n          \"data-[highlighted]:text-destructive data-[highlighted]:before:bg-destructive/10 dark:data-[highlighted]:before:bg-destructive/20\",\n        ],\n      },\n    },\n  },\n);\n\ntype ContextMenuItemProps = BaseContextMenu.Item.Props &\n  VariantProps<typeof contextMenuItemVariants> & {\n    unstyled?: boolean;\n  };\n\nfunction ContextMenuItem({\n  className,\n  variant = \"default\",\n  unstyled = false,\n  ...props\n}: ContextMenuItemProps) {\n  return (\n    <BaseContextMenu.Item\n      className={cn(\n        unstyled ? \"\" : contextMenuItemVariants({ variant }),\n        className,\n      )}\n      data-slot=\"context-menu-item\"\n      {...props}\n    />\n  );\n}\n\ntype ContextMenuLinkItemProps = BaseContextMenu.LinkItem.Props &\n  VariantProps<typeof contextMenuItemVariants> & {\n    unstyled?: boolean;\n  };\n\nfunction ContextMenuLinkItem({\n  className,\n  variant = \"default\",\n  unstyled = false,\n  ...props\n}: ContextMenuLinkItemProps) {\n  return (\n    <BaseContextMenu.LinkItem\n      className={cn(\n        unstyled ? \"\" : contextMenuItemVariants({ variant }),\n        className,\n      )}\n      data-slot=\"context-menu-link-item\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuSeparator({\n  className,\n  ...props\n}: BaseContextMenu.Separator.Props) {\n  return (\n    <BaseContextMenu.Separator\n      className={cn(\"bg-border pointer-events-none my-1 h-px\", className)}\n      data-slot=\"context-menu-separator\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuLabel({\n  className,\n  inset,\n  ...props\n}: BaseContextMenu.GroupLabel.Props & {\n  inset?: boolean;\n}) {\n  return (\n    <BaseContextMenu.GroupLabel\n      className={cn(\n        \"px-3.5 py-1.5 text-xs text-muted-foreground font-medium select-none data-inset:pl-8\",\n        className,\n      )}\n      data-inset={inset}\n      data-slot=\"context-menu-label\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuCheckboxItem({\n  className,\n  ...props\n}: BaseContextMenu.CheckboxItem.Props) {\n  return (\n    <BaseContextMenu.CheckboxItem\n      className={cn(className)}\n      data-slot=\"context-menu-checkbox-item\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuRadioItem({\n  className,\n  ...props\n}: BaseContextMenu.RadioItem.Props) {\n  return (\n    <BaseContextMenu.RadioItem\n      className={className}\n      data-slot=\"context-menu-radio-item\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuSub(props: BaseContextMenu.SubmenuRoot.Props) {\n  return (\n    <BaseContextMenu.SubmenuRoot data-slot=\"context-menu-sub\" {...props} />\n  );\n}\n\nfunction ContextMenuSubTrigger({\n  className,\n  ...props\n}: BaseContextMenu.SubmenuTrigger.Props) {\n  return (\n    <BaseContextMenu.SubmenuTrigger\n      className={className}\n      data-slot=\"context-menu-sub-trigger\"\n      {...props}\n    />\n  );\n}\n\nfunction ContextMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground ml-auto text-xs tracking-widest\",\n        className,\n      )}\n      data-slot=\"context-menu-shortcut\"\n      {...props}\n    />\n  );\n}\n\ntype ContextMenuContentProps = BaseContextMenu.Popup.Props & {\n  side?: BaseContextMenu.Positioner.Props[\"side\"];\n  sideOffset?: BaseContextMenu.Positioner.Props[\"sideOffset\"];\n  align?: BaseContextMenu.Positioner.Props[\"align\"];\n  alignOffset?: BaseContextMenu.Positioner.Props[\"alignOffset\"];\n  showArrow?: boolean;\n  matchAnchorWidth?: boolean;\n};\n\nfunction ContextMenuContent({\n  children,\n  className,\n  align = \"center\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 4,\n  showArrow = false,\n  matchAnchorWidth = false,\n  ...props\n}: ContextMenuContentProps) {\n  return (\n    <BaseContextMenu.Portal>\n      <BaseContextMenu.Positioner\n        align={align}\n        alignOffset={alignOffset}\n        className={cn(\n          matchAnchorWidth && \"w-[var(--anchor-width)]\",\n          \"max-h-(--available-height)\",\n        )}\n        data-slot=\"context-menu-positioner\"\n        side={side}\n        sideOffset={sideOffset}\n      >\n        <BaseContextMenu.Popup\n          className={cn(\n            \"bg-popover text-popover-foreground rounded-md shadow-md py-1\",\n            \"overlay-outline animate-popup\",\n            className,\n          )}\n          data-slot=\"context-menu-content\"\n          {...props}\n        >\n          {showArrow && <ContextMenuArrow />}\n          {children}\n        </BaseContextMenu.Popup>\n      </BaseContextMenu.Positioner>\n    </BaseContextMenu.Portal>\n  );\n}\n\nfunction ContextMenuSubContent({\n  align = \"start\",\n  side = \"right\",\n  sideOffset = -4,\n  alignOffset = 0,\n  ...props\n}: ContextMenuContentProps) {\n  return (\n    <ContextMenuContent\n      align={align}\n      alignOffset={alignOffset}\n      data-slot=\"context-menu-sub-content\"\n      side={side}\n      sideOffset={sideOffset}\n      {...props}\n    />\n  );\n}\n\ninterface ContextMenuCheckboxItemContentProps\n  extends BaseContextMenu.CheckboxItem.Props {\n  indicatorPlacement?: \"start\" | \"end\";\n  indicatorIcon?: React.ReactNode;\n}\n\nfunction ContextMenuCheckboxItemContent({\n  className,\n  children,\n  checked,\n  indicatorPlacement = \"start\",\n  indicatorIcon = <CheckIcon className=\"size-4\" />,\n  ...props\n}: ContextMenuCheckboxItemContentProps) {\n  return (\n    <BaseContextMenu.CheckboxItem\n      checked={checked}\n      className={cn(\n        \"grid items-center gap-2 py-1.5 pr-3 pl-3.5 text-sm\",\n        \"outline-none select-none cursor-default\",\n        \"highlight-on-active\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-50\",\n        indicatorPlacement === \"start\" && \"grid-cols-[1rem_1fr]\",\n        indicatorPlacement === \"end\" && \"grid-cols-[1fr_1rem]\",\n        className,\n      )}\n      data-slot=\"context-menu-checkbox-item-content\"\n      {...props}\n    >\n      <BaseContextMenu.CheckboxItemIndicator\n        className={cn(\n          \"flex items-center justify-center row-start-1\",\n          \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n          indicatorPlacement === \"start\" ? \"col-start-1\" : \"col-start-2\",\n        )}\n      >\n        {indicatorIcon}\n      </BaseContextMenu.CheckboxItemIndicator>\n      <div\n        className={cn(\n          \"flex items-center gap-2 row-start-1\",\n          indicatorPlacement === \"start\" ? \"col-start-2\" : \"col-start-1\",\n        )}\n      >\n        {children}\n      </div>\n    </BaseContextMenu.CheckboxItem>\n  );\n}\n\ninterface ContextMenuRadioItemContentProps\n  extends BaseContextMenu.RadioItem.Props {\n  indicatorPlacement?: \"start\" | \"end\";\n  indicatorIcon?: React.ReactNode;\n}\n\nfunction ContextMenuRadioItemContent({\n  children,\n  className,\n  indicatorPlacement = \"start\",\n  indicatorIcon = <CircleIcon className=\"size-2.5 fill-current\" />,\n  ...props\n}: ContextMenuRadioItemContentProps) {\n  return (\n    <BaseContextMenu.RadioItem\n      className={cn(\n        \"grid items-center gap-2 py-1.5 pr-3 pl-2 text-sm\",\n        \"outline-none select-none cursor-default\",\n        \"highlight-on-active\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-50\",\n        indicatorPlacement === \"start\" && \"grid-cols-[1rem_1fr]\",\n        indicatorPlacement === \"end\" && \"grid-cols-[1fr_1rem] pl-4\",\n        className,\n      )}\n      data-slot=\"context-menu-radio-item-content\"\n      {...props}\n    >\n      <BaseContextMenu.RadioItemIndicator\n        className={cn(\n          \"flex items-center justify-center row-start-1\",\n          \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n          indicatorPlacement === \"start\" ? \"col-start-1\" : \"col-start-2\",\n        )}\n      >\n        {indicatorIcon}\n      </BaseContextMenu.RadioItemIndicator>\n      <div\n        className={cn(\n          \"flex items-center gap-2 row-start-1\",\n          indicatorPlacement === \"start\" ? \"col-start-2\" : \"col-start-1\",\n        )}\n      >\n        {children}\n      </div>\n    </BaseContextMenu.RadioItem>\n  );\n}\n\nfunction ContextMenuSubTriggerGroup({\n  children,\n  className,\n  variant = \"default\",\n  unstyled = false,\n  ...props\n}: BaseContextMenu.SubmenuTrigger.Props &\n  VariantProps<typeof contextMenuItemVariants> & {\n    unstyled?: boolean;\n  }) {\n  return (\n    <BaseContextMenu.SubmenuTrigger\n      className={cn(\n        unstyled ? \"\" : contextMenuItemVariants({ variant }),\n        className,\n      )}\n      data-slot=\"context-menu-sub-trigger-group\"\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto size-4\" />\n    </BaseContextMenu.SubmenuTrigger>\n  );\n}\n\nexport {\n  ContextMenu,\n  ContextMenuTrigger,\n  ContextMenuPortal,\n  ContextMenuBackdrop,\n  ContextMenuPositioner,\n  ContextMenuPopup,\n  ContextMenuArrow,\n  ContextMenuGroup,\n  ContextMenuLabel,\n  ContextMenuItem,\n  ContextMenuLinkItem,\n  ContextMenuCheckboxItem,\n  ContextMenuRadioGroup,\n  ContextMenuRadioItem,\n  ContextMenuSeparator,\n  ContextMenuShortcut,\n  ContextMenuSub,\n  ContextMenuSubTrigger,\n  // Composite components\n  ContextMenuContent,\n  ContextMenuCheckboxItemContent,\n  ContextMenuRadioItemContent,\n  ContextMenuSubTriggerGroup,\n  ContextMenuSubContent,\n};\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}