Last active
November 2, 2022 02:16
-
-
Save dbernheisel/3658f66c433756435dad729095735b42 to your computer and use it in GitHub Desktop.
Theme Chooser in Phoenix and JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// loaded with a <script> in <head> (not defer or async). Not async or deferred so that it | |
// executes before content is loaded to prevent flashing your light theme first before switching to dark. | |
// Works best with a class-based dark/light theme with Tailwind, | |
// in tailwind.config.js => darkMode: "class", | |
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)") | |
// colorScheme determines browser UI elements being light or dark | |
const colorScheme = document.head.querySelector("meta[name='color-scheme']") | |
// themeColor colors the browser chrome in some cases, like Google Chrome on mobile and Safari on desktop. | |
const themeColor = document.head.querySelector("meta[name='theme-color']") | |
const light = "#FFFFFF" // light background color | |
const dark = "#1F0E2B" // dark background color | |
window.currentTheme = () => window.localStorage.theme || "system" | |
window.darkMode = function() { | |
document.documentElement.classList.add("dark") | |
if(colorScheme) colorScheme.setAttribute("content", "dark") | |
if(themeColor) themeColor.setAttribute("content", dark) | |
} | |
window.lightMode = function() { | |
document.documentElement.classList.remove("dark") | |
if(colorScheme) colorScheme.setAttribute("content", "light") | |
if(themeColor) themeColor.setAttribute("content", light) | |
} | |
window.updateTheme = function(theme) { | |
switch(theme) { | |
case "light": | |
localStorage.theme = "light" | |
lightMode() | |
break; | |
case "dark": | |
localStorage.theme = "dark" | |
darkMode() | |
break; | |
default: | |
localStorage.removeItem("theme") | |
prefersDark.matches ? darkMode() : lightMode() | |
break; | |
} | |
} | |
prefersDark.addEventListener("change", e => { | |
if (localStorage.theme) return | |
e.matches ? darkMode() : lightMode() | |
}); | |
updateTheme(localStorage.theme) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// loaded with a <script defer> in <head> so the DOM is present so it can find the element. | |
const el = document.getElementById("themeChooser") | |
if(el) { | |
const currentTheme = window.currentTheme() | |
const option = document.getElementById(`theme-${currentTheme}`) | |
if(option) { option.selected = currentTheme === option.value } | |
el.addEventListener("change", (e) => window.updateTheme(e.target.value)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment