UNPKG

ng-mat-select-infinite-scroll

Version:

Adds missing infinite scroll functionality for the angular material select component

148 lines (141 loc) 7.24 kB
import * as i0 from '@angular/core'; import { Injectable, EventEmitter, Directive, Input, Output, NgModule } from '@angular/core'; import { takeUntil, debounceTime, tap, delay } from 'rxjs/operators'; import { Subject, fromEvent } from 'rxjs'; import * as i1 from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select'; class InfiniteScrollService { constructor(ngZone) { this.ngZone = ngZone; this.threshold = '15%'; this.debounceTime = 150; this.thrPx = 0; this.thrPc = 0; this.destroyed$ = new Subject(); } initialize(panel, selectItemHeightPx, config) { this.threshold = config.threshold; this.debounceTime = config.debounceTime; this.complete = config.complete; this.panel = panel; this.selectItemHeightPx = selectItemHeightPx; this.evaluateThreshold(); } 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(infiniteScrollCallback) { fromEvent(this.panel, 'scroll').pipe(takeUntil(this.destroyed$), debounceTime(this.debounceTime), tap((event) => { this.handleScrollEvent(event, infiniteScrollCallback); })).subscribe(); } handleScrollEvent(event, infiniteScrollCallback) { this.ngZone.runOutsideAngular(() => { if (this.complete) { return; } const countOfRenderedOptions = Math.round(this.panel.scrollHeight / this.selectItemHeightPx); const infiniteScrollDistance = this.selectItemHeightPx * 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(infiniteScrollCallback); } }); } destroy() { this.destroyed$.next(); this.destroyed$.complete(); } } InfiniteScrollService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InfiniteScrollService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); InfiniteScrollService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InfiniteScrollService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InfiniteScrollService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i0.NgZone }]; } }); /** The height of the select items in `em` units. */ const SELECT_ITEM_HEIGHT_EM = 3; class MatSelectInfiniteScrollDirective { constructor(matSelect, infiniteScrollService) { this.matSelect = matSelect; this.infiniteScrollService = infiniteScrollService; this.threshold = '15%'; this.debounceTime = 150; this.infiniteScroll = new EventEmitter(); this.destroyed$ = new Subject(); } ngAfterViewInit() { this.matSelect.openedChange.pipe( //Wait for the panel to be rendered (https://github.com/angular/components/issues/30596) delay(0), takeUntil(this.destroyed$)).subscribe((opened) => { if (opened) { const panel = this.matSelect.panel.nativeElement; const selectItemHeightPx = this.getSelectItemHeightPx(panel); this.infiniteScrollService.initialize(panel, selectItemHeightPx, { threshold: this.threshold, debounceTime: this.debounceTime, complete: this.complete }); this.infiniteScrollService.registerScrollListener(() => this.infiniteScroll.emit()); } }); } getSelectItemHeightPx(panel) { return parseFloat(getComputedStyle(panel).fontSize) * SELECT_ITEM_HEIGHT_EM; } ngOnDestroy() { this.destroyed$.next(true); this.destroyed$.complete(); this.infiniteScrollService.destroy(); } } MatSelectInfiniteScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollDirective, deps: [{ token: i1.MatSelect }, { token: InfiniteScrollService }], target: i0.ɵɵFactoryTarget.Directive }); MatSelectInfiniteScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: MatSelectInfiniteScrollDirective, selector: "[msInfiniteScroll]", inputs: { threshold: "threshold", debounceTime: "debounceTime", complete: "complete" }, outputs: { infiniteScroll: "infiniteScroll" }, providers: [InfiniteScrollService], ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollDirective, decorators: [{ type: Directive, args: [{ selector: '[msInfiniteScroll]', providers: [InfiniteScrollService] }] }], ctorParameters: function () { return [{ type: i1.MatSelect }, { type: InfiniteScrollService }]; }, propDecorators: { threshold: [{ type: Input }], debounceTime: [{ type: Input }], complete: [{ type: Input }], infiniteScroll: [{ type: Output }] } }); class MatSelectInfiniteScrollModule { } MatSelectInfiniteScrollModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); MatSelectInfiniteScrollModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollModule, declarations: [MatSelectInfiniteScrollDirective], imports: [MatSelectModule], exports: [MatSelectInfiniteScrollDirective] }); MatSelectInfiniteScrollModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollModule, imports: [MatSelectModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MatSelectInfiniteScrollModule, decorators: [{ type: NgModule, args: [{ declarations: [MatSelectInfiniteScrollDirective], imports: [ MatSelectModule, ], exports: [MatSelectInfiniteScrollDirective] }] }] }); /* * Public API Surface of ng-mat-select-infinite-scroll */ /** * Generated bundle index. Do not edit. */ export { MatSelectInfiniteScrollDirective, MatSelectInfiniteScrollModule }; //# sourceMappingURL=ng-mat-select-infinite-scroll.mjs.map