import * as React from 'react';
import { ContextMenu as ContextMenuPrimitive } from '@base-ui-components/react/context-menu';
import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
function ContextMenu({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
}
function ContextMenuTrigger({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
return <ContextMenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />;
}
function ContextMenuGroup({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
return <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />;
}
function ContextMenuSub({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubmenuRoot>) {
return <ContextMenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />;
}
function ContextMenuRadioGroup({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
return <ContextMenuPrimitive.RadioGroup data-slot="context-menu-radio-group" {...props} />;
}
function ContextMenuSubTrigger({
className,
inset,
children,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.SubmenuTrigger> & {
inset?: boolean;
}) {
return (
<ContextMenuPrimitive.SubmenuTrigger
data-slot="context-menu-sub-trigger"
data-inset={inset}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:ps-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
className,
)}
{...props}
>
{children}
<ChevronRightIcon className="ms-auto opacity-60" />
</ContextMenuPrimitive.SubmenuTrigger>
);
}
function ContextMenuSubPopup({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Popup>) {
return (
<ContextMenuPrimitive.Popup
data-slot="context-menu-sub-popup"
className={cn(
'bg-popover outline-none text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
className,
)}
{...props}
/>
);
}
function ContextMenuSubContent({
className,
align,
sideOffset = 4,
alignOffset = 0,
side,
anchor,
children,
}: React.ComponentProps<typeof ContextMenuPrimitive.Popup> & {
align?: ContextMenuPrimitive.Positioner.Props['align'];
sideOffset?: ContextMenuPrimitive.Positioner.Props['sideOffset'];
alignOffset?: ContextMenuPrimitive.Positioner.Props['alignOffset'];
side?: ContextMenuPrimitive.Positioner.Props['side'];
anchor?: ContextMenuPrimitive.Positioner.Props['anchor'];
}) {
return (
<ContextMenuPortal>
<ContextMenuPositioner
align={align}
sideOffset={sideOffset}
alignOffset={alignOffset}
side={side}
anchor={anchor}
>
<ContextMenuSubPopup className={className}>{children}</ContextMenuSubPopup>
</ContextMenuPositioner>
</ContextMenuPortal>
);
}
function ContextMenuPopup({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Popup>) {
return (
<ContextMenuPrimitive.Popup
data-slot="context-menu-content"
className={cn(
'bg-popover outline-none text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
className,
)}
{...props}
/>
);
}
function ContextMenuContent({
className,
align = 'start',
sideOffset = 4,
alignOffset = 0,
side = 'bottom',
anchor,
children,
}: React.ComponentProps<typeof ContextMenuPrimitive.Popup> & {
align?: ContextMenuPrimitive.Positioner.Props['align'];
sideOffset?: ContextMenuPrimitive.Positioner.Props['sideOffset'];
alignOffset?: ContextMenuPrimitive.Positioner.Props['alignOffset'];
side?: ContextMenuPrimitive.Positioner.Props['side'];
anchor?: ContextMenuPrimitive.Positioner.Props['anchor'];
}) {
return (
<ContextMenuPortal>
<ContextMenuPositioner
align={align}
sideOffset={sideOffset}
alignOffset={alignOffset}
side={side}
anchor={anchor}
>
<ContextMenuPopup className={className}>{children}</ContextMenuPopup>
</ContextMenuPositioner>
</ContextMenuPortal>
);
}
function ContextMenuItem({
className,
inset,
variant = 'default',
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
inset?: boolean;
variant?: 'default' | 'destructive';
}) {
return (
<ContextMenuPrimitive.Item
data-slot="context-menu-item"
data-inset={inset}
data-variant={variant}
className={cn(
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:ps-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
/>
);
}
function ContextMenuCheckboxItem({
className,
children,
checked,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {
return (
<ContextMenuPrimitive.CheckboxItem
data-slot="context-menu-checkbox-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pe-2 ps-7 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
checked={checked}
{...props}
>
<span className="pointer-events-none absolute start-2 flex size-3.5 items-center justify-center">
<ContextMenuPrimitive.CheckboxItemIndicator>
<CheckIcon className="size-4 text-primary" />
</ContextMenuPrimitive.CheckboxItemIndicator>
</span>
{children}
</ContextMenuPrimitive.CheckboxItem>
);
}
function ContextMenuRadioItem({
className,
children,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {
return (
<ContextMenuPrimitive.RadioItem
data-slot="context-menu-radio-item"
className={cn(
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 ps-7 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className,
)}
{...props}
>
<span className="pointer-events-none absolute start-2 flex size-3.5 items-center justify-center">
<ContextMenuPrimitive.RadioItemIndicator>
<CircleIcon className="size-1.5 fill-primary" />
</ContextMenuPrimitive.RadioItemIndicator>
</span>
{children}
</ContextMenuPrimitive.RadioItem>
);
}
function ContextMenuGroupLabel({
className,
inset,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.GroupLabel> & {
inset?: boolean;
}) {
return (
<ContextMenuPrimitive.GroupLabel
data-slot="context-menu-group-label"
data-inset={inset}
className={cn('text-muted-foreground px-2 py-1.5 text-xs font-medium data-[inset]:ps-7', className)}
{...props}
/>
);
}
function ContextMenuSeparator({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
return (
<ContextMenuPrimitive.Separator
data-slot="context-menu-separator"
className={cn('bg-border -mx-1 my-1 h-px', className)}
{...props}
/>
);
}
function ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
return (
<span
data-slot="context-menu-shortcut"
className={cn('text-muted-foreground ms-auto text-xs tracking-widest', className)}
{...props}
/>
);
}
function ContextMenuPositioner({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Positioner>) {
return (
<ContextMenuPrimitive.Positioner data-slot="context-menu-positioner" className="z-50 outline-none" {...props} />
);
}
function ContextMenuPortal({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Positioner>) {
return <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />;
}
export {
ContextMenu,
ContextMenuTrigger,
ContextMenuContent,
ContextMenuItem,
ContextMenuCheckboxItem,
ContextMenuRadioItem,
ContextMenuGroupLabel,
ContextMenuSeparator,
ContextMenuShortcut,
ContextMenuGroup,
ContextMenuPortal,
ContextMenuSub,
ContextMenuSubPopup,
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuRadioGroup,
ContextMenuPositioner,
};