From 7e1c7b94bfc505934cbed1fd4172e6cf4e2f2dc0 Mon Sep 17 00:00:00 2001 From: Jimmy Cai Date: Sat, 19 Sep 2020 00:43:52 +0200 Subject: [PATCH] feat(darkmode): listen to browser color preference change If no color preference is set by user --- assets/ts/darkmode.ts | 46 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/assets/ts/darkmode.ts b/assets/ts/darkmode.ts index 0ca35c8..e1bce49 100644 --- a/assets/ts/darkmode.ts +++ b/assets/ts/darkmode.ts @@ -1,29 +1,57 @@ export default () => { const toggleDarkMode = document.getElementById('dark-mode-toggle'); const darkModeKey = 'StackDarkMode'; + const darkModeItem = localStorage.getItem(darkModeKey); const darkModeEnabled = localStorage.getItem(darkModeKey) === 'true'; + const supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true; + const mql = window.matchMedia('(prefers-color-scheme: dark)'); let darkMode = false; - if (darkModeEnabled) { + if (darkModeItem && darkModeEnabled || !darkModeItem && supportDarkMode) { + /** + * Enable dark mode if: + * 1. If dark mode is set already (in local storage) + * 2. No color scheme preference is set in localstorage, and user's browser indicates preference for dark mode + */ darkMode = true; } - else { - darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches === true; - } - - document.body.style.setProperty('transition', 'background-color .3s ease'); - - toggleDarkMode.addEventListener('click', (e) => { - darkMode = !darkMode; + const setBodyClass = () => { if (darkMode) { document.body.classList.add('theme-dark'); } else { document.body.classList.remove('theme-dark'); } + } + const mediaQueryListener = (e) => { + darkMode = e.matches; + setBodyClass(); + } + + let listening = false; + if (!darkModeItem) { + /** + * If no dark mode preference is set in local storage, listen to browser color preference change + */ + mql.addEventListener('change', mediaQueryListener); + listening = true; + } + + document.body.style.setProperty('transition', 'background-color .3s ease'); + + toggleDarkMode.addEventListener('click', (e) => { + darkMode = !darkMode; + setBodyClass(); localStorage.setItem(darkModeKey, darkMode.toString()); + + if (listening) { + /** + * Remove listener once user set color preference in website + */ + mql.removeEventListener('change', mediaQueryListener); + } }) } \ No newline at end of file