UNPKG

@thisissoon/angular-scrollspy

Version:

A simple lightweight library for Angular which automatically updates links to indicate the currently active section in the viewport

449 lines (440 loc) 13.6 kB
import { __spread } from 'tslib'; import { Directive, Input, HostBinding, ChangeDetectorRef, Injectable, ContentChildren, Component, NgModule } from '@angular/core'; import { InViewportModule } from '@thisissoon/angular-inviewport'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A directive used to add an `active` class to a nav item * when the section is in the viewport * * \@example * ```html * <a snScrollSpyItem for="foo" href="#section1">Section 1</a> * ``` * */ var ScrollSpyItemDirective = /** @class */ (function () { /** * Creates an instance of ScrollSpyItemDirective. * @memberof ScrollSpyItemDirective */ function ScrollSpyItemDirective(cdRef) { this.cdRef = cdRef; /** * True if the nav item is the active item in the `items` list * for `ScrollSpyDirective` instance * * \@memberof ScrollSpyItemDirective */ this.active = false; /** * If true means the section is in the viewport * * \@memberof ScrollSpyItemDirective */ this.inViewport = false; } Object.defineProperty(ScrollSpyItemDirective.prototype, "section", { /** * Id of section that links navigates to * * @readonly * @memberof ScrollSpyItemDirective */ get: /** * Id of section that links navigates to * * \@readonly * \@memberof ScrollSpyItemDirective * @return {?} */ function () { return this.href.replace('#', ''); }, enumerable: true, configurable: true }); /** * Manually trigger change detection * * @memberof ScrollSpyItemDirective */ /** * Manually trigger change detection * * \@memberof ScrollSpyItemDirective * @return {?} */ ScrollSpyItemDirective.prototype.detectChanges = /** * Manually trigger change detection * * \@memberof ScrollSpyItemDirective * @return {?} */ function () { this.cdRef.detectChanges(); }; ScrollSpyItemDirective.decorators = [ { type: Directive, args: [{ selector: '[snScrollSpyItem]', },] } ]; /** @nocollapse */ ScrollSpyItemDirective.ctorParameters = function () { return [ { type: ChangeDetectorRef } ]; }; ScrollSpyItemDirective.propDecorators = { active: [{ type: HostBinding, args: ['class.active',] }], for: [{ type: Input }], href: [{ type: Input }] }; return ScrollSpyItemDirective; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Service that stores a list of `Spy`'s and the state * of their nav items `inViewport` and `active` state * */ var ScrollSpyService = /** @class */ (function () { function ScrollSpyService() { /** * List of `Spy`'s * * \@memberof ScrollSpyService */ this.spys = []; /** * Stores requests to add items to spy when spy hasn't been created * yet. Once spy has been added then request will be made again. * * \@memberof ScrollSpyService */ this.buffer = []; } /** * Add spy to list of `spys` * * @memberof ScrollSpyService */ /** * Add spy to list of `spys` * * \@memberof ScrollSpyService * @param {?} id * @param {?} items * @return {?} */ ScrollSpyService.prototype.addSpy = /** * Add spy to list of `spys` * * \@memberof ScrollSpyService * @param {?} id * @param {?} items * @return {?} */ function (id, items) { var _this = this; this.spys.push({ id: id, items: items }); /** @type {?} */ var buffer = this.buffer.filter(function (i) { return i.spyId === id; }); this.buffer = this.buffer.filter(function (i) { return i.spyId !== id; }); buffer.forEach(function (i) { return _this.setSpySectionStatus(i.sectionId, i.spyId, i.inViewport); }); }; /** * Remove spy from list of `spys` * * @memberof ScrollSpyService */ /** * Remove spy from list of `spys` * * \@memberof ScrollSpyService * @param {?} id * @return {?} */ ScrollSpyService.prototype.removeSpy = /** * Remove spy from list of `spys` * * \@memberof ScrollSpyService * @param {?} id * @return {?} */ function (id) { /** @type {?} */ var i = this.spys.findIndex(function (s) { return s.id === id; }); this.spys.splice(i, 1); }; /** * Set the `inViewport` status for a spy item then sets the active * to true for the first item in the list that has `inViewport` * set to true * * @memberof ScrollSpyService */ /** * Set the `inViewport` status for a spy item then sets the active * to true for the first item in the list that has `inViewport` * set to true * * \@memberof ScrollSpyService * @param {?} sectionId * @param {?} spyId * @param {?} inViewport * @return {?} */ ScrollSpyService.prototype.setSpySectionStatus = /** * Set the `inViewport` status for a spy item then sets the active * to true for the first item in the list that has `inViewport` * set to true * * \@memberof ScrollSpyService * @param {?} sectionId * @param {?} spyId * @param {?} inViewport * @return {?} */ function (sectionId, spyId, inViewport) { /** @type {?} */ var spy = this.spys.find(function (s) { return s.id === spyId; }); if (!spy) { this.buffer.push({ sectionId: sectionId, spyId: spyId, inViewport: inViewport }); return; } /** @type {?} */ var item = spy.items.find(function (i) { return i.section === sectionId; }); if (!item) { return; } item.inViewport = inViewport; /** @type {?} */ var firstInViewport = spy.items.filter(function (i) { return i.inViewport; })[0]; spy.items.forEach(function (i) { return (i.active = false); }); if (firstInViewport) { firstInViewport.active = true; firstInViewport.detectChanges(); } }; ScrollSpyService.decorators = [ { type: Injectable } ]; return ScrollSpyService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Adds `active` class to navigation links when section is in the viewport. * Used in conjuction with `snScrollItem` directive which should be added * to anchor links in the nav * * \@example * ``` * <ul role="navigation" snScrollSpy id="foo"> * <li><a snScrollSpyItem for="foo" href="#section1">Section 1</a></li> * <li><a snScrollSpyItem for="foo" href="#section2">Section 2</a></li> * <li><a snScrollSpyItem for="foo" href="#section3">Section 3</a></li> * <li><a snScrollSpyItem for="foo" href="#section4">Section 4</a></li> * </ul> * ``` * */ var ScrollSpyDirective = /** @class */ (function () { /** * Creates an instance of ScrollSpyDirective. * @memberof ScrollSpyDirective */ function ScrollSpyDirective(scrollSpySvc) { this.scrollSpySvc = scrollSpySvc; } /** * Adds spy to list of spys in `ScrollSpyService` * * @memberof ScrollSpyDirective */ /** * Adds spy to list of spys in `ScrollSpyService` * * \@memberof ScrollSpyDirective * @return {?} */ ScrollSpyDirective.prototype.ngAfterViewInit = /** * Adds spy to list of spys in `ScrollSpyService` * * \@memberof ScrollSpyDirective * @return {?} */ function () { this.scrollSpySvc.addSpy(this.id, this.items); }; /** * Remove spy from list of spys when directive is destroyed * * @memberof ScrollSpyDirective */ /** * Remove spy from list of spys when directive is destroyed * * \@memberof ScrollSpyDirective * @return {?} */ ScrollSpyDirective.prototype.ngOnDestroy = /** * Remove spy from list of spys when directive is destroyed * * \@memberof ScrollSpyDirective * @return {?} */ function () { this.scrollSpySvc.removeSpy(this.id); }; ScrollSpyDirective.decorators = [ { type: Directive, args: [{ selector: '[snScrollSpy]', },] } ]; /** @nocollapse */ ScrollSpyDirective.ctorParameters = function () { return [ { type: ScrollSpyService } ]; }; ScrollSpyDirective.propDecorators = { items: [{ type: ContentChildren, args: [ScrollSpyItemDirective,] }], id: [{ type: Input }] }; return ScrollSpyDirective; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A component to wrap section content within that will update the * `ScrollSpyService` when it's in view * * \@example * ```html * <sn-scroll-spy-section id="section1" for="foo"> * ... * </sn-scroll-spy-section> * ``` */ var ScrollSpySectionComponent = /** @class */ (function () { /** * Creates an instance of ScrollSpySectionComponent. * @memberof ScrollSpySectionComponent */ function ScrollSpySectionComponent(scrollSpySvc) { this.scrollSpySvc = scrollSpySvc; } /** * Updates `ScrollSpy` section when element enters/leaves viewport * * @memberof ScrollSpySectionComponent */ /** * Updates `ScrollSpy` section when element enters/leaves viewport * * \@memberof ScrollSpySectionComponent * @param {?} inViewport * @return {?} */ ScrollSpySectionComponent.prototype.onInViewportChange = /** * Updates `ScrollSpy` section when element enters/leaves viewport * * \@memberof ScrollSpySectionComponent * @param {?} inViewport * @return {?} */ function (inViewport) { this.scrollSpySvc.setSpySectionStatus(this.id, this.for, inViewport); }; ScrollSpySectionComponent.decorators = [ { type: Component, args: [{ selector: 'sn-scroll-spy-section', template: "<div\n class=\"sn-hidden\"\n snInViewport\n (inViewportChange)=\"onInViewportChange($event)\">\n</div>\n<ng-content></ng-content>\n", styles: [":host{display:block;position:relative}.sn-hidden{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;z-index:-1}"] }] } ]; /** @nocollapse */ ScrollSpySectionComponent.ctorParameters = function () { return [ { type: ScrollSpyService } ]; }; ScrollSpySectionComponent.propDecorators = { id: [{ type: Input }], for: [{ type: Input }] }; return ScrollSpySectionComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ var directives = [ScrollSpyDirective, ScrollSpyItemDirective]; /** @type {?} */ var components = [ScrollSpySectionComponent]; /** @type {?} */ var providers = [ScrollSpyService]; /** * A simple lightweight library for Angular which automatically * updates links to indicate the currently active section in the viewport * */ var ScrollSpyModule = /** @class */ (function () { function ScrollSpyModule() { } /** * Specify a static method for root module to ensure providers are * only provided once but allows the module to still be imported * into other modules without reproviding services. * * @memberof ScrollSpyModule */ /** * Specify a static method for root module to ensure providers are * only provided once but allows the module to still be imported * into other modules without reproviding services. * * \@memberof ScrollSpyModule * @return {?} */ ScrollSpyModule.forRoot = /** * Specify a static method for root module to ensure providers are * only provided once but allows the module to still be imported * into other modules without reproviding services. * * \@memberof ScrollSpyModule * @return {?} */ function () { return { ngModule: ScrollSpyModule, providers: __spread(providers), }; }; ScrollSpyModule.decorators = [ { type: NgModule, args: [{ imports: [InViewportModule], declarations: __spread(directives, components), exports: __spread(directives, components), },] } ]; return ScrollSpyModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { ScrollSpyDirective, ScrollSpyItemDirective, ScrollSpySectionComponent, ScrollSpyService, ScrollSpyModule }; //# sourceMappingURL=thisissoon-angular-scrollspy.js.map