'use client'; import * as React from 'react'; import { Popover as PopoverPrimitive } from 'radix-ui'; import { AnimatePresence, motion, type HTMLMotionProps, type Transition, } from 'motion/react'; import { cn } from '@workspace/ui/lib/utils'; type PopoverContextType = { isOpen: boolean; }; const PopoverContext = React.createContext( undefined, ); const usePopover = (): PopoverContextType => { const context = React.useContext(PopoverContext); if (!context) { throw new Error('usePopover must be used within a Popover'); } return context; }; type Side = 'top' | 'bottom' | 'left' | 'right'; const getInitialPosition = (side: Side) => { switch (side) { case 'top': return { y: 15 }; case 'bottom': return { y: -15 }; case 'left': return { x: 15 }; case 'right': return { x: -15 }; } }; type PopoverProps = React.ComponentProps; function Popover({ children, ...props }: PopoverProps) { 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 PopoverTriggerProps = React.ComponentProps< typeof PopoverPrimitive.Trigger >; function PopoverTrigger(props: PopoverTriggerProps) { return ; } type PopoverContentProps = React.ComponentProps< typeof PopoverPrimitive.Content > & HTMLMotionProps<'div'> & { transition?: Transition; }; function PopoverContent({ className, align = 'center', side = 'bottom', sideOffset = 4, transition = { type: 'spring', stiffness: 300, damping: 25 }, children, ...props }: PopoverContentProps) { const { isOpen } = usePopover(); const initialPosition = getInitialPosition(side); return ( {isOpen && ( {children} )} ); } type PopoverAnchorProps = React.ComponentProps; function PopoverAnchor({ ...props }: PopoverAnchorProps) { return ; } export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, usePopover, type PopoverContextType, type PopoverProps, type PopoverTriggerProps, type PopoverContentProps, type PopoverAnchorProps, };