mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-06-29 20:06:00 -04:00
move light/dark class from <body> to <html> and inline restoration script to (hopefully) improve the white flashes
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/* 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.
|
||||
|
||||
import { getDarkPref } 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");
|
||||
}
|
||||
|
||||
// TODO: fix real-time switching (works but bulb icon isn't updated)
|
||||
// window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => e.matches && setDark(true));
|
||||
// window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", (e) => e.matches && setDark(false));
|
||||
} catch (error) {}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { h } from "preact";
|
||||
import { useState, useEffect } from "preact/hooks";
|
||||
import { isDark, setDarkClass, setDarkPref } from "../utils/theme.js";
|
||||
import { isDark, setDarkPref } from "../utils/theme.js";
|
||||
|
||||
// react components:
|
||||
import BulbOn from "../assets/bulb-on.svg";
|
||||
@@ -11,7 +11,9 @@ const ThemeToggle = () => {
|
||||
const [dark, setDark] = useState(isDark());
|
||||
|
||||
useEffect(() => {
|
||||
return setDarkClass(dark);
|
||||
// sets appropriate `<html class="...">`
|
||||
document.documentElement.classList.remove("dark", "light");
|
||||
document.documentElement.classList.add(dark ? "dark" : "light");
|
||||
}, [dark]);
|
||||
|
||||
const handleToggle = () => {
|
||||
|
||||
@@ -1,28 +1,8 @@
|
||||
import { h, render } from "preact";
|
||||
import { getDarkPref, setDarkClass } from "./utils/theme.js";
|
||||
|
||||
// react components:
|
||||
import ThemeToggle from "./components/ThemeToggle.js";
|
||||
|
||||
// check for existing preference in local storage
|
||||
const pref = getDarkPref();
|
||||
|
||||
// do initialization before *any* react-related stuff to avoid white flashes as much as possible
|
||||
if (pref) {
|
||||
// restore user's preference if they've explicitly toggled it in the past
|
||||
setDarkClass(pref === "true");
|
||||
} else {
|
||||
// check for OS dark mode preference and switch accordingly
|
||||
// https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme
|
||||
try {
|
||||
setDarkClass(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
||||
} catch (e) {}
|
||||
|
||||
// TODO: fix real-time switching (works but bulb icon isn't updated)
|
||||
// window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => e.matches && setDark(true));
|
||||
// window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", (e) => e.matches && setDark(false));
|
||||
}
|
||||
|
||||
// finally render the nifty lightbulb in the header
|
||||
if (typeof window !== "undefined" && document.querySelector(".theme-toggle")) {
|
||||
render(<ThemeToggle />, document.querySelector(".theme-toggle"));
|
||||
|
||||
@@ -3,17 +3,6 @@ const storageKey = "dark_mode";
|
||||
export const getDarkPref = () => localStorage.getItem(storageKey);
|
||||
export const setDarkPref = (pref) => localStorage.setItem(storageKey, pref);
|
||||
|
||||
// use the body class as a hint to what the theme was set to outside of the button component
|
||||
// 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.body.classList?.contains("dark");
|
||||
|
||||
// sets appropriate `<body class="...">`
|
||||
export const setDarkClass = (dark) => {
|
||||
if (dark) {
|
||||
document.body.classList.add("dark");
|
||||
document.body.classList.remove("light");
|
||||
} else {
|
||||
document.body.classList.add("light");
|
||||
document.body.classList.remove("dark");
|
||||
}
|
||||
};
|
||||
export const isDark = () => document.documentElement.classList.contains("dark");
|
||||
|
||||
Reference in New Issue
Block a user