1
- import React , { cloneElement } from 'react' ;
2
- import BootstrapMixin from './BootstrapMixin' ;
3
1
import classNames from 'classnames' ;
2
+ import React from 'react' ;
3
+ import elementType from 'react-prop-types/lib/elementType' ;
4
+
5
+ import BootstrapMixin from './BootstrapMixin' ;
6
+ import Grid from './Grid' ;
7
+ import NavBrand from './NavBrand' ;
4
8
5
- import ValidComponentChildren from './utils/ValidComponentChildren' ;
6
9
import createChainedFunction from './utils/createChainedFunction' ;
7
- import elementType from 'react-prop-types/lib/elementType' ;
8
10
import deprecationWarning from './utils/deprecationWarning' ;
11
+ import ValidComponentChildren from './utils/ValidComponentChildren' ;
9
12
10
13
const Navbar = React . createClass ( {
11
14
mixins : [ BootstrapMixin ] ,
@@ -58,7 +61,8 @@ const Navbar = React.createClass({
58
61
return ! this . _isChanging ;
59
62
} ,
60
63
61
- componentDidMount ( ) {
64
+ componentWillMount ( ) {
65
+ // TODO: Use the `deprecated` PropType once we're on React 0.14.
62
66
if ( this . props . brand ) {
63
67
deprecationWarning ( 'Navbar brand attribute' , 'NavBrand Component' ) ;
64
68
}
@@ -80,106 +84,118 @@ const Navbar = React.createClass({
80
84
return this . props . navExpanded != null ? this . props . navExpanded : this . state . navExpanded ;
81
85
} ,
82
86
83
- navbrandChild ( ) {
84
- let navChild =
85
- ValidComponentChildren . findValidComponents ( this . props . children , child => {
86
- return child . props . bsRole === 'brand' ;
87
- } ) ;
88
-
89
- return navChild ;
90
- } ,
91
-
92
- hasNavbrandChild ( ) {
93
- return this . navbrandChild ( ) . length > 0 ;
87
+ hasNavBrandChild ( ) {
88
+ return ValidComponentChildren . findValidComponents (
89
+ this . props . children , child => child . props . bsRole === 'brand'
90
+ ) . length > 0 ;
94
91
} ,
95
92
96
93
render ( ) {
97
- let classes = this . getBsClassSet ( ) ;
98
- let ComponentClass = this . props . componentClass ;
99
-
100
- classes [ 'navbar-fixed-top' ] = this . props . fixedTop ;
101
- classes [ 'navbar-fixed-bottom' ] = this . props . fixedBottom ;
102
- classes [ 'navbar-static-top' ] = this . props . staticTop ;
103
- classes [ 'navbar-inverse' ] = this . props . inverse ;
104
-
105
- let displayHeader = ( this . props . brand || this . props . toggleButton || this . props . toggleNavKey != null ) && ! this . hasNavbrandChild ( ) ;
94
+ const {
95
+ brand,
96
+ toggleButton,
97
+ toggleNavKey,
98
+ fixedTop,
99
+ fixedBottom,
100
+ staticTop,
101
+ inverse,
102
+ componentClass : ComponentClass ,
103
+ fluid,
104
+ className,
105
+ children,
106
+ ...props
107
+ } = this . props ;
108
+
109
+ const classes = this . getBsClassSet ( ) ;
110
+ classes [ 'navbar-fixed-top' ] = fixedTop ;
111
+ classes [ 'navbar-fixed-bottom' ] = fixedBottom ;
112
+ classes [ 'navbar-static-top' ] = staticTop ;
113
+ classes [ 'navbar-inverse' ] = inverse ;
114
+
115
+ const showHeader =
116
+ ( brand || toggleButton || toggleNavKey != null ) &&
117
+ ! this . hasNavBrandChild ( ) ;
106
118
107
119
return (
108
- < ComponentClass { ...this . props } className = { classNames ( this . props . className , classes ) } >
109
- < div className = { this . props . fluid ? 'container-fluid' : 'container' } >
110
- { displayHeader ? this . renderHeader ( ) : null }
111
- { ValidComponentChildren . map ( this . props . children , this . renderChildren ) }
112
- </ div >
120
+ < ComponentClass { ...props } className = { classNames ( className , classes ) } >
121
+ < Grid fluid = { fluid } >
122
+ { showHeader ? this . renderBrandHeader ( ) : null }
123
+ { ValidComponentChildren . map ( children , this . renderChild ) }
124
+ </ Grid >
113
125
</ ComponentClass >
114
126
) ;
115
127
} ,
116
128
117
- renderNavBrand ( child , index ) {
118
- let navbrandEl = cloneElement ( child , {
119
- navbar : true ,
120
- toggleNavKey : this . props . toggleNavKey ,
121
- toggleButton : this . props . toggleButton ,
122
- handleToggle : this . handleToggle ,
123
- key : child . key ? child . key : index
124
- } ) ;
125
-
126
- return this . renderHeader ( navbrandEl ) ;
127
- } ,
128
-
129
- renderChild ( child , index ) {
130
- return cloneElement ( child , {
131
- navbar : true ,
132
- collapsible : this . props . toggleNavKey != null && this . props . toggleNavKey === child . props . eventKey ,
133
- expanded : this . props . toggleNavKey != null && this . props . toggleNavKey === child . props . eventKey && this . isNavExpanded ( ) ,
134
- key : child . key ? child . key : index
135
- } ) ;
136
- } ,
129
+ renderBrandHeader ( ) {
130
+ let { brand} = this . props ;
131
+ if ( brand ) {
132
+ brand = < NavBrand > { brand } </ NavBrand > ;
133
+ }
137
134
138
- renderChildren ( child , index ) {
139
- return ( child . props . navbrand ) ? this . renderNavBrand ( child , index ) : this . renderChild ( child , index ) ;
135
+ return this . renderHeader ( brand ) ;
140
136
} ,
141
137
142
- renderHeader ( navbrandEl ) {
143
- let brand = navbrandEl || '' ;
144
-
145
- if ( ! brand && this . props . brand ) {
146
- if ( React . isValidElement ( this . props . brand ) ) {
147
- brand = cloneElement ( this . props . brand , {
148
- className : classNames ( this . props . brand . props . className , 'navbar-brand' )
149
- } ) ;
150
- } else {
151
- brand = < span className = "navbar-brand" > { this . props . brand } </ span > ;
152
- }
153
- }
138
+ renderHeader ( brand ) {
139
+ const hasToggle =
140
+ this . props . toggleButton || this . props . toggleNavKey != null ;
154
141
155
142
return (
156
143
< div className = "navbar-header" >
157
144
{ brand }
158
- { ( this . props . toggleButton || this . props . toggleNavKey != null ) ? this . renderToggleButton ( ) : null }
145
+ { hasToggle ? this . renderToggleButton ( ) : null }
159
146
</ div >
160
147
) ;
161
148
} ,
162
149
163
- renderToggleButton ( ) {
164
- let children ;
150
+ renderChild ( child , index ) {
151
+ const key = child . key != null ? child . key : index ;
152
+
153
+ if ( child . props . bsRole === 'brand' ) {
154
+ return React . cloneElement ( this . renderHeader ( child ) , { key} ) ;
155
+ }
156
+
157
+ const { toggleNavKey} = this . props ;
158
+ const collapsible =
159
+ toggleNavKey != null && toggleNavKey === child . props . eventKey ;
165
160
166
- if ( React . isValidElement ( this . props . toggleButton ) ) {
167
- return cloneElement ( this . props . toggleButton , {
168
- className : classNames ( this . props . toggleButton . props . className , 'navbar-toggle' ) ,
169
- onClick : createChainedFunction ( this . handleToggle , this . props . toggleButton . props . onClick )
161
+ return React . cloneElement ( child , {
162
+ navbar : true ,
163
+ collapsible,
164
+ expanded : collapsible && this . isNavExpanded ( ) ,
165
+ key
166
+ } ) ;
167
+ } ,
168
+
169
+ renderToggleButton ( ) {
170
+ const { toggleButton} = this . props ;
171
+
172
+ if ( React . isValidElement ( toggleButton ) ) {
173
+ return React . cloneElement ( toggleButton , {
174
+ className : classNames ( toggleButton . props . className , 'navbar-toggle' ) ,
175
+ onClick : createChainedFunction (
176
+ this . handleToggle , toggleButton . props . onClick
177
+ )
170
178
} ) ;
171
179
}
172
180
173
- children = ( this . props . toggleButton != null ) ?
174
- this . props . toggleButton : [
181
+ let children ;
182
+ if ( toggleButton != null ) {
183
+ children = toggleButton ;
184
+ } else {
185
+ children = [
175
186
< span className = "sr-only" key = { 0 } > Toggle navigation</ span > ,
176
187
< span className = "icon-bar" key = { 1 } > </ span > ,
177
188
< span className = "icon-bar" key = { 2 } > </ span > ,
178
189
< span className = "icon-bar" key = { 3 } > </ span >
179
190
] ;
191
+ }
180
192
181
193
return (
182
- < button className = "navbar-toggle" type = "button" onClick = { this . handleToggle } >
194
+ < button
195
+ type = "button"
196
+ onClick = { this . handleToggle }
197
+ className = "navbar-toggle"
198
+ >
183
199
{ children }
184
200
</ button >
185
201
) ;
0 commit comments