1
6import * as React from "react";
7import * as RadixContextMenu from "@radix-ui/react-context-menu";
8import { clsx } from "clsx";
9
10export const ContextMenu = RadixContextMenu.Root;
11export const ContextMenuTrigger = RadixContextMenu.Trigger;
12export const ContextMenuGroup = RadixContextMenu.Group;
13export const ContextMenuPortal = RadixContextMenu.Portal;
14export const ContextMenuRadioGroup = RadixContextMenu.RadioGroup;
15
16export const ContextMenuContent = React.forwardRef<
17 React.ElementRef<typeof RadixContextMenu.Content>,
18 React.ComponentPropsWithoutRef<typeof RadixContextMenu.Content>
19>(({ className, ...props }, ref) => (
20 <RadixContextMenu.Portal>
21 <RadixContextMenu.Content
22 ref={ref}
23 className={clsx(
24 "z-50 min-w-[10rem] rounded-md border border-border bg-popover p-1",
25 "text-popover-foreground shadow-md focus:outline-none",
26 className,
27 )}
28 {...props}
29 />
30 </RadixContextMenu.Portal>
31));
32ContextMenuContent.displayName = "ContextMenuContent";
33
34export const ContextMenuItem = React.forwardRef<
35 React.ElementRef<typeof RadixContextMenu.Item>,
36 React.ComponentPropsWithoutRef<typeof RadixContextMenu.Item>
37>(({ className, ...props }, ref) => (
38 <RadixContextMenu.Item
39 ref={ref}
40 className={clsx(
41 "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm",
42 "outline-none data-[highlighted]:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
43 className,
44 )}
45 {...props}
46 />
47));
48ContextMenuItem.displayName = "ContextMenuItem";
49
50export const ContextMenuCheckboxItem = React.forwardRef<
51 React.ElementRef<typeof RadixContextMenu.CheckboxItem>,
52 React.ComponentPropsWithoutRef<typeof RadixContextMenu.CheckboxItem>
53>(({ className, children, checked, ...props }, ref) => (
54 <RadixContextMenu.CheckboxItem
55 ref={ref}
56 checked={checked ?? false}
57 className={clsx(
58 "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm",
59 "outline-none data-[highlighted]:bg-accent",
60 className,
61 )}
62 {...props}
63 >
64 <RadixContextMenu.ItemIndicator>✓</RadixContextMenu.ItemIndicator>
65 {children}
66 </RadixContextMenu.CheckboxItem>
67));
68ContextMenuCheckboxItem.displayName = "ContextMenuCheckboxItem";
69
70export const ContextMenuLabel = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
71 <div className={clsx("px-2 py-1.5 text-xs text-muted-foreground", className)} {...props} />
72);
73
74export const ContextMenuSeparator = ({
75 className,
76 ...props
77}: React.ComponentPropsWithoutRef<typeof RadixContextMenu.Separator>) => (
78 <RadixContextMenu.Separator className={clsx("my-1 h-px bg-border", className)} {...props} />
79);
80