@@ -10,8 +10,10 @@ import AppsManager from 'lib/AppsManager';
10
10
import AppsMenu from 'components/Sidebar/AppsMenu.react' ;
11
11
import AppName from 'components/Sidebar/AppName.react' ;
12
12
import FooterMenu from 'components/Sidebar/FooterMenu.react' ;
13
- import React , { useState } from 'react ' ;
13
+ import isInsidePopover from 'lib/isInsidePopover ' ;
14
14
import ParseApp from 'lib/ParseApp' ;
15
+ import Pin from 'components/Sidebar/Pin.react' ;
16
+ import React , { useEffect , useState } from 'react' ;
15
17
import SidebarHeader from 'components/Sidebar/SidebarHeader.react' ;
16
18
import SidebarSection from 'components/Sidebar/SidebarSection.react' ;
17
19
import SidebarSubItem from 'components/Sidebar/SidebarSubItem.react' ;
@@ -29,7 +31,46 @@ const Sidebar = ({
29
31
primaryBackgroundColor,
30
32
secondaryBackgroundColor
31
33
} , { currentApp } ) => {
34
+ const collapseWidth = 980 ;
32
35
const [ appsMenuOpen , setAppsMenuOpen ] = useState ( false ) ;
36
+ const [ collapsed , setCollapsed ] = useState ( false ) ;
37
+ const [ fixed , setFixed ] = useState ( true ) ;
38
+ let currentWidth = window . innerWidth ;
39
+
40
+ const windowResizeHandler = ( ) => {
41
+ if ( window . innerWidth <= collapseWidth && currentWidth > collapseWidth ) {
42
+ if ( document . body . className . indexOf ( ' expanded' ) === - 1 ) {
43
+ document . body . className += ' expanded' ;
44
+ }
45
+ setCollapsed ( true ) ;
46
+ setFixed ( false ) ;
47
+ } else if ( window . innerWidth > collapseWidth && currentWidth <= collapseWidth ) {
48
+ document . body . className = document . body . className . replace ( ' expanded' , '' ) ;
49
+ setCollapsed ( false ) ;
50
+ setFixed ( true ) ;
51
+ }
52
+ // Update window width
53
+ currentWidth = window . innerWidth ;
54
+ }
55
+
56
+ useEffect ( ( ) => {
57
+ window . addEventListener ( 'resize' , windowResizeHandler ) ;
58
+
59
+ return ( ) => {
60
+ window . removeEventListener ( 'resize' , windowResizeHandler ) ;
61
+ }
62
+ } ) ;
63
+
64
+ const sidebarClasses = [ styles . sidebar ] ;
65
+ if ( fixed ) {
66
+ document . body . className = document . body . className . replace ( ' expanded' , '' ) ;
67
+ } else if ( ! fixed && collapsed ) {
68
+ sidebarClasses . push ( styles . collapsed ) ;
69
+ if ( document . body . className . indexOf ( ' expanded' ) === - 1 ) {
70
+ document . body . className += ' expanded' ;
71
+ }
72
+ }
73
+
33
74
const _subMenu = subsections => {
34
75
if ( ! subsections ) {
35
76
return null ;
@@ -54,25 +95,40 @@ const Sidebar = ({
54
95
) ;
55
96
}
56
97
57
- const apps = [ ] . concat ( AppsManager . apps ( ) ) . sort ( ( a , b ) => ( a . name < b . name ? - 1 : ( a . name > b . name ? 1 : 0 ) ) ) ;
98
+ const onPinClick = ( ) => {
99
+ if ( fixed ) {
100
+ setFixed ( false ) ;
101
+ setCollapsed ( true ) ;
102
+ setAppsMenuOpen ( false ) ;
103
+ } else {
104
+ setFixed ( true ) ;
105
+ setCollapsed ( false ) ;
106
+ }
107
+ } ;
58
108
59
109
let sidebarContent ;
60
110
if ( appsMenuOpen ) {
111
+ const apps = [ ] . concat ( AppsManager . apps ( ) ) . sort ( ( a , b ) => ( a . name < b . name ? - 1 : ( a . name > b . name ? 1 : 0 ) ) ) ;
61
112
sidebarContent = (
62
113
< AppsMenu
63
114
apps = { apps }
64
115
current = { currentApp }
116
+ onPinClick = { onPinClick }
65
117
onSelect = { ( ) => setAppsMenuOpen ( false ) } />
66
118
) ;
67
119
} else {
120
+ const topContent = collapsed
121
+ ? < Pin onClick = { onPinClick } />
122
+ : appSelector && (
123
+ < div className = { styles . apps } >
124
+ < AppName name = { currentApp . name } onClick = { ( ) => setAppsMenuOpen ( true ) } onPinClick = { onPinClick } />
125
+ </ div >
126
+ ) || undefined ;
127
+
68
128
sidebarContent = (
69
129
< >
70
- { appSelector && (
71
- < div className = { styles . apps } >
72
- < AppName name = { currentApp . name } onClick = { ( ) => setAppsMenuOpen ( true ) } />
73
- </ div >
74
- ) }
75
130
< div className = { styles . content } >
131
+ { topContent }
76
132
{ sections . map ( ( {
77
133
name,
78
134
icon,
@@ -84,15 +140,15 @@ const Sidebar = ({
84
140
return (
85
141
< SidebarSection
86
142
key = { name }
87
- name = { name }
143
+ name = { collapsed ? null : name }
88
144
icon = { icon }
89
145
style = { style }
90
146
link = { prefix + link }
91
147
active = { active }
92
148
primaryBackgroundColor = { primaryBackgroundColor }
93
149
secondaryBackgroundColor = { secondaryBackgroundColor }
94
150
>
95
- { active ? _subMenu ( subsections ) : null }
151
+ { ! collapsed && active ? _subMenu ( subsections ) : null }
96
152
</ SidebarSection >
97
153
) ;
98
154
} ) }
@@ -101,16 +157,39 @@ const Sidebar = ({
101
157
)
102
158
}
103
159
104
- return < div className = { styles . sidebar } >
105
- < SidebarHeader />
106
- { sidebarContent }
107
- < div className = { styles . footer } >
108
- < a target = '_blank' href = 'http://parseplatform.org/' > Open Source Hub</ a >
109
- < a target = '_blank' href = 'https://github.com/parse-community' > GitHub</ a >
110
- < a target = '_blank' href = 'http://docs.parseplatform.org/' > Docs</ a >
111
- < FooterMenu />
160
+ return (
161
+ < div
162
+ className = { sidebarClasses . join ( ' ' ) }
163
+ onMouseEnter = {
164
+ ! fixed && collapsed
165
+ ? ( ) => setCollapsed ( false )
166
+ : undefined
167
+ }
168
+ onMouseLeave = {
169
+ ! collapsed && ! fixed
170
+ ? ( e => {
171
+ if ( ! isInsidePopover ( e . relatedTarget ) ) {
172
+ setAppsMenuOpen ( false ) ;
173
+ setCollapsed ( true ) ;
174
+ }
175
+ } )
176
+ : undefined
177
+ }
178
+ >
179
+ < SidebarHeader isCollapsed = { ! appsMenuOpen && collapsed } />
180
+ { sidebarContent }
181
+ < div className = { styles . footer } >
182
+ { ! collapsed && (
183
+ < >
184
+ < a target = '_blank' href = 'http://parseplatform.org/' > Open Source Hub</ a >
185
+ < a target = '_blank' href = 'https://github.com/parse-community' > GitHub</ a >
186
+ < a target = '_blank' href = 'http://docs.parseplatform.org/' > Docs</ a >
187
+ </ >
188
+ ) }
189
+ < FooterMenu isCollapsed = { ! appsMenuOpen && collapsed } />
190
+ </ div >
112
191
</ div >
113
- </ div >
192
+ ) ;
114
193
}
115
194
116
195
Sidebar . contextTypes = {
0 commit comments