@@ -4,14 +4,21 @@ import {
4
4
Label ,
5
5
Nav ,
6
6
NavList ,
7
+ NavGroup ,
7
8
NavExpandable ,
8
9
PageContextConsumer ,
9
10
capitalize ,
10
11
Flex ,
11
- FlexItem
12
+ FlexItem ,
13
+ Divider
12
14
} from '@patternfly/react-core' ;
13
15
import { css } from '@patternfly/react-styles' ;
14
16
import { Location } from '@reach/router' ;
17
+
18
+ const DIVIDER_STYLES = {
19
+ marginTop : 'var(--pf-t--global--spacer--md)' ,
20
+ marginBottom : 'var(--pf-t--global--spacer--md)'
21
+ } ;
15
22
import { makeSlug } from '../../helpers' ;
16
23
import globalBreakpointXl from '@patternfly/react-tokens/dist/esm/t_global_breakpoint_xl' ;
17
24
import { trackEvent } from '../../helpers' ;
@@ -163,20 +170,76 @@ export const SideNav = ({ groupedRoutes = {}, navItems = [] }) => {
163
170
}
164
171
} , [ ] ) ;
165
172
173
+ const processedItems = React . useMemo ( ( ) => {
174
+ const result = [ ] ;
175
+ let currentGroup = null ;
176
+ let groupItems = [ ] ;
177
+
178
+ for ( let i = 0 ; i < navItems . length ; i ++ ) {
179
+ const item = navItems [ i ] ;
180
+
181
+ if ( item . header ) {
182
+ if ( currentGroup ) {
183
+ result . push ( { type : 'group' , title : currentGroup , items : groupItems } ) ;
184
+ }
185
+ currentGroup = item . header ;
186
+ groupItems = [ ] ;
187
+ } else if ( item . divider ) {
188
+ if ( currentGroup ) {
189
+ result . push ( { type : 'group' , title : currentGroup , items : groupItems } ) ;
190
+ currentGroup = null ;
191
+ groupItems = [ ] ;
192
+ }
193
+ result . push ( { type : 'divider' , key : item . divider } ) ;
194
+ } else {
195
+ currentGroup ? groupItems . push ( item ) : result . push ( { type : 'item' , ...item } ) ;
196
+ }
197
+ }
198
+
199
+ if ( currentGroup ) {
200
+ result . push ( { type : 'group' , title : currentGroup , items : groupItems } ) ;
201
+ }
202
+
203
+ return result ;
204
+ } , [ navItems ] ) ;
205
+
166
206
return (
167
207
< Nav aria-label = "Side Nav" theme = "light" >
168
208
< NavList className = "ws-side-nav-list" >
169
- { navItems . map ( ( { section, text, href } ) =>
170
- section ? (
171
- < Location key = { section } > { ( { location } ) => ExpandableNav ( { groupedRoutes, location, section } ) } </ Location >
172
- ) : (
173
- NavItem ( {
174
- text : text || capitalize ( href . replace ( / \/ / g, '' ) . replace ( / - / g, ' ' ) ) ,
175
- href : href
176
- } )
177
- )
178
- ) }
209
+ { processedItems . map ( processed => {
210
+ if ( processed . type === 'divider' ) {
211
+ return < Divider key = { processed . key } style = { DIVIDER_STYLES } /> ;
212
+ }
213
+
214
+ if ( processed . type === 'group' ) {
215
+ return (
216
+ < NavGroup key = { processed . title } title = { processed . title } >
217
+ { processed . items . map ( item =>
218
+ item . section ? (
219
+ < Location key = { item . section } >
220
+ { ( { location } ) => ExpandableNav ( { groupedRoutes, location, section : item . section } ) }
221
+ </ Location >
222
+ ) : NavItem ( {
223
+ key : item . href ,
224
+ text : item . text || capitalize ( item . href . replace ( / \/ / g, '' ) . replace ( / - / g, ' ' ) ) ,
225
+ href : item . href
226
+ } )
227
+ ) }
228
+ </ NavGroup >
229
+ ) ;
230
+ }
231
+
232
+ return processed . section ? (
233
+ < Location key = { processed . section } >
234
+ { ( { location } ) => ExpandableNav ( { groupedRoutes, location, section : processed . section } ) }
235
+ </ Location >
236
+ ) : NavItem ( {
237
+ key : processed . href ,
238
+ text : processed . text || capitalize ( processed . href . replace ( / \/ / g, '' ) . replace ( / - / g, ' ' ) ) ,
239
+ href : processed . href
240
+ } ) ;
241
+ } ) }
179
242
</ NavList >
180
243
</ Nav >
181
244
) ;
182
- } ;
245
+ } ;
0 commit comments