"use client"; import { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { cn } from "@/lib/utils"; export function ModalShell({ open, children, className, zIndexClassName = "z-[60]", onBackdropClick, /** 内容偏高时从顶部留白展示,避免卡片内滚动 */ alignTop = false, }: { open: boolean; children: React.ReactNode; className?: string; zIndexClassName?: string; /** 点击遮罩时触发(子内容已阻止冒泡) */ onBackdropClick?: () => void; alignTop?: boolean; }) { const [mounted, setMounted] = useState(false); useEffect(() => { /* eslint-disable-next-line react-hooks/set-state-in-effect -- document.body portal only after mount; avoids SSR mismatch */ setMounted(true); }, []); if (!mounted) { return null; } return createPortal(
{ onBackdropClick(); } : undefined } >
e.stopPropagation()} > {children}
, document.body, ); }