@@ -34,6 +34,8 @@ var _lodashFunctionDebounce = require('lodash/function/debounce');
3434
3535var _lodashFunctionDebounce2 = _interopRequireDefault ( _lodashFunctionDebounce ) ;
3636
37+ var uid = 0 ;
38+
3739/**
3840 * A combo-box component for React Bootstrap
3941 *
@@ -54,35 +56,49 @@ var Combo = (function (_React$Component) {
5456 _inherits ( Combo , _React$Component ) ;
5557
5658 function Combo ( props ) {
57- var _this = this ;
58-
5959 _classCallCheck ( this , Combo ) ;
6060
6161 _get ( Object . getPrototypeOf ( Combo . prototype ) , 'constructor' , this ) . call ( this , props ) ;
6262
63+ /**
64+ * The html id
65+ *
66+ * @memberOf Combo
67+ * @instance
68+ * @private
69+ * @type {string }
70+ */
71+ this . id = 'al-combo-' + ++ uid ;
72+
6373 /**
6474 * Height of the browser viewport
6575 *
6676 * @memberOf Combo
6777 * @instance
6878 * @private
69- * @type {Number }
79+ * @type {number }
7080 */
7181 this . viewportHeight = 0 ;
7282
7383 /**
74- * Handles browser resize events, debounced by 150ms, executed on requestAnimationFrame
84+ * Handles browser resize events, debounced by 150ms
7585 *
7686 * @memberof Combo
7787 * @instance
7888 * @private
7989 * @method handleResize
8090 */
81- this . handleResize = ( 0 , _lodashFunctionDebounce2 [ 'default' ] ) ( function ( ) {
82- window . requestAnimationFrame ( function ( ) {
83- _this . onResize ( ) ;
84- } ) ;
85- } , 150 ) ;
91+ this . handleResize = ( 0 , _lodashFunctionDebounce2 [ 'default' ] ) ( this . onResize . bind ( this ) , 150 ) ;
92+
93+ /**
94+ * Holds component state
95+ *
96+ * @memberof Combo
97+ * @instance
98+ * @private
99+ * @type {Object }
100+ */
101+ this . state = { maxHeight : null } ;
86102 }
87103
88104 /**
@@ -93,47 +109,14 @@ var Combo = (function (_React$Component) {
93109 * @private
94110 * @method shouldComponentUpdate
95111 * @param {Object } props - A props config
112+ * @param {Object } state - A new component state
96113 * @return {boolean } true if the component needs to be re-rendered
97114 */
98115
99116 _createClass ( Combo , [ {
100117 key : 'shouldComponentUpdate' ,
101- value : function shouldComponentUpdate ( props ) {
102- return props . onChange !== this . props . onChange || props . items !== this . props . items || props . value !== this . props . value ;
103- }
104-
105- /**
106- * Invoked every time the viewport is resized
107- *
108- * @memberof Combo
109- * @instance
110- * @private
111- * @method onResize
112- */
113- } , {
114- key : 'onResize' ,
115- value : function onResize ( ) {
116- var height = window . innerHeight ,
117- combo ,
118- menu ,
119- closed ;
120-
121- if ( this . viewportHeight === height ) {
122- return ;
123- }
124- this . viewportHeight = height ;
125-
126- combo = this . refs . combo ;
127- menu = _react2 [ 'default' ] . findDOMNode ( combo . refs . menu ) ;
128- closed = ! combo . state . open ;
129-
130- if ( closed ) {
131- combo . setDropdownState ( true ) ;
132- }
133- menu . style . maxHeight = height - menu . getBoundingClientRect ( ) . top + 'px' ;
134- if ( closed ) {
135- combo . setDropdownState ( false ) ;
136- }
118+ value : function shouldComponentUpdate ( props , state ) {
119+ return props . onChange !== this . props . onChange || props . items !== this . props . items || props . value !== this . props . value || state . maxHeight !== this . state . maxHeight ;
137120 }
138121
139122 /**
@@ -165,6 +148,27 @@ var Combo = (function (_React$Component) {
165148 window . removeEventListener ( 'resize' , this . handleResize ) ;
166149 }
167150
151+ /**
152+ * Invoked every time the viewport is resized
153+ *
154+ * @memberof Combo
155+ * @instance
156+ * @private
157+ * @method onResize
158+ */
159+ } , {
160+ key : 'onResize' ,
161+ value : function onResize ( ) {
162+ var height = window . innerHeight ;
163+
164+ if ( this . viewportHeight === height ) {
165+ return ;
166+ }
167+ this . viewportHeight = height ;
168+
169+ this . setState ( { maxHeight : height - _react2 [ 'default' ] . findDOMNode ( this ) . getBoundingClientRect ( ) . bottom - 5 } ) ;
170+ }
171+
168172 /**
169173 * Normalizes a dropdown item config object.
170174 *
@@ -178,7 +182,9 @@ var Combo = (function (_React$Component) {
178182 } , {
179183 key : 'normalize' ,
180184 value : function normalize ( value ) {
181- return ( 0 , _lodashLangIsString2 [ 'default' ] ) ( value ) ? '-' === value ? { divider : true } : { label : value } : value ;
185+ var divider = '-' === value ? { divider : true } : { label : value } ;
186+
187+ return ( 0 , _lodashLangIsString2 [ 'default' ] ) ( value ) ? divider : value ;
182188 }
183189
184190 /**
@@ -195,6 +201,78 @@ var Combo = (function (_React$Component) {
195201 return this . normalize ( this . props . items [ this . props . value ] ) . label ;
196202 }
197203
204+ /**
205+ * Renders a button
206+ *
207+ * @memberof Combo
208+ * @instance
209+ * @private
210+ * @method renderButton
211+ * @return {ReactElement } a virtual DOM tree
212+ */
213+ } , {
214+ key : 'renderButton' ,
215+ value : function renderButton ( ) {
216+ return _react2 [ 'default' ] . createElement (
217+ _reactBootstrap . Button ,
218+ { block : true , bsRole : 'toggle' , className : 'dropdown-toggle' } ,
219+ _react2 [ 'default' ] . createElement (
220+ 'div' ,
221+ null ,
222+ this . getLabel ( ) ,
223+ _react2 [ 'default' ] . createElement ( 'span' , { className : 'caret' } )
224+ )
225+ ) ;
226+ }
227+
228+ /**
229+ * Renders a menu item
230+ *
231+ * @memberof Combo
232+ * @instance
233+ * @private
234+ * @method renderMenuItem
235+ * @param {Object|string } item - a dropdown item config
236+ * @param {string } i - a dropdown item key
237+ * @return {ReactElement } a virtual DOM tree
238+ */
239+ } , {
240+ key : 'renderMenuItem' ,
241+ value : function renderMenuItem ( item , i ) {
242+ item = this . normalize ( item ) ;
243+ if ( item . divider ) {
244+ return _react2 [ 'default' ] . createElement ( _reactBootstrap . MenuItem , { key : i , divider : true } ) ;
245+ }
246+ return _react2 [ 'default' ] . createElement (
247+ _reactBootstrap . MenuItem ,
248+ _extends ( { key : i , eventKey : i , active : i === this . props . value } , item ) ,
249+ _react2 [ 'default' ] . createElement (
250+ 'div' ,
251+ null ,
252+ item . label
253+ )
254+ ) ;
255+ }
256+
257+ /**
258+ * Renders a menu
259+ *
260+ * @memberof Combo
261+ * @instance
262+ * @private
263+ * @method renderMenu
264+ * @return {ReactElement } a virtual DOM tree
265+ */
266+ } , {
267+ key : 'renderMenu' ,
268+ value : function renderMenu ( ) {
269+ return _react2 [ 'default' ] . createElement (
270+ _reactBootstrap . Dropdown . Menu ,
271+ { style : this . state } ,
272+ ( 0 , _lodashCollectionMap2 [ 'default' ] ) ( this . props . items , this . renderMenuItem , this )
273+ ) ;
274+ }
275+
198276 /**
199277 * Invoked when the component is about to be unmounted from the DOM tree
200278 *
@@ -207,33 +285,11 @@ var Combo = (function (_React$Component) {
207285 } , {
208286 key : 'render' ,
209287 value : function render ( ) {
210- var _this2 = this ;
211-
212- var _props = this . props ;
213- var items = _props . items ;
214- var value = _props . value ;
215- var onChange = _props . onChange ;
216-
217288 return _react2 [ 'default' ] . createElement (
218- _reactBootstrap . DropdownButton ,
219- { block : true , noCaret : true , ref : 'combo' , className : 'al-combo' , title : _react2 [ 'default' ] . createElement (
220- 'div' ,
221- { className : 'wrap' } ,
222- this . getLabel ( ) ,
223- _react2 [ 'default' ] . createElement ( 'span' , { className : 'caret' } )
224- ) , onSelect : onChange . bind ( this ) } ,
225- ( 0 , _lodashCollectionMap2 [ 'default' ] ) ( items , function ( item , i ) {
226- item = _this2 . normalize ( item ) ;
227- return _react2 [ 'default' ] . createElement (
228- _reactBootstrap . MenuItem ,
229- _extends ( { key : i , eventKey : i , active : i === value } , item ) ,
230- _react2 [ 'default' ] . createElement (
231- 'div' ,
232- null ,
233- item . label
234- )
235- ) ;
236- } )
289+ _reactBootstrap . Dropdown ,
290+ { className : 'al-combo' , id : this . id , onSelect : this . props . onChange } ,
291+ this . renderButton ( ) ,
292+ this . renderMenu ( )
237293 ) ;
238294 }
239295 } ] ) ;
0 commit comments