Skip to content

Commit dafa4ce

Browse files
committed
[fixed] updated to React Bootstrap v0.26.1, performance improvements
1 parent cbba809 commit dafa4ce

11 files changed

Lines changed: 707 additions & 421 deletions

File tree

_index.scss

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
11
.al-combo {
2-
&, * {
3-
&:focus {
4-
outline-style: none;
5-
}
6-
}
72
&, > .dropdown-menu {
83
width: 100%;
94
}
10-
> .btn > .wrap {
5+
&, > .dropdown-menu > li > a {
6+
outline-style: none;
7+
}
8+
> .btn > div > span:first-child, > .dropdown-menu, > .dropdown-menu > li div {
9+
overflow-x: hidden;
10+
}
11+
> .btn > div > span:first-child, > .dropdown-menu > li div {
12+
text-overflow: ellipsis;
13+
}
14+
> .btn > div {
1115
align-items: center;
1216
display: flex;
1317
> span:first-child {
14-
flex-grow: 1;
15-
overflow-x: hidden;
16-
text-overflow: ellipsis;
18+
flex: 1;
1719
}
1820
}
1921
> .dropdown-menu {
20-
overflow-x: hidden;
2122
overflow-y: auto;
2223
> li {
23-
&, * {
24-
user-select: none;
25-
}
24+
user-select: none;
2625
&.active > a {
2726
pointer-events: none;
2827
}
2928
&.dropdown-header > div {
3029
cursor: default;
3130
}
3231
> a {
33-
-khtml-user-drag: none;
3432
-webkit-user-drag: none;
35-
> div {
36-
overflow-x: hidden;
37-
text-overflow: ellipsis;
38-
}
33+
-khtml-user-drag: none;
34+
-moz-user-drag: none;
35+
-o-user-drag: none;
36+
user-drag: none;
3937
}
4038
}
4139
}

bin/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import {JS, NativeProcess, SASSLint} from 'webcompiler';
44
import {join} from 'path';
55

6-
var rootDir = join(__dirname, '..'),
6+
const rootDir = join(__dirname, '..'),
77
binDir = join(rootDir, 'bin'),
88
buildDir = join(rootDir, 'build'),
99
libDir = join(rootDir, 'lib'),

bin/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import {DevServer} from 'webcompiler';
55
import {join} from 'path';
66

7-
var rootDir = join(__dirname, '..'),
7+
const rootDir = join(__dirname, '..'),
88
devDir = join(rootDir, 'development'),
99
server = new DevServer(join(devDir, 'script.js'), join(devDir, 'app.scss'), devDir);
1010

build/Combo.js

Lines changed: 128 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ var _lodashFunctionDebounce = require('lodash/function/debounce');
3434

3535
var _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

Comments
 (0)