48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import * as React from "react";
|
|
|
|
// --- Icons ---
|
|
import { MoonStarIcon } from "@/components/shared/tiptap/tiptap-icons/moon-star-icon";
|
|
import { SunIcon } from "@/components/shared/tiptap/tiptap-icons/sun-icon";
|
|
// --- UI Primitives ---
|
|
import { Button } from "@/components/shared/tiptap/tiptap-ui-primitive/button";
|
|
|
|
export function ThemeToggle() {
|
|
const [isDarkMode, setIsDarkMode] = React.useState<boolean>(false);
|
|
|
|
React.useEffect(() => {
|
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
const handleChange = () => setIsDarkMode(mediaQuery.matches);
|
|
mediaQuery.addEventListener("change", handleChange);
|
|
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
}, []);
|
|
|
|
React.useEffect(() => {
|
|
const initialDarkMode =
|
|
!!document.querySelector('meta[name="color-scheme"][content="dark"]') ||
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
setIsDarkMode(initialDarkMode);
|
|
}, []);
|
|
|
|
React.useEffect(() => {
|
|
document.documentElement.classList.toggle("dark", isDarkMode);
|
|
}, [isDarkMode]);
|
|
|
|
const toggleDarkMode = () => setIsDarkMode((isDark) => !isDark);
|
|
|
|
return (
|
|
<Button
|
|
onClick={toggleDarkMode}
|
|
aria-label={`Switch to ${isDarkMode ? "light" : "dark"} mode`}
|
|
data-style="ghost"
|
|
>
|
|
{isDarkMode ? (
|
|
<MoonStarIcon className="tiptap-button-icon" />
|
|
) : (
|
|
<SunIcon className="tiptap-button-icon" />
|
|
)}
|
|
</Button>
|
|
);
|
|
}
|