ng-virtual-list 14.3.2 → 14.4.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/README.md +9 -8
- package/esm2020/lib/components/ng-virtual-list-item.component.mjs +4 -4
- package/esm2020/lib/const/index.mjs +3 -2
- package/esm2020/lib/models/base-virtual-list-item-component.mjs +1 -1
- package/esm2020/lib/models/index.mjs +2 -3
- package/esm2020/lib/ng-virtual-list.component.mjs +55 -23
- package/esm2020/lib/utils/buffer-interpolation.mjs +27 -0
- package/esm2020/lib/utils/index.mjs +2 -6
- package/esm2020/lib/utils/trackBox.mjs +62 -13
- package/esm2020/lib/utils/tracker.mjs +1 -1
- package/fesm2015/ng-virtual-list.mjs +325 -218
- package/fesm2015/ng-virtual-list.mjs.map +1 -1
- package/fesm2020/ng-virtual-list.mjs +324 -217
- package/fesm2020/ng-virtual-list.mjs.map +1 -1
- package/lib/components/ng-virtual-list-item.component.d.ts +7 -7
- package/lib/const/index.d.ts +2 -1
- package/lib/models/base-virtual-list-item-component.d.ts +0 -1
- package/lib/models/index.d.ts +1 -4
- package/lib/ng-virtual-list.component.d.ts +78 -67
- package/lib/utils/buffer-interpolation.d.ts +5 -0
- package/lib/utils/index.d.ts +3 -6
- package/lib/utils/trackBox.d.ts +20 -2
- package/lib/utils/tracker.d.ts +11 -4
- package/package.json +1 -1
|
@@ -41,7 +41,8 @@ var SnappingMethods;
|
|
|
41
41
|
})(SnappingMethods || (SnappingMethods = {}));
|
|
42
42
|
|
|
43
43
|
const DEFAULT_ITEM_SIZE = 24;
|
|
44
|
-
const
|
|
44
|
+
const DEFAULT_BUFFER_SIZE = 2;
|
|
45
|
+
const DEFAULT_MAX_BUFFER_SIZE = 100;
|
|
45
46
|
const DEFAULT_LIST_SIZE = 400;
|
|
46
47
|
const DEFAULT_SNAP = false;
|
|
47
48
|
const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
|
|
@@ -208,28 +209,14 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
208
209
|
}
|
|
209
210
|
NgVirtualListItemComponent.__nextId = 0;
|
|
210
211
|
NgVirtualListItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
211
|
-
NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden
|
|
212
|
+
NgVirtualListItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
212
213
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
213
214
|
type: Component,
|
|
214
215
|
args: [{ selector: 'ng-virtual-list-item', host: {
|
|
215
216
|
'class': 'ngvl__item',
|
|
216
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden
|
|
217
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"data\">\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': data.config.snapped,\r\n 'snapped-out': data.config.snappedOut}\">\r\n <ng-container *ngIf=\"itemRenderer\">\r\n <ng-container [ngTemplateOutlet]=\"itemRenderer\"\r\n [ngTemplateOutletContext]=\"{data: data.data || {}, config: data.config}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n</ng-container>", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden}.ngvl-item__container{margin:0;padding:0;overflow:hidden;background-color:#fff;width:inherit;height:inherit}\n"] }]
|
|
217
218
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; } });
|
|
218
219
|
|
|
219
|
-
const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
|
|
220
|
-
/**
|
|
221
|
-
* Determines the axis membership of a virtual list
|
|
222
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
|
|
223
|
-
* @author Evgenii Grebennikov
|
|
224
|
-
* @email djonnyx@gmail.com
|
|
225
|
-
*/
|
|
226
|
-
const isDirection = (src, expected) => {
|
|
227
|
-
if (HORIZONTAL_ALIASES.includes(expected)) {
|
|
228
|
-
return HORIZONTAL_ALIASES.includes(src);
|
|
229
|
-
}
|
|
230
|
-
return VERTICAL_ALIASES.includes(src);
|
|
231
|
-
};
|
|
232
|
-
|
|
233
220
|
/**
|
|
234
221
|
* Simple debounce function.
|
|
235
222
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/debounce.ts
|
|
@@ -277,137 +264,45 @@ const toggleClassName = (el, className, removeClassName) => {
|
|
|
277
264
|
};
|
|
278
265
|
|
|
279
266
|
/**
|
|
280
|
-
*
|
|
281
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/
|
|
267
|
+
* Scroll event.
|
|
268
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
|
|
282
269
|
* @author Evgenii Grebennikov
|
|
283
270
|
* @email djonnyx@gmail.com
|
|
284
271
|
*/
|
|
285
|
-
class
|
|
286
|
-
constructor(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
this.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
this.
|
|
295
|
-
this.
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
this.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
set trackingPropertyName(v) {
|
|
310
|
-
this._trackingPropertyName = v;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* tracking by propName
|
|
314
|
-
*/
|
|
315
|
-
track(items, components, snapedComponent, direction) {
|
|
316
|
-
if (!items) {
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
|
|
320
|
-
let isRegularSnapped = false;
|
|
321
|
-
for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
|
|
322
|
-
const item = items[i], itemTrackingProperty = item[idPropName];
|
|
323
|
-
if (this._trackMap) {
|
|
324
|
-
if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
|
|
325
|
-
const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
|
|
326
|
-
const compId = comp?.instance?.id;
|
|
327
|
-
if (comp !== undefined && compId === diId) {
|
|
328
|
-
const indexByUntrackedItems = untrackedItems.findIndex(v => {
|
|
329
|
-
return v.instance.id === compId;
|
|
330
|
-
});
|
|
331
|
-
if (indexByUntrackedItems > -1) {
|
|
332
|
-
if (snapedComponent) {
|
|
333
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
334
|
-
isRegularSnapped = true;
|
|
335
|
-
snapedComponent.instance.item = item;
|
|
336
|
-
snapedComponent.instance.show();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
comp.instance.item = item;
|
|
340
|
-
if (snapedComponent) {
|
|
341
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
342
|
-
comp.instance.hide();
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
comp.instance.show();
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
comp.instance.show();
|
|
350
|
-
}
|
|
351
|
-
untrackedItems.splice(indexByUntrackedItems, 1);
|
|
352
|
-
continue;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
delete this._trackMap[itemTrackingProperty];
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
if (untrackedItems.length > 0) {
|
|
359
|
-
const comp = untrackedItems.shift(), item = items[i];
|
|
360
|
-
if (comp) {
|
|
361
|
-
if (snapedComponent) {
|
|
362
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
363
|
-
isRegularSnapped = true;
|
|
364
|
-
snapedComponent.instance.item = item;
|
|
365
|
-
snapedComponent.instance.show();
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
comp.instance.item = item;
|
|
369
|
-
if (snapedComponent) {
|
|
370
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
371
|
-
comp.instance.hide();
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
comp.instance.show();
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
comp.instance.show();
|
|
379
|
-
}
|
|
380
|
-
if (this._trackMap) {
|
|
381
|
-
this._trackMap[itemTrackingProperty] = comp.instance.id;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
if (untrackedItems.length) {
|
|
387
|
-
for (let i = 0, l = untrackedItems.length; i < l; i++) {
|
|
388
|
-
const comp = untrackedItems[i];
|
|
389
|
-
comp.instance.hide();
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
if (!isRegularSnapped) {
|
|
393
|
-
if (snapedComponent) {
|
|
394
|
-
snapedComponent.instance.item = null;
|
|
395
|
-
snapedComponent.instance.hide();
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
untrackComponentByIdProperty(component) {
|
|
400
|
-
if (!component) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
const propertyIdName = this._trackingPropertyName;
|
|
404
|
-
if (this._trackMap && component[propertyIdName] !== undefined) {
|
|
405
|
-
delete this._trackMap[propertyIdName];
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
dispose() {
|
|
409
|
-
this._trackMap = null;
|
|
272
|
+
class ScrollEvent {
|
|
273
|
+
constructor(params) {
|
|
274
|
+
this._direction = 1;
|
|
275
|
+
this._scrollSize = 0;
|
|
276
|
+
this._scrollWeight = 0;
|
|
277
|
+
this._isVertical = true;
|
|
278
|
+
this._listSize = 0;
|
|
279
|
+
this._size = 0;
|
|
280
|
+
this._isStart = true;
|
|
281
|
+
this._isEnd = false;
|
|
282
|
+
this._delta = 0;
|
|
283
|
+
this._scrollDelta = 0;
|
|
284
|
+
const { direction, isVertical, container, list, delta, scrollDelta } = params;
|
|
285
|
+
this._direction = direction;
|
|
286
|
+
this._isVertical = isVertical;
|
|
287
|
+
this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
|
|
288
|
+
this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
|
|
289
|
+
this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
|
|
290
|
+
this._size = isVertical ? container.offsetHeight : container.offsetWidth;
|
|
291
|
+
this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
|
|
292
|
+
this._delta = delta;
|
|
293
|
+
this._scrollDelta = scrollDelta;
|
|
294
|
+
this._isStart = this._scrollSize === 0;
|
|
410
295
|
}
|
|
296
|
+
get direction() { return this._direction; }
|
|
297
|
+
get scrollSize() { return this._scrollSize; }
|
|
298
|
+
get scrollWeight() { return this._scrollWeight; }
|
|
299
|
+
get isVertical() { return this._isVertical; }
|
|
300
|
+
get listSize() { return this._listSize; }
|
|
301
|
+
get size() { return this._size; }
|
|
302
|
+
get isStart() { return this._isStart; }
|
|
303
|
+
get isEnd() { return this._isEnd; }
|
|
304
|
+
get delta() { return this._delta; }
|
|
305
|
+
get scrollDelta() { return this._scrollDelta; }
|
|
411
306
|
}
|
|
412
307
|
|
|
413
308
|
/**
|
|
@@ -681,6 +576,167 @@ class CacheMap extends EventEmitter {
|
|
|
681
576
|
}
|
|
682
577
|
}
|
|
683
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Tracks display items by property
|
|
581
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
|
|
582
|
+
* @author Evgenii Grebennikov
|
|
583
|
+
* @email djonnyx@gmail.com
|
|
584
|
+
*/
|
|
585
|
+
class Tracker {
|
|
586
|
+
constructor(trackingPropertyName) {
|
|
587
|
+
/**
|
|
588
|
+
* display objects dictionary of indexes by id
|
|
589
|
+
*/
|
|
590
|
+
this._displayObjectIndexMapById = {};
|
|
591
|
+
/**
|
|
592
|
+
* Dictionary displayItems propertyNameId by items propertyNameId
|
|
593
|
+
*/
|
|
594
|
+
this._trackMap = {};
|
|
595
|
+
this._trackingPropertyName = trackingPropertyName;
|
|
596
|
+
}
|
|
597
|
+
set displayObjectIndexMapById(v) {
|
|
598
|
+
if (this._displayObjectIndexMapById === v) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this._displayObjectIndexMapById = v;
|
|
602
|
+
}
|
|
603
|
+
get displayObjectIndexMapById() {
|
|
604
|
+
return this._displayObjectIndexMapById;
|
|
605
|
+
}
|
|
606
|
+
get trackMap() {
|
|
607
|
+
return this._trackMap;
|
|
608
|
+
}
|
|
609
|
+
set trackingPropertyName(v) {
|
|
610
|
+
this._trackingPropertyName = v;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* tracking by propName
|
|
614
|
+
*/
|
|
615
|
+
track(items, components, snapedComponent, direction) {
|
|
616
|
+
if (!items) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
|
|
620
|
+
let isRegularSnapped = false;
|
|
621
|
+
for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
|
|
622
|
+
const item = items[i], itemTrackingProperty = item[idPropName];
|
|
623
|
+
if (this._trackMap) {
|
|
624
|
+
if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
|
|
625
|
+
const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
|
|
626
|
+
const compId = comp?.instance?.id;
|
|
627
|
+
if (comp !== undefined && compId === diId) {
|
|
628
|
+
const indexByUntrackedItems = untrackedItems.findIndex(v => {
|
|
629
|
+
return v.instance.id === compId;
|
|
630
|
+
});
|
|
631
|
+
if (indexByUntrackedItems > -1) {
|
|
632
|
+
if (snapedComponent) {
|
|
633
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
634
|
+
isRegularSnapped = true;
|
|
635
|
+
snapedComponent.instance.item = item;
|
|
636
|
+
snapedComponent.instance.show();
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
comp.instance.item = item;
|
|
640
|
+
if (snapedComponent) {
|
|
641
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
642
|
+
comp.instance.hide();
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
comp.instance.show();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
comp.instance.show();
|
|
650
|
+
}
|
|
651
|
+
untrackedItems.splice(indexByUntrackedItems, 1);
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
delete this._trackMap[itemTrackingProperty];
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (untrackedItems.length > 0) {
|
|
659
|
+
const comp = untrackedItems.shift(), item = items[i];
|
|
660
|
+
if (comp) {
|
|
661
|
+
if (snapedComponent) {
|
|
662
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
663
|
+
isRegularSnapped = true;
|
|
664
|
+
snapedComponent.instance.item = item;
|
|
665
|
+
snapedComponent.instance.show();
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
comp.instance.item = item;
|
|
669
|
+
if (snapedComponent) {
|
|
670
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
671
|
+
comp.instance.hide();
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
comp.instance.show();
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
comp.instance.show();
|
|
679
|
+
}
|
|
680
|
+
if (this._trackMap) {
|
|
681
|
+
this._trackMap[itemTrackingProperty] = comp.instance.id;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (untrackedItems.length) {
|
|
687
|
+
for (let i = 0, l = untrackedItems.length; i < l; i++) {
|
|
688
|
+
const comp = untrackedItems[i];
|
|
689
|
+
comp.instance.hide();
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (!isRegularSnapped) {
|
|
693
|
+
if (snapedComponent) {
|
|
694
|
+
snapedComponent.instance.item = null;
|
|
695
|
+
snapedComponent.instance.hide();
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
untrackComponentByIdProperty(component) {
|
|
700
|
+
if (!component) {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
const propertyIdName = this._trackingPropertyName;
|
|
704
|
+
if (this._trackMap && component[propertyIdName] !== undefined) {
|
|
705
|
+
delete this._trackMap[propertyIdName];
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
dispose() {
|
|
709
|
+
this._trackMap = null;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
const DEFAULT_EXTRA = {
|
|
714
|
+
extremumThreshold: 2,
|
|
715
|
+
bufferSize: 10,
|
|
716
|
+
};
|
|
717
|
+
const bufferInterpolation = (currentBufferValue, array, value, extra) => {
|
|
718
|
+
const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra ?? DEFAULT_EXTRA;
|
|
719
|
+
if (currentBufferValue < value) {
|
|
720
|
+
let i = 0;
|
|
721
|
+
while (i < extremumThreshold) {
|
|
722
|
+
array.push(value);
|
|
723
|
+
i++;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
array.push(value);
|
|
728
|
+
}
|
|
729
|
+
while (array.length >= bufferSize) {
|
|
730
|
+
array.shift();
|
|
731
|
+
}
|
|
732
|
+
const l = array.length;
|
|
733
|
+
let buffer = 0;
|
|
734
|
+
for (let i = 0; i < l; i++) {
|
|
735
|
+
buffer += array[i];
|
|
736
|
+
}
|
|
737
|
+
return Math.ceil(buffer / l);
|
|
738
|
+
};
|
|
739
|
+
|
|
684
740
|
const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
|
|
685
741
|
var ItemDisplayMethods;
|
|
686
742
|
(function (ItemDisplayMethods) {
|
|
@@ -689,6 +745,7 @@ var ItemDisplayMethods;
|
|
|
689
745
|
ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
|
|
690
746
|
ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
|
|
691
747
|
})(ItemDisplayMethods || (ItemDisplayMethods = {}));
|
|
748
|
+
const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
|
|
692
749
|
/**
|
|
693
750
|
* An object that performs tracking, calculations and caching.
|
|
694
751
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
|
|
@@ -699,11 +756,22 @@ class TrackBox extends CacheMap {
|
|
|
699
756
|
constructor(trackingPropertyName) {
|
|
700
757
|
super();
|
|
701
758
|
this._isSnappingMethodAdvanced = false;
|
|
759
|
+
this._trackingPropertyName = TRACK_BY_PROPERTY_NAME;
|
|
702
760
|
this._deletedItemsMap = {};
|
|
703
761
|
this._crudDetected = false;
|
|
704
762
|
this._previousTotalSize = 0;
|
|
705
763
|
this._scrollDelta = 0;
|
|
706
|
-
this.
|
|
764
|
+
this.isAdaptiveBuffer = true;
|
|
765
|
+
this._bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
|
|
766
|
+
this._maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
|
|
767
|
+
this._bufferSizeSequence = [];
|
|
768
|
+
this._bufferSize = 0;
|
|
769
|
+
this._defaultBufferSize = 0;
|
|
770
|
+
this._maxBufferSize = this._defaultBufferSize;
|
|
771
|
+
this._resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
|
|
772
|
+
this._previousScrollSize = 0;
|
|
773
|
+
this._trackingPropertyName = trackingPropertyName;
|
|
774
|
+
this.initialize();
|
|
707
775
|
}
|
|
708
776
|
set items(v) {
|
|
709
777
|
if (this._items === v) {
|
|
@@ -733,7 +801,10 @@ class TrackBox extends CacheMap {
|
|
|
733
801
|
* Set the trackBy property
|
|
734
802
|
*/
|
|
735
803
|
set trackingPropertyName(v) {
|
|
736
|
-
this._tracker.trackingPropertyName = v;
|
|
804
|
+
this._trackingPropertyName = this._tracker.trackingPropertyName = v;
|
|
805
|
+
}
|
|
806
|
+
initialize() {
|
|
807
|
+
this._tracker = new Tracker(this._trackingPropertyName);
|
|
737
808
|
}
|
|
738
809
|
set(id, bounds) {
|
|
739
810
|
if (this._map.has(id)) {
|
|
@@ -753,6 +824,7 @@ class TrackBox extends CacheMap {
|
|
|
753
824
|
}
|
|
754
825
|
}
|
|
755
826
|
get scrollDelta() { return this._scrollDelta; }
|
|
827
|
+
get bufferSize() { return this._bufferSize; }
|
|
756
828
|
lifeCircle() {
|
|
757
829
|
this.fireChangeIfNeed();
|
|
758
830
|
this.lifeCircleDo();
|
|
@@ -846,6 +918,8 @@ class TrackBox extends CacheMap {
|
|
|
846
918
|
*/
|
|
847
919
|
getItemPosition(id, stickyMap, options) {
|
|
848
920
|
const opt = { fromItemId: id, stickyMap, ...options };
|
|
921
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
922
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
849
923
|
const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
|
|
850
924
|
...opt,
|
|
851
925
|
dynamicSize: this._crudDetected || opt.dynamicSize,
|
|
@@ -863,6 +937,8 @@ class TrackBox extends CacheMap {
|
|
|
863
937
|
if (opt.dynamicSize) {
|
|
864
938
|
this.cacheElements();
|
|
865
939
|
}
|
|
940
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
941
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
866
942
|
const metrics = this.recalculateMetrics({
|
|
867
943
|
...opt,
|
|
868
944
|
collection: items,
|
|
@@ -871,6 +947,7 @@ class TrackBox extends CacheMap {
|
|
|
871
947
|
deletedItemsMap,
|
|
872
948
|
});
|
|
873
949
|
this._delta += metrics.delta;
|
|
950
|
+
this.updateAdaptiveBufferParams(metrics, items.length);
|
|
874
951
|
this._previousTotalSize = metrics.totalSize;
|
|
875
952
|
this._deletedItemsMap = {};
|
|
876
953
|
this._crudDetected = false;
|
|
@@ -886,6 +963,26 @@ class TrackBox extends CacheMap {
|
|
|
886
963
|
getNearestItem(scrollSize, items, itemSize, isVertical) {
|
|
887
964
|
return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
|
|
888
965
|
}
|
|
966
|
+
updateAdaptiveBufferParams(metrics, totalItemsLength) {
|
|
967
|
+
this.disposeClearBufferSizeTimer();
|
|
968
|
+
const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
|
|
969
|
+
this._previousScrollSize = scrollSize;
|
|
970
|
+
const bufferRawSize = Math.min(Math.floor(delta / metrics.typicalItemSize) * 5, totalItemsLength), minBufferSize = bufferRawSize < this._defaultBufferSize ? this._defaultBufferSize : bufferRawSize, bufferValue = minBufferSize > this._maxBufferSize ? this._maxBufferSize : minBufferSize;
|
|
971
|
+
this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
|
|
972
|
+
extremumThreshold: this._bufferSequenceExtraThreshold,
|
|
973
|
+
bufferSize: this._maxBufferSequenceLength,
|
|
974
|
+
});
|
|
975
|
+
this.startResetBufferSizeTimer();
|
|
976
|
+
}
|
|
977
|
+
startResetBufferSizeTimer() {
|
|
978
|
+
this._resetBufferSizeTimer = setTimeout(() => {
|
|
979
|
+
this._bufferSize = this._defaultBufferSize;
|
|
980
|
+
this._bufferSizeSequence = [];
|
|
981
|
+
}, this._resetBufferSizeTimeout);
|
|
982
|
+
}
|
|
983
|
+
disposeClearBufferSizeTimer() {
|
|
984
|
+
clearTimeout(this._resetBufferSizeTimer);
|
|
985
|
+
}
|
|
889
986
|
/**
|
|
890
987
|
* Calculates the position of an element based on the given scrollSize
|
|
891
988
|
*/
|
|
@@ -937,30 +1034,30 @@ class TrackBox extends CacheMap {
|
|
|
937
1034
|
* Calculates list metrics
|
|
938
1035
|
*/
|
|
939
1036
|
recalculateMetrics(options) {
|
|
940
|
-
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize,
|
|
941
|
-
const { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
|
|
1037
|
+
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
|
|
1038
|
+
const bufferSize = Math.max(minBufferSize, this._bufferSize), { width, height } = bounds, sizeProperty = isVertical ? HEIGHT_PROP_NAME : WIDTH_PROP_NAME, size = isVertical ? height : width, totalLength = collection.length, typicalItemSize = itemSize, w = isVertical ? width : typicalItemSize, h = isVertical ? typicalItemSize : height, map = this._map, snapshot = this._snapshot, checkOverscrollItemsLimit = Math.ceil(size / typicalItemSize), snippedPos = Math.floor(scrollSize), leftItemsWeights = [], isFromId = fromItemId !== undefined && (typeof fromItemId === 'number' && fromItemId > -1)
|
|
942
1039
|
|| (typeof fromItemId === 'string' && fromItemId > '-1');
|
|
943
1040
|
let leftItemsOffset = 0, rightItemsOffset = 0;
|
|
944
1041
|
if (enabledBufferOptimization) {
|
|
945
1042
|
switch (this.scrollDirection) {
|
|
946
1043
|
case 1: {
|
|
947
1044
|
leftItemsOffset = 0;
|
|
948
|
-
rightItemsOffset =
|
|
1045
|
+
rightItemsOffset = bufferSize;
|
|
949
1046
|
break;
|
|
950
1047
|
}
|
|
951
1048
|
case -1: {
|
|
952
|
-
leftItemsOffset =
|
|
1049
|
+
leftItemsOffset = bufferSize;
|
|
953
1050
|
rightItemsOffset = 0;
|
|
954
1051
|
break;
|
|
955
1052
|
}
|
|
956
1053
|
case 0:
|
|
957
1054
|
default: {
|
|
958
|
-
leftItemsOffset = rightItemsOffset =
|
|
1055
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
959
1056
|
}
|
|
960
1057
|
}
|
|
961
1058
|
}
|
|
962
1059
|
else {
|
|
963
|
-
leftItemsOffset = rightItemsOffset =
|
|
1060
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
964
1061
|
}
|
|
965
1062
|
let itemsFromStartToScrollEnd = -1, itemsFromDisplayEndToOffsetEnd = 0, itemsFromStartToDisplayEnd = -1, leftItemLength = 0, rightItemLength = 0, leftItemsWeight = 0, rightItemsWeight = 0, leftHiddenItemsWeight = 0, totalItemsToDisplayEndWeight = 0, leftSizeOfAddedItems = 0, leftSizeOfUpdatedItems = 0, leftSizeOfDeletedItems = 0, itemById = undefined, itemByIdPos = 0, targetDisplayItemIndex = -1, isTargetInOverscroll = false, actualScrollSize = itemByIdPos, totalSize = 0, startIndex, isFromItemIdFound = false;
|
|
966
1063
|
// If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
|
|
@@ -1135,9 +1232,9 @@ class TrackBox extends CacheMap {
|
|
|
1135
1232
|
}
|
|
1136
1233
|
itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
|
|
1137
1234
|
itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
|
|
1138
|
-
leftItemLength = Math.min(itemsFromStartToScrollEnd,
|
|
1139
|
-
rightItemLength = itemsFromStartToDisplayEnd +
|
|
1140
|
-
? totalLength - itemsFromStartToDisplayEnd :
|
|
1235
|
+
leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
|
|
1236
|
+
rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
|
|
1237
|
+
? totalLength - itemsFromStartToDisplayEnd : bufferSize;
|
|
1141
1238
|
leftItemsWeight = leftItemLength * typicalItemSize;
|
|
1142
1239
|
rightItemsWeight = rightItemLength * typicalItemSize;
|
|
1143
1240
|
leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
|
|
@@ -1234,6 +1331,9 @@ class TrackBox extends CacheMap {
|
|
|
1234
1331
|
if (snap) {
|
|
1235
1332
|
const startIndex = itemsFromStartToScrollEnd + itemsOnDisplayLength - 1;
|
|
1236
1333
|
for (let i = Math.min(startIndex, totalLength > 0 ? totalLength - 1 : 0), l = totalLength; i < l; i++) {
|
|
1334
|
+
if (!items[i]) {
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1237
1337
|
const id = items[i].id, sticky = stickyMap[id], size = dynamicSize
|
|
1238
1338
|
? this.get(id)?.[sizeProperty] || typicalItemSize
|
|
1239
1339
|
: typicalItemSize;
|
|
@@ -1268,6 +1368,9 @@ class TrackBox extends CacheMap {
|
|
|
1268
1368
|
if (i >= totalLength) {
|
|
1269
1369
|
break;
|
|
1270
1370
|
}
|
|
1371
|
+
if (!items[i]) {
|
|
1372
|
+
continue;
|
|
1373
|
+
}
|
|
1271
1374
|
const id = items[i].id, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
|
|
1272
1375
|
if (id !== stickyItem?.id && id !== endStickyItem?.id) {
|
|
1273
1376
|
const snapped = snap && (stickyMap[id] === 1 && pos <= scrollSize || stickyMap[id] === 2 && pos >= scrollSize + boundsSize - size), measures = {
|
|
@@ -1379,54 +1482,13 @@ class TrackBox extends CacheMap {
|
|
|
1379
1482
|
}
|
|
1380
1483
|
dispose() {
|
|
1381
1484
|
super.dispose();
|
|
1485
|
+
this.disposeClearBufferSizeTimer();
|
|
1382
1486
|
if (this._tracker) {
|
|
1383
1487
|
this._tracker.dispose();
|
|
1384
1488
|
}
|
|
1385
1489
|
}
|
|
1386
1490
|
}
|
|
1387
1491
|
|
|
1388
|
-
/**
|
|
1389
|
-
* Scroll event.
|
|
1390
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
|
|
1391
|
-
* @author Evgenii Grebennikov
|
|
1392
|
-
* @email djonnyx@gmail.com
|
|
1393
|
-
*/
|
|
1394
|
-
class ScrollEvent {
|
|
1395
|
-
constructor(params) {
|
|
1396
|
-
this._direction = 1;
|
|
1397
|
-
this._scrollSize = 0;
|
|
1398
|
-
this._scrollWeight = 0;
|
|
1399
|
-
this._isVertical = true;
|
|
1400
|
-
this._listSize = 0;
|
|
1401
|
-
this._size = 0;
|
|
1402
|
-
this._isStart = true;
|
|
1403
|
-
this._isEnd = false;
|
|
1404
|
-
this._delta = 0;
|
|
1405
|
-
this._scrollDelta = 0;
|
|
1406
|
-
const { direction, isVertical, container, list, delta, scrollDelta } = params;
|
|
1407
|
-
this._direction = direction;
|
|
1408
|
-
this._isVertical = isVertical;
|
|
1409
|
-
this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
|
|
1410
|
-
this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
|
|
1411
|
-
this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
|
|
1412
|
-
this._size = isVertical ? container.offsetHeight : container.offsetWidth;
|
|
1413
|
-
this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
|
|
1414
|
-
this._delta = delta;
|
|
1415
|
-
this._scrollDelta = scrollDelta;
|
|
1416
|
-
this._isStart = this._scrollSize === 0;
|
|
1417
|
-
}
|
|
1418
|
-
get direction() { return this._direction; }
|
|
1419
|
-
get scrollSize() { return this._scrollSize; }
|
|
1420
|
-
get scrollWeight() { return this._scrollWeight; }
|
|
1421
|
-
get isVertical() { return this._isVertical; }
|
|
1422
|
-
get listSize() { return this._listSize; }
|
|
1423
|
-
get size() { return this._size; }
|
|
1424
|
-
get isStart() { return this._isStart; }
|
|
1425
|
-
get isEnd() { return this._isEnd; }
|
|
1426
|
-
get delta() { return this._delta; }
|
|
1427
|
-
get scrollDelta() { return this._scrollDelta; }
|
|
1428
|
-
}
|
|
1429
|
-
|
|
1430
1492
|
/**
|
|
1431
1493
|
* Base disposable component
|
|
1432
1494
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/disposableComponent.ts
|
|
@@ -1464,6 +1526,20 @@ const isSnappingMethodDefault = (method) => {
|
|
|
1464
1526
|
const IS_FIREFOX = navigator.userAgent.toLowerCase().includes('firefox');
|
|
1465
1527
|
const FIREFOX_SCROLLBAR_OVERLAP_SIZE = 12;
|
|
1466
1528
|
|
|
1529
|
+
const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
|
|
1530
|
+
/**
|
|
1531
|
+
* Determines the axis membership of a virtual list
|
|
1532
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/14.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
|
|
1533
|
+
* @author Evgenii Grebennikov
|
|
1534
|
+
* @email djonnyx@gmail.com
|
|
1535
|
+
*/
|
|
1536
|
+
const isDirection = (src, expected) => {
|
|
1537
|
+
if (HORIZONTAL_ALIASES.includes(expected)) {
|
|
1538
|
+
return HORIZONTAL_ALIASES.includes(src);
|
|
1539
|
+
}
|
|
1540
|
+
return VERTICAL_ALIASES.includes(src);
|
|
1541
|
+
};
|
|
1542
|
+
|
|
1467
1543
|
/**
|
|
1468
1544
|
* Virtual list component.
|
|
1469
1545
|
* Maximum performance for extremely large lists.
|
|
@@ -1514,8 +1590,17 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1514
1590
|
this.$dynamicSize = this._$dynamicSize.asObservable();
|
|
1515
1591
|
this._$direction = new BehaviorSubject(DEFAULT_DIRECTION);
|
|
1516
1592
|
this.$direction = this._$direction.asObservable();
|
|
1517
|
-
this._$
|
|
1518
|
-
this.$
|
|
1593
|
+
this._$bufferSize = new BehaviorSubject(DEFAULT_BUFFER_SIZE);
|
|
1594
|
+
this.$bufferSize = this._$bufferSize.asObservable();
|
|
1595
|
+
this._maxBufferSizeTransform = (v) => {
|
|
1596
|
+
const bufferSize = this._$bufferSize.getValue();
|
|
1597
|
+
if (v === undefined || v <= bufferSize) {
|
|
1598
|
+
return bufferSize;
|
|
1599
|
+
}
|
|
1600
|
+
return v;
|
|
1601
|
+
};
|
|
1602
|
+
this._$maxBufferSize = new BehaviorSubject(DEFAULT_MAX_BUFFER_SIZE);
|
|
1603
|
+
this.$maxBufferSize = this._$maxBufferSize.asObservable();
|
|
1519
1604
|
this._$trackBy = new BehaviorSubject(TRACK_BY_PROPERTY_NAME);
|
|
1520
1605
|
this.$trackBy = this._$trackBy.asObservable();
|
|
1521
1606
|
this._isVertical = this.getIsVertical();
|
|
@@ -1635,7 +1720,7 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1635
1720
|
$trackBy.pipe(takeUntil(this._$unsubscribe), tap(v => {
|
|
1636
1721
|
this._trackBox.trackingPropertyName = v;
|
|
1637
1722
|
})).subscribe();
|
|
1638
|
-
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $
|
|
1723
|
+
const $bounds = this._$bounds.asObservable().pipe(filter(b => !!b)), $items = this.$items.pipe(map(i => !i ? [] : i)), $scrollSize = this._$scrollSize.asObservable(), $itemSize = this.$itemSize.pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = this.$bufferSize.pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = this.$maxBufferSize.pipe(map(v => v < 0 ? DEFAULT_MAX_BUFFER_SIZE : v)), $stickyMap = this.$stickyMap.pipe(map(v => !v ? {} : v)), $snap = this.$snap, $isVertical = this.$direction.pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = this.$dynamicSize, $enabledBufferOptimization = this.$enabledBufferOptimization, $snappingMethod = this.$snappingMethod.pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = this.$cacheVersion;
|
|
1639
1724
|
$isVertical.pipe(takeUntil(this._$unsubscribe), tap(v => {
|
|
1640
1725
|
this._isVertical = v;
|
|
1641
1726
|
const el = this._elementRef.nativeElement;
|
|
@@ -1648,12 +1733,12 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1648
1733
|
this.listenCacheChangesIfNeed(dynamicSize);
|
|
1649
1734
|
})).subscribe();
|
|
1650
1735
|
combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
|
|
1651
|
-
$
|
|
1652
|
-
]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize,
|
|
1736
|
+
$bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
|
|
1737
|
+
]).pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
|
|
1653
1738
|
let actualScrollSize = (this._isVertical ? this._container?.nativeElement.scrollTop ?? 0 : this._container?.nativeElement.scrollLeft) ?? 0;
|
|
1654
1739
|
const { width, height } = bounds, opts = {
|
|
1655
1740
|
bounds: { width, height }, dynamicSize, isVertical, itemSize,
|
|
1656
|
-
|
|
1741
|
+
bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
|
|
1657
1742
|
}, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
|
|
1658
1743
|
this.resetBoundsSize(isVertical, totalSize);
|
|
1659
1744
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
@@ -1676,7 +1761,10 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1676
1761
|
}
|
|
1677
1762
|
return of(displayItems);
|
|
1678
1763
|
})).subscribe();
|
|
1679
|
-
this
|
|
1764
|
+
const $itemRenderer = this.$itemRenderer;
|
|
1765
|
+
$itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
|
|
1766
|
+
this._$renderer.next(v);
|
|
1767
|
+
})).subscribe();
|
|
1680
1768
|
}
|
|
1681
1769
|
/**
|
|
1682
1770
|
* Readonly. Returns the unique identifier of the component.
|
|
@@ -1786,16 +1874,37 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1786
1874
|
;
|
|
1787
1875
|
get direction() { return this._$direction.getValue(); }
|
|
1788
1876
|
/**
|
|
1789
|
-
*
|
|
1877
|
+
* @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
|
|
1790
1878
|
*/
|
|
1791
1879
|
set itemsOffset(v) {
|
|
1792
|
-
|
|
1880
|
+
throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
|
|
1881
|
+
}
|
|
1882
|
+
;
|
|
1883
|
+
/**
|
|
1884
|
+
* Number of elements outside the scope of visibility. Default value is 2.
|
|
1885
|
+
*/
|
|
1886
|
+
set bufferSize(v) {
|
|
1887
|
+
if (this._$bufferSize.getValue() === v) {
|
|
1793
1888
|
return;
|
|
1794
1889
|
}
|
|
1795
|
-
this._$
|
|
1890
|
+
this._$bufferSize.next(v);
|
|
1796
1891
|
}
|
|
1797
1892
|
;
|
|
1798
|
-
get
|
|
1893
|
+
get bufferSize() { return this._$bufferSize.getValue(); }
|
|
1894
|
+
/**
|
|
1895
|
+
* Maximum number of elements outside the scope of visibility. Default value is 100.
|
|
1896
|
+
* If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
|
|
1897
|
+
* The greater the scroll size, the more elements are allocated for rendering.
|
|
1898
|
+
*/
|
|
1899
|
+
set maxBufferSize(v) {
|
|
1900
|
+
const val = this._maxBufferSizeTransform(v);
|
|
1901
|
+
if (this._$maxBufferSize.getValue() === val) {
|
|
1902
|
+
return;
|
|
1903
|
+
}
|
|
1904
|
+
this._$maxBufferSize.next(val);
|
|
1905
|
+
}
|
|
1906
|
+
;
|
|
1907
|
+
get maxBufferSize() { return this._$maxBufferSize.getValue(); }
|
|
1799
1908
|
/**
|
|
1800
1909
|
* The name of the property by which tracking is performed
|
|
1801
1910
|
*/
|
|
@@ -1822,12 +1931,6 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1822
1931
|
get snappingMethod() { return this._$snappingMethod.getValue(); }
|
|
1823
1932
|
get isSnappingMethodAdvanced() { return this._isSnappingMethodAdvanced; }
|
|
1824
1933
|
get $cacheVersion() { return this._$cacheVersion.asObservable(); }
|
|
1825
|
-
setupRenderer() {
|
|
1826
|
-
const $itemRenderer = this.$itemRenderer;
|
|
1827
|
-
$itemRenderer.pipe(takeUntil(this._$unsubscribe), distinctUntilChanged(), filter(v => !!v), tap(v => {
|
|
1828
|
-
this._$renderer.next(v);
|
|
1829
|
-
})).subscribe();
|
|
1830
|
-
}
|
|
1831
1934
|
/** @internal */
|
|
1832
1935
|
ngOnInit() {
|
|
1833
1936
|
this.onInit();
|
|
@@ -1940,7 +2043,7 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
1940
2043
|
}
|
|
1941
2044
|
const { width, height } = this._$bounds.getValue() || { width: 0, height: 0 }, stickyMap = this.stickyMap, items = this.items, isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
|
|
1942
2045
|
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
1943
|
-
|
|
2046
|
+
bufferSize: this.bufferSize, maxBufferSize: this.maxBufferSize, scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
|
|
1944
2047
|
snap: this.snap, fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization,
|
|
1945
2048
|
}, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
1946
2049
|
if (scrollSize === -1) {
|
|
@@ -2048,7 +2151,7 @@ class NgVirtualListComponent extends DisposableComponent {
|
|
|
2048
2151
|
}
|
|
2049
2152
|
NgVirtualListComponent.__nextId = 0;
|
|
2050
2153
|
NgVirtualListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2051
|
-
NgVirtualListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2154
|
+
NgVirtualListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: "items", snap: "snap", enabledBufferOptimization: "enabledBufferOptimization", itemRenderer: "itemRenderer", stickyMap: "stickyMap", itemSize: "itemSize", dynamicSize: "dynamicSize", direction: "direction", itemsOffset: "itemsOffset", bufferSize: "bufferSize", maxBufferSize: "maxBufferSize", trackBy: "trackBy", snappingMethod: "snappingMethod" }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, read: (ElementRef) }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, read: (ElementRef) }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, read: ViewContainerRef }], usesInheritance: true, ngImport: i0, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2052
2155
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
2053
2156
|
type: Component,
|
|
2054
2157
|
args: [{ selector: 'ng-virtual-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, template: "<div *ngIf=\"snap\" #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n<div #container part=\"scroller\" class=\"ngvl__scroller\">\r\n <ul #list part=\"list\" class=\"ngvl__list\">\r\n <ng-container #renderersContainer></ng-container>\r\n </ul>\r\n</div>", styles: [":host{position:relative;display:block;width:400px;overflow:hidden}:host(.horizontal){height:48px}:host(.horizontal) .ngvl__list{display:inline-flex}:host(.horizontal) .ngvl__scroller{overflow:auto hidden}:host(.vertical) .ngvl__scroller{overflow:hidden auto}:host(.vertical){height:320px}.ngvl__scroller{overflow:auto;width:100%;height:100%}.ngvl__list-snapper{pointer-events:none;position:absolute;list-style:none;left:0;top:0;z-index:1}.ngvl__list{position:relative;list-style:none;padding:0;margin:0;width:100%;height:100%}\n"] }]
|
|
@@ -2089,6 +2192,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2089
2192
|
type: Input
|
|
2090
2193
|
}], itemsOffset: [{
|
|
2091
2194
|
type: Input
|
|
2195
|
+
}], bufferSize: [{
|
|
2196
|
+
type: Input
|
|
2197
|
+
}], maxBufferSize: [{
|
|
2198
|
+
type: Input
|
|
2092
2199
|
}], trackBy: [{
|
|
2093
2200
|
type: Input
|
|
2094
2201
|
}], snappingMethod: [{
|
|
@@ -2118,5 +2225,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2118
2225
|
* Generated bundle index. Do not edit.
|
|
2119
2226
|
*/
|
|
2120
2227
|
|
|
2121
|
-
export {
|
|
2228
|
+
export { Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, SnappingMethods };
|
|
2122
2229
|
//# sourceMappingURL=ng-virtual-list.mjs.map
|