summaryrefslogtreecommitdiff
path: root/src/components/ThemeToggle.astro
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/ThemeToggle.astro')
-rw-r--r--src/components/ThemeToggle.astro90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro
new file mode 100644
index 0000000..7621daf
--- /dev/null
+++ b/src/components/ThemeToggle.astro
@@ -0,0 +1,90 @@
+<theme-toggle class="ms-2 sm:ms-4">
+ <button class="hover:text-accent relative h-9 w-9 cursor-pointer rounded-md p-2" type="button">
+ <span class="sr-only">Dark Theme</span>
+ <svg
+ aria-hidden="true"
+ class="absolute start-1/2 top-1/2 h-7 w-7 -translate-x-1/2 -translate-y-1/2 scale-100 opacity-100 transition-all dark:scale-0 dark:opacity-0"
+ fill="none"
+ focusable="false"
+ id="sun-svg"
+ stroke-width="1.5"
+ viewBox="0 0 24 24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path
+ d="M12 18C15.3137 18 18 15.3137 18 12C18 8.68629 15.3137 6 12 6C8.68629 6 6 8.68629 6 12C6 15.3137 8.68629 18 12 18Z"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"></path>
+ <path d="M22 12L23 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M12 2V1" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path>
+ <path d="M12 23V22" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M20 20L19 19" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M20 4L19 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M4 20L5 19" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M4 4L5 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ <path d="M1 12L2 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
+ ></path>
+ </svg>
+ <svg
+ aria-hidden="true"
+ class="absolute start-1/2 top-1/2 h-7 w-7 -translate-x-1/2 -translate-y-1/2 scale-0 opacity-0 transition-all dark:scale-100 dark:opacity-100"
+ fill="none"
+ focusable="false"
+ id="moon-svg"
+ stroke="currentColor"
+ stroke-width="1.5"
+ viewBox="0 0 24 24"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <path d="M0 0h24v24H0z" fill="none" stroke="none"></path>
+ <path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"
+ ></path>
+ <path d="M17 4a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2"></path>
+ <path d="M19 11h2m-1 -1v2"></path>
+ </svg>
+ </button>
+</theme-toggle>
+
+<script>
+ // Note that if you fire the theme-change event outside of this component, it will not be reflected in the button's aria-checked attribute. You will need to add an event listener if you want that.
+ import { rootInDarkMode } from "@/utils/domElement";
+
+ class ThemeToggle extends HTMLElement {
+ constructor() {
+ super();
+ const button = this.querySelector<HTMLButtonElement>("button");
+
+ if (button) {
+ // set aria role value
+ button.setAttribute("role", "switch");
+ button.setAttribute("aria-checked", String(rootInDarkMode()));
+
+ // button event
+ button.addEventListener("click", () => {
+ // invert theme
+ let themeChangeEvent = new CustomEvent("theme-change", {
+ detail: {
+ theme: rootInDarkMode() ? "light" : "dark",
+ },
+ });
+ // dispatch event -> ThemeProvider.astro
+ document.dispatchEvent(themeChangeEvent);
+
+ // set the aria-checked attribute
+ button.setAttribute("aria-checked", String(rootInDarkMode()));
+ });
+ } else {
+ console.warn("Theme Toggle: No button found");
+ }
+ }
+ }
+
+ customElements.define("theme-toggle", ThemeToggle);
+</script>