From 59c7d4567380d1a9c80e96eb958fdbdd512ce006 Mon Sep 17 00:00:00 2001 From: Alexander Neonxp Kiryukhin Date: Sun, 3 Nov 2024 20:08:36 +0300 Subject: новая жизнь блога MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/hugo-theme-stack/assets/ts/colorScheme.ts | 92 ++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 themes/hugo-theme-stack/assets/ts/colorScheme.ts (limited to 'themes/hugo-theme-stack/assets/ts/colorScheme.ts') diff --git a/themes/hugo-theme-stack/assets/ts/colorScheme.ts b/themes/hugo-theme-stack/assets/ts/colorScheme.ts new file mode 100644 index 0000000..978e98e --- /dev/null +++ b/themes/hugo-theme-stack/assets/ts/colorScheme.ts @@ -0,0 +1,92 @@ +type colorScheme = 'light' | 'dark' | 'auto'; + +class StackColorScheme { + private localStorageKey = 'StackColorScheme'; + private currentScheme: colorScheme; + private systemPreferScheme: colorScheme; + + constructor(toggleEl: HTMLElement) { + this.bindMatchMedia(); + this.currentScheme = this.getSavedScheme(); + if (window.matchMedia('(prefers-color-scheme: dark)').matches === true) + this.systemPreferScheme = 'dark' + else + this.systemPreferScheme = 'light'; + + this.dispatchEvent(document.documentElement.dataset.scheme as colorScheme); + + if (toggleEl) + this.bindClick(toggleEl); + + if (document.body.style.transition == '') + document.body.style.setProperty('transition', 'background-color .3s ease'); + } + + private saveScheme() { + localStorage.setItem(this.localStorageKey, this.currentScheme); + } + + private bindClick(toggleEl: HTMLElement) { + toggleEl.addEventListener('click', (e) => { + if (this.isDark()) { + /// Disable dark mode + this.currentScheme = 'light'; + } + else { + this.currentScheme = 'dark'; + } + + this.setBodyClass(); + + if (this.currentScheme == this.systemPreferScheme) { + /// Set to auto + this.currentScheme = 'auto'; + } + + this.saveScheme(); + }) + } + + private isDark() { + return (this.currentScheme == 'dark' || this.currentScheme == 'auto' && this.systemPreferScheme == 'dark'); + } + + private dispatchEvent(colorScheme: colorScheme) { + const event = new CustomEvent('onColorSchemeChange', { + detail: colorScheme + }); + window.dispatchEvent(event); + } + + private setBodyClass() { + if (this.isDark()) { + document.documentElement.dataset.scheme = 'dark'; + } + else { + document.documentElement.dataset.scheme = 'light'; + } + + this.dispatchEvent(document.documentElement.dataset.scheme as colorScheme); + } + + private getSavedScheme(): colorScheme { + const savedScheme = localStorage.getItem(this.localStorageKey); + + if (savedScheme == 'light' || savedScheme == 'dark' || savedScheme == 'auto') return savedScheme; + else return 'auto'; + } + + private bindMatchMedia() { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { + if (e.matches) { + this.systemPreferScheme = 'dark'; + } + else { + this.systemPreferScheme = 'light'; + } + this.setBodyClass(); + }); + } +} + +export default StackColorScheme; -- cgit v1.2.3