ng-virtual-list 17.3.2 → 17.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/esm2022/lib/components/ng-virtual-list-item.component.mjs +4 -4
- package/esm2022/lib/const/index.mjs +3 -2
- package/esm2022/lib/models/base-virtual-list-item-component.mjs +1 -1
- package/esm2022/lib/models/index.mjs +2 -3
- package/esm2022/lib/ng-virtual-list.component.mjs +38 -14
- package/esm2022/lib/utils/buffer-interpolation.mjs +27 -0
- package/esm2022/lib/utils/index.mjs +2 -6
- package/esm2022/lib/utils/trackBox.mjs +63 -13
- package/esm2022/lib/utils/tracker.mjs +1 -1
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/ng-virtual-list.mjs +309 -209
- package/fesm2022/ng-virtual-list.mjs.map +1 -1
- package/lib/components/ng-virtual-list-item.component.d.ts +9 -9
- 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 +61 -51
- 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
- package/public-api.d.ts +1 -0
|
@@ -42,7 +42,8 @@ var SnappingMethods;
|
|
|
42
42
|
})(SnappingMethods || (SnappingMethods = {}));
|
|
43
43
|
|
|
44
44
|
const DEFAULT_ITEM_SIZE = 24;
|
|
45
|
-
const
|
|
45
|
+
const DEFAULT_BUFFER_SIZE = 2;
|
|
46
|
+
const DEFAULT_MAX_BUFFER_SIZE = 100;
|
|
46
47
|
const DEFAULT_LIST_SIZE = 400;
|
|
47
48
|
const DEFAULT_SNAP = false;
|
|
48
49
|
const DEFAULT_ENABLED_BUFFER_OPTIMIZATION = false;
|
|
@@ -209,29 +210,15 @@ class NgVirtualListItemComponent extends BaseVirtualListItemComponent {
|
|
|
209
210
|
styles.zIndex = HIDDEN_ZINDEX;
|
|
210
211
|
}
|
|
211
212
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgVirtualListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
212
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@if (data(); as item) {\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': item.config.snapped,\r\n 'snapped-out': item.config.snappedOut}\">\r\n @if (itemRenderer(); as renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data || {}, config: item.config}\" />\r\n }\r\n </li>\r\n}", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden
|
|
213
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NgVirtualListItemComponent, selector: "ng-virtual-list-item", host: { classAttribute: "ngvl__item" }, usesInheritance: true, ngImport: i0, template: "@if (data(); as item) {\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': item.config.snapped,\r\n 'snapped-out': item.config.snappedOut}\">\r\n @if (itemRenderer(); as renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data || {}, config: item.config}\" />\r\n }\r\n </li>\r\n}", 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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
213
214
|
}
|
|
214
215
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgVirtualListItemComponent, decorators: [{
|
|
215
216
|
type: Component,
|
|
216
217
|
args: [{ selector: 'ng-virtual-list-item', standalone: false, host: {
|
|
217
218
|
'class': 'ngvl__item',
|
|
218
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (data(); as item) {\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': item.config.snapped,\r\n 'snapped-out': item.config.snappedOut}\">\r\n @if (itemRenderer(); as renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data || {}, config: item.config}\" />\r\n }\r\n </li>\r\n}", styles: [":host{display:block;position:absolute;left:0;top:0;box-sizing:border-box;overflow:hidden
|
|
219
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (data(); as item) {\r\n <li #listItem part=\"item\" class=\"ngvl-item__container\" [ngClass]=\"{'snapped': item.config.snapped,\r\n 'snapped-out': item.config.snappedOut}\">\r\n @if (itemRenderer(); as renderer) {\r\n <ng-container [ngTemplateOutlet]=\"renderer\"\r\n [ngTemplateOutletContext]=\"{data: item.data || {}, config: item.config}\" />\r\n }\r\n </li>\r\n}", 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"] }]
|
|
219
220
|
}], ctorParameters: () => [] });
|
|
220
221
|
|
|
221
|
-
const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
|
|
222
|
-
/**
|
|
223
|
-
* Determines the axis membership of a virtual list
|
|
224
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
|
|
225
|
-
* @author Evgenii Grebennikov
|
|
226
|
-
* @email djonnyx@gmail.com
|
|
227
|
-
*/
|
|
228
|
-
const isDirection = (src, expected) => {
|
|
229
|
-
if (HORIZONTAL_ALIASES.includes(expected)) {
|
|
230
|
-
return HORIZONTAL_ALIASES.includes(src);
|
|
231
|
-
}
|
|
232
|
-
return VERTICAL_ALIASES.includes(src);
|
|
233
|
-
};
|
|
234
|
-
|
|
235
222
|
/**
|
|
236
223
|
* Simple debounce function.
|
|
237
224
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/debounce.ts
|
|
@@ -279,137 +266,44 @@ const toggleClassName = (el, className, removeClassName) => {
|
|
|
279
266
|
};
|
|
280
267
|
|
|
281
268
|
/**
|
|
282
|
-
*
|
|
283
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/
|
|
269
|
+
* Scroll event.
|
|
270
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
|
|
284
271
|
* @author Evgenii Grebennikov
|
|
285
272
|
* @email djonnyx@gmail.com
|
|
286
273
|
*/
|
|
287
|
-
class
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
get
|
|
306
|
-
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
this.
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
this.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
|
|
323
|
-
let isRegularSnapped = false;
|
|
324
|
-
for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
|
|
325
|
-
const item = items[i], itemTrackingProperty = item[idPropName];
|
|
326
|
-
if (this._trackMap) {
|
|
327
|
-
if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
|
|
328
|
-
const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
|
|
329
|
-
const compId = comp?.instance?.id;
|
|
330
|
-
if (comp !== undefined && compId === diId) {
|
|
331
|
-
const indexByUntrackedItems = untrackedItems.findIndex(v => {
|
|
332
|
-
return v.instance.id === compId;
|
|
333
|
-
});
|
|
334
|
-
if (indexByUntrackedItems > -1) {
|
|
335
|
-
if (snapedComponent) {
|
|
336
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
337
|
-
isRegularSnapped = true;
|
|
338
|
-
snapedComponent.instance.item = item;
|
|
339
|
-
snapedComponent.instance.show();
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
comp.instance.item = item;
|
|
343
|
-
if (snapedComponent) {
|
|
344
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
345
|
-
comp.instance.hide();
|
|
346
|
-
}
|
|
347
|
-
else {
|
|
348
|
-
comp.instance.show();
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
comp.instance.show();
|
|
353
|
-
}
|
|
354
|
-
untrackedItems.splice(indexByUntrackedItems, 1);
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
delete this._trackMap[itemTrackingProperty];
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (untrackedItems.length > 0) {
|
|
362
|
-
const comp = untrackedItems.shift(), item = items[i];
|
|
363
|
-
if (comp) {
|
|
364
|
-
if (snapedComponent) {
|
|
365
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
366
|
-
isRegularSnapped = true;
|
|
367
|
-
snapedComponent.instance.item = item;
|
|
368
|
-
snapedComponent.instance.show();
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
comp.instance.item = item;
|
|
372
|
-
if (snapedComponent) {
|
|
373
|
-
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
374
|
-
comp.instance.hide();
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
comp.instance.show();
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
381
|
-
comp.instance.show();
|
|
382
|
-
}
|
|
383
|
-
if (this._trackMap) {
|
|
384
|
-
this._trackMap[itemTrackingProperty] = comp.instance.id;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
if (untrackedItems.length) {
|
|
390
|
-
for (let i = 0, l = untrackedItems.length; i < l; i++) {
|
|
391
|
-
const comp = untrackedItems[i];
|
|
392
|
-
comp.instance.hide();
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
if (!isRegularSnapped) {
|
|
396
|
-
if (snapedComponent) {
|
|
397
|
-
snapedComponent.instance.item = null;
|
|
398
|
-
snapedComponent.instance.hide();
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
untrackComponentByIdProperty(component) {
|
|
403
|
-
if (!component) {
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
const propertyIdName = this._trackingPropertyName;
|
|
407
|
-
if (this._trackMap && component[propertyIdName] !== undefined) {
|
|
408
|
-
delete this._trackMap[propertyIdName];
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
dispose() {
|
|
412
|
-
this._trackMap = null;
|
|
274
|
+
class ScrollEvent {
|
|
275
|
+
_direction = 1;
|
|
276
|
+
get direction() { return this._direction; }
|
|
277
|
+
_scrollSize = 0;
|
|
278
|
+
get scrollSize() { return this._scrollSize; }
|
|
279
|
+
_scrollWeight = 0;
|
|
280
|
+
get scrollWeight() { return this._scrollWeight; }
|
|
281
|
+
_isVertical = true;
|
|
282
|
+
get isVertical() { return this._isVertical; }
|
|
283
|
+
_listSize = 0;
|
|
284
|
+
get listSize() { return this._listSize; }
|
|
285
|
+
_size = 0;
|
|
286
|
+
get size() { return this._size; }
|
|
287
|
+
_isStart = true;
|
|
288
|
+
get isStart() { return this._isStart; }
|
|
289
|
+
_isEnd = false;
|
|
290
|
+
get isEnd() { return this._isEnd; }
|
|
291
|
+
_delta = 0;
|
|
292
|
+
get delta() { return this._delta; }
|
|
293
|
+
_scrollDelta = 0;
|
|
294
|
+
get scrollDelta() { return this._scrollDelta; }
|
|
295
|
+
constructor(params) {
|
|
296
|
+
const { direction, isVertical, container, list, delta, scrollDelta } = params;
|
|
297
|
+
this._direction = direction;
|
|
298
|
+
this._isVertical = isVertical;
|
|
299
|
+
this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
|
|
300
|
+
this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
|
|
301
|
+
this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
|
|
302
|
+
this._size = isVertical ? container.offsetHeight : container.offsetWidth;
|
|
303
|
+
this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
|
|
304
|
+
this._delta = delta;
|
|
305
|
+
this._scrollDelta = scrollDelta;
|
|
306
|
+
this._isStart = this._scrollSize === 0;
|
|
413
307
|
}
|
|
414
308
|
}
|
|
415
309
|
|
|
@@ -684,6 +578,168 @@ class CacheMap extends EventEmitter {
|
|
|
684
578
|
}
|
|
685
579
|
}
|
|
686
580
|
|
|
581
|
+
/**
|
|
582
|
+
* Tracks display items by property
|
|
583
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/tracker.ts
|
|
584
|
+
* @author Evgenii Grebennikov
|
|
585
|
+
* @email djonnyx@gmail.com
|
|
586
|
+
*/
|
|
587
|
+
class Tracker {
|
|
588
|
+
/**
|
|
589
|
+
* display objects dictionary of indexes by id
|
|
590
|
+
*/
|
|
591
|
+
_displayObjectIndexMapById = {};
|
|
592
|
+
set displayObjectIndexMapById(v) {
|
|
593
|
+
if (this._displayObjectIndexMapById === v) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
this._displayObjectIndexMapById = v;
|
|
597
|
+
}
|
|
598
|
+
get displayObjectIndexMapById() {
|
|
599
|
+
return this._displayObjectIndexMapById;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Dictionary displayItems propertyNameId by items propertyNameId
|
|
603
|
+
*/
|
|
604
|
+
_trackMap = {};
|
|
605
|
+
get trackMap() {
|
|
606
|
+
return this._trackMap;
|
|
607
|
+
}
|
|
608
|
+
_trackingPropertyName;
|
|
609
|
+
set trackingPropertyName(v) {
|
|
610
|
+
this._trackingPropertyName = v;
|
|
611
|
+
}
|
|
612
|
+
constructor(trackingPropertyName) {
|
|
613
|
+
this._trackingPropertyName = trackingPropertyName;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* tracking by propName
|
|
617
|
+
*/
|
|
618
|
+
track(items, components, snapedComponent, direction) {
|
|
619
|
+
if (!items) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
const idPropName = this._trackingPropertyName, untrackedItems = [...components], isDown = direction === 0 || direction === 1;
|
|
623
|
+
let isRegularSnapped = false;
|
|
624
|
+
for (let i = isDown ? 0 : items.length - 1, l = isDown ? items.length : 0; isDown ? i < l : i >= l; isDown ? i++ : i--) {
|
|
625
|
+
const item = items[i], itemTrackingProperty = item[idPropName];
|
|
626
|
+
if (this._trackMap) {
|
|
627
|
+
if (this._trackMap.hasOwnProperty(itemTrackingProperty)) {
|
|
628
|
+
const diId = this._trackMap[itemTrackingProperty], compIndex = this._displayObjectIndexMapById[diId], comp = components[compIndex];
|
|
629
|
+
const compId = comp?.instance?.id;
|
|
630
|
+
if (comp !== undefined && compId === diId) {
|
|
631
|
+
const indexByUntrackedItems = untrackedItems.findIndex(v => {
|
|
632
|
+
return v.instance.id === compId;
|
|
633
|
+
});
|
|
634
|
+
if (indexByUntrackedItems > -1) {
|
|
635
|
+
if (snapedComponent) {
|
|
636
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
637
|
+
isRegularSnapped = true;
|
|
638
|
+
snapedComponent.instance.item = item;
|
|
639
|
+
snapedComponent.instance.show();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
comp.instance.item = item;
|
|
643
|
+
if (snapedComponent) {
|
|
644
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
645
|
+
comp.instance.hide();
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
comp.instance.show();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
comp.instance.show();
|
|
653
|
+
}
|
|
654
|
+
untrackedItems.splice(indexByUntrackedItems, 1);
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
delete this._trackMap[itemTrackingProperty];
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
if (untrackedItems.length > 0) {
|
|
662
|
+
const comp = untrackedItems.shift(), item = items[i];
|
|
663
|
+
if (comp) {
|
|
664
|
+
if (snapedComponent) {
|
|
665
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
666
|
+
isRegularSnapped = true;
|
|
667
|
+
snapedComponent.instance.item = item;
|
|
668
|
+
snapedComponent.instance.show();
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
comp.instance.item = item;
|
|
672
|
+
if (snapedComponent) {
|
|
673
|
+
if (item['config']['snapped'] || item['config']['snappedOut']) {
|
|
674
|
+
comp.instance.hide();
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
comp.instance.show();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
comp.instance.show();
|
|
682
|
+
}
|
|
683
|
+
if (this._trackMap) {
|
|
684
|
+
this._trackMap[itemTrackingProperty] = comp.instance.id;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (untrackedItems.length) {
|
|
690
|
+
for (let i = 0, l = untrackedItems.length; i < l; i++) {
|
|
691
|
+
const comp = untrackedItems[i];
|
|
692
|
+
comp.instance.hide();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (!isRegularSnapped) {
|
|
696
|
+
if (snapedComponent) {
|
|
697
|
+
snapedComponent.instance.item = null;
|
|
698
|
+
snapedComponent.instance.hide();
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
untrackComponentByIdProperty(component) {
|
|
703
|
+
if (!component) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
const propertyIdName = this._trackingPropertyName;
|
|
707
|
+
if (this._trackMap && component[propertyIdName] !== undefined) {
|
|
708
|
+
delete this._trackMap[propertyIdName];
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
dispose() {
|
|
712
|
+
this._trackMap = null;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const DEFAULT_EXTRA = {
|
|
717
|
+
extremumThreshold: 2,
|
|
718
|
+
bufferSize: 10,
|
|
719
|
+
};
|
|
720
|
+
const bufferInterpolation = (currentBufferValue, array, value, extra) => {
|
|
721
|
+
const { extremumThreshold = DEFAULT_EXTRA.extremumThreshold, bufferSize = DEFAULT_EXTRA.bufferSize, } = extra ?? DEFAULT_EXTRA;
|
|
722
|
+
if (currentBufferValue < value) {
|
|
723
|
+
let i = 0;
|
|
724
|
+
while (i < extremumThreshold) {
|
|
725
|
+
array.push(value);
|
|
726
|
+
i++;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
else {
|
|
730
|
+
array.push(value);
|
|
731
|
+
}
|
|
732
|
+
while (array.length >= bufferSize) {
|
|
733
|
+
array.shift();
|
|
734
|
+
}
|
|
735
|
+
const l = array.length;
|
|
736
|
+
let buffer = 0;
|
|
737
|
+
for (let i = 0; i < l; i++) {
|
|
738
|
+
buffer += array[i];
|
|
739
|
+
}
|
|
740
|
+
return Math.ceil(buffer / l);
|
|
741
|
+
};
|
|
742
|
+
|
|
687
743
|
const TRACK_BOX_CHANGE_EVENT_NAME = 'change';
|
|
688
744
|
var ItemDisplayMethods;
|
|
689
745
|
(function (ItemDisplayMethods) {
|
|
@@ -692,6 +748,7 @@ var ItemDisplayMethods;
|
|
|
692
748
|
ItemDisplayMethods[ItemDisplayMethods["DELETE"] = 2] = "DELETE";
|
|
693
749
|
ItemDisplayMethods[ItemDisplayMethods["NOT_CHANGED"] = 3] = "NOT_CHANGED";
|
|
694
750
|
})(ItemDisplayMethods || (ItemDisplayMethods = {}));
|
|
751
|
+
const DEFAULT_BUFFER_EXTREMUM_THRESHOLD = 15, DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH = 30, DEFAULT_RESET_BUFFER_SIZE_TIMEOUT = 10000;
|
|
695
752
|
/**
|
|
696
753
|
* An object that performs tracking, calculations and caching.
|
|
697
754
|
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/trackBox.ts
|
|
@@ -732,11 +789,16 @@ class TrackBox extends CacheMap {
|
|
|
732
789
|
* Set the trackBy property
|
|
733
790
|
*/
|
|
734
791
|
set trackingPropertyName(v) {
|
|
735
|
-
this._tracker.trackingPropertyName = v;
|
|
792
|
+
this._trackingPropertyName = this._tracker.trackingPropertyName = v;
|
|
736
793
|
}
|
|
794
|
+
_trackingPropertyName = TRACK_BY_PROPERTY_NAME;
|
|
737
795
|
constructor(trackingPropertyName) {
|
|
738
796
|
super();
|
|
739
|
-
this.
|
|
797
|
+
this._trackingPropertyName = trackingPropertyName;
|
|
798
|
+
this.initialize();
|
|
799
|
+
}
|
|
800
|
+
initialize() {
|
|
801
|
+
this._tracker = new Tracker(this._trackingPropertyName);
|
|
740
802
|
}
|
|
741
803
|
set(id, bounds) {
|
|
742
804
|
if (this._map.has(id)) {
|
|
@@ -761,6 +823,16 @@ class TrackBox extends CacheMap {
|
|
|
761
823
|
_previousTotalSize = 0;
|
|
762
824
|
_scrollDelta = 0;
|
|
763
825
|
get scrollDelta() { return this._scrollDelta; }
|
|
826
|
+
isAdaptiveBuffer = true;
|
|
827
|
+
_bufferSequenceExtraThreshold = DEFAULT_BUFFER_EXTREMUM_THRESHOLD;
|
|
828
|
+
_maxBufferSequenceLength = DEFAULT_MAX_BUFFER_SEQUENCE_LENGTH;
|
|
829
|
+
_bufferSizeSequence = [];
|
|
830
|
+
_bufferSize = 0;
|
|
831
|
+
get bufferSize() { return this._bufferSize; }
|
|
832
|
+
_defaultBufferSize = 0;
|
|
833
|
+
_maxBufferSize = this._defaultBufferSize;
|
|
834
|
+
_resetBufferSizeTimeout = DEFAULT_RESET_BUFFER_SIZE_TIMEOUT;
|
|
835
|
+
_resetBufferSizeTimer;
|
|
764
836
|
lifeCircle() {
|
|
765
837
|
this.fireChangeIfNeed();
|
|
766
838
|
this.lifeCircleDo();
|
|
@@ -854,6 +926,8 @@ class TrackBox extends CacheMap {
|
|
|
854
926
|
*/
|
|
855
927
|
getItemPosition(id, stickyMap, options) {
|
|
856
928
|
const opt = { fromItemId: id, stickyMap, ...options };
|
|
929
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
930
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
857
931
|
const { scrollSize, isFromItemIdFound } = this.recalculateMetrics({
|
|
858
932
|
...opt,
|
|
859
933
|
dynamicSize: this._crudDetected || opt.dynamicSize,
|
|
@@ -871,6 +945,8 @@ class TrackBox extends CacheMap {
|
|
|
871
945
|
if (opt.dynamicSize) {
|
|
872
946
|
this.cacheElements();
|
|
873
947
|
}
|
|
948
|
+
this._defaultBufferSize = opt.bufferSize;
|
|
949
|
+
this._maxBufferSize = opt.maxBufferSize;
|
|
874
950
|
const metrics = this.recalculateMetrics({
|
|
875
951
|
...opt,
|
|
876
952
|
collection: items,
|
|
@@ -879,6 +955,7 @@ class TrackBox extends CacheMap {
|
|
|
879
955
|
deletedItemsMap,
|
|
880
956
|
});
|
|
881
957
|
this._delta += metrics.delta;
|
|
958
|
+
this.updateAdaptiveBufferParams(metrics, items.length);
|
|
882
959
|
this._previousTotalSize = metrics.totalSize;
|
|
883
960
|
this._deletedItemsMap = {};
|
|
884
961
|
this._crudDetected = false;
|
|
@@ -894,6 +971,27 @@ class TrackBox extends CacheMap {
|
|
|
894
971
|
getNearestItem(scrollSize, items, itemSize, isVertical) {
|
|
895
972
|
return this.getElementFromStart(scrollSize, items, this._map, itemSize, isVertical);
|
|
896
973
|
}
|
|
974
|
+
_previousScrollSize = 0;
|
|
975
|
+
updateAdaptiveBufferParams(metrics, totalItemsLength) {
|
|
976
|
+
this.disposeClearBufferSizeTimer();
|
|
977
|
+
const scrollSize = metrics.scrollSize + this._delta, delta = Math.abs(this._previousScrollSize - scrollSize);
|
|
978
|
+
this._previousScrollSize = scrollSize;
|
|
979
|
+
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;
|
|
980
|
+
this._bufferSize = bufferInterpolation(this._bufferSize, this._bufferSizeSequence, bufferValue, {
|
|
981
|
+
extremumThreshold: this._bufferSequenceExtraThreshold,
|
|
982
|
+
bufferSize: this._maxBufferSequenceLength,
|
|
983
|
+
});
|
|
984
|
+
this.startResetBufferSizeTimer();
|
|
985
|
+
}
|
|
986
|
+
startResetBufferSizeTimer() {
|
|
987
|
+
this._resetBufferSizeTimer = setTimeout(() => {
|
|
988
|
+
this._bufferSize = this._defaultBufferSize;
|
|
989
|
+
this._bufferSizeSequence = [];
|
|
990
|
+
}, this._resetBufferSizeTimeout);
|
|
991
|
+
}
|
|
992
|
+
disposeClearBufferSizeTimer() {
|
|
993
|
+
clearTimeout(this._resetBufferSizeTimer);
|
|
994
|
+
}
|
|
897
995
|
/**
|
|
898
996
|
* Calculates the position of an element based on the given scrollSize
|
|
899
997
|
*/
|
|
@@ -945,30 +1043,30 @@ class TrackBox extends CacheMap {
|
|
|
945
1043
|
* Calculates list metrics
|
|
946
1044
|
*/
|
|
947
1045
|
recalculateMetrics(options) {
|
|
948
|
-
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize,
|
|
949
|
-
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)
|
|
1046
|
+
const { fromItemId, bounds, collection, dynamicSize, isVertical, itemSize, bufferSize: minBufferSize, scrollSize, snap, stickyMap, enabledBufferOptimization, previousTotalSize, crudDetected, deletedItemsMap } = options;
|
|
1047
|
+
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)
|
|
950
1048
|
|| (typeof fromItemId === 'string' && fromItemId > '-1');
|
|
951
1049
|
let leftItemsOffset = 0, rightItemsOffset = 0;
|
|
952
1050
|
if (enabledBufferOptimization) {
|
|
953
1051
|
switch (this.scrollDirection) {
|
|
954
1052
|
case 1: {
|
|
955
1053
|
leftItemsOffset = 0;
|
|
956
|
-
rightItemsOffset =
|
|
1054
|
+
rightItemsOffset = bufferSize;
|
|
957
1055
|
break;
|
|
958
1056
|
}
|
|
959
1057
|
case -1: {
|
|
960
|
-
leftItemsOffset =
|
|
1058
|
+
leftItemsOffset = bufferSize;
|
|
961
1059
|
rightItemsOffset = 0;
|
|
962
1060
|
break;
|
|
963
1061
|
}
|
|
964
1062
|
case 0:
|
|
965
1063
|
default: {
|
|
966
|
-
leftItemsOffset = rightItemsOffset =
|
|
1064
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
967
1065
|
}
|
|
968
1066
|
}
|
|
969
1067
|
}
|
|
970
1068
|
else {
|
|
971
|
-
leftItemsOffset = rightItemsOffset =
|
|
1069
|
+
leftItemsOffset = rightItemsOffset = bufferSize;
|
|
972
1070
|
}
|
|
973
1071
|
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;
|
|
974
1072
|
// If the list is dynamic or there are new elements in the collection, then it switches to the long algorithm.
|
|
@@ -1143,9 +1241,9 @@ class TrackBox extends CacheMap {
|
|
|
1143
1241
|
}
|
|
1144
1242
|
itemsFromStartToScrollEnd = Math.floor(scrollSize / typicalItemSize);
|
|
1145
1243
|
itemsFromStartToDisplayEnd = Math.ceil((scrollSize + size) / typicalItemSize);
|
|
1146
|
-
leftItemLength = Math.min(itemsFromStartToScrollEnd,
|
|
1147
|
-
rightItemLength = itemsFromStartToDisplayEnd +
|
|
1148
|
-
? totalLength - itemsFromStartToDisplayEnd :
|
|
1244
|
+
leftItemLength = Math.min(itemsFromStartToScrollEnd, bufferSize);
|
|
1245
|
+
rightItemLength = itemsFromStartToDisplayEnd + bufferSize > totalLength
|
|
1246
|
+
? totalLength - itemsFromStartToDisplayEnd : bufferSize;
|
|
1149
1247
|
leftItemsWeight = leftItemLength * typicalItemSize;
|
|
1150
1248
|
rightItemsWeight = rightItemLength * typicalItemSize;
|
|
1151
1249
|
leftHiddenItemsWeight = itemsFromStartToScrollEnd * typicalItemSize;
|
|
@@ -1242,6 +1340,9 @@ class TrackBox extends CacheMap {
|
|
|
1242
1340
|
if (snap) {
|
|
1243
1341
|
const startIndex = itemsFromStartToScrollEnd + itemsOnDisplayLength - 1;
|
|
1244
1342
|
for (let i = Math.min(startIndex, totalLength > 0 ? totalLength - 1 : 0), l = totalLength; i < l; i++) {
|
|
1343
|
+
if (!items[i]) {
|
|
1344
|
+
continue;
|
|
1345
|
+
}
|
|
1245
1346
|
const id = items[i].id, sticky = stickyMap[id], size = dynamicSize
|
|
1246
1347
|
? this.get(id)?.[sizeProperty] || typicalItemSize
|
|
1247
1348
|
: typicalItemSize;
|
|
@@ -1276,6 +1377,9 @@ class TrackBox extends CacheMap {
|
|
|
1276
1377
|
if (i >= totalLength) {
|
|
1277
1378
|
break;
|
|
1278
1379
|
}
|
|
1380
|
+
if (!items[i]) {
|
|
1381
|
+
continue;
|
|
1382
|
+
}
|
|
1279
1383
|
const id = items[i].id, size = dynamicSize ? this.get(id)?.[sizeProperty] || typicalItemSize : typicalItemSize;
|
|
1280
1384
|
if (id !== stickyItem?.id && id !== endStickyItem?.id) {
|
|
1281
1385
|
const snapped = snap && (stickyMap[id] === 1 && pos <= scrollSize || stickyMap[id] === 2 && pos >= scrollSize + boundsSize - size), measures = {
|
|
@@ -1387,54 +1491,13 @@ class TrackBox extends CacheMap {
|
|
|
1387
1491
|
}
|
|
1388
1492
|
dispose() {
|
|
1389
1493
|
super.dispose();
|
|
1494
|
+
this.disposeClearBufferSizeTimer();
|
|
1390
1495
|
if (this._tracker) {
|
|
1391
1496
|
this._tracker.dispose();
|
|
1392
1497
|
}
|
|
1393
1498
|
}
|
|
1394
1499
|
}
|
|
1395
1500
|
|
|
1396
|
-
/**
|
|
1397
|
-
* Scroll event.
|
|
1398
|
-
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/scrollEvent.ts
|
|
1399
|
-
* @author Evgenii Grebennikov
|
|
1400
|
-
* @email djonnyx@gmail.com
|
|
1401
|
-
*/
|
|
1402
|
-
class ScrollEvent {
|
|
1403
|
-
_direction = 1;
|
|
1404
|
-
get direction() { return this._direction; }
|
|
1405
|
-
_scrollSize = 0;
|
|
1406
|
-
get scrollSize() { return this._scrollSize; }
|
|
1407
|
-
_scrollWeight = 0;
|
|
1408
|
-
get scrollWeight() { return this._scrollWeight; }
|
|
1409
|
-
_isVertical = true;
|
|
1410
|
-
get isVertical() { return this._isVertical; }
|
|
1411
|
-
_listSize = 0;
|
|
1412
|
-
get listSize() { return this._listSize; }
|
|
1413
|
-
_size = 0;
|
|
1414
|
-
get size() { return this._size; }
|
|
1415
|
-
_isStart = true;
|
|
1416
|
-
get isStart() { return this._isStart; }
|
|
1417
|
-
_isEnd = false;
|
|
1418
|
-
get isEnd() { return this._isEnd; }
|
|
1419
|
-
_delta = 0;
|
|
1420
|
-
get delta() { return this._delta; }
|
|
1421
|
-
_scrollDelta = 0;
|
|
1422
|
-
get scrollDelta() { return this._scrollDelta; }
|
|
1423
|
-
constructor(params) {
|
|
1424
|
-
const { direction, isVertical, container, list, delta, scrollDelta } = params;
|
|
1425
|
-
this._direction = direction;
|
|
1426
|
-
this._isVertical = isVertical;
|
|
1427
|
-
this._scrollSize = isVertical ? container.scrollTop : container.scrollLeft;
|
|
1428
|
-
this._scrollWeight = isVertical ? container.scrollHeight : container.scrollWidth;
|
|
1429
|
-
this._listSize = isVertical ? list.offsetHeight : list.offsetWidth;
|
|
1430
|
-
this._size = isVertical ? container.offsetHeight : container.offsetWidth;
|
|
1431
|
-
this._isEnd = (this._scrollSize + this._size) === this._scrollWeight;
|
|
1432
|
-
this._delta = delta;
|
|
1433
|
-
this._scrollDelta = scrollDelta;
|
|
1434
|
-
this._isStart = this._scrollSize === 0;
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
1501
|
const ADVANCED_PATTERNS = [SnappingMethods.ADVANCED, 'advanced'], DEFAULT_PATTERN = [SnappingMethods.NORMAL, 'normal'];
|
|
1439
1502
|
const isSnappingMethodAdvenced = (method) => {
|
|
1440
1503
|
return ADVANCED_PATTERNS.includes(method);
|
|
@@ -1446,6 +1509,20 @@ const isSnappingMethodDefault = (method) => {
|
|
|
1446
1509
|
const IS_FIREFOX = navigator.userAgent.toLowerCase().includes('firefox');
|
|
1447
1510
|
const FIREFOX_SCROLLBAR_OVERLAP_SIZE = 12;
|
|
1448
1511
|
|
|
1512
|
+
const HORIZONTAL_ALIASES = [Directions.HORIZONTAL, 'horizontal'], VERTICAL_ALIASES = [Directions.VERTICAL, 'vertical'];
|
|
1513
|
+
/**
|
|
1514
|
+
* Determines the axis membership of a virtual list
|
|
1515
|
+
* @link https://github.com/DjonnyX/ng-virtual-list/blob/17.x/projects/ng-virtual-list/src/lib/utils/isDirection.ts
|
|
1516
|
+
* @author Evgenii Grebennikov
|
|
1517
|
+
* @email djonnyx@gmail.com
|
|
1518
|
+
*/
|
|
1519
|
+
const isDirection = (src, expected) => {
|
|
1520
|
+
if (HORIZONTAL_ALIASES.includes(expected)) {
|
|
1521
|
+
return HORIZONTAL_ALIASES.includes(src);
|
|
1522
|
+
}
|
|
1523
|
+
return VERTICAL_ALIASES.includes(src);
|
|
1524
|
+
};
|
|
1525
|
+
|
|
1449
1526
|
/**
|
|
1450
1527
|
* Virtual list component.
|
|
1451
1528
|
* Maximum performance for extremely large lists.
|
|
@@ -1530,10 +1607,35 @@ class NgVirtualListComponent {
|
|
|
1530
1607
|
* Determines the direction in which elements are placed. Default value is "vertical".
|
|
1531
1608
|
*/
|
|
1532
1609
|
direction = input(DEFAULT_DIRECTION);
|
|
1610
|
+
_itemOffsetTransform = {
|
|
1611
|
+
transform: (v) => {
|
|
1612
|
+
throw Error('"itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".');
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
/**
|
|
1616
|
+
* Number of elements outside the scope of visibility. Default value is 2.
|
|
1617
|
+
* @deprecated "itemOffset" parameter is deprecated. Use "bufferSize" and "maxBufferSize".
|
|
1618
|
+
*/
|
|
1619
|
+
itemsOffset = input(DEFAULT_BUFFER_SIZE, { ...this._itemOffsetTransform });
|
|
1533
1620
|
/**
|
|
1534
1621
|
* Number of elements outside the scope of visibility. Default value is 2.
|
|
1535
1622
|
*/
|
|
1536
|
-
|
|
1623
|
+
bufferSize = input(DEFAULT_BUFFER_SIZE);
|
|
1624
|
+
_maxBufferSizeTransform = {
|
|
1625
|
+
transform: (v) => {
|
|
1626
|
+
const bufferSize = this.bufferSize();
|
|
1627
|
+
if (v === undefined || v <= bufferSize) {
|
|
1628
|
+
return bufferSize;
|
|
1629
|
+
}
|
|
1630
|
+
return v;
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
/**
|
|
1634
|
+
* Maximum number of elements outside the scope of visibility. Default value is 100.
|
|
1635
|
+
* If maxBufferSize is set to be greater than bufferSize, then adaptive buffer mode is enabled.
|
|
1636
|
+
* The greater the scroll size, the more elements are allocated for rendering.
|
|
1637
|
+
*/
|
|
1638
|
+
maxBufferSize = input(DEFAULT_MAX_BUFFER_SIZE, { ...this._maxBufferSizeTransform });
|
|
1537
1639
|
/**
|
|
1538
1640
|
* Snapping method.
|
|
1539
1641
|
* 'default' - Normal group rendering.
|
|
@@ -1637,7 +1739,7 @@ class NgVirtualListComponent {
|
|
|
1637
1739
|
$trackBy.pipe(takeUntilDestroyed(), tap(v => {
|
|
1638
1740
|
this._trackBox.trackingPropertyName = v;
|
|
1639
1741
|
})).subscribe();
|
|
1640
|
-
const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $
|
|
1742
|
+
const $bounds = toObservable(this._bounds).pipe(filter(b => !!b)), $items = toObservable(this.items).pipe(map(i => !i ? [] : i)), $scrollSize = toObservable(this._scrollSize), $itemSize = toObservable(this.itemSize).pipe(map(v => v <= 0 ? DEFAULT_ITEM_SIZE : v)), $bufferSize = toObservable(this.bufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $maxBufferSize = toObservable(this.maxBufferSize).pipe(map(v => v < 0 ? DEFAULT_BUFFER_SIZE : v)), $stickyMap = toObservable(this.stickyMap).pipe(map(v => !v ? {} : v)), $snap = toObservable(this.snap), $isVertical = toObservable(this.direction).pipe(map(v => this.getIsVertical(v || DEFAULT_DIRECTION))), $dynamicSize = toObservable(this.dynamicSize), $enabledBufferOptimization = toObservable(this.enabledBufferOptimization), $snappingMethod = toObservable(this.snappingMethod).pipe(map(v => this.getIsSnappingMethodAdvanced(v || DEFAULT_SNAPPING_METHOD))), $cacheVersion = toObservable(this._cacheVersion);
|
|
1641
1743
|
$isVertical.pipe(takeUntilDestroyed(), tap(v => {
|
|
1642
1744
|
this._isVertical = v;
|
|
1643
1745
|
const el = this._elementRef.nativeElement;
|
|
@@ -1650,12 +1752,12 @@ class NgVirtualListComponent {
|
|
|
1650
1752
|
this.listenCacheChangesIfNeed(dynamicSize);
|
|
1651
1753
|
})).subscribe();
|
|
1652
1754
|
combineLatest([this.$initialized, $bounds, $items, $stickyMap, $scrollSize, $itemSize,
|
|
1653
|
-
$
|
|
1654
|
-
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize,
|
|
1755
|
+
$bufferSize, $maxBufferSize, $snap, $isVertical, $dynamicSize, $enabledBufferOptimization, $cacheVersion,
|
|
1756
|
+
]).pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(([initialized]) => !!initialized), switchMap(([, bounds, items, stickyMap, scrollSize, itemSize, bufferSize, maxBufferSize, snap, isVertical, dynamicSize, enabledBufferOptimization, cacheVersion,]) => {
|
|
1655
1757
|
let actualScrollSize = (this._isVertical ? this._container()?.nativeElement.scrollTop ?? 0 : this._container()?.nativeElement.scrollLeft) ?? 0;
|
|
1656
1758
|
const { width, height } = bounds, opts = {
|
|
1657
1759
|
bounds: { width, height }, dynamicSize, isVertical, itemSize,
|
|
1658
|
-
|
|
1760
|
+
bufferSize, maxBufferSize, scrollSize: actualScrollSize, snap, enabledBufferOptimization,
|
|
1659
1761
|
}, { displayItems, totalSize } = this._trackBox.updateCollection(items, stickyMap, opts);
|
|
1660
1762
|
this.resetBoundsSize(isVertical, totalSize);
|
|
1661
1763
|
this.createDisplayComponentsIfNeed(displayItems);
|
|
@@ -1678,9 +1780,6 @@ class NgVirtualListComponent {
|
|
|
1678
1780
|
}
|
|
1679
1781
|
return of(displayItems);
|
|
1680
1782
|
})).subscribe();
|
|
1681
|
-
this.setupRenderer();
|
|
1682
|
-
}
|
|
1683
|
-
setupRenderer() {
|
|
1684
1783
|
const $itemRenderer = toObservable(this.itemRenderer);
|
|
1685
1784
|
$itemRenderer.pipe(takeUntilDestroyed(), distinctUntilChanged(), filter(v => !!v), tap(v => {
|
|
1686
1785
|
this._itemRenderer.set(v);
|
|
@@ -1802,7 +1901,8 @@ class NgVirtualListComponent {
|
|
|
1802
1901
|
}
|
|
1803
1902
|
const { width, height } = this._bounds() || { width: DEFAULT_LIST_SIZE, height: DEFAULT_LIST_SIZE }, stickyMap = this.stickyMap(), items = this.items(), isVertical = this._isVertical, delta = this._trackBox.delta, opts = {
|
|
1804
1903
|
bounds: { width, height }, collection: items, dynamicSize, isVertical: this._isVertical, itemSize,
|
|
1805
|
-
|
|
1904
|
+
bufferSize: this.bufferSize(), maxBufferSize: this.maxBufferSize(),
|
|
1905
|
+
scrollSize: (isVertical ? container.nativeElement.scrollTop : container.nativeElement.scrollLeft) + delta,
|
|
1806
1906
|
snap: this.snap(), fromItemId: id, enabledBufferOptimization: this.enabledBufferOptimization(),
|
|
1807
1907
|
}, scrollSize = this._trackBox.getItemPosition(id, stickyMap, opts), params = { [isVertical ? TOP_PROP_NAME : LEFT_PROP_NAME]: scrollSize, behavior };
|
|
1808
1908
|
if (scrollSize === -1) {
|
|
@@ -1933,7 +2033,7 @@ class NgVirtualListComponent {
|
|
|
1933
2033
|
}
|
|
1934
2034
|
}
|
|
1935
2035
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgVirtualListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1936
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, stickyMap: { classPropertyName: "stickyMap", publicName: "stickyMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, itemsOffset: { classPropertyName: "itemsOffset", publicName: "itemsOffset", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n<div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n}\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"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
2036
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: NgVirtualListComponent, selector: "ng-virtual-list", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, snap: { classPropertyName: "snap", publicName: "snap", isSignal: true, isRequired: false, transformFunction: null }, enabledBufferOptimization: { classPropertyName: "enabledBufferOptimization", publicName: "enabledBufferOptimization", isSignal: true, isRequired: false, transformFunction: null }, itemRenderer: { classPropertyName: "itemRenderer", publicName: "itemRenderer", isSignal: true, isRequired: true, transformFunction: null }, stickyMap: { classPropertyName: "stickyMap", publicName: "stickyMap", isSignal: true, isRequired: false, transformFunction: null }, itemSize: { classPropertyName: "itemSize", publicName: "itemSize", isSignal: true, isRequired: false, transformFunction: null }, dynamicSize: { classPropertyName: "dynamicSize", publicName: "dynamicSize", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, itemsOffset: { classPropertyName: "itemsOffset", publicName: "itemsOffset", isSignal: true, isRequired: false, transformFunction: null }, bufferSize: { classPropertyName: "bufferSize", publicName: "bufferSize", isSignal: true, isRequired: false, transformFunction: null }, maxBufferSize: { classPropertyName: "maxBufferSize", publicName: "maxBufferSize", isSignal: true, isRequired: false, transformFunction: null }, snappingMethod: { classPropertyName: "snappingMethod", publicName: "snappingMethod", isSignal: true, isRequired: false, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onScroll: "onScroll", onScrollEnd: "onScrollEnd" }, viewQueries: [{ propertyName: "_snappedContainer", first: true, predicate: ["snapped"], descendants: true, isSignal: true }, { propertyName: "_container", first: true, predicate: ["container"], descendants: true, isSignal: true }, { propertyName: "_list", first: true, predicate: ["list"], descendants: true, isSignal: true }, { propertyName: "_listContainerRef", first: true, predicate: ["renderersContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "_snapContainerRef", first: true, predicate: ["snapRendererContainer"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "@if (snap()) {\r\n<div #snapped part=\"snapped-item\" class=\"ngvl__list-snapper\">\r\n <ng-container #snapRendererContainer></ng-container>\r\n</div>\r\n}\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"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom });
|
|
1937
2037
|
}
|
|
1938
2038
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgVirtualListComponent, decorators: [{
|
|
1939
2039
|
type: Component,
|
|
@@ -1969,5 +2069,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1969
2069
|
* Generated bundle index. Do not edit.
|
|
1970
2070
|
*/
|
|
1971
2071
|
|
|
1972
|
-
export {
|
|
2072
|
+
export { Directions, NgVirtualListComponent, NgVirtualListItemComponent, NgVirtualListModule, ScrollEvent, SnappingMethods, debounce, toggleClassName };
|
|
1973
2073
|
//# sourceMappingURL=ng-virtual-list.mjs.map
|