11import React from 'react' ;
22import {
3- Page ,
3+ Avatar ,
4+ Brand ,
5+ Button ,
6+ ButtonVariant ,
7+ Divider ,
8+ Dropdown ,
9+ DropdownGroup ,
10+ DropdownItem ,
11+ DropdownList ,
12+ Masthead ,
13+ MastheadBrand ,
14+ MastheadContent ,
15+ MastheadMain ,
16+ MastheadToggle ,
17+ Menu ,
18+ MenuContent ,
19+ MenuItem ,
20+ MenuList ,
21+ MenuToggle ,
422 Nav ,
5- NavList ,
623 NavItem ,
7- PageSidebar ,
8- PageSidebarBody ,
24+ NavList ,
25+ Page ,
926 PageSection ,
1027 PageSectionVariants ,
11- Menu ,
12- MenuContent ,
13- MenuList ,
14- MenuItem
28+ PageSidebar ,
29+ PageSidebarBody ,
30+ PageToggleButton ,
31+ SkipToContent ,
32+ Toolbar ,
33+ ToolbarContent ,
34+ ToolbarGroup ,
35+ ToolbarItem
1536} from '@patternfly/react-core' ;
16- import DashboardHeader from '../DashboardHeader' ;
37+ import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon' ;
38+ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon' ;
39+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon' ;
40+ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon' ;
41+ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon' ;
42+ import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon' ;
43+ import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg' ;
44+ import pfLogo from '@patternfly/react-core/src/demos/assets/pf-logo.svg' ;
1745
1846export const NavFlyout : React . FunctionComponent = ( ) => {
47+ const [ isDropdownOpen , setIsDropdownOpen ] = React . useState ( false ) ;
48+ const [ isKebabDropdownOpen , setIsKebabDropdownOpen ] = React . useState ( false ) ;
49+ const [ isFullKebabDropdownOpen , setIsFullKebabDropdownOpen ] = React . useState ( false ) ;
50+ const [ isMobileView , setIsMobileView ] = React . useState ( false ) ;
51+ const [ isSidebarOpenDesktop , setIsSidebarOpenDesktop ] = React . useState ( true ) ;
52+ const [ isSidebarOpenMobile , setIsSidebarOpenMobile ] = React . useState ( false ) ;
1953 const [ activeItem , setActiveItem ] = React . useState < number | string > ( 0 ) ;
2054
2155 const onNavSelect = (
@@ -27,6 +61,23 @@ export const NavFlyout: React.FunctionComponent = () => {
2761 }
2862 ) => setActiveItem ( selectedItem . itemId ) ;
2963
64+ const onDropdownToggle = ( ) => setIsDropdownOpen ( ( prevState ) => ! prevState ) ;
65+ const onDropdownSelect = ( ) => setIsDropdownOpen ( false ) ;
66+ const onKebabDropdownToggle = ( ) => setIsKebabDropdownOpen ( ( prevState ) => ! prevState ) ;
67+ const onKebabDropdownSelect = ( ) => setIsKebabDropdownOpen ( false ) ;
68+ const onFullKebabToggle = ( ) => setIsFullKebabDropdownOpen ( ( prevState ) => ! prevState ) ;
69+ const onFullKebabSelect = ( ) => setIsFullKebabDropdownOpen ( false ) ;
70+ const onSidebarToggleDesktop = ( ) => setIsSidebarOpenDesktop ( ( prevState ) => ! prevState ) ;
71+ const onSidebarToggleMobile = ( ) => setIsSidebarOpenMobile ( ( prevState ) => ! prevState ) ;
72+
73+ interface PageOptions {
74+ mobileView : boolean ;
75+ windowSize : number ;
76+ }
77+
78+ const onPageResize = ( _event : MouseEvent | TouchEvent | React . KeyboardEvent , { mobileView } : PageOptions ) =>
79+ setIsMobileView ( mobileView ) ;
80+
3081 const onMenuSelect = ( _event : React . MouseEvent | undefined , itemId : string | number | undefined ) => {
3182 itemId && setActiveItem ( itemId ) ;
3283 } ;
@@ -56,8 +107,139 @@ export const NavFlyout: React.FunctionComponent = () => {
56107 curFlyout = < FlyoutMenu depth = { i } > { curFlyout } </ FlyoutMenu > ;
57108 }
58109
110+ const kebabDropdownItems = (
111+ < >
112+ < DropdownItem >
113+ < CogIcon /> Settings
114+ </ DropdownItem >
115+ < DropdownItem >
116+ < HelpIcon /> Help
117+ </ DropdownItem >
118+ </ >
119+ ) ;
120+ const userDropdownItems = (
121+ < >
122+ < DropdownItem key = "group 2 profile" > My profile</ DropdownItem >
123+ < DropdownItem key = "group 2 user" > User management</ DropdownItem >
124+ < DropdownItem key = "group 2 logout" > Logout</ DropdownItem >
125+ </ >
126+ ) ;
127+
128+ const headerToolbar = (
129+ < Toolbar id = "toolbar" isFullHeight isStatic >
130+ < ToolbarContent >
131+ < ToolbarGroup
132+ variant = "icon-button-group"
133+ align = { { default : 'alignRight' } }
134+ spacer = { { default : 'spacerNone' , md : 'spacerMd' } }
135+ >
136+ < ToolbarItem >
137+ < Button aria-label = "Notifications" variant = { ButtonVariant . plain } icon = { < BellIcon /> } onClick = { ( ) => { } } />
138+ </ ToolbarItem >
139+ < ToolbarGroup variant = "icon-button-group" visibility = { { default : 'hidden' , lg : 'visible' } } >
140+ < ToolbarItem >
141+ < Button aria-label = "Settings" variant = { ButtonVariant . plain } icon = { < CogIcon /> } />
142+ </ ToolbarItem >
143+ < ToolbarItem >
144+ < Button aria-label = "Help" variant = { ButtonVariant . plain } icon = { < QuestionCircleIcon /> } />
145+ </ ToolbarItem >
146+ </ ToolbarGroup >
147+ < ToolbarItem visibility = { { default : 'hidden' , md : 'visible' , lg : 'hidden' } } >
148+ < Dropdown
149+ isOpen = { isKebabDropdownOpen }
150+ onSelect = { onKebabDropdownSelect }
151+ onOpenChange = { setIsKebabDropdownOpen }
152+ popperProps = { { position : 'right' } }
153+ toggle = { ( toggleRef ) => (
154+ < MenuToggle
155+ ref = { toggleRef }
156+ isExpanded = { isKebabDropdownOpen }
157+ onClick = { onKebabDropdownToggle }
158+ variant = "plain"
159+ aria-label = "Settings and help"
160+ >
161+ < EllipsisVIcon aria-hidden = "true" />
162+ </ MenuToggle >
163+ ) }
164+ >
165+ < DropdownList > { kebabDropdownItems } </ DropdownList >
166+ </ Dropdown >
167+ </ ToolbarItem >
168+ < ToolbarItem visibility = { { md : 'hidden' } } >
169+ < Dropdown
170+ isOpen = { isFullKebabDropdownOpen }
171+ onSelect = { onFullKebabSelect }
172+ onOpenChange = { setIsFullKebabDropdownOpen }
173+ popperProps = { { position : 'right' } }
174+ toggle = { ( toggleRef ) => (
175+ < MenuToggle
176+ ref = { toggleRef }
177+ isExpanded = { isFullKebabDropdownOpen }
178+ onClick = { onFullKebabToggle }
179+ variant = "plain"
180+ aria-label = "Toolbar menu"
181+ >
182+ < EllipsisVIcon aria-hidden = "true" />
183+ </ MenuToggle >
184+ ) }
185+ >
186+ < DropdownGroup key = "group 2" aria-label = "User actions" >
187+ < DropdownList > { userDropdownItems } </ DropdownList >
188+ </ DropdownGroup >
189+ < Divider />
190+ < DropdownList > { kebabDropdownItems } </ DropdownList >
191+ </ Dropdown >
192+ </ ToolbarItem >
193+ </ ToolbarGroup >
194+ < ToolbarItem visibility = { { default : 'hidden' , md : 'visible' } } >
195+ < Dropdown
196+ isOpen = { isDropdownOpen }
197+ onSelect = { onDropdownSelect }
198+ onOpenChange = { setIsDropdownOpen }
199+ popperProps = { { position : 'right' } }
200+ toggle = { ( toggleRef ) => (
201+ < MenuToggle
202+ ref = { toggleRef }
203+ isExpanded = { isDropdownOpen }
204+ onClick = { onDropdownToggle }
205+ icon = { < Avatar src = { imgAvatar } alt = "" /> }
206+ isFullHeight
207+ >
208+ Ned Username
209+ </ MenuToggle >
210+ ) }
211+ >
212+ < DropdownList > { userDropdownItems } </ DropdownList >
213+ </ Dropdown >
214+ </ ToolbarItem >
215+ </ ToolbarContent >
216+ </ Toolbar >
217+ ) ;
218+
219+ const Header = (
220+ < Masthead >
221+ < MastheadToggle >
222+ < PageToggleButton
223+ onSidebarToggle = { isMobileView ? onSidebarToggleMobile : onSidebarToggleDesktop }
224+ variant = "plain"
225+ aria-label = "Global navigation"
226+ >
227+ < BarsIcon />
228+ </ PageToggleButton >
229+ </ MastheadToggle >
230+ < MastheadMain >
231+ < MastheadBrand >
232+ < Brand src = { pfLogo } alt = "PatternFly" heights = { { default : '36px' } } />
233+ </ MastheadBrand >
234+ </ MastheadMain >
235+ < MastheadContent > { headerToolbar } </ MastheadContent >
236+ </ Masthead >
237+ ) ;
238+
239+ const isSidebarOpen = isMobileView ? isSidebarOpenMobile : isSidebarOpenDesktop ;
240+
59241 const Sidebar = (
60- < PageSidebar style = { { overflow : 'visible' } } >
242+ < PageSidebar isSidebarOpen = { isSidebarOpen } style = { isSidebarOpen ? { overflow : 'visible' } : { } } >
61243 < PageSidebarBody >
62244 < Nav onSelect = { onNavSelect } >
63245 < NavList >
@@ -77,8 +259,17 @@ export const NavFlyout: React.FunctionComponent = () => {
77259 </ PageSidebar >
78260 ) ;
79261
262+ const pageId = 'main-content-page-layout-flyout-nav' ;
263+ const PageSkipToContent = < SkipToContent href = { `#${ pageId } ` } > Skip to Content</ SkipToContent > ;
264+
80265 return (
81- < Page header = { < DashboardHeader /> } sidebar = { Sidebar } isManagedSidebar >
266+ < Page
267+ header = { Header }
268+ sidebar = { Sidebar }
269+ onPageResize = { onPageResize }
270+ skipToContent = { PageSkipToContent }
271+ mainContainerId = { pageId }
272+ >
82273 < PageSection variant = { PageSectionVariants . darker } > Section with darker background</ PageSection >
83274 < PageSection variant = { PageSectionVariants . dark } > Section with dark background</ PageSection >
84275 < PageSection variant = { PageSectionVariants . light } > Section with light background</ PageSection >
0 commit comments