@bcodes/ngx-theme-service
Version:
Configurable theme switching service for use with CSS variables
236 lines (231 loc) • 7.18 kB
JavaScript
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