"use client"; import React from "react"; import * as PopoverPrimitive from "@radix-ui/react-popover"; import { paperMixin } from "../styles"; import { cls } from "../util"; import { useInjectStyles } from "../hooks"; import { usePortalContainer } from "../hooks/PortalContainerContext"; export type PopoverSide = "top" | "right" | "bottom" | "left"; export type PopoverAlign = "start" | "center" | "end"; export interface PopoverProps { trigger: React.ReactNode; children: React.ReactNode; open?: boolean; onOpenChange?: (open: boolean) => void; side?: PopoverSide; sideOffset?: number; align?: PopoverAlign; alignOffset?: number; arrowPadding?: number; sticky?: "partial" | "always"; hideWhenDetached?: boolean; avoidCollisions?: boolean; enabled?: boolean; modal?: boolean; className?: string; portalContainer?: HTMLElement | null; } export function Popover({ trigger, children, open, onOpenChange, side, sideOffset = 5, align, alignOffset, arrowPadding, sticky, hideWhenDetached, avoidCollisions, enabled = true, modal = false, portalContainer, className }: PopoverProps) { useInjectStyles("Popover", popoverStyles); // Get the portal container from context const contextContainer = usePortalContainer(); // Prioritize manual prop, fallback to context container const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined; if (!enabled) return <>{trigger}; return {trigger} {children} ; } const popoverStyles = ` /* ... (styles remain unchanged) ... */ .PopoverContent { animation-duration: 400ms; animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); will-change: transform, opacity; } .PopoverContent[data-state='open'][data-side='top'] { animation-name: slideDownAndFade; } .PopoverContent[data-state='open'][data-side='right'] { animation-name: slideLeftAndFade; } .PopoverContent[data-state='open'][data-side='bottom'] { animation-name: slideUpAndFade; } .PopoverContent[data-state='open'][data-side='left'] { animation-name: slideRightAndFade; } @keyframes slideUpAndFade { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideRightAndFade { from { opacity: 0; transform: translateX(-2px); } to { opacity: 1; transform: translateX(0); } } @keyframes slideDownAndFade { from { opacity: 0; transform: translateY(-2px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideLeftAndFade { from { opacity: 0; transform: translateX(2px); } to { opacity: 1; transform: translateX(0); } } `;