import * as React from "react" import { View } from "@tarojs/components" import { X } from "lucide-react-taro" import { cn } from "@/lib/utils" import { Portal } from "@/components/ui/portal" import { useKeyboardOffset } from "@/lib/hooks/use-keyboard-offset" const DialogContext = React.createContext<{ open?: boolean onOpenChange?: (open: boolean) => void } | null>(null) const usePresence = (open: boolean | undefined, durationMs: number) => { const [present, setPresent] = React.useState(!!open) const timeoutRef = React.useRef | null>(null) React.useEffect(() => { if (open) { if (timeoutRef.current) clearTimeout(timeoutRef.current) timeoutRef.current = null setPresent(true) return } timeoutRef.current = setTimeout(() => setPresent(false), durationMs) return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current) timeoutRef.current = null } }, [open, durationMs]) return present } interface DialogProps { children: React.ReactNode open?: boolean defaultOpen?: boolean onOpenChange?: (open: boolean) => void modal?: boolean } const Dialog = ({ children, open: openProp, defaultOpen, onOpenChange }: DialogProps) => { const [openState, setOpenState] = React.useState(defaultOpen || false) const open = openProp !== undefined ? openProp : openState const handleOpenChange = (newOpen: boolean) => { if (openProp === undefined) { setOpenState(newOpen) } onOpenChange?.(newOpen) } return ( {children} ) } const DialogTrigger = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & { asChild?: boolean } >(({ className, children, asChild, ...props }, ref) => { const context = React.useContext(DialogContext) return ( { e.stopPropagation() context?.onOpenChange?.(true) }} {...props} > {children} ) }) DialogTrigger.displayName = "DialogTrigger" const DialogPortal = ({ children }: { children: React.ReactNode }) => { const context = React.useContext(DialogContext) const present = usePresence(context?.open, 200) if (!present) return null return {children} } const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, onClick, ...props }, ref) => { const context = React.useContext(DialogContext) const state = context?.open ? "open" : "closed" return ( { e.stopPropagation() onClick?.(e) context?.onOpenChange?.(false) }} {...props} /> ) }) DialogOverlay.displayName = "DialogOverlay" interface DialogContentProps extends React.ComponentPropsWithoutRef { closeClassName?: string } const DialogContent = React.forwardRef< React.ElementRef, DialogContentProps >(({ className, children, style, closeClassName, ...props }, ref) => { const context = React.useContext(DialogContext) const offset = useKeyboardOffset() const state = context?.open ? "open" : "closed" return ( context?.onOpenChange?.(false)} > 0 ? `calc(50% - ${offset / 2}px)` : undefined }} onClick={(e) => e.stopPropagation()} {...props} > {children} { e.stopPropagation() context?.onOpenChange?.(false) }} > Close ) }) DialogContent.displayName = "DialogContent" const DialogHeader = ({ className, ...props }: React.ComponentPropsWithoutRef) => ( ) DialogHeader.displayName = "DialogHeader" const DialogFooter = ({ className, ...props }: React.ComponentPropsWithoutRef) => ( ) DialogFooter.displayName = "DialogFooter" const DialogTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogTitle.displayName = "DialogTitle" const DialogDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DialogDescription.displayName = "DialogDescription" const DialogClose = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { const context = React.useContext(DialogContext) return ( { e.stopPropagation() context?.onOpenChange?.(false) }} {...props} /> ) }) DialogClose.displayName = "DialogClose" export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, }