11import React from 'react'
22import PropTypes from 'prop-types'
3+ import cx from 'classnames'
4+ import ListGroup from '../ListGroup/ListGroup'
35
46//
5- // HEY MIKE, LOOK RIGHT HERE!
6- // YEAH YOU! QUIT BEING LAZY, HERE ARE YOUR TASKS!
7+ // HEY MIKE, LOOK RIGHT HERE! YEAH YOU! QUIT BEING LAZY, HERE ARE YOUR TASKS!
78//
8- // TODO markup from https://github.com/patternfly/patternfly-ng/blob/master/src/app/navigation/vertical-navigation.component.html
9+ // TODO markup from
10+ // https://github.com/patternfly/patternfly-ng/blob/master/src/app/navigation/ve
11+ // r tical-navigation.component.html
912// TODO write stories for it so you can view it
1013// TODO look at different view states and the props necessary
1114// TODO look into other behaviors
12- // TODO behaviors from https://github.com/patternfly/patternfly-ng/blob/master/src/app/navigation/vertical-navigation.component.ts
15+ // TODO behaviors from
16+ // https://github.com/patternfly/patternfly-ng/blob/master/src/app/navigation/ve
17+ // r tical-navigation.component.ts
1318// TODO write tests
14- // TODO compare with http://www.patternfly.org/pattern-library/navigation/vertical-navigation/
19+ // TODO compare with
20+ // http://www.patternfly.org/pattern-library/navigation/vertical-navigation/
1521//
1622
1723/**
@@ -20,19 +26,250 @@ import PropTypes from 'prop-types'
2026export default class VerticalNavigation extends React . Component {
2127 constructor ( ) {
2228 super ( )
23- this . state = { }
29+ this . state = {
30+ hideTopBanner : false ,
31+ navCollapsed : false
32+ }
33+ this . handleNavBarToggleClick = this
34+ . handleNavBarToggleClick
35+ . bind ( this )
36+ }
37+
38+ handleNavBarToggleClick ( ) {
39+ const { hideTopBanner } = this . state
40+ this . setState ( {
41+ hideTopBanner : ! hideTopBanner
42+ } )
43+ }
44+
45+ handlePrimaryClick ( item ) {
46+ // TODO
47+ }
48+
49+ handlePrimaryHover ( item ) {
50+ // TODO
51+ }
52+
53+ handlePrimaryBlur ( item ) {
54+ // TODO
55+ }
56+
57+ handleSecondaryClick ( item ) {
58+ // TODO
59+ }
60+
61+ handleSecondaryHover ( item ) {
62+ // TODO
63+ }
64+
65+ handleSecondaryBlur ( item ) {
66+ // TODO
67+ }
68+
69+ handleTertiaryClick ( item ) {
70+ // TODO
71+ }
72+
73+ handleTertiaryHover ( item ) {
74+ // TODO
75+ }
76+
77+ handleTertiaryBlur ( item ) {
78+ // TODO
79+ }
80+
81+ renderBadges ( badges ) {
82+ const { showBadges } = this . props
83+ return showBadges && badges && (
84+ < div className = "badge-container-pf" >
85+ { badges . map ( badge => (
86+ < div
87+ /* TODO key? */
88+ className = { cx ( 'badge' , badge . badgeClass ) }
89+ tooltip = { badge . tooltip } /* TODO is this ng-specific? */
90+ container = "body" /* TODO is this ng-specific? */
91+ placement = "right" /* TODO is this ng-specific? */
92+ >
93+ { badge . count && badge . iconStyleClass && (
94+ < span className = { badge . iconStyleClass } />
95+ ) }
96+ { badge . count && < span > { badge . count } span > }
97+ div >
98+ ) ) }
99+ div >
100+ )
101+ }
102+
103+ renderItem ( item , depth ) {
104+ // TODO LEFT OFF HERE-- reducing code duplication!!!
105+ const { showMobileSecondary, showMobileTertiary } = this . props
106+ return (
107+ < ListGroupItem
108+ /* TODO key? */
109+ listItem = { true }
110+ className = { cx ( {
111+ [ `${ depth } -nav-item-pf` ] : item . children && item . children . length > 0 ,
112+ 'active' : item . trackActiveState ,
113+ 'is-hover' : item . trackHoverState ,
114+ 'mobile-nav-item-pf' : item . mobileItem && ( depth === 'secondary' ? showMobileSecondary : true ) ,
115+ [ `mobile-${ depth } -item-pf` ] : item . mobileItem && ( depth === 'secondary' ? showMobileTertiary : false )
116+ } ) }
117+ onMouseEnter = { ( ) => { this . handlePrimaryHover ( item ) } }
118+ onMouseLeave = { ( ) => { this . handlePrimaryBlur ( item ) } }
119+ >
120+ < a onClick = { this . handlePrimaryClick ( item ) } >
121+ { item . iconStyleClass && (
122+ < span className = { cx ( item . iconStyleClass , { hidden : hiddenIcons } ) }
123+ tooltip = { item . title } /* TODO is this ng-specific? */
124+ container = "body" /* TODO is this ng-specific? */
125+ placement = "bottom" /* TODO is this ng-specific? */
126+ isDisabled = { ! navCollapsed }
127+ containerClass = "nav-pf-vertical-tooltip" /* TODO is this ng-specific? */
128+ />
129+ ) /* TODO [ngClass]="{hidden: hiddenIcons}" */ }
130+ < span className = "list-group-item-value" > { item . title } span >
131+ { this . renderBadges ( item . badges ) }
132+ a >
133+ { item . children && item . children . length > 0 && (
134+ < div className = "nav-pf-secondary-nav" >
135+ < div className = "nav-item-pf-header" >
136+ < a
137+ className = { cx ( 'secondary-collapse-toggle-pf' , { collapsed : item . secondaryCollapsed } ) }
138+ onClick = { ( ) => { this . collapseSecondaryNav ( item ) } }
139+ />
140+ < span > { item . title } span >
141+ div >
142+ < ListGroup >
143+ { item . children . map ( secondaryItem => (
144+ < ListGroupItem
145+ /* TODO key? */
146+ className = { {
147+ 'tertiary-nav-item-pf' : secondaryItem . children && secondaryItem . children . length > 0 ,
148+ 'active' : secondaryItem . trackActiveState ,
149+ 'is-hover' : secondaryItem . trackHoverState ,
150+ 'mobile-nav-item-pf' : secondaryItem . mobileItem
151+ } }
152+ onMouseEnter = { ( ) => { this . handleSecondaryHover ( secondaryItem ) } }
153+ onMouseLeave = { ( ) => { this . handleSecondaryBlur ( secondaryItem ) } }
154+ >
155+ < a
156+ onClick = { ( ) => { this . handleSecondaryClick ( item , secondaryItem ) } }
157+ >
158+ < span className = "list-group-item-value" > { secondaryItem . title } span >
159+ { this . renderBadges ( secondaryItem . badges ) }
160+ a >
161+ { /* TODO tertiary has nothing here */ }
162+ { secondaryItem . children && secondaryItem . children . length > 0 && (
163+ < div className = "nav-pf-tertiary-nav" >
164+ < div className = "nav-item-pf-header" >
165+ < a
166+ className = { cx ( 'tertiary-collapse-toggle-pf' , {
167+ collapsed : secondaryItem . tertiaryCollapsed
168+ } ) }
169+ onClick = { ( ) => { this . collapseTertiaryNav ( secondaryItem ) } }
170+ />
171+ < span > { secondaryItem . title } span >
172+ div >
173+ < ListGroup >
174+ { /* TODO TERTIARY */ }
175+ ListGroup >
176+ div >
177+ ) }
178+ ListGroupItem >
179+ ) ) }
180+ ListGroup >
181+ div >
182+ ) }
183+ ListGroupItem >
184+ )
24185 }
25186
26187 render ( ) {
27- const { children } = this . props
188+ const {
189+ children,
190+ hidden,
191+ persistentSecondary,
192+ pinnableMenus,
193+ hiddenIcons,
194+ showBadges,
195+ showMobileNav,
196+ showMobileSecondary,
197+ showMobileTertiary,
198+ forceHidden
199+ } = this . props
200+ const {
201+ hideTopBanner,
202+ navCollapsed,
203+ inMobileState,
204+ navCollapsed,
205+ activeSecondary,
206+ hoverSecondaryNav,
207+ hoverTertiaryNav,
208+ collapsedSecondaryNav,
209+ collapsedTertiaryNav
210+ } = this . state
28211
29- if ( children ) {
30- return < div > { children } div >
31- } else {
32- return < div > Nothing to see here?div > // TODO fix me?
33- }
212+ const topBanner = (
213+ < div >
214+ < div className = "navbar-header" >
215+ < button
216+ type = "button"
217+ className = "navbar-toggle"
218+ onClick = { this . handleNavBarToggleClick } >
219+ < span className = "sr-only" > Toggle navigationspan >
220+ { /* TODO i18n? */ }
221+ < span className = "icon-bar" />
222+ < span className = "icon-bar" />
223+ < span className = "icon-bar" />
224+ button >
225+ < span className = "navbar-brand" >
226+ < img className = "navbar-brand-icon" /> { /* TODO */ } 227+ < span className = "navbar-brand-txt" > span >
228+ { /* TODO {{brandAlt}} */ }
229+ span >
230+ div >
231+ < nav class = "collapse navbar-collapse" >
232+ { /* TODO this was an */ }
233+ nav >
234+ div >
235+ )
236+
237+ const navItems = [ 'T' , 'O' , 'D' , 'O' ] // TODO should these come from children or props?
238+ // TODO move all the ListGroupItem markup into the VerticalNavigationItem component
239+
240+ const navbar = (
241+ < nav
242+ className = { cx ( 'navbar navbar-pf-vertical pfng-vertical-container' , hideTopBanner && 'pfng-vertical-hide-nav' ) } >
243+ { ! hideTopBanner && topBanner }
244+ < div
245+ className = { cx ( 'nav-pf-vertical' , {
246+ 'nav-pf-vertical-collapsible-menus' : pinnableMenus ,
247+ 'hidden-icons-pf' : hiddenIcons ,
248+ 'nav-pf-vertical-with-badges' : showBadges ,
249+ 'secondary-visible-pf' : activeSecondary ,
250+ 'show-mobile-secondary' : showMobileSecondary ,
251+ 'show-mobile-tertiary' : showMobileTertiary ,
252+ 'hover-secondary-nav-pf' : hoverSecondaryNav ,
253+ 'hover-tertiary-nav-pf' : hoverTertiaryNav ,
254+ 'collapsed-secondary-nav-pf' : collapsedSecondaryNav ,
255+ 'collapsed-tertiary-nav-pf' : collapsedTertiaryNav ,
256+ 'hidden' : inMobileState ,
257+ 'collapsed' : navCollapsed ,
258+ 'force-hide-secondary-nav-pf' : forceHidden ,
259+ 'show-mobile-nav' : showMobileNav
260+ } ) }
261+ >
262+ < ListGroup >
263+ { navItems . map ( ( item ) => { this . renderItem ( item , 'secondary' ) } ) }
264+ ListGroup >
265+ div >
266+ nav >
267+ )
268+
269+ return < div > { navbar } div >
34270 }
35271}
272+
36273VerticalNavigation . propTypes = {
37274 /** Child node rendered as expanded content of the TODO??? */
38275 children : PropTypes . node
0 commit comments