UNPKG

@thejlifex/ngx-scroll-spy

Version:

An Angular library that can spy the position of elements (inside a scrollable container) and emit the currently active (visible) element in the viewport.

68 lines 8.69 kB
import { isPlatformServer } from '@angular/common'; import { Directive, Input, HostBinding, Inject, PLATFORM_ID } from '@angular/core'; import { filter, Subject, takeUntil } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "./scroll-spy.service"; /** * Spies on the spyTarget that has the provided `spyTargetId`. */ export class SpyDirective { constructor(scrollSpyService, platformId, changeDetectorRef) { this.scrollSpyService = scrollSpyService; this.platformId = platformId; this.changeDetectorRef = changeDetectorRef; /** * Class name to add to this element when the spyTarget has transitioned into a state of intersection (is visisble). * * @default * 'active' */ this.spyActiveClass = 'active'; this.directiveDestroyed$ = new Subject(); } ngOnInit() { if (isPlatformServer(this.platformId)) { return; } if (!this.spyTargetId) { throw new Error('SpyDirective: spyTargetId needs to be set.'); } this.scrollSpyService.getSpyTargetIsIntersecting$(this.spyTargetContainerId) .pipe(takeUntil(this.directiveDestroyed$), filter((event) => event.spyTarget.id === this.spyTargetId && event.spyTarget.containerId === this.spyTargetContainerId)) .subscribe((event) => { this.activeClassInDOM = event.isIntersecting ? this.spyActiveClass : undefined; /** * Manually trigger change detection to update activeClass in the DOM * (Needed for the case changeDetection OnPush is used). */ this.changeDetectorRef.detectChanges(); }); } ngOnDestroy() { this.directiveDestroyed$.next(); this.directiveDestroyed$.complete(); } } SpyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.4", ngImport: i0, type: SpyDirective, deps: [{ token: i1.ScrollSpyService }, { token: PLATFORM_ID }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); SpyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.4", type: SpyDirective, isStandalone: true, selector: "[spy]", inputs: { spyTargetId: "spyTargetId", spyTargetContainerId: "spyTargetContainerId", spyActiveClass: "spyActiveClass" }, host: { properties: { "class": "this.activeClassInDOM" } }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.4", ngImport: i0, type: SpyDirective, decorators: [{ type: Directive, args: [{ selector: '[spy]', standalone: true }] }], ctorParameters: function () { return [{ type: i1.ScrollSpyService }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { spyTargetId: [{ type: Input }], spyTargetContainerId: [{ type: Input }], spyActiveClass: [{ type: Input }], activeClassInDOM: [{ type: HostBinding, args: ['class'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3B5LmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zY3JvbGwtc3B5L3NyYy9saWIvc3B5LmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsV0FBVyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBQ3pILE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7O0FBR2xEOztHQUVHO0FBS0gsTUFBTSxPQUFPLFlBQVk7SUEwQnZCLFlBQ1UsZ0JBQWtDLEVBQ2IsVUFBa0IsRUFDdkMsaUJBQW9DO1FBRnBDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDYixlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ3ZDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFmOUM7Ozs7O1dBS0c7UUFDTSxtQkFBYyxHQUFXLFFBQVEsQ0FBQztRQUluQyx3QkFBbUIsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO0lBTTlDLENBQUM7SUFFTCxRQUFRO1FBQ04sSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDckMsT0FBTztTQUNSO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1NBQy9EO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQzthQUN6RSxJQUFJLENBQ0gsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUNuQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNmLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxXQUFXO2VBQ3BDLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxvQkFBb0IsQ0FDN0QsQ0FDRjthQUNBLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ25CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDL0U7OztlQUdHO1lBQ0gsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3RDLENBQUM7O3lHQTVEVSxZQUFZLGtEQTRCYixXQUFXOzZGQTVCVixZQUFZOzJGQUFaLFlBQVk7a0JBSnhCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjs7MEJBNkJJLE1BQU07MkJBQUMsV0FBVzs0RUF2QlosV0FBVztzQkFBbkIsS0FBSztnQkFPRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBUUcsY0FBYztzQkFBdEIsS0FBSztnQkFFZ0IsZ0JBQWdCO3NCQUFyQyxXQUFXO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc1BsYXRmb3JtU2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgRGlyZWN0aXZlLCBJbnB1dCwgT25Jbml0LCBPbkRlc3Ryb3ksIEhvc3RCaW5kaW5nLCBJbmplY3QsIFBMQVRGT1JNX0lELCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBTY3JvbGxTcHlTZXJ2aWNlIH0gZnJvbSAnLi9zY3JvbGwtc3B5LnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNwaWVzIG9uIHRoZSBzcHlUYXJnZXQgdGhhdCBoYXMgdGhlIHByb3ZpZGVkIGBzcHlUYXJnZXRJZGAuXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHtcclxuICBzZWxlY3RvcjogJ1tzcHldJyxcclxuICBzdGFuZGFsb25lOiB0cnVlXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTcHlEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIC8qKlxyXG4gICAqIElEIG9mIHRoZSBzcHlUYXJnZXQgdG8gc3B5LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNweVRhcmdldElkITogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBAb3B0aW9uYWxcclxuICAgKlxyXG4gICAqIElEIG9mIHRoZSBzcHlUYXJnZXRDb250YWluZXIgY29udGFpbmluZyB0aGUgc3B5VGFyZ2V0LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNweVRhcmdldENvbnRhaW5lcklkPzogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBDbGFzcyBuYW1lIHRvIGFkZCB0byB0aGlzIGVsZW1lbnQgd2hlbiB0aGUgc3B5VGFyZ2V0IGhhcyB0cmFuc2l0aW9uZWQgaW50byBhIHN0YXRlIG9mIGludGVyc2VjdGlvbiAoaXMgdmlzaXNibGUpLlxyXG4gICAqXHJcbiAgICogQGRlZmF1bHRcclxuICAgKiAnYWN0aXZlJ1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHNweUFjdGl2ZUNsYXNzOiBzdHJpbmcgPSAnYWN0aXZlJztcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcycpIGFjdGl2ZUNsYXNzSW5ET00/OiBzdHJpbmc7XHJcblxyXG4gIHByaXZhdGUgZGlyZWN0aXZlRGVzdHJveWVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBzY3JvbGxTcHlTZXJ2aWNlOiBTY3JvbGxTcHlTZXJ2aWNlLFxyXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBzdHJpbmcsXHJcbiAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZlxyXG4gICkgeyB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMuc3B5VGFyZ2V0SWQpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTcHlEaXJlY3RpdmU6IHNweVRhcmdldElkIG5lZWRzIHRvIGJlIHNldC4nKTtcclxuICAgIH1cclxuICAgIHRoaXMuc2Nyb2xsU3B5U2VydmljZS5nZXRTcHlUYXJnZXRJc0ludGVyc2VjdGluZyQodGhpcy5zcHlUYXJnZXRDb250YWluZXJJZClcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGlyZWN0aXZlRGVzdHJveWVkJCksXHJcbiAgICAgICAgZmlsdGVyKChldmVudCkgPT5cclxuICAgICAgICAgIGV2ZW50LnNweVRhcmdldC5pZCA9PT0gdGhpcy5zcHlUYXJnZXRJZFxyXG4gICAgICAgICAgJiYgZXZlbnQuc3B5VGFyZ2V0LmNvbnRhaW5lcklkID09PSB0aGlzLnNweVRhcmdldENvbnRhaW5lcklkXHJcbiAgICAgICAgKVxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVDbGFzc0luRE9NID0gZXZlbnQuaXNJbnRlcnNlY3RpbmcgPyB0aGlzLnNweUFjdGl2ZUNsYXNzIDogdW5kZWZpbmVkO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1hbnVhbGx5IHRyaWdnZXIgY2hhbmdlIGRldGVjdGlvbiB0byB1cGRhdGUgYWN0aXZlQ2xhc3MgaW4gdGhlIERPTVxyXG4gICAgICAgICAqIChOZWVkZWQgZm9yIHRoZSBjYXNlIGNoYW5nZURldGVjdGlvbiBPblB1c2ggaXMgdXNlZCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmRpcmVjdGl2ZURlc3Ryb3llZCQubmV4dCgpO1xyXG4gICAgdGhpcy5kaXJlY3RpdmVEZXN0cm95ZWQkLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==