UNPKG

@thisissoon/angular-scrollspy

Version:

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

508 lines (494 loc) 18 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@thisissoon/angular-inviewport')) : typeof define === 'function' && define.amd ? define('@thisissoon/angular-scrollspy', ['exports', '@angular/core', '@thisissoon/angular-inviewport'], factory) : (factory((global.thisissoon = global.thisissoon || {}, global.thisissoon['angular-scrollspy'] = {}),global.ng.core,global.angularInviewport)); }(this, (function (exports,core,angularInviewport) { 'use strict'; /** * @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: core.Directive, args: [{ selector: '[snScrollSpyItem]', },] } ]; /** @nocollapse */ ScrollSpyItemDirective.ctorParameters = function () { return [ { type: core.ChangeDetectorRef } ]; }; ScrollSpyItemDirective.propDecorators = { active: [{ type: core.HostBinding, args: ['class.active',] }], for: [{ type: core.Input }], href: [{ type: core.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: core.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: core.Directive, args: [{ selector: '[snScrollSpy]', },] } ]; /** @nocollapse */ ScrollSpyDirective.ctorParameters = function () { return [ { type: ScrollSpyService } ]; }; ScrollSpyDirective.propDecorators = { items: [{ type: core.ContentChildren, args: [ScrollSpyItemDirective,] }], id: [{ type: core.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: core.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: core.Input }], for: [{ type: core.Input }] }; return ScrollSpySectionComponent; }()); /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** * @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: core.NgModule, args: [{ imports: [angularInviewport.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 */ exports.ScrollSpyDirective = ScrollSpyDirective; exports.ScrollSpyItemDirective = ScrollSpyItemDirective; exports.ScrollSpySectionComponent = ScrollSpySectionComponent; exports.ScrollSpyService = ScrollSpyService; exports.ScrollSpyModule = ScrollSpyModule; Object.defineProperty(exports, '__esModule', { value: true }); }))); //# sourceMappingURL=thisissoon-angular-scrollspy.umd.js.map