@html-next/vertical-collection 3.0.0-0 → 3.0.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -32,14 +32,14 @@ export default class DynamicRadar extends Radar {
|
|
|
32
32
|
this.skipList = null;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
scheduleUpdate(didUpdateItems) {
|
|
35
|
+
scheduleUpdate(didUpdateItems, promiseResolve) {
|
|
36
36
|
// Cancel incremental render check, since we'll be remeasuring anyways
|
|
37
37
|
if (this._nextIncrementalRender !== null) {
|
|
38
38
|
this._nextIncrementalRender.cancel();
|
|
39
39
|
this._nextIncrementalRender = null;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
super.scheduleUpdate(didUpdateItems);
|
|
42
|
+
super.scheduleUpdate(didUpdateItems, promiseResolve);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
afterUpdate() {
|
|
@@ -105,6 +105,7 @@ export default class Radar {
|
|
|
105
105
|
|
|
106
106
|
this._componentPool = [];
|
|
107
107
|
this._prependComponentPool = [];
|
|
108
|
+
this._appendComponentPool = []; // https://github.com/html-next/vertical-collection/issues/296
|
|
108
109
|
|
|
109
110
|
// Boundaries
|
|
110
111
|
this._occludedContentBefore = new OccludedContent(occlusionTagName);
|
|
@@ -223,7 +224,7 @@ export default class Radar {
|
|
|
223
224
|
*
|
|
224
225
|
* @private
|
|
225
226
|
*/
|
|
226
|
-
scheduleUpdate(didUpdateItems) {
|
|
227
|
+
scheduleUpdate(didUpdateItems, promiseResolve) {
|
|
227
228
|
if (didUpdateItems === true) {
|
|
228
229
|
// Set the update items flag first, in case scheduleUpdate has already been called
|
|
229
230
|
// but the RAF hasn't yet run
|
|
@@ -238,11 +239,11 @@ export default class Radar {
|
|
|
238
239
|
this._nextUpdate = null;
|
|
239
240
|
this._scrollTop = this._scrollContainer.scrollTop;
|
|
240
241
|
|
|
241
|
-
this.update();
|
|
242
|
+
this.update(promiseResolve);
|
|
242
243
|
});
|
|
243
244
|
}
|
|
244
245
|
|
|
245
|
-
update() {
|
|
246
|
+
update(promiseResolve) {
|
|
246
247
|
if (this._didUpdateItems === true) {
|
|
247
248
|
this._determineUpdateType();
|
|
248
249
|
this._didUpdateItems = false;
|
|
@@ -252,7 +253,12 @@ export default class Radar {
|
|
|
252
253
|
this._updateIndexes();
|
|
253
254
|
this._updateVirtualComponents();
|
|
254
255
|
|
|
255
|
-
this.schedule('measure',
|
|
256
|
+
this.schedule('measure', () => {
|
|
257
|
+
if (promiseResolve) {
|
|
258
|
+
promiseResolve();
|
|
259
|
+
}
|
|
260
|
+
this.afterUpdate();
|
|
261
|
+
});
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
afterUpdate() {
|
|
@@ -554,6 +560,8 @@ export default class Radar {
|
|
|
554
560
|
const {
|
|
555
561
|
virtualComponents,
|
|
556
562
|
_occludedContentAfter,
|
|
563
|
+
_appendComponentPool,
|
|
564
|
+
shouldRecycle,
|
|
557
565
|
_itemContainer
|
|
558
566
|
} = this;
|
|
559
567
|
|
|
@@ -564,6 +572,29 @@ export default class Radar {
|
|
|
564
572
|
} else {
|
|
565
573
|
virtualComponents.insertAt(virtualComponents.get('length') - 1, component);
|
|
566
574
|
component.rendered = true;
|
|
575
|
+
|
|
576
|
+
// shouldRecycle=false breaks UI when scrolling the elements fast.
|
|
577
|
+
// Reference https://github.com/html-next/vertical-collection/issues/296
|
|
578
|
+
// Components that are both new and appended still need to be rendered at the end because Glimmer.
|
|
579
|
+
// We have to move them _after_ they render, so we schedule that if they exist
|
|
580
|
+
if(!shouldRecycle) {
|
|
581
|
+
_appendComponentPool.unshift(component);
|
|
582
|
+
|
|
583
|
+
if (this._nextLayout === null) {
|
|
584
|
+
this._nextLayout = this.schedule('layout', () => {
|
|
585
|
+
this._nextLayout = null;
|
|
586
|
+
|
|
587
|
+
while (_appendComponentPool.length > 0) {
|
|
588
|
+
const component = _appendComponentPool.pop();
|
|
589
|
+
|
|
590
|
+
// Changes with each inserted component
|
|
591
|
+
const relativeNode = _occludedContentAfter.realUpperBound;
|
|
592
|
+
|
|
593
|
+
insertRangeBefore(this._itemContainer, relativeNode, component.realUpperBound, component.realLowerBound);
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
}
|
|
567
598
|
}
|
|
568
599
|
}
|
|
569
600
|
|
|
@@ -200,6 +200,24 @@ const VerticalCollection = Component.extend({
|
|
|
200
200
|
}
|
|
201
201
|
},
|
|
202
202
|
|
|
203
|
+
/* Public API Methods
|
|
204
|
+
@index => number
|
|
205
|
+
This will return offset height of the indexed item.
|
|
206
|
+
*/
|
|
207
|
+
scrollToItem(index) {
|
|
208
|
+
const { _radar } = this;
|
|
209
|
+
// Getting the offset height from Radar
|
|
210
|
+
let scrollTop = _radar.getOffsetForIndex(index);
|
|
211
|
+
_radar._scrollContainer.scrollTop = scrollTop;
|
|
212
|
+
// To scroll exactly to specified index, we are changing the prevIndex values to specified index
|
|
213
|
+
_radar._prevFirstVisibleIndex = _radar._prevFirstItemIndex = index;
|
|
214
|
+
// Components will be rendered after schedule 'measure' inside 'update' method.
|
|
215
|
+
// In our case, we need to focus the element after component is rendered. So passing the promise.
|
|
216
|
+
return new Promise ((resolve) => {
|
|
217
|
+
_radar.scheduleUpdate(false, resolve);
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
|
|
203
221
|
// –––––––––––––– Setup/Teardown
|
|
204
222
|
didInsertElement() {
|
|
205
223
|
this.schedule('sync', () => {
|
|
@@ -210,6 +228,10 @@ const VerticalCollection = Component.extend({
|
|
|
210
228
|
willDestroy() {
|
|
211
229
|
this.token.cancel();
|
|
212
230
|
this._radar.destroy();
|
|
231
|
+
let registerAPI = this.get('registerAPI');
|
|
232
|
+
if (registerAPI) {
|
|
233
|
+
registerAPI(null);
|
|
234
|
+
}
|
|
213
235
|
clearTimeout(this._nextSendActions);
|
|
214
236
|
},
|
|
215
237
|
|
|
@@ -280,6 +302,43 @@ const VerticalCollection = Component.extend({
|
|
|
280
302
|
}
|
|
281
303
|
};
|
|
282
304
|
}
|
|
305
|
+
|
|
306
|
+
/* Public methods to Expose to parent
|
|
307
|
+
|
|
308
|
+
Usage:
|
|
309
|
+
|
|
310
|
+
Template:
|
|
311
|
+
|
|
312
|
+
{{vertical-collection registerAPI=(action "registerAPI")}}
|
|
313
|
+
|
|
314
|
+
Component:
|
|
315
|
+
|
|
316
|
+
export default Component.extend({
|
|
317
|
+
actions: {
|
|
318
|
+
registerAPI(api) {
|
|
319
|
+
this.set('collectionAPI', api);
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
scrollToItem() {
|
|
323
|
+
let collectionAPI = this.get('collectionAPI');
|
|
324
|
+
collectionAPI.scrollToItem(index);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
Need to pass this property in the vertical-collection template
|
|
329
|
+
Listen in the component actions and do your custom logic
|
|
330
|
+
This API will have below methods.
|
|
331
|
+
1. scrollToItem
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
let registerAPI = get(this, 'registerAPI');
|
|
335
|
+
if (registerAPI) {
|
|
336
|
+
/* List of methods to be exposed to public should be added here */
|
|
337
|
+
let publicAPI = {
|
|
338
|
+
scrollToItem: this.scrollToItem.bind(this)
|
|
339
|
+
};
|
|
340
|
+
registerAPI(publicAPI);
|
|
341
|
+
}
|
|
283
342
|
}
|
|
284
343
|
});
|
|
285
344
|
|
|
@@ -307,4 +366,4 @@ function calculateStartingIndex(items, idForFirstItem, key, renderFromLast) {
|
|
|
307
366
|
return startingIndex;
|
|
308
367
|
}
|
|
309
368
|
|
|
310
|
-
export default VerticalCollection;
|
|
369
|
+
export default VerticalCollection;
|