Files
portfolio/src/components/ThemeSwitcher.astro

115 lines
3.0 KiB
Plaintext

---
import { Icon } from "astro-icon/components";
---
<span
class="theme:switcher flex justify-center text-center align-middle text-2xl"
onclick="toggleTheme()"
>
<span class="theme:light-mode">
<Icon name="fa7-solid:sun" />
</span>
<span class="theme:dark-mode">
<Icon name="fa7-solid:moon" />
</span>
</span>
<script is:inline>
function updateThemeIconAndAriaLabel(
currentTheme = theme.getTheme(),
systemTheme = theme.getSystemTheme()
) {
if (
currentTheme === "dark" ||
(currentTheme === "auto" && systemTheme === "dark")
) {
updateToDark();
} else if (
currentTheme === "light" ||
(currentTheme === "auto" && systemTheme === "light")
) {
updateToLight();
}
}
function updateToDark() {
const lightModeIcons = document.getElementsByClassName("theme:light-mode");
const darkModeIcons = document.getElementsByClassName("theme:dark-mode");
for (let icon of lightModeIcons) {
icon.classList.add("hidden");
}
for (let icon of darkModeIcons) {
icon.classList.remove("hidden");
}
const themeSwitchers = document.getElementsByClassName("theme:switcher");
for (let switcher of themeSwitchers) {
switcher.setAttribute(
"aria-label",
"Theme toggle button: click to activate light mode."
);
}
}
function updateToLight() {
const lightModeIcons = document.getElementsByClassName("theme:light-mode");
const darkModeIcons = document.getElementsByClassName("theme:dark-mode");
for (let icon of lightModeIcons) {
icon.classList.remove("hidden");
}
for (let icon of darkModeIcons) {
icon.classList.add("hidden");
}
const themeSwitchers = document.getElementsByClassName("theme:switcher");
for (let switcher of themeSwitchers) {
switcher.setAttribute(
"aria-label",
"Theme toggle button: click to activate dark mode."
);
}
}
function toggleTheme() {
const currentTheme = theme.getTheme();
const defaultTheme = theme.getDefaultTheme();
const systemTheme = theme.getSystemTheme();
let newTheme;
if (defaultTheme === "auto") {
newTheme =
currentTheme === "auto" || currentTheme === systemTheme
? systemTheme === "dark"
? "light"
: "dark"
: "auto";
} else {
newTheme =
currentTheme === defaultTheme
? defaultTheme === "dark"
? "light"
: "dark"
: currentTheme === "auto"
? systemTheme === "dark"
? "light"
: "dark"
: defaultTheme;
}
theme.setTheme(newTheme);
updateThemeIconAndAriaLabel(newTheme, systemTheme);
}
document.addEventListener("theme-changed", (e) =>
updateThemeIconAndAriaLabel(e.detail.currentTheme, e.detail.systemTheme)
);
updateThemeIconAndAriaLabel();
document.addEventListener("astro:after-swap", () => {
updateThemeIconAndAriaLabel();
});
</script>