feat: listen for changes on OS theme to switch accordingly

As long as the visitor has not changed the default theme, the site will
change between dark and light themes matching the OS setting.
main
welpo 2 years ago
parent 2f80b0b5ad
commit 9a1f5db45c
No known key found for this signature in database
GPG Key ID: A2F978CF4EC1F5A6

@ -1,27 +1,31 @@
const themeSwitcher = document.querySelector('.theme-switcher input');
const currentTheme = localStorage.getItem('theme');
let currentTheme = localStorage.getItem('theme');
let userHasManuallyChangedTheme = currentTheme !== null;
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
themeSwitcher.checked = theme === 'dark';
localStorage.setItem('theme', theme);
currentTheme = theme;
}
// detect the user's preferred color scheme and activate it
if (currentTheme) {
document.documentElement.setAttribute( 'data-theme', currentTheme);
themeSwitcher.checked = currentTheme === 'dark';
setTheme(currentTheme);
} else {
const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
document.documentElement.setAttribute( 'data-theme', isSystemDark? 'dark' : 'light');
themeSwitcher.checked = isSystemDark;
setTheme(isSystemDark ? 'dark' : 'light');
}
// switch between themes
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}
else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
}
const newTheme = e.target.checked ? 'dark' : 'light';
setTheme(newTheme);
userHasManuallyChangedTheme = true;
}
// event listener on checkbox change
themeSwitcher.addEventListener('change', switchTheme, false);
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (!userHasManuallyChangedTheme) {
setTheme(e.matches ? 'dark' : 'light');
}
});

Loading…
Cancel
Save