'use client';
import * as React from 'react';
import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
import { Check, ChevronRight, Circle } from 'lucide-react';
import {
AnimatePresence,
motion,
type HTMLMotionProps,
type Transition,
} from 'motion/react';
import { cn } from '@workspace/ui/lib/utils';
import {
MotionHighlight,
MotionHighlightItem,
} from '@/registry/effects/motion-highlight';
type DropdownMenuContextType = {
isOpen: boolean;
highlightTransition: Transition;
animateOnHover: boolean;
};
const DropdownMenuContext = React.createContext<
DropdownMenuContextType | undefined
>(undefined);
const useDropdownMenu = (): DropdownMenuContextType => {
const context = React.useContext(DropdownMenuContext);
if (!context) {
throw new Error('useDropdownMenu must be used within a DropdownMenu');
}
return context;
};
type DropdownMenuProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Root
> & {
transition?: Transition;
animateOnHover?: boolean;
};
function DropdownMenu({
children,
transition = { type: 'spring', stiffness: 350, damping: 35 },
animateOnHover = true,
...props
}: DropdownMenuProps) {
const [isOpen, setIsOpen] = React.useState(
props?.open ?? props?.defaultOpen ?? false,
);
React.useEffect(() => {
if (props?.open !== undefined) setIsOpen(props.open);
}, [props?.open]);
const handleOpenChange = React.useCallback(
(open: boolean) => {
setIsOpen(open);
props.onOpenChange?.(open);
},
[props],
);
return (
{children}
);
}
type DropdownMenuTriggerProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Trigger
>;
function DropdownMenuTrigger(props: DropdownMenuTriggerProps) {
return (
);
}
type DropdownMenuGroupProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Group
>;
function DropdownMenuGroup(props: DropdownMenuGroupProps) {
return (
);
}
type DropdownMenuPortalProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Portal
>;
function DropdownMenuPortal(props: DropdownMenuPortalProps) {
return (
);
}
type DropdownMenuSubProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Sub
>;
function DropdownMenuSub(props: DropdownMenuSubProps) {
return ;
}
type DropdownMenuRadioGroupProps = React.ComponentProps<
typeof DropdownMenuPrimitive.RadioGroup
>;
function DropdownMenuRadioGroup(props: DropdownMenuRadioGroupProps) {
return (
);
}
type DropdownMenuSubTriggerProps = React.ComponentProps<
typeof DropdownMenuPrimitive.SubTrigger
> & {
inset?: boolean;
};
function DropdownMenuSubTrigger({
className,
children,
inset,
disabled,
...props
}: DropdownMenuSubTriggerProps) {
return (
{children}
);
}
type DropdownMenuSubContentProps = React.ComponentProps<
typeof DropdownMenuPrimitive.SubContent
>;
function DropdownMenuSubContent({
className,
...props
}: DropdownMenuSubContentProps) {
return (
);
}
type DropdownMenuContentProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Content
> &
HTMLMotionProps<'div'> & {
transition?: Transition;
};
function DropdownMenuContent({
className,
children,
sideOffset = 4,
transition = { duration: 0.2 },
...props
}: DropdownMenuContentProps) {
const { isOpen, highlightTransition, animateOnHover } = useDropdownMenu();
return (
{isOpen && (
{children}
)}
);
}
type DropdownMenuItemProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Item
> & {
inset?: boolean;
variant?: 'default' | 'destructive';
};
function DropdownMenuItem({
className,
children,
inset,
disabled,
variant = 'default',
...props
}: DropdownMenuItemProps) {
return (
{children}
);
}
type DropdownMenuCheckboxItemProps = React.ComponentProps<
typeof DropdownMenuPrimitive.CheckboxItem
>;
function DropdownMenuCheckboxItem({
className,
children,
checked,
disabled,
...props
}: DropdownMenuCheckboxItemProps) {
return (
{children}
);
}
type DropdownMenuRadioItemProps = React.ComponentProps<
typeof DropdownMenuPrimitive.RadioItem
>;
function DropdownMenuRadioItem({
className,
children,
disabled,
...props
}: DropdownMenuRadioItemProps) {
return (
{children}
);
}
type DropdownMenuLabelProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Label
> & {
inset?: boolean;
};
function DropdownMenuLabel({
className,
inset,
...props
}: DropdownMenuLabelProps) {
return (
);
}
type DropdownMenuSeparatorProps = React.ComponentProps<
typeof DropdownMenuPrimitive.Separator
>;
function DropdownMenuSeparator({
className,
...props
}: DropdownMenuSeparatorProps) {
return (
);
}
type DropdownMenuShortcutProps = React.ComponentProps<'span'>;
function DropdownMenuShortcut({
className,
...props
}: DropdownMenuShortcutProps) {
return (
);
}
export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
type DropdownMenuProps,
type DropdownMenuTriggerProps,
type DropdownMenuContentProps,
type DropdownMenuItemProps,
type DropdownMenuCheckboxItemProps,
type DropdownMenuRadioItemProps,
type DropdownMenuLabelProps,
type DropdownMenuSeparatorProps,
type DropdownMenuShortcutProps,
type DropdownMenuGroupProps,
type DropdownMenuPortalProps,
type DropdownMenuSubProps,
type DropdownMenuSubContentProps,
type DropdownMenuSubTriggerProps,
type DropdownMenuRadioGroupProps,
};