@@ -8,7 +8,11 @@ import { inlineMock } from './mock';
88
99export type ContainerType = Element | DocumentFragment ;
1010
11- export type GetContainer = string | ContainerType | ( ( ) => ContainerType ) ;
11+ export type GetContainer =
12+ | string
13+ | ContainerType
14+ | ( ( ) => ContainerType )
15+ | false ;
1216
1317export interface PortalProps {
1418 /** Customize container element. Default will create a div in document.body when `open` */
@@ -18,10 +22,17 @@ export interface PortalProps {
1822 open ?: boolean ;
1923 /** Lock screen scroll when open */
2024 autoLock ?: boolean ;
25+
26+ /** @private debug name. Do not use in prod */
27+ debug ?: string ;
2128}
2229
2330const getPortalContainer = ( getContainer : GetContainer ) => {
24- if ( ! canUseDom ( ) ) {
31+ if ( getContainer === false ) {
32+ return false ;
33+ }
34+
35+ if ( ! canUseDom ( ) || ! getContainer ) {
2536 return null ;
2637 }
2738
@@ -35,7 +46,7 @@ const getPortalContainer = (getContainer: GetContainer) => {
3546} ;
3647
3748export default function Portal ( props : PortalProps ) {
38- const { open, autoLock, getContainer, children } = props ;
49+ const { open, autoLock, getContainer, debug , children } = props ;
3950
4051 const [ mergedRender , setMergedRender ] = React . useState ( open ) ;
4152
@@ -47,23 +58,36 @@ export default function Portal(props: PortalProps) {
4758 } , [ open ] ) ;
4859
4960 // ======================== Container ========================
50- const customizeContainer = getPortalContainer ( getContainer ) ;
61+ const [ innerContainer , setInnerContainer ] = React . useState <
62+ ContainerType | false
63+ > ( ( ) => getPortalContainer ( getContainer ) ) ;
64+
65+ React . useEffect ( ( ) => {
66+ const customizeContainer = getPortalContainer ( getContainer ) ;
67+
68+ // Tell component that we check this in effect which is safe to be `null`
69+ setInnerContainer ( customizeContainer ?? null ) ;
70+ } ) ;
5171
5272 const [ defaultContainer , queueCreate ] = useDom (
53- mergedRender && ! customizeContainer ,
73+ mergedRender && ! innerContainer ,
74+ debug ,
5475 ) ;
55- const mergedContainer = customizeContainer || defaultContainer ;
76+ const mergedContainer = innerContainer ?? defaultContainer ;
5677
5778 // ========================= Render ==========================
5879 // Do not render when nothing need render
59- if ( ! mergedRender || ! canUseDom ( ) ) {
80+ // When innerContainer is `undefined`, it may not ready since user use ref in the same render
81+ if ( ! mergedRender || ! canUseDom ( ) || innerContainer === undefined ) {
6082 return null ;
6183 }
6284
63- console . log ( inlineMock ( ) ) ;
85+ // Render inline
86+ const renderInline = mergedContainer === false || inlineMock ( ) ;
87+
6488 return (
6589 < OrderContext . Provider value = { queueCreate } >
66- { inlineMock ( ) ? children : createPortal ( children , mergedContainer ) }
90+ { renderInline ? children : createPortal ( children , mergedContainer ) }
6791 </ OrderContext . Provider >
6892 ) ;
6993}
0 commit comments