79 أسطر
2.3 KiB
TypeScript
79 أسطر
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import type { Language } from "@/data/portfolio";
|
|
|
|
type Theme = "light" | "dark";
|
|
|
|
const STORAGE_KEY = "grace-portfolio-theme";
|
|
|
|
function applyTheme(theme: Theme) {
|
|
document.documentElement.dataset.theme = theme;
|
|
document.documentElement.style.colorScheme = theme;
|
|
}
|
|
|
|
export function ThemeToggle({ language }: { language: Language }) {
|
|
const [theme, setTheme] = useState<Theme>("light");
|
|
|
|
useEffect(() => {
|
|
const savedTheme = window.localStorage.getItem(STORAGE_KEY);
|
|
const nextTheme = savedTheme === "dark" ? "dark" : "light";
|
|
applyTheme(nextTheme);
|
|
setTheme(nextTheme);
|
|
}, []);
|
|
|
|
const nextTheme: Theme = theme === "dark" ? "light" : "dark";
|
|
const label =
|
|
language === "ar"
|
|
? theme === "dark"
|
|
? "\u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u0648\u0636\u0639 \u0627\u0644\u0641\u0627\u062a\u062d"
|
|
: "\u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u0648\u0636\u0639 \u0627\u0644\u062f\u0627\u0643\u0646"
|
|
: theme === "dark"
|
|
? "Switch to light mode"
|
|
: "Switch to dark mode";
|
|
|
|
function handleToggle() {
|
|
applyTheme(nextTheme);
|
|
window.localStorage.setItem(STORAGE_KEY, nextTheme);
|
|
setTheme(nextTheme);
|
|
}
|
|
|
|
return (
|
|
<button type="button" className="theme-toggle" onClick={handleToggle} aria-label={label} title={label}>
|
|
<span className="sr-only">{label}</span>
|
|
<svg
|
|
className="sun-icon"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="1.8"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
aria-hidden="true"
|
|
>
|
|
<circle cx="12" cy="12" r="4" />
|
|
<path d="M12 2v2" />
|
|
<path d="M12 20v2" />
|
|
<path d="m4.93 4.93 1.41 1.41" />
|
|
<path d="m17.66 17.66 1.41 1.41" />
|
|
<path d="M2 12h2" />
|
|
<path d="M20 12h2" />
|
|
<path d="m6.34 17.66-1.41 1.41" />
|
|
<path d="m19.07 4.93-1.41 1.41" />
|
|
</svg>
|
|
<svg
|
|
className="moon-icon"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="1.8"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
aria-hidden="true"
|
|
>
|
|
<path d="M20.8 14.7A8.5 8.5 0 0 1 9.3 3.2 8.5 8.5 0 1 0 20.8 14.7Z" />
|
|
</svg>
|
|
</button>
|
|
);
|
|
}
|