UNPKG

angular-dark-mode

Version:

Add dark mode to your Angular applications with ease!

1 lines 8.43 kB
{"version":3,"file":"angular-dark-mode.mjs","sources":["../../../projects/angular-dark-mode/src/lib/dark-mode-options.ts","../../../projects/angular-dark-mode/src/lib/default-options.ts","../../../projects/angular-dark-mode/src/lib/isNil.ts","../../../projects/angular-dark-mode/src/lib/media-query.ts","../../../projects/angular-dark-mode/src/lib/media-query.service.ts","../../../projects/angular-dark-mode/src/lib/dark-mode.service.ts","../../../projects/angular-dark-mode/src/public-api.ts","../../../projects/angular-dark-mode/src/angular-dark-mode.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { DarkModeOptions } from './types';\n\n/**\n * InjectionToken to override default options\n *\n * @example\n *\n * providers: [\n * {\n * provide: DARK_MODE_OPTIONS,\n * useValue: {\n * darkModeClass: 'my-dark-mode',\n * lightModeClass: 'my-light-mode',\n * },\n * },\n * ]\n */\nexport const DARK_MODE_OPTIONS = new InjectionToken<Partial<DarkModeOptions>>(\n 'DARK_MODE_OPTIONS'\n);\n","import { DarkModeOptions } from './types';\n\n/**\n * Default options used in DarkModeService\n */\nexport const defaultOptions: DarkModeOptions = {\n darkModeClass: 'dark-mode',\n lightModeClass: 'light-mode',\n preloadingClass: 'dark-mode-preloading',\n storageKey: 'dark-mode',\n element: document.body,\n};\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any */\nexport function isNil(value: any): value is null | undefined {\n return value === null || value === undefined;\n}\n","export const prefersDarkSchemeQuery = '(prefers-color-scheme: dark)';\n","import { Injectable } from '@angular/core';\nimport { prefersDarkSchemeQuery } from './media-query';\n\n@Injectable({ providedIn: 'root' })\nexport class MediaQueryService {\n matchMedia(query: string): MediaQueryList {\n return window.matchMedia(query);\n }\n\n prefersDarkMode(): boolean {\n return this.matchMedia(prefersDarkSchemeQuery).matches;\n }\n}\n","import {\n Inject,\n Injectable,\n Optional,\n Renderer2,\n RendererFactory2,\n} from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { distinctUntilChanged } from 'rxjs/operators';\nimport { DARK_MODE_OPTIONS } from './dark-mode-options';\nimport { defaultOptions } from './default-options';\nimport { isNil } from './isNil';\nimport { MediaQueryService } from './media-query.service';\nimport { DarkModeOptions } from './types';\n\n@Injectable({ providedIn: 'root' })\nexport class DarkModeService {\n private readonly options: DarkModeOptions;\n private readonly renderer: Renderer2;\n private readonly darkModeSubject$: BehaviorSubject<boolean>;\n\n constructor(\n private rendererFactory: RendererFactory2,\n private mediaQueryService: MediaQueryService,\n // prettier-ignore\n @Optional() @Inject(DARK_MODE_OPTIONS) private providedOptions: DarkModeOptions | null\n ) {\n this.options = { ...defaultOptions, ...(this.providedOptions || {}) };\n this.renderer = this.rendererFactory.createRenderer(null, null);\n this.darkModeSubject$ = new BehaviorSubject(this.getInitialDarkModeValue());\n this.darkModeSubject$.getValue() ? this.enable() : this.disable();\n this.removePreloadingClass();\n }\n\n /**\n * An Observable representing current dark mode.\n * Only fires the initial and distinct values.\n */\n get darkMode$(): Observable<boolean> {\n return this.darkModeSubject$.asObservable().pipe(distinctUntilChanged());\n }\n\n toggle(): void {\n this.darkModeSubject$.getValue() ? this.disable() : this.enable();\n }\n\n enable(): void {\n const { element, darkModeClass, lightModeClass } = this.options;\n this.renderer.removeClass(element, lightModeClass);\n this.renderer.addClass(element, darkModeClass);\n this.saveDarkModeToStorage(true);\n this.darkModeSubject$.next(true);\n }\n\n disable(): void {\n const { element, darkModeClass, lightModeClass } = this.options;\n this.renderer.removeClass(element, darkModeClass);\n this.renderer.addClass(element, lightModeClass);\n this.saveDarkModeToStorage(false);\n this.darkModeSubject$.next(false);\n }\n\n private getInitialDarkModeValue(): boolean {\n const darkModeFromStorage = this.getDarkModeFromStorage();\n\n if (isNil(darkModeFromStorage)) {\n return this.mediaQueryService.prefersDarkMode();\n }\n\n return darkModeFromStorage;\n }\n\n private saveDarkModeToStorage(darkMode: boolean): void {\n localStorage.setItem(this.options.storageKey, JSON.stringify({ darkMode }));\n }\n\n private getDarkModeFromStorage(): boolean | null {\n const storageItem = localStorage.getItem(this.options.storageKey);\n\n if (storageItem) {\n try {\n return JSON.parse(storageItem)?.darkMode;\n } catch (error) {\n console.error(\n 'Invalid darkMode localStorage item:',\n storageItem,\n 'falling back to color scheme media query'\n );\n }\n }\n\n return null;\n }\n\n private removePreloadingClass(): void {\n // defer to next tick\n setTimeout(() => {\n this.renderer.removeClass(\n this.options.element,\n this.options.preloadingClass\n );\n });\n }\n}\n","/*\n * Public API Surface of angular-dark-mode\n */\n\nexport * from './lib/dark-mode-options';\nexport * from './lib/dark-mode.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}