Allow theme button to toggle between 3 themes: system (prefers-dark-theme), dark, light

This commit is contained in:
badblocks 2025-03-27 23:16:10 -07:00
parent b9c4d7a61d
commit 2cb35e853d
2 changed files with 25 additions and 13 deletions

View file

@ -13,18 +13,27 @@ const $$ = selector => Array.from(document.querySelector(selector));
function initThemeToggle() { function initThemeToggle() {
const themeToggleButton = document.getElementById("theme-toggle-btn"); const themeToggleButton = document.getElementById("theme-toggle-btn");
if (!themeToggleButton) return; if (!themeToggleButton) return;
themeToggleButton.classList.toggle("btn-ghost", !("theme" in localStorage));
themeToggleButton.addEventListener("click", () => { themeToggleButton.addEventListener("click", () => {
const documentRoot = document.documentElement; const documentRoot = document.documentElement;
const isSystemTheme = themeToggleButton.classList.contains("btn-ghost");
const isDarkTheme = documentRoot.classList.contains("dark"); const isDarkTheme = documentRoot.classList.contains("dark");
const newTheme = isDarkTheme ? "light" : "dark"; const newTheme = isSystemTheme ? "dark" : (isDarkTheme ? "light" : "system");
if (newTheme === "light") { if (newTheme === "system") {
documentRoot.classList.remove("dark"); documentRoot.classList.toggle("dark", window.matchMedia("(prefers-color-scheme: dark)").matches);
documentRoot.setAttribute("data-theme", window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
localStorage.removeItem("theme");
} else { } else {
documentRoot.classList.add("dark"); if (newTheme === "light") {
documentRoot.classList.remove("dark");
} else if (newTheme === "dark") {
documentRoot.classList.add("dark");
}
documentRoot.setAttribute("data-theme", newTheme);
localStorage.setItem("theme", newTheme);
} }
documentRoot.setAttribute("data-theme", newTheme); themeToggleButton.classList.toggle("btn-ghost", newTheme === "system");
localStorage.setItem("theme", newTheme);
}); });
} }

View file

@ -5,7 +5,7 @@
{% url 'settings' as settings_url %} {% url 'settings' as settings_url %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-theme="light"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -14,13 +14,16 @@
<!-- Inline script to set the theme before rendering --> <!-- Inline script to set the theme before rendering -->
<script> <script>
(function () { (function () {
const savedTheme = localStorage.getItem('theme'); // On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (savedTheme === 'dark') { document.documentElement.classList.toggle(
document.documentElement.classList.add('dark'); "dark",
document.documentElement.setAttribute('data-theme', 'dark'); localStorage.getItem("theme") === "dark" ||
(!(localStorage.getItem("theme")) && window.matchMedia("(prefers-color-scheme: dark)").matches)
);
if (localStorage.getItem("theme")) {
document.documentElement.setAttribute("data-theme", localStorage.getItem("theme"));
} else { } else {
document.documentElement.classList.remove('dark'); document.documentElement.setAttribute("data-theme", window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
document.documentElement.setAttribute('data-theme', 'light');
} }
})(); })();
</script> </script>