UNPKG

@bcodes/ngx-theme-service

Version:

Configurable theme switching service for use with CSS variables

236 lines (231 loc) 7.18 kB
import { __spread } from 'tslib'; import { DOCUMENT } from '@angular/common'; import { InjectionToken, Injectable, Inject, ɵɵdefineInjectable, ɵɵinject } from '@angular/core'; import { Subject, BehaviorSubject, timer } from 'rxjs'; import { tap, switchMap, takeUntil } from 'rxjs/operators'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Apply a CSS class to the `<html>` element when switching themes * @record */ function ThemeTransitionConfig() { } if (false) { /** @type {?} */ ThemeTransitionConfig.prototype.className; /** * remove class after duration in milliseconds * @type {?} */ ThemeTransitionConfig.prototype.duration; } /** * @record */ function ThemeServiceConfig() { } if (false) { /** @type {?} */ ThemeServiceConfig.prototype.themes; /** * theme that should always be on the target element if using explicit default theme * @type {?|undefined} */ ThemeServiceConfig.prototype.defaultTheme; /** * optional transition configuration * @type {?|undefined} */ ThemeServiceConfig.prototype.transitionConfig; /** * themes applied to <html> by default. Supply CSS selector to change * @type {?|undefined} */ ThemeServiceConfig.prototype.targetElementSelector; } /** @type {?} */ var THEME_CONFIG = new InjectionToken('ThemeService: Config'); // https://angular.io/guide/angular-compiler-options#strictmetadataemit // @dynamic var ThemeService = /** @class */ (function () { function ThemeService(config, document) { this.config = config; this.document = document; this.stopListening$ = new Subject(); this.selectedTheme = new BehaviorSubject(this.config.defaultTheme || ''); this.selectedTheme$ = this.selectedTheme.asObservable(); this.setupSubscription(); } /** * @param {?} className * @return {?} */ ThemeService.prototype.switchTheme = /** * @param {?} className * @return {?} */ function (className) { this.selectedTheme.next(className); }; /** * @private * @return {?} */ ThemeService.prototype.setupSubscription = /** * @private * @return {?} */ function () { var _this = this; /** @type {?} */ var transitionConfig = this.config.transitionConfig; /** @type {?} */ var nonDefaultThemes = this.config.themes.filter((/** * @param {?} c * @return {?} */ function (c) { return c !== _this.config.defaultTheme; })); this.selectedTheme .pipe(tap((/** * @param {?} theme * @return {?} */ function (theme) { _this.removeClasses(nonDefaultThemes); // Conditional literal entries: // https://2ality.com/2017/04/conditional-literal-entries.html /** @type {?} */ var toAdd = __spread((theme ? [theme] : []), (transitionConfig ? [transitionConfig.className] : [])); _this.addClasses(toAdd); })), transitionConfig ? switchMap((/** * @param {?} value * @return {?} */ function (value) { return timer(transitionConfig.duration).pipe(tap((/** * @param {?} x * @return {?} */ function (x) { _this.removeClasses([ transitionConfig.className, ]); }))); })) : tap((/** * @param {?} x * @return {?} */ function (x) { })), takeUntil(this.stopListening$)) .subscribe(); }; /** * @private * @param {?} arr * @return {?} */ ThemeService.prototype.removeClasses = /** * @private * @param {?} arr * @return {?} */ function (arr) { var _a; (_a = this.targetElement.classList).remove.apply(_a, __spread(arr)); }; /** * @private * @param {?} arr * @return {?} */ ThemeService.prototype.addClasses = /** * @private * @param {?} arr * @return {?} */ function (arr) { var _a; (_a = this.targetElement.classList).add.apply(_a, __spread(arr)); }; Object.defineProperty(ThemeService.prototype, "targetElement", { get: /** * @private * @return {?} */ function () { /** @type {?} */ var elem; if (this.config.targetElementSelector) { elem = this.document.querySelector(this.config.targetElementSelector); if (!elem) { console.warn(this.config.targetElementSelector + " not found, defaulting to <html>"); } } if (!elem) { elem = this.document.documentElement; } return elem; }, enumerable: true, configurable: true }); /** * @return {?} */ ThemeService.prototype.ngOnDestroy = /** * @return {?} */ function () { this.stopListening$.next(true); }; ThemeService.decorators = [ { type: Injectable, args: [{ providedIn: 'root', },] } ]; /** @nocollapse */ ThemeService.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Inject, args: [THEME_CONFIG,] }] }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT,] }] } ]; }; /** @nocollapse */ ThemeService.ngInjectableDef = ɵɵdefineInjectable({ factory: function ThemeService_Factory() { return new ThemeService(ɵɵinject(THEME_CONFIG), ɵɵinject(DOCUMENT)); }, token: ThemeService, providedIn: "root" }); return ThemeService; }()); if (false) { /** * @type {?} * @private */ ThemeService.prototype.stopListening$; /** * @type {?} * @private */ ThemeService.prototype.selectedTheme; /** @type {?} */ ThemeService.prototype.selectedTheme$; /** * @type {?} * @private */ ThemeService.prototype.config; /** * @type {?} * @private */ ThemeService.prototype.document; } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { THEME_CONFIG, ThemeService }; //# sourceMappingURL=bcodes-ngx-theme-service.js.map