1
1
import React , { useEffect , ReactNode , useState } from 'react'
2
- import { createPortal , render } from 'react-dom'
2
+ import { createPortal } from 'react-dom'
3
+ import { createRoot } from 'react-dom/client'
3
4
import { Drawer , DEFAULT_DRAWER_WIDTH } from '@adminjs/design-system'
4
5
import { ThemeProvider } from 'styled-components'
5
6
@@ -20,6 +21,30 @@ export type DrawerPortalProps = {
20
21
}
21
22
22
23
const DRAWER_PORTAL_ID = 'drawerPortal'
24
+ const DRAWER_PORTAL_WRAPPER_ID = 'drawerPortalWrapper'
25
+
26
+ const DrawerWrapper = ( { onMount } ) => {
27
+ useEffect ( ( ) => {
28
+ onMount ( )
29
+ } , [ ] )
30
+ return (
31
+ < ThemeProvider theme = { ( window as any ) . THEME } >
32
+ < Drawer id = { DRAWER_PORTAL_ID } className = "hidden" />
33
+ </ ThemeProvider >
34
+ )
35
+ }
36
+
37
+ const createPortalContainer = ( id : string ) => {
38
+ let container = document . getElementById ( id )
39
+
40
+ if ( ! container ) {
41
+ container = window . document . createElement ( 'div' )
42
+ container . id = id
43
+ window . document . body . appendChild ( container )
44
+ }
45
+
46
+ return container
47
+ }
23
48
24
49
/**
25
50
* Shows all of its children in a Drawer on the right.
@@ -36,34 +61,39 @@ const DRAWER_PORTAL_ID = 'drawerPortal'
36
61
* @subcategory Application
37
62
*/
38
63
export const DrawerPortal : React . FC < DrawerPortalProps > = ( { children, width } ) => {
39
- const [ drawerElement , setDrawerElement ] = useState < HTMLElement | null > (
40
- window . document . getElementById ( DRAWER_PORTAL_ID ) ,
41
- )
42
- if ( ! drawerElement && window ) {
43
- const innerWrapper = window . document . createElement ( 'div' )
44
- const DrawerWrapper = (
45
- < ThemeProvider theme = { ( window as any ) . THEME } >
46
- < Drawer id = { DRAWER_PORTAL_ID } className = "hidden" />
47
- </ ThemeProvider >
48
- )
49
- window . document . body . appendChild ( innerWrapper )
50
- render ( DrawerWrapper , innerWrapper , ( ) => {
51
- setDrawerElement ( window . document . getElementById ( DRAWER_PORTAL_ID ) )
52
- } )
64
+ const [ drawerElement , setDrawerElement ] = useState ( document . getElementById ( DRAWER_PORTAL_ID ) )
65
+
66
+ const handleDrawerMount = ( ) => {
67
+ setDrawerElement ( document . getElementById ( DRAWER_PORTAL_ID ) )
53
68
}
54
69
70
+ useEffect ( ( ) => {
71
+ const innerWrapperElement = createPortalContainer ( DRAWER_PORTAL_WRAPPER_ID )
72
+ if ( ! drawerElement && window ) {
73
+ const drawerRoot = createRoot ( innerWrapperElement )
74
+ drawerRoot . render ( < DrawerWrapper onMount = { handleDrawerMount } /> )
75
+ }
76
+
77
+ return ( ) => {
78
+ const innerWrapper = document . getElementById ( DRAWER_PORTAL_WRAPPER_ID )
79
+ if ( innerWrapper ) document . body . removeChild ( innerWrapper )
80
+ }
81
+ } , [ ] )
82
+
55
83
useEffect ( ( ) => {
56
84
if ( drawerElement ) {
57
85
drawerElement . classList . remove ( 'hidden' )
58
86
if ( width ) {
59
- drawerElement . style . width = Array . isArray ( width ) ? width [ 0 ] . toString ( ) : width . toString ( )
87
+ drawerElement . style . width = Array . isArray ( width )
88
+ ? width [ 0 ] . toString ( )
89
+ : width . toString ( )
60
90
}
61
91
return ( ) : void => {
62
92
drawerElement . style . width = DEFAULT_DRAWER_WIDTH
63
93
drawerElement . classList . add ( 'hidden' )
64
94
}
65
95
}
66
- return ( ) : void => undefined
96
+ return ( ) => undefined
67
97
} , [ drawerElement ] )
68
98
69
99
if ( ! drawerElement ) {
0 commit comments