Last active
August 7, 2025 05:11
-
-
Save Davis-3450/437feef2b9e7138309f2c8fb9162722c to your computer and use it in GitHub Desktop.
Theme switch for astro.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| placeholder | |
| --- | |
| <script is:inline> | |
| const getThemePreference = () => { | |
| if (typeof localStorage !== "undefined" && localStorage.getItem("theme")) { | |
| return localStorage.getItem("theme"); | |
| } | |
| return window.matchMedia("(prefers-color-scheme: dark)").matches | |
| ? "dark" | |
| : "light"; | |
| }; | |
| const isDark = getThemePreference() === "dark"; | |
| document.documentElement.classList[isDark ? "add" : "remove"]("dark"); | |
| if (typeof localStorage !== "undefined") { | |
| const observer = new MutationObserver(() => { | |
| const isDark = document.documentElement.classList.contains("dark"); | |
| localStorage.setItem("theme", isDark ? "dark" : "light"); | |
| }); | |
| observer.observe(document.documentElement, { | |
| attributes: true, | |
| attributeFilter: ["class"], | |
| }); | |
| } | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as React from "react"; | |
| import { Moon, Sun } from "lucide-react"; | |
| import { Button } from "@/components/ui/button"; // shadcn button | |
| export function ModeToggle() { | |
| const [theme, setThemeState] = React.useState<"light" | "dark">("light"); | |
| // Initialize theme from localStorage or DOM | |
| React.useEffect(() => { | |
| const savedTheme = localStorage.getItem("theme"); | |
| if (savedTheme) { | |
| setThemeState(savedTheme as "light" | "dark"); | |
| } else { | |
| // Fallback to DOM state | |
| const isDarkMode = document.documentElement.classList.contains("dark"); | |
| setThemeState(isDarkMode ? "dark" : "light"); | |
| } | |
| }, []); | |
| // Apply theme changes | |
| React.useEffect(() => { | |
| document.documentElement.classList[theme === "dark" ? "add" : "remove"]( | |
| "dark" | |
| ); | |
| localStorage.setItem("theme", theme); | |
| }, [theme]); | |
| const toggleTheme = () => { | |
| // toggle the theme to the opposite of the current theme | |
| setThemeState(theme === "dark" ? "light" : "dark"); | |
| }; | |
| return ( | |
| <Button variant="outline" size="icon" onClick={toggleTheme}> | |
| <Sun className="h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" /> | |
| <Moon className="absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" /> | |
| <span className="sr-only">Toggle theme</span> | |
| </Button> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment