1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2026-06-29 19:05:58 -04:00

set the color-scheme CSS property to either light or dark onChange

https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme
This commit is contained in:
2021-12-16 19:53:13 -05:00
parent 7fbdf16573
commit 6bfbc363d7
4 changed files with 30 additions and 20 deletions
+8 -12
View File
@@ -1,17 +1,13 @@
/* eslint-disable no-var */
// A super tiny script to restore dark mode off the bat (to hopefully avoid blinding flashes of white).
// NOTE: This is inlined by Hugo/esbuild (see layouts/partials/head/restore-theme.html) instead of Webpack.
// ANOTHER NOTE: Whenever this code is changed, its (minified) CSP hash *MUST* be updated manually in vercel.json.
import { getDarkPref } from "./src/utils/theme.js";
import { getDarkPref, updateDOM } from "./src/utils/theme.js";
try {
var cl = document.documentElement.classList;
var pref = getDarkPref();
// set `<html class="dark">` if either the user has explicitly toggled in the past or if their OS is in dark mode
if (pref === "true" || (!pref && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
cl.remove("light");
cl.add("dark");
}
} catch (error) {}
// Set root class and color-scheme property to dark if either...
// - the user has explicitly toggled it previously.
// - the user's OS is in dark mode.
const pref = getDarkPref();
updateDOM(pref === "true" || (!pref && window.matchMedia("(prefers-color-scheme: dark)").matches));
} catch (e) {}
+3 -6
View File
@@ -1,6 +1,6 @@
import { h } from "preact";
import { useState, useEffect, useCallback } from "preact/hooks";
import { isDark, getDarkPref, setDarkPref } from "../utils/theme.js";
import { isDark, getDarkPref, setDarkPref, updateDOM } from "../utils/theme.js";
// react components:
import BulbOn from "../assets/bulb-on.svg";
@@ -28,11 +28,8 @@ const ThemeToggle = () => {
} catch (e) {}
}, [saved, matchCallback]);
useEffect(() => {
// sets appropriate `<html class="...">`
document.documentElement.classList.remove("dark", "light");
document.documentElement.classList.add(dark ? "dark" : "light");
}, [dark]);
// sets appropriate `<html class="...">` and `color-scheme` CSS property when mode changes
useEffect(() => updateDOM(dark), [dark]);
const handleToggle = () => {
// only update the local storage preference if the user explicitly presses the lightbulb
+18 -1
View File
@@ -1,3 +1,7 @@
// class names (`<html class="...">`) for each theme
const lightClass = "light";
const darkClass = "dark";
// store preference in local storage
const storageKey = "dark_mode";
export const getDarkPref = () => localStorage.getItem(storageKey);
@@ -5,4 +9,17 @@ export const setDarkPref = (pref) => localStorage.setItem(storageKey, pref);
// use the `<html class="...">` as a hint to what the theme was set to outside of the button component
// there's probably (definitely) a cleaner way to do this..?
export const isDark = () => document.documentElement.classList.contains("dark");
export const isDark = () => document.documentElement.classList.contains(darkClass);
// sets appropriate `<html class="...">` and `color-scheme` CSS property
export const updateDOM = (dark) => {
const root = document.documentElement;
// set `<html class="...">`
root.classList.remove(darkClass, lightClass);
root.classList.add(dark ? darkClass : lightClass);
// ...and the CSS `color-scheme` property:
// https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme
root.style.colorScheme = dark ? "dark" : "light";
};