1
- import React from 'react'
1
+ import React , { useState , useRef , useLayoutEffect , useEffect } from 'react'
2
+ import PropTypes from 'prop-types'
2
3
import clsx from 'clsx'
3
-
4
+ import useComponentSize from '@rehooks/component-size'
4
5
import { makeStyles , useTheme } from '@material-ui/core/styles'
5
6
import useMediaQuery from '@material-ui/core/useMediaQuery'
6
7
import Drawer from '@material-ui/core/Drawer'
7
8
import Hidden from '@material-ui/core/Hidden'
8
9
9
- import AppHeader from '../../_common/AppHeader/AppHeader'
10
- import AppSidebar from '../../_common/AppSidebar/AppSidebar'
10
+ import AppHeader from '../../_common/AppHeader'
11
11
import AppFooter from '../../_common/AppFooter'
12
+ import AppSidebar from '../../_common/AppSidebar'
13
+
14
+ export default function DashboardLayout (
15
+ { header, footer, sidebar, content, children } = {
16
+ header : AppHeader ,
17
+ footer : AppFooter ,
18
+ sidebar : AppSidebar ,
19
+ } ,
20
+ ) {
21
+ const refHeaderContainer = useRef ( null )
22
+ const refSidebarContainer = useRef ( null )
23
+ const refFooterContainer = useRef ( null )
12
24
13
- export default function Dashboard ( { children } ) {
14
25
const classes = useStyles ( )
15
26
const theme = useTheme ( )
16
27
const isDesktop = useMediaQuery ( theme . breakpoints . up ( 'md' ) )
17
28
const isMobile = ! isDesktop
18
29
19
- const [ isSidebarOpenMobile , setIsSidebarOpenMobile ] = React . useState ( false )
20
- const [ isSidebarCollapsedDesktop , setIsSidebarCollapsedDesktop ] = React . useState ( false )
30
+ const [ contentOffset , setContentOffset ] = useState ( 0 )
31
+ const [ isSidebarOpenMobile , setIsSidebarOpenMobile ] = useState ( false )
32
+ const [ isSidebarOpenDesktop , setIsSidebarOpenDesktop ] = useState ( false )
33
+ const [ isSidebarCollapsedDesktop , setIsSidebarCollapsedDesktop ] = useState ( false )
34
+
35
+ const headerSize = useComponentSize ( refHeaderContainer )
36
+ const sidebarSize = useComponentSize ( refSidebarContainer )
37
+ const footerSize = useComponentSize ( refFooterContainer )
38
+
39
+ const HeaderComponent = header
40
+ const SidebarComponent = sidebar
41
+ const FooterComponent = footer
21
42
22
43
function handleSidebarMobileToggle ( ) {
23
44
setIsSidebarOpenMobile ( ! isSidebarOpenMobile )
@@ -34,27 +55,33 @@ export default function Dashboard({ children }) {
34
55
}
35
56
}
36
57
58
+ function handleSidebarToggleCollapse ( ) {
59
+ setIsSidebarCollapsedDesktop ( ! setIsSidebarCollapsedDesktop )
60
+ }
61
+
37
62
return (
38
63
< div className = { classes . dashboardContainer } >
39
64
< div
65
+ ref = { refHeaderContainer }
40
66
className = { clsx (
41
67
classes . headerContainer ,
42
68
isDesktop && classes . headerContainerDesktop ,
43
69
isDesktop &&
44
70
isSidebarCollapsedDesktop &&
45
71
classes . headerContainerDesktopDrawerCollapsed ,
46
72
) }
73
+ style = { {
74
+ width : `calc(100% - ${ sidebarSize . width } px)` ,
75
+ } }
47
76
>
48
- < AppHeader onToggle = { handleSidebarToggle } />
77
+ { HeaderComponent && < HeaderComponent /> }
49
78
</ div >
50
79
< div
80
+ ref = { refSidebarContainer }
51
81
className = { clsx (
52
82
classes . sidebarContainer ,
53
83
isMobile && classes . sidebarContainerMobile ,
54
- isDesktop && classes . sidebarContainerDesktop ,
55
- isDesktop &&
56
- isSidebarCollapsedDesktop &&
57
- classes . sidebarContainerDesktopDrawerCollapsed ,
84
+ isDesktop && isSidebarCollapsedDesktop && classes . sidebarContainerCollapsed ,
58
85
) }
59
86
>
60
87
< Hidden mdUp implementation = "css" >
@@ -64,12 +91,13 @@ export default function Dashboard({ children }) {
64
91
open = { isSidebarOpenMobile }
65
92
onClose = { handleSidebarMobileToggle }
66
93
classes = { {
67
- paper : clsx ( classes . drawer , classes . drawerMobile ) ,
94
+ paper : clsx ( classes . drawer ) , // classes.drawerMobile
68
95
} }
69
96
ModalProps = { {
70
97
keepMounted : true , // Better open performance on mobile.
71
98
} }
72
99
>
100
+ { SidebarComponent && < SidebarComponent /> }
73
101
{ /* <Sidebar
74
102
isDesktop={isDesktop}
75
103
isMobile={isMobile}
@@ -81,14 +109,12 @@ export default function Dashboard({ children }) {
81
109
< Hidden smDown implementation = "css" >
82
110
< Drawer
83
111
classes = { {
84
- paper : clsx (
85
- classes . drawer ,
86
- classes . drawerDesktop ,
87
- isSidebarCollapsedDesktop && classes . drawerDesktopCollapsed ,
88
- ) ,
112
+ paper : clsx ( classes . drawer ) ,
89
113
} }
90
114
variant = "permanent"
91
115
>
116
+ { SidebarComponent && < SidebarComponent /> }
117
+ { /* {sidebar} */ }
92
118
{ /* <Sidebar
93
119
isDesktop={isDesktop}
94
120
isMobile={isMobile}
@@ -98,44 +124,52 @@ export default function Dashboard({ children }) {
98
124
</ Drawer >
99
125
</ Hidden >
100
126
</ div >
101
- < main className = { classes . content } >
102
- < div className = { classes . headerSpacer } />
103
- { children }
104
- < AppFooter />
127
+ < main
128
+ className = { classes . mainContainer }
129
+ style = { {
130
+ paddingTop : headerSize . height ,
131
+ } }
132
+ >
133
+ < div className = { classes . contentContainer } > { children } </ div >
134
+ < div className = { classes . footerContainer } >
135
+ { FooterComponent && < FooterComponent /> }
136
+ </ div >
105
137
</ main >
106
138
</ div >
107
139
)
108
140
}
109
141
142
+ DashboardLayout . props = {
143
+ header : PropTypes . elementType ,
144
+ sidebar : PropTypes . elementType ,
145
+ footer : PropTypes . elementType ,
146
+ }
147
+
110
148
const useStyles = makeStyles ( theme => ( {
111
149
dashboardContainer : {
112
150
display : 'flex' ,
113
151
background : '#f5f5f5' ,
114
152
} ,
115
153
headerContainer : {
116
154
top : 0 ,
117
- left : 0 ,
155
+ left : 'auto' ,
118
156
right : 0 ,
157
+ display : 'flex' ,
158
+ alignItems : 'stretch' ,
119
159
position : 'absolute' ,
120
160
zIndex : theme . zIndex . drawer + 1 ,
121
161
transition : theme . transitions . create ( [ 'width' , 'margin' ] , {
122
162
easing : theme . transitions . easing . sharp ,
123
163
duration : theme . transitions . duration . leavingScreen ,
124
164
} ) ,
125
165
} ,
126
- headerContainerDesktop : {
127
- left : 'auto' ,
128
- width : `calc(100% - ${ theme . sidebar . width } px)` ,
129
- transition : theme . transitions . create ( [ 'width' , 'margin' ] , {
130
- easing : theme . transitions . easing . sharp ,
131
- duration : theme . transitions . duration . enteringScreen ,
132
- } ) ,
133
- } ,
134
- headerContainerDesktopDrawerCollapsed : {
135
- width : `calc(100% - ${ theme . sidebar . widthCollapsed } px)` ,
136
- } ,
137
166
sidebarContainer : {
167
+ display : 'flex' ,
168
+ alignItems : 'stretch' ,
138
169
position : 'relative' ,
170
+ top : 0 ,
171
+ bottom : 0 ,
172
+ flexDirection : 'row' ,
139
173
[ theme . breakpoints . up ( 'md' ) ] : {
140
174
width : theme . sidebar . width ,
141
175
flexShrink : 0 ,
@@ -148,40 +182,25 @@ const useStyles = makeStyles(theme => ({
148
182
sidebarContainerMobile : {
149
183
width : 0 ,
150
184
} ,
151
- sidebarContainerDesktop : {
152
- width : theme . sidebar . width ,
153
- } ,
154
- sidebarContainerDesktopDrawerCollapsed : {
155
- [ theme . breakpoints . up ( 'md' ) ] : {
156
- width : theme . sidebar . widthCollapsed ,
157
- } ,
158
- } ,
159
- drawer : { } ,
160
- drawerMobile : {
161
- width : theme . sidebar . width ,
185
+ sidebarContainerCollapsed : {
186
+ width : theme . sidebar . widthCollapsed ,
162
187
} ,
163
- drawerDesktop : {
188
+ drawer : {
164
189
width : '100%' ,
165
190
position : 'absolute' ,
166
191
} ,
167
- drawerDesktopCollapsed : {
168
- overflowX : 'hidden' ,
169
- } ,
170
- headerSpacer : theme . mixins . toolbar ,
171
- content : {
192
+ mainContainer : {
172
193
flexGrow : 1 ,
173
194
height : '100vh' ,
174
195
overflow : 'auto' ,
175
196
flexDirection : 'column' ,
176
197
display : 'flex' ,
177
198
} ,
178
- paper : {
179
- padding : theme . spacing ( 2 ) ,
180
- display : 'flex' ,
181
- overflow : 'auto' ,
182
- flexDirection : 'column' ,
199
+ contentContainer : {
200
+ position : 'relative' ,
201
+ flex : 1 ,
183
202
} ,
184
- fixedHeight : {
185
- height : 240 ,
203
+ footerContainer : {
204
+ position : 'relative' ,
186
205
} ,
187
206
} ) )
0 commit comments