"use client"; import * as React from "react"; import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui"; import { IconCheck, IconChevronRight } from "@tabler/icons-react"; import { liquidMenuSurfaceClasses } from "./liquid-menu-surface"; import { MenuHighlightContext, SUPER_HOVER_ATTR, useMenuHighlight, } from "./menu-highlight"; import { cn } from "../lib/utils"; const contentClasses = cn( "relative z-50 overflow-x-hidden overflow-y-auto p-1", liquidMenuSurfaceClasses, ); const subContentClasses = cn( "relative z-50 isolate overflow-x-hidden overflow-y-auto p-1", liquidMenuSurfaceClasses, "after:pointer-events-none after:absolute after:inset-y-1 after:left-0 after:w-px after:bg-neutral-500/20", ); // ── Primitives ────────────────────────────────────────────────────────────── function DropdownMenu({ ...props }: React.ComponentProps) { return ; } function DropdownMenuPortal({ ...props }: React.ComponentProps) { return ( ); } function DropdownMenuTrigger({ ...props }: React.ComponentProps) { return ( ); } function DropdownMenuContent({ className, align = "start", sideOffset = 4, children, ...props }: React.ComponentProps) { const contentRef = React.useRef(null); const glass = useMenuHighlight(contentRef); return ( {glass.element}
{children}
); } function DropdownMenuGroup({ ...props }: React.ComponentProps) { return ( ); } function DropdownMenuItem({ className, inset, variant = "default", onPointerEnter, onFocus, ...props }: React.ComponentProps & { inset?: boolean; variant?: "default" | "destructive"; }) { const { reportHover } = React.useContext(MenuHighlightContext); return ( { reportHover(e.currentTarget); onFocus?.(e); }} onPointerEnter={(e) => { reportHover(e.currentTarget); onPointerEnter?.(e); }} className={cn( "group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm font-medium leading-5 outline-hidden select-none focus-visible:text-accent-foreground not-data-[variant=destructive]:focus-visible:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus-visible:text-destructive data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground/75 data-[variant=destructive]:*:[svg]:text-destructive", className, )} {...props} /> ); } function DropdownMenuCheckboxItem({ className, children, checked, inset, onPointerEnter, onFocus, ...props }: React.ComponentProps & { inset?: boolean; }) { const { reportHover } = React.useContext(MenuHighlightContext); return ( { reportHover(e.currentTarget); onFocus?.(e); }} onPointerEnter={(e) => { reportHover(e.currentTarget); onPointerEnter?.(e); }} className={cn( "relative flex cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2.5 text-sm font-medium leading-5 outline-hidden select-none focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground/75", className, )} {...(checked !== undefined ? { checked } : {})} {...props} > {children} ); } function DropdownMenuRadioGroup({ ...props }: React.ComponentProps) { return ( ); } function DropdownMenuRadioItem({ className, children, inset, onPointerEnter, onFocus, ...props }: React.ComponentProps & { inset?: boolean; }) { const { reportHover } = React.useContext(MenuHighlightContext); return ( { reportHover(e.currentTarget); onFocus?.(e); }} onPointerEnter={(e) => { reportHover(e.currentTarget); onPointerEnter?.(e); }} className={cn( "relative flex cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2.5 text-sm font-medium leading-5 outline-hidden select-none focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground/75", className, )} {...props} > {children} ); } function DropdownMenuLabel({ className, inset, ...props }: React.ComponentProps & { inset?: boolean; }) { return ( ); } function DropdownMenuSeparator({ className, ...props }: React.ComponentProps) { return ( ); } function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) { return ( ); } function DropdownMenuSub({ ...props }: React.ComponentProps) { return ; } function DropdownMenuSubTrigger({ className, inset, children, onPointerEnter, onFocus, ...props }: React.ComponentProps & { inset?: boolean; }) { const { reportHover } = React.useContext(MenuHighlightContext); return ( { reportHover(e.currentTarget); onFocus?.(e); }} onPointerEnter={(e) => { reportHover(e.currentTarget); onPointerEnter?.(e); }} className={cn( "flex cursor-default items-center gap-2 rounded-lg px-2.5 py-1.5 text-sm font-medium leading-5 outline-hidden select-none focus-visible:text-accent-foreground not-data-[variant=destructive]:focus-visible:**:text-accent-foreground data-inset:pl-8 data-[state=open]:bg-black/[0.045] dark:data-[state=open]:bg-white/[0.08] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg]:text-muted-foreground/75", className, )} {...props} > {children} ); } function DropdownMenuSubContent({ className, children, ...props }: React.ComponentProps) { const contentRef = React.useRef(null); const glass = useMenuHighlight(contentRef); return ( {glass.element}
{children}
); } export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, };