import * as DialogPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; import * as React from "react"; import { cn } from "@/lib/utils"; const DialogContext = React.createContext<{ onOpenChange?: (open: boolean) => void; open?: boolean; }>({}); const Dialog = ({ onOpenChange, open, ...props }: React.ComponentPropsWithoutRef) => { const [isOpened, setIsOpened] = React.useState(false); // for internal control const handleOpenChange = (open: boolean) => { if (onOpenChange) { onOpenChange(open); } else { setIsOpened(open); } }; return ( ); }; Dialog.displayName = DialogPrimitive.Root.displayName; const DialogTrigger = DialogPrimitive.Trigger; const DialogPortal = DialogPrimitive.Portal; const DialogClose = DialogPrimitive.Close; const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; const DialogContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => { const contentRef = React.useRef(null); const { onOpenChange, open } = React.useContext(DialogContext); React.useEffect(() => { if (!open) return; const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; const body = document.body; const originalPaddingRight = body.style.paddingRight; const originalOverflow = body.style.overflow; if (scrollbarWidth > 0) { body.style.paddingRight = `${scrollbarWidth}px`; } return () => { body.style.overflow = originalOverflow; body.style.paddingRight = originalPaddingRight; }; }, [open]); // Handle outside interactions properly with Command components const handleInteractOutside = React.useCallback( (event: Event | React.MouseEvent) => { // Don't close when clicking inside popovers, dropdowns, or command components const target = event.target as HTMLElement; if ( target.closest("[data-radix-popper-content-wrapper]") || target.closest("[cmdk-root]") || target.closest("[data-radix-command-root]") ) { event.preventDefault(); return; } if (onOpenChange) { event.preventDefault(); event.stopPropagation(); onOpenChange(false); } }, [onOpenChange], ); const hasPaddingOverride = className?.includes("p-0"); // Separate DialogFooter from other children for proper layout const childrenArray = React.Children.toArray(children); const dialogFooter = childrenArray.find( (child) => React.isValidElement(child) && child.type === DialogFooter, ); const otherChildren = childrenArray.filter( (child) => !(React.isValidElement(child) && child.type === DialogFooter), ); return ( {/* Custom overlay for modal=false - no click handler to avoid Command conflicts */}
event.preventDefault()} {...props} >
{otherChildren}
{/* DialogFooter outside scrollable area with proper spacing */} {dialogFooter && (
{dialogFooter}
)} Close
); }); DialogContent.displayName = DialogPrimitive.Content.displayName; const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
); DialogHeader.displayName = "DialogHeader"; const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
); DialogFooter.displayName = "DialogFooter"; const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogTitle.displayName = DialogPrimitive.Title.displayName; const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); DialogDescription.displayName = DialogPrimitive.Description.displayName; export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };