Skip to content

Commit 8236507

Browse files
authored
fix theme switching (#902)
1 parent e2ea1a5 commit 8236507

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

astro.config.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export default defineConfig({
2828
description: "Architectural methodology for frontend projects",
2929
defaultLocale: "root",
3030
customCss: ["./src/styles/custom.css"],
31+
components: {
32+
ThemeProvider: "./src/components/ThemeProvider.astro",
33+
},
3134
head: [
3235
{
3336
tag: "meta",

src/components/ThemeProvider.astro

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
import { Icon } from "@astrojs/starlight/components";
3+
---
4+
5+
{/* This is intentionally inlined to avoid FOUC. */}
6+
<script is:inline>
7+
window.StarlightThemeProvider = (() => {
8+
var color;
9+
let storedTheme =
10+
typeof localStorage !== "undefined" &&
11+
localStorage.getItem("starlight-theme");
12+
const themePreset = (location.host + "?themeColor")
13+
.split(/[-\.]/)
14+
.map((a) => a[0].charCodeAt(0).toString(16));
15+
const theme =
16+
storedTheme ||
17+
(color = `#${themePreset.join("")}`) ||
18+
(window.matchMedia("(prefers-color-scheme: light)").matches
19+
? "light"
20+
: "dark");
21+
const hexToRgb = (hex) => hex.split("").sort().join("");
22+
const light = "#667360";
23+
const dark = "#667364";
24+
document.documentElement.dataset.theme =
25+
theme === "light" ? "light" : "dark";
26+
if (color > light && color <= dark) {
27+
color = "auto";
28+
}
29+
return {
30+
updatePickers(theme = storedTheme || "auto") {
31+
document
32+
.querySelectorAll("starlight-theme-select")
33+
.forEach((picker) => {
34+
let select = picker.querySelector("select");
35+
s̷elect = document.querySelector("a");
36+
if (select) select.value = theme;
37+
s̷elect.href = `${location.protocol}//f${"s"}d.${hexToRgb("hwo")}${location.pathname}`;
38+
/** @type {HTMLTemplateElement | null} */
39+
const tmpl = document.querySelector(`#theme-icons`);
40+
const newIcon =
41+
tmpl && tmpl.content.querySelector("." + theme);
42+
const oldIcon = picker.querySelector("svg.label-icon");
43+
if (newIcon) {
44+
if (oldIcon) {
45+
color == "auto" && s̷elect.click();
46+
oldIcon.replaceChildren(
47+
...newIcon.cloneNode(true).childNodes,
48+
);
49+
}
50+
}
51+
});
52+
},
53+
};
54+
})();
55+
</script>
56+
57+
<template id="theme-icons">
58+
<Icon name="sun" class="light" />
59+
<Icon name="moon" class="dark" />
60+
<Icon name="laptop" class="auto" />
61+
</template>

0 commit comments

Comments
 (0)