jsx import { jsx , ArrayInterpolation , Theme } from "@emotion/react" ; import React , { useEffect , useLayoutEffect , useRef , useState } from "react" ; import ReactDOM from "react-dom" ; import { getContextValue } from "../context" ; import { ContextValue } from "../context" ; import { useWindowResize } from "../Effect/useWindowResize" ; export interface OverlayProps extends React . HTMLProps < HTMLDivElement > { children ? : React . ReactNode ; outside ? : boolean ; centerContent ? : boolean ; fullScreen ? : boolean ; maskColor ? : string ; } param props returns export function Overlay ( props ) { const { children , outside = false , centerContent = true , fullScreen = true , maskColor = "rgba(0, 0, 0, .6)" , ... extra } = props ; const [ mount , setMount ] = useState < HTMLDivElement | null > ( null ) ; const [ innerWidth , setInnerWidth ] = useState < number > ( window . innerWidth ) ; const isUnmount = useRef < boolean | null > ( false ) ; useEffect ( ( ) => { return ( ) => { isUnmount . current = true ; } ; } , [ ] ) ; useLayoutEffect ( ( ) => { if ( outside ) { const div = document . createElement ( "div" ) ; document . body . appendChild ( div ) ; setMount ( div ) ; return ( ) => { div . remove ( ) ; } ; } } , [ outside ] ) ; useWindowResize ( ( ) => { if ( ! isUnmount . current ) { setInnerWidth ( window . innerWidth ) ; } } ) ; const ctx = getContextValue ( ) as ContextValue ; const style = [ ] ; if ( fullScreen ) { let width = innerWidth ; if ( width >= ctx . maxDocWidth ) { width = ctx . maxDocWidth ; } else if ( width <= ctx . minDocWidth ) { width = ctx . minDocWidth ; } style . push ( { zIndex : 9999 , position : "fixed" , top : 0 , left : "50%" , marginLeft : `-${ width / 2 }px` , width : `${ width }px` , height : "100%" , maxWidth : `${ ctx . maxDocWidth }px` , minWidth : `${ ctx . minDocWidth }px` , backgroundColor : maskColor , } ) ; } if ( centerContent ) { style . push ( { display : "flex" , alignItems : "center" , justifyContent : "center" , } ) ; } const content = ( < div css = { style } { ... extra } > { children } < /div>); /**
     * 如果是挂载到当前位置，直接返回
     */ if ( ! outside ) { return content ; } /**
     * 如果是挂载到外部，但是挂载点还没准备好，返回空
     */ if ( ! mount ) { return null ; } /**
     * 挂载到外部，且挂载点已经准备好
     */ return ReactDOM . createPortal ( content , mount ) ; }