import * as React from "react"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { cn } from "../../libs/utils"; import { X } from "lucide-react"; import { Button } from "../button"; import { VisuallyHidden } from "../../libs/visuallyHidden"; import { createContext, useContext } from "react"; import { usePortalContainer } from "../../../hooks/PortalContainerProvider"; interface ModalProps { children: React.ReactNode | React.ReactNode[]; isOpen: boolean; onClose: () => void; description?: string; noCloseButton?: boolean; className?: string; allowOverflow?: boolean; disableCloseOnClickOutside?: boolean; size?: "sm" | "md" | "lg" | "xl"; action?: React.ReactNode; } const ModalContext = createContext(false) export function useIsInModal() { return !!useContext(ModalContext); } export function ModalContextProvider({ children }: { children: React.ReactNode }) { return {children} } export function Modal({ className, children, isOpen, onClose, description = "Modal Description", noCloseButton = false, allowOverflow = false, disableCloseOnClickOutside = false, size = "md", action }: ModalProps) { const handleOpenChange = (open: boolean) => { if (!open) { onClose(); } }; function getSizeClasses() { switch (size) { case "sm": return "max-w-[20vw]"; case "md": return "max-w-[60vw] lg:max-w-[40vw]"; case "lg": return "max-w-[80vw] md:max-w-[60vw]"; case "xl": return "max-w-[95vw] lg:max-w-[80vw]"; default: return "max-w-[60vw] lg:max-w-[40vw]"; } } return ( { if (!disableCloseOnClickOutside || open) { handleOpenChange(open); } }} > {allowOverflow && } {description}
{action && ( <> {action} )} {!noCloseButton && ( handleOpenChange(false)} asChild autoFocus={false}> )}
{children}
); } export const ModalTitle = ({ children, show = true, className, description, showDivider = false, ...props }: React.HTMLAttributes & { show?: boolean; description?: string, showDivider?: boolean }) => { if (!show) { return ( {children} {description && {description}} ) } return ( <> {children} {description && ( {description} )} ); }; export const ModalBody = ({ children, className, ...props }: React.HTMLAttributes) => { return (
{children}
); }; interface ModalFooterProps extends React.HTMLAttributes { align?: "left" | "right" | "center"; children: React.ReactNode | React.ReactNode[]; className?: string; } export const ModalFooter = ({ align = "right", children, className, ...props }: ModalFooterProps) => { const alignClass = { left: "justify-start", center: "justify-center", right: "justify-end", }; return (
{children}
); }; const Dialog = DialogPrimitive.Root; 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 container = usePortalContainer(); return ( { event.preventDefault(); }} className={cn( "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", className )} {...props} > {children} ); }); DialogContent.displayName = DialogPrimitive.Content.displayName; const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogDescription.displayName = DialogPrimitive.Description.displayName const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogTitle.displayName = DialogPrimitive.Title.displayName export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogTitle, DialogDescription, };