[Archived] Archived WIP of vielle.dev
at master 2.2 kB view raw
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>