UNPKG

@ng-web-apis/intersection-observer

Version:

A library for declarative use of Intersection Observer API with Angular

261 lines (245 loc) 11.9 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, ElementRef, Directive, Injectable, NgModule } from '@angular/core'; import { Observable, share } from 'rxjs'; import { WA_WINDOW } from '@ng-web-apis/common'; const SafeObserver = typeof IntersectionObserver !== 'undefined' ? IntersectionObserver : class { root = null; rootMargin = ''; thresholds = []; observe() { } unobserve() { } disconnect() { } takeRecords() { return []; } }; const WA_INTERSECTION_ROOT = new InjectionToken('[WA_INTERSECTION_ROOT]'); /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_ROOT} */ const INTERSECTION_ROOT = WA_INTERSECTION_ROOT; const WA_INTERSECTION_ROOT_MARGIN_DEFAULT = '0px 0px 0px 0px'; /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_ROOT_MARGIN_DEFAULT} */ const INTERSECTION_ROOT_MARGIN_DEFAULT = WA_INTERSECTION_ROOT_MARGIN_DEFAULT; const WA_INTERSECTION_ROOT_MARGIN = new InjectionToken('[WA_INTERSECTION_ROOT_MARGIN]', { providedIn: 'root', factory: () => INTERSECTION_ROOT_MARGIN_DEFAULT, }); /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_ROOT_MARGIN} */ const INTERSECTION_ROOT_MARGIN = WA_INTERSECTION_ROOT_MARGIN; function rootMarginFactory() { return (inject(ElementRef).nativeElement.getAttribute('waIntersectionRootMargin') || INTERSECTION_ROOT_MARGIN_DEFAULT); } const WA_INTERSECTION_THRESHOLD_DEFAULT = 0; /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_THRESHOLD_DEFAULT} */ const INTERSECTION_THRESHOLD_DEFAULT = WA_INTERSECTION_THRESHOLD_DEFAULT; const WA_INTERSECTION_THRESHOLD = new InjectionToken('[WA_INTERSECTION_THRESHOLD]', { providedIn: 'root', factory: () => INTERSECTION_THRESHOLD_DEFAULT, }); /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_THRESHOLD} */ const INTERSECTION_THRESHOLD = WA_INTERSECTION_THRESHOLD; function thresholdFactory() { return (inject(ElementRef) .nativeElement.getAttribute('waIntersectionThreshold') ?.split(',') .map(parseFloat) || INTERSECTION_THRESHOLD_DEFAULT); } class WaIntersectionObserverDirective extends SafeObserver { callbacks = new Map(); margin = ''; threshold = ''; constructor() { const root = inject(INTERSECTION_ROOT, { optional: true }); super((entries) => { this.callbacks.forEach((callback, element) => { const filtered = entries.filter(({ target }) => target === element); return filtered.length && callback(filtered, this); }); }, { root: root?.nativeElement, rootMargin: rootMarginFactory(), threshold: thresholdFactory(), }); } observe(target, callback = () => { }) { super.observe(target); this.callbacks.set(target, callback); } unobserve(target) { super.unobserve(target); this.callbacks.delete(target); } ngOnDestroy() { this.disconnect(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionObserverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: WaIntersectionObserverDirective, isStandalone: true, selector: "[waIntersectionObserver]", inputs: { margin: ["waIntersectionRootMargin", "margin"], threshold: ["waIntersectionThreshold", "threshold"] }, exportAs: ["IntersectionObserver"], usesInheritance: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionObserverDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[waIntersectionObserver]', inputs: ['margin: waIntersectionRootMargin', 'threshold: waIntersectionThreshold'], exportAs: 'IntersectionObserver', }] }], ctorParameters: function () { return []; } }); /** * @deprecated: use {@link WaIntersectionObserverDirective} */ const IntersectionObserverDirective = WaIntersectionObserverDirective; /** * @deprecated: use {@link WaIntersectionObserver} */ const WaObserver = WaIntersectionObserverDirective; class IntersectionObserveeService extends Observable { constructor() { const nativeElement = inject(ElementRef).nativeElement; const observer = inject(WaIntersectionObserverDirective); super((subscriber) => { observer.observe(nativeElement, (entries) => { subscriber.next(entries); }); return () => { observer.unobserve(nativeElement); }; }); return this.pipe(share()); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserveeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserveeService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserveeService, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); class WaIntersectionObservee { waIntersectionObservee = inject(IntersectionObserveeService); static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionObservee, deps: [], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: WaIntersectionObservee, isStandalone: true, selector: "[waIntersectionObservee]", outputs: { waIntersectionObservee: "waIntersectionObservee" }, providers: [IntersectionObserveeService], ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionObservee, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[waIntersectionObservee]', outputs: ['waIntersectionObservee'], providers: [IntersectionObserveeService], }] }] }); /** * @deprecated: use {@link WaIntersectionObservee} */ const IntersectionObserveeDirective = WaIntersectionObservee; /** * @deprecated: use {@link WaIntersectionObservee} */ const WaObservee = WaIntersectionObservee; class WaIntersectionRoot { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: WaIntersectionRoot, isStandalone: true, selector: "[waIntersectionRoot]", providers: [ { provide: INTERSECTION_ROOT, useExisting: ElementRef, }, ], ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: WaIntersectionRoot, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[waIntersectionRoot]', providers: [ { provide: INTERSECTION_ROOT, useExisting: ElementRef, }, ], }] }] }); /** * @deprecated: use {@link WaIntersectionRoot} */ const IntersectionRootDirective = WaIntersectionRoot; const WaIntersectionObserver = [ WaIntersectionObserverDirective, WaIntersectionObservee, WaIntersectionRoot, ]; /** * @deprecated: use {@link WaIntersectionObserver} */ class IntersectionObserverModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverModule, imports: [WaIntersectionObserverDirective, WaIntersectionObservee, WaIntersectionRoot], exports: [WaIntersectionObserverDirective, WaIntersectionObservee, WaIntersectionRoot] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverModule }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverModule, decorators: [{ type: NgModule, args: [{ imports: [ WaIntersectionObserverDirective, WaIntersectionObservee, WaIntersectionRoot, ], exports: [ WaIntersectionObserverDirective, WaIntersectionObservee, WaIntersectionRoot, ], }] }] }); class IntersectionObserverService extends Observable { nativeElement = inject(ElementRef).nativeElement; rootMargin = inject(INTERSECTION_ROOT_MARGIN); threshold = inject(INTERSECTION_THRESHOLD); root = inject(INTERSECTION_ROOT, { optional: true })?.nativeElement ?? null; constructor() { super((subscriber) => { const observer = new SafeObserver((entries) => { subscriber.next(entries); }, { root: this.root, rootMargin: this.rootMargin, threshold: this.threshold, }); observer.observe(this.nativeElement); return () => { observer.disconnect(); }; }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: IntersectionObserverService, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); const WA_INTERSECTION_OBSERVER_SUPPORT = new InjectionToken('[WA_INTERSECTION_OBSERVER_SUPPORT]: [INTERSECTION_OBSERVER_SUPPORT]', { providedIn: 'root', factory: () => !!inject(WA_WINDOW).IntersectionObserver, }); /** * @deprecated: drop in v5.0, use {@link WA_INTERSECTION_OBSERVER_SUPPORT} */ const INTERSECTION_OBSERVER_SUPPORT = WA_INTERSECTION_OBSERVER_SUPPORT; /** * Generated bundle index. Do not edit. */ export { INTERSECTION_OBSERVER_SUPPORT, INTERSECTION_ROOT, INTERSECTION_ROOT_MARGIN, INTERSECTION_ROOT_MARGIN_DEFAULT, INTERSECTION_THRESHOLD, INTERSECTION_THRESHOLD_DEFAULT, IntersectionObserveeDirective, IntersectionObserveeService, IntersectionObserverDirective, IntersectionObserverModule, IntersectionObserverService, IntersectionRootDirective, WA_INTERSECTION_OBSERVER_SUPPORT, WA_INTERSECTION_ROOT, WA_INTERSECTION_ROOT_MARGIN, WA_INTERSECTION_ROOT_MARGIN_DEFAULT, WA_INTERSECTION_THRESHOLD, WA_INTERSECTION_THRESHOLD_DEFAULT, WaIntersectionObservee, WaIntersectionObserver, WaIntersectionObserverDirective, WaIntersectionRoot, WaObservee, WaObserver }; //# sourceMappingURL=ng-web-apis-intersection-observer.mjs.map