Skip to content

Instantly share code, notes, and snippets.

@EmanH
Created May 21, 2023 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EmanH/b928a152c04425f2ad2f96612aa80f79 to your computer and use it in GitHub Desktop.
Save EmanH/b928a152c04425f2ad2f96612aa80f79 to your computer and use it in GitHub Desktop.
Theme Service - light, dark and system mode
import { DOCUMENT } from '@angular/common'
import { Inject, Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs'
@Injectable({
providedIn: 'root'
})
export class ThemeService {
modeOptions: IModeOption[] = [
{ name: 'Light', value: 'light' },
{ name: 'Dark', value: 'dark' },
{ name: 'System', value: 'system' }
]
isDark = new BehaviorSubject<boolean>(false)
mode = new BehaviorSubject<IModeOption>(this.modeOptions[2])
public get isSystemMode () {
return this.mode.value.value === 'system'
}
public get isLightMode () {
return this.mode.value.value === 'light'
}
public get isDarkMode () {
return this.mode.value.value === 'dark'
}
constructor(
@Inject(DOCUMENT) private document: Document
) {
this.isDark.subscribe(isDark => this.document.documentElement.classList.toggle('dark', isDark))
const mode = localStorage.getItem('theme-mode')
if (mode) {
this.setMode(this.modeOptions.find(option => option.value === mode) ?? this.modeOptions[0])
}
window.matchMedia("(prefers-color-scheme: dark)").addEventListener('change',({ matches }) => {
if (this.isSystemMode) {
if (matches) {
this.isDark.next(true);
} else {
this.isDark.next(false);
}
}
})
}
public checkSystemPreference() {
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
this.isDark.next(true);
} else {
this.isDark.next(false);
}
}
public setMode(mode: IModeOption) {
this.mode.next(mode)
localStorage.setItem('theme-mode', mode.value)
if (this.isSystemMode) {
this.checkSystemPreference()
} else {
this.isDark.next(this.isDarkMode)
}
}
}
export type TModeTypes = 'light' | 'dark' | 'system'
export interface IModeOption {
name: string;
value: TModeTypes;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment