Skip to content

Commit 3d60890

Browse files
Support delayed stabilisation for simple list
In order to allow items animation
1 parent 6aed24f commit 3d60890

File tree

5 files changed

+85
-34
lines changed

5 files changed

+85
-34
lines changed

examples/index.es6

+12-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ const examples = [
5656
length: 10000,
5757
itemRenderer: renderVariableHeightItem
5858
},
59+
{
60+
length: 10000,
61+
itemRenderer: renderVariableHeightItem,
62+
className: 'is-animated',
63+
stableFrameDelay: 500
64+
},
5965
{
6066
axis: 'x',
6167
length: 10000,
@@ -126,9 +132,13 @@ const examples = [
126132
export default class extends React.Component {
127133
renderExamples() {
128134
return examples.map((props, key) =>
129-
<div key={key} className={`example axis-${props.axis}`}>
135+
<div key={key}
136+
className={`example axis-${props.axis} ${props.className}`}
137+
>
130138
<strong>Props</strong>
131-
<pre className='props'>{JSON.stringify(props, null, 2)}</pre>
139+
<pre className='props'>{
140+
JSON.stringify(props, null, 2).replace(/\\n\s+/g, ' ')
141+
}</pre>
132142
<strong>Component</strong>
133143
<div className='component'><ReactList {...props} /></div>
134144
</div>

examples/index.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@
159159
var examples = [{
160160
length: 10000,
161161
itemRenderer: renderVariableHeightItem
162+
}, {
163+
length: 10000,
164+
itemRenderer: renderVariableHeightItem,
165+
className: 'is-animated',
166+
stableFrameDelay: 500
162167
}, {
163168
axis: 'x',
164169
length: 10000,
@@ -230,7 +235,9 @@
230235
return examples.map(function (props, key) {
231236
return _react2.default.createElement(
232237
'div',
233-
{ key: key, className: 'example axis-' + props.axis },
238+
{ key: key,
239+
className: 'example axis-' + props.axis + ' ' + props.className
240+
},
234241
_react2.default.createElement(
235242
'strong',
236243
null,
@@ -239,7 +246,7 @@
239246
_react2.default.createElement(
240247
'pre',
241248
{ className: 'props' },
242-
JSON.stringify(props, null, 2)
249+
JSON.stringify(props, null, 2).replace(/\\n\s+/g, ' ')
243250
),
244251
_react2.default.createElement(
245252
'strong',

index.html

+11
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@
8181
.even {
8282
background: linear-gradient(#ddd, #ccc);
8383
}
84+
85+
@keyframes grow {
86+
0% { max-height: 0; }
87+
100% { max-height: 120px; }
88+
}
89+
90+
.is-animated .item {
91+
line-height: 120px;
92+
overflow: hidden;
93+
animation: grow 0.5s ease 0s;
94+
}
8495
</style>
8596
</head>
8697

react-list.es6

+12-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module.exports = class ReactList extends Component {
5555
length: PropTypes.number,
5656
pageSize: PropTypes.number,
5757
scrollParentGetter: PropTypes.func,
58+
stableFrameDelay: PropTypes.number,
5859
threshold: PropTypes.number,
5960
type: PropTypes.oneOf(['simple', 'variable', 'uniform']),
6061
useStaticSize: PropTypes.bool,
@@ -87,6 +88,7 @@ module.exports = class ReactList extends Component {
8788

8889
componentWillReceiveProps(next) {
8990
let {from, size, itemsPerRow} = this.state;
91+
clearTimeout(this.updateFrameTimeoutId);
9092
this.maybeSetState(this.constrain(from, size, itemsPerRow, next), NOOP);
9193
}
9294

@@ -97,6 +99,7 @@ module.exports = class ReactList extends Component {
9799
}
98100

99101
componentDidUpdate() {
102+
let {stableFrameDelay, type} = this.props;
100103

101104
// If the list has reached an unstable state, prevent an infinite loop.
102105
if (this.unstable) return;
@@ -113,7 +116,14 @@ module.exports = class ReactList extends Component {
113116
}, 0);
114117
}
115118

116-
this.updateFrame();
119+
if (type === 'simple' && stableFrameDelay) {
120+
this.updateFrameTimeoutId = setTimeout(
121+
this.updateFrame, stableFrameDelay
122+
);
123+
} else {
124+
this.updateFrame();
125+
}
126+
117127
}
118128

119129
maybeSetState(b, cb) {
@@ -126,6 +136,7 @@ module.exports = class ReactList extends Component {
126136
window.removeEventListener('resize', this.updateFrame);
127137
this.scrollParent.removeEventListener('scroll', this.updateFrame, PASSIVE);
128138
this.scrollParent.removeEventListener('mousewheel', NOOP, PASSIVE);
139+
clearTimeout(this.updateFrameTimeoutId);
129140
}
130141

131142
getOffset(el) {

react-list.js

+41-29
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
size = _state.size,
149149
itemsPerRow = _state.itemsPerRow;
150150

151+
clearTimeout(this.updateFrameTimeoutId);
151152
this.maybeSetState(this.constrain(from, size, itemsPerRow, next), NOOP);
152153
}
153154
}, {
@@ -162,6 +163,11 @@
162163
value: function componentDidUpdate() {
163164
var _this2 = this;
164165

166+
var _props = this.props,
167+
stableFrameDelay = _props.stableFrameDelay,
168+
type = _props.type;
169+
170+
165171
// If the list has reached an unstable state, prevent an infinite loop.
166172
if (this.unstable) return;
167173

@@ -177,7 +183,11 @@
177183
}, 0);
178184
}
179185

180-
this.updateFrame();
186+
if (type === 'simple' && stableFrameDelay) {
187+
this.updateFrameTimeoutId = setTimeout(this.updateFrame, stableFrameDelay);
188+
} else {
189+
this.updateFrame();
190+
}
181191
}
182192
}, {
183193
key: 'maybeSetState',
@@ -192,6 +202,7 @@
192202
window.removeEventListener('resize', this.updateFrame);
193203
this.scrollParent.removeEventListener('scroll', this.updateFrame, PASSIVE);
194204
this.scrollParent.removeEventListener('mousewheel', NOOP, PASSIVE);
205+
clearTimeout(this.updateFrameTimeoutId);
195206
}
196207
}, {
197208
key: 'getOffset',
@@ -208,9 +219,9 @@
208219
}, {
209220
key: 'getScrollParent',
210221
value: function getScrollParent() {
211-
var _props = this.props,
212-
axis = _props.axis,
213-
scrollParentGetter = _props.scrollParentGetter;
222+
var _props2 = this.props,
223+
axis = _props2.axis,
224+
scrollParentGetter = _props2.scrollParentGetter;
214225

215226
if (scrollParentGetter) return scrollParentGetter();
216227
var el = findDOMNode(this);
@@ -274,9 +285,9 @@
274285
}, {
275286
key: 'hasDeterminateSize',
276287
value: function hasDeterminateSize() {
277-
var _props2 = this.props,
278-
itemSizeGetter = _props2.itemSizeGetter,
279-
type = _props2.type;
288+
var _props3 = this.props,
289+
itemSizeGetter = _props3.itemSizeGetter,
290+
type = _props3.type;
280291

281292
return type === 'uniform' || itemSizeGetter;
282293
}
@@ -296,9 +307,9 @@
296307
}, {
297308
key: 'getItemSizeAndItemsPerRow',
298309
value: function getItemSizeAndItemsPerRow() {
299-
var _props3 = this.props,
300-
axis = _props3.axis,
301-
useStaticSize = _props3.useStaticSize;
310+
var _props4 = this.props,
311+
axis = _props4.axis,
312+
useStaticSize = _props4.useStaticSize;
302313
var _state2 = this.state,
303314
itemSize = _state2.itemSize,
304315
itemsPerRow = _state2.itemsPerRow;
@@ -375,9 +386,9 @@
375386

376387
if (elEnd > end) return cb();
377388

378-
var _props4 = this.props,
379-
pageSize = _props4.pageSize,
380-
length = _props4.length;
389+
var _props5 = this.props,
390+
pageSize = _props5.pageSize,
391+
length = _props5.length;
381392

382393
var size = Math.min(this.state.size + pageSize, length);
383394
this.maybeSetState({ size: size }, cb);
@@ -391,9 +402,9 @@
391402
start = _getStartAndEnd2.start,
392403
end = _getStartAndEnd2.end;
393404

394-
var _props5 = this.props,
395-
length = _props5.length,
396-
pageSize = _props5.pageSize;
405+
var _props6 = this.props,
406+
length = _props6.length,
407+
pageSize = _props6.pageSize;
397408

398409
var space = 0;
399410
var from = 0;
@@ -488,11 +499,11 @@
488499
value: function getSizeOf(index) {
489500
var cache = this.cache,
490501
items = this.items;
491-
var _props6 = this.props,
492-
axis = _props6.axis,
493-
itemSizeGetter = _props6.itemSizeGetter,
494-
itemSizeEstimator = _props6.itemSizeEstimator,
495-
type = _props6.type;
502+
var _props7 = this.props,
503+
axis = _props7.axis,
504+
itemSizeGetter = _props7.itemSizeGetter,
505+
itemSizeEstimator = _props7.itemSizeEstimator,
506+
type = _props7.type;
496507
var _state4 = this.state,
497508
from = _state4.from,
498509
itemSize = _state4.itemSize,
@@ -579,9 +590,9 @@
579590
value: function renderItems() {
580591
var _this3 = this;
581592

582-
var _props7 = this.props,
583-
itemRenderer = _props7.itemRenderer,
584-
itemsRenderer = _props7.itemsRenderer;
593+
var _props8 = this.props,
594+
itemRenderer = _props8.itemRenderer,
595+
itemsRenderer = _props8.itemsRenderer;
585596
var _state6 = this.state,
586597
from = _state6.from,
587598
size = _state6.size;
@@ -596,11 +607,11 @@
596607
}, {
597608
key: 'render',
598609
value: function render() {
599-
var _props8 = this.props,
600-
axis = _props8.axis,
601-
length = _props8.length,
602-
type = _props8.type,
603-
useTranslate3d = _props8.useTranslate3d;
610+
var _props9 = this.props,
611+
axis = _props9.axis,
612+
length = _props9.length,
613+
type = _props9.type,
614+
useTranslate3d = _props9.useTranslate3d;
604615
var _state7 = this.state,
605616
from = _state7.from,
606617
itemsPerRow = _state7.itemsPerRow;
@@ -649,6 +660,7 @@
649660
length: _react.PropTypes.number,
650661
pageSize: _react.PropTypes.number,
651662
scrollParentGetter: _react.PropTypes.func,
663+
stableFrameDelay: _react.PropTypes.number,
652664
threshold: _react.PropTypes.number,
653665
type: _react.PropTypes.oneOf(['simple', 'variable', 'uniform']),
654666
useStaticSize: _react.PropTypes.bool,

0 commit comments

Comments
 (0)