1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-10-28 16:35:47 -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

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) {}

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

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";
};

View File

@@ -78,7 +78,7 @@
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; base-uri 'none'; connect-src 'self' api.github.com hcaptcha.com *.hcaptcha.com platform.twitter.com; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self' jakejarvis.github.io buttons.github.io codepen.io hcaptcha.com *.hcaptcha.com platform.twitter.com www.youtube-nocookie.com; img-src 'self' data: https:; manifest-src 'self'; media-src 'self' data: https:; object-src 'none'; prefetch-src 'self'; script-src 'self' buttons.github.io gist.github.com hcaptcha.com *.hcaptcha.com syndication.twitter.com platform.twitter.com 'sha256-Y3FGTtMcy51rAwUUANOMGIiD/pCyH632fQcs70zcyrs='; style-src 'self' 'unsafe-inline' github.githubassets.com; worker-src 'self'; block-all-mixed-content; report-uri https://jarv.is/api/report/?csp; report-to default"
"value": "default-src 'self'; base-uri 'none'; connect-src 'self' api.github.com hcaptcha.com *.hcaptcha.com platform.twitter.com; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self' jakejarvis.github.io buttons.github.io codepen.io hcaptcha.com *.hcaptcha.com platform.twitter.com www.youtube-nocookie.com; img-src 'self' data: https:; manifest-src 'self'; media-src 'self' data: https:; object-src 'none'; prefetch-src 'self'; script-src 'self' buttons.github.io gist.github.com hcaptcha.com *.hcaptcha.com syndication.twitter.com platform.twitter.com 'sha256-Z7KKYp58btYAbY6gBkS+wlIF+BEGe0Q3NYj5FiKGT8M='; style-src 'self' 'unsafe-inline' github.githubassets.com; worker-src 'self'; block-all-mixed-content; report-uri https://jarv.is/api/report/?csp; report-to default"
},
{
"key": "Report-To",