[Archived] Archived WIP of vielle.dev
1---
2import Sun from "@/assets/sun.svg";
3import Moon from "@/assets/moon.svg";
4
5interface Props {
6 colours: {
7 bg: string;
8 fg: string;
9 };
10}
11
12const { colours } = Astro.props;
13---
14
15<button
16 aria-label="toggle colour scheme"
17 id="colour-toggle"
18 style="visibility: hidden"
19>
20 <Sun data-mode-light />
21 <Moon data-mode-dark />
22</button>
23
24<style define:vars={colours}>
25 #colour-toggle {
26 background-color: var(--bg);
27
28 border: none;
29 border-radius: 50%;
30 padding: 5px;
31
32 width: 34px;
33 height: 34px;
34
35 & svg {
36 fill: var(--fg);
37 stroke: var(--fg);
38 }
39 }
40</style>
41
42<script>
43 const root = document.querySelector(":root");
44 if (!(root instanceof HTMLElement)) throw new Error(":root is not html");
45
46 const button = document.getElementById("colour-toggle");
47 if (!button) throw new Error("No #colour-toggle element");
48
49 const modeToggled = {
50 light: document.querySelectorAll("[data-mode-light]"),
51 dark: document.querySelectorAll("[data-mode-dark]"),
52 };
53
54 const cookies = document.cookie
55 .split("; ")
56 .reduce<
57 Record<string, string>
58 >((prev, cur) => ({ ...prev, [cur.split("=")[0]]: cur.split("=")[1] }), {});
59
60 const mediaMode = matchMedia("(prefers-color-scheme: light)").matches;
61 const cookieMode =
62 cookies["colour-mode"] === "light"
63 ? true
64 : cookies["colour-mode"] === "dark"
65 ? false
66 : undefined;
67 let lightMode = cookieMode ?? mediaMode;
68
69 const updateColourScheme = () => {
70 root.style.colorScheme = lightMode ? "light" : "dark";
71 document.cookie = `colour-mode=${root.style.colorScheme};path=/`;
72
73 modeToggled[lightMode ? "light" : "dark"].forEach((el) => {
74 if (!(el instanceof SVGElement || el instanceof HTMLElement)) return;
75 el.style.display = "block";
76 });
77
78 modeToggled[!lightMode ? "light" : "dark"].forEach((el) => {
79 if (!(el instanceof SVGElement || el instanceof HTMLElement)) return;
80 el.style.display = "none";
81 });
82 };
83
84 updateColourScheme();
85 button.addEventListener("click", () => {
86 lightMode = !lightMode;
87 updateColourScheme();
88 });
89 button.style.visibility = "visible";
90</script>