diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-03 10:56:21 +0300 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-03 10:56:21 +0300 |
| commit | 456cf011b36de91c9936994b1fa45703adcd309b (patch) | |
| tree | 8e60daf998f731ac50d100fa490eaecae1168042 /src/components/ThemeToggle.astro | |
Initial fork of chrismwilliams/astro-theme-cactus theme
Diffstat (limited to 'src/components/ThemeToggle.astro')
| -rw-r--r-- | src/components/ThemeToggle.astro | 90 |
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> |
