ngx-lazy-mat-select
Version:
Lazy load for mat-select
84 lines • 10.9 kB
JavaScript
import { Directive, EventEmitter, Input, Output } from '@angular/core';
import { Subject, debounceTime, fromEvent, takeUntil, tap } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/select";
/** The height of the select items in `em` units. */
const SELECT_ITEM_HEIGHT_EM = 3;
export class NgxLazyMatSelectDirective {
constructor(matSelect, ngZone) {
this.matSelect = matSelect;
this.ngZone = ngZone;
this.threshold = '15%';
this.debounceTime = 150;
this.infiniteScroll = new EventEmitter();
this.thrPx = 0;
this.thrPc = 0;
this.singleOptionHeight = SELECT_ITEM_HEIGHT_EM;
this.destroyed$ = new Subject();
}
ngOnInit() {
this.evaluateThreshold();
}
ngAfterViewInit() {
this.matSelect.openedChange.pipe(takeUntil(this.destroyed$)).subscribe((opened) => {
if (opened) {
this.panel = this.matSelect.panel.nativeElement;
this.singleOptionHeight = this.getSelectItemHeightPx();
this.registerScrollListener();
}
});
}
ngOnDestroy() {
this.destroyed$.next(true);
this.destroyed$.complete();
}
evaluateThreshold() {
if (this.threshold.lastIndexOf('%') > -1) {
this.thrPx = 0;
this.thrPc = (parseFloat(this.threshold) / 100);
}
else {
this.thrPx = parseFloat(this.threshold);
this.thrPc = 0;
}
}
registerScrollListener() {
fromEvent(this.panel, 'scroll').pipe(takeUntil(this.destroyed$), debounceTime(this.debounceTime), tap((event) => {
this.handleScrollEvent(event);
})).subscribe();
}
handleScrollEvent(event) {
this.ngZone.runOutsideAngular(() => {
if (this.complete) {
return;
}
const countOfRenderedOptions = this.matSelect.options.length;
const infiniteScrollDistance = this.singleOptionHeight * countOfRenderedOptions;
const threshold = this.thrPc !== 0 ? (infiniteScrollDistance * this.thrPc) : this.thrPx;
const scrolledDistance = this.panel.clientHeight + event.target.scrollTop;
if ((scrolledDistance + threshold) >= infiniteScrollDistance) {
this.ngZone.run(() => this.infiniteScroll.emit());
}
});
}
getSelectItemHeightPx() {
return parseFloat(getComputedStyle(this.panel).fontSize) * SELECT_ITEM_HEIGHT_EM;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgxLazyMatSelectDirective, deps: [{ token: i1.MatSelect }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgxLazyMatSelectDirective, selector: "[ngxLazyMatSelect]", inputs: { threshold: "threshold", debounceTime: "debounceTime", complete: "complete" }, outputs: { infiniteScroll: "infiniteScroll" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgxLazyMatSelectDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngxLazyMatSelect]'
}]
}], ctorParameters: function () { return [{ type: i1.MatSelect }, { type: i0.NgZone }]; }, propDecorators: { threshold: [{
type: Input
}], debounceTime: [{
type: Input
}], complete: [{
type: Input
}], infiniteScroll: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWxhenktbWF0LXNlbGVjdC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbGF6eS1tYXQtc2VsZWN0L3NyYy9saWIvbmd4LWxhenktbWF0LXNlbGVjdC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7O0FBRXhFLG9EQUFvRDtBQUNwRCxNQUFNLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUtoQyxNQUFNLE9BQU8seUJBQXlCO0lBY3BDLFlBQW9CLFNBQW9CLEVBQVUsTUFBYztRQUE1QyxjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQVUsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVp2RCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGlCQUFZLEdBQUcsR0FBRyxDQUFDO1FBRWxCLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUc1QyxVQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsVUFBSyxHQUFHLENBQUMsQ0FBQztRQUNWLHVCQUFrQixHQUFHLHFCQUFxQixDQUFDO1FBRTNDLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO0lBRzVDLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQzlCLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQzNCLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDckIsSUFBSSxN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aEIsS0FBSztnQkFDSSxjQUFjO3NCQUF2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIElucHV0LCBOZ1pvbmUsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcbmltcG9ydCB7IFN1YmplY3QsIGRlYm91bmNlVGltZSwgZnJvbUV2ZW50LCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMnO1xuXG4vKiogVGhlIGhlaWdodCBvZiB0aGUgc2VsZWN0IGl0ZW1zIGluIGBlbWAgdW5pdHMuICovXG5jb25zdCBTRUxFQ1RfSVRFTV9IRUlHSFRfRU0gPSAzO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbmd4TGF6eU1hdFNlbGVjdF0nXG59KVxuZXhwb3J0IGNsYXNzIE5neExhenlNYXRTZWxlY3REaXJlY3RpdmUge1xuXG4gIEBJbnB1dCgpIHRocmVzaG9sZCA9ICcxNSUnO1xuICBASW5wdXQoKSBkZWJvdW5jZVRpbWUgPSAxNTA7XG4gIEBJbnB1dCgpIGNvbXBsZXRlITogYm9vbGVhbjtcbiAgQE91dHB1dCgpIGluZmluaXRlU2Nyb2xsID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByaXZhdGUgcGFuZWwhOiBFbGVtZW50O1xuICBwcml2YXRlIHRoclB4ID0gMDtcbiAgcHJpdmF0ZSB0aHJQYyA9IDA7XG4gIHByaXZhdGUgc2luZ2xlT3B0aW9uSGVpZ2h0ID0gU0VMRUNUX0lURU1fSEVJR0hUX0VNO1xuXG4gIHByaXZhdGUgZGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBtYXRTZWxlY3Q6IE1hdFNlbGVjdCwgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkge1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5ldmFsdWF0ZVRocmVzaG9sZCgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMubWF0U2VsZWN0Lm9wZW5lZENoYW5nZS5waXBlKFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJClcbiAgICApLnN1YnNjcmliZSgob3BlbmVkKSA9PiB7XG4gICAgICBpZiAob3BlbmVkKSB7XG4gICAgICAgIHRoaXMucGFuZWwgPSB0aGlzLm1hdFNlbGVjdC5wYW5lbC5uYXRpdmVFbGVtZW50O1xuICAgICAgICB0aGlzLnNpbmdsZU9wdGlvbkhlaWdodCA9IHRoaXMuZ2V0U2VsZWN0SXRlbUhlaWdodFB4KCk7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJTY3JvbGxMaXN0ZW5lcigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95ZWQkLm5leHQodHJ1ZSk7XG4gICAgdGhpcy5kZXN0cm95ZWQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBldmFsdWF0ZVRocmVzaG9sZCgpIHtcbiAgICBpZiAodGhpcy50aHJlc2hvbGQubGFzdEluZGV4T2YoJyUnKSA+IC0xKSB7XG4gICAgICB0aGlzLnRoclB4ID0gMDtcbiAgICAgIHRoaXMudGhyUGMgPSAocGFyc2VGbG9hdCh0aGlzLnRocmVzaG9sZCkgLyAxMDApO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhyUHggPSBwYXJzZUZsb2F0KHRoaXMudGhyZXNob2xkKTtcbiAgICAgIHRoaXMudGhyUGMgPSAwO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyU2Nyb2xsTGlzdGVuZXIoKSB7XG4gICAgZnJvbUV2ZW50KHRoaXMucGFuZWwsICdzY3JvbGwnKS5waXBlKFxuICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveWVkJCksXG4gICAgICBkZWJvdW5jZVRpbWUodGhpcy5kZWJvdW5jZVRpbWUpLFxuICAgICAgdGFwKChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLmhhbmRsZVNjcm9sbEV2ZW50KGV2ZW50KTtcbiAgICAgIH0pXG4gICAgKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGhhbmRsZVNjcm9sbEV2ZW50KGV2ZW50OiBhbnkpIHtcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5jb21wbGV0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBjb3VudE9mUmVuZGVyZWRPcHRpb25zID0gdGhpcy5tYXRTZWxlY3Qub3B0aW9ucy5sZW5ndGg7XG4gICAgICBjb25zdCBpbmZpbml0ZVNjcm9sbERpc3RhbmNlID0gdGhpcy5zaW5nbGVPcHRpb25IZWlnaHQgKiBjb3VudE9mUmVuZGVyZWRPcHRpb25zO1xuICAgICAgY29uc3QgdGhyZXNob2xkID0gdGhpcy50aHJQYyAhPT0gMCA/IChpbmZpbml0ZVNjcm9sbERpc3RhbmNlICogdGhpcy50aHJQYykgOiB0aGlzLnRoclB4O1xuXG4gICAgICBjb25zdCBzY3JvbGxlZERpc3RhbmNlID0gdGhpcy5wYW5lbC5jbGllbnRIZWlnaHQgKyBldmVudC50YXJnZXQuc2Nyb2xsVG9wO1xuXG4gICAgICBpZiAoKHNjcm9sbGVkRGlzdGFuY2UgKyB0aHJlc2hvbGQpID49IGluZmluaXRlU2Nyb2xsRGlzdGFuY2UpIHtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuaW5maW5pdGVTY3JvbGwuZW1pdCgpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldFNlbGVjdEl0ZW1IZWlnaHRQeCgpOiBudW1iZXIge1xuICAgIHJldHVybiBwYXJzZUZsb2F0KGdldENvbXB1dGVkU3R5bGUodGhpcy5wYW5lbCkuZm9udFNpemUpICogU0VMRUNUX0lURU1fSEVJR0hUX0VNO1xuICB9XG5cbn1cbiJdfQ==