106 lines
2.7 KiB
TypeScript
106 lines
2.7 KiB
TypeScript
import { themes } from "../config/theme.config";
|
|
|
|
export const applyTheme = (themeId: string) => {
|
|
const theme = themes.find((t) => t.id === themeId);
|
|
const root = document.documentElement;
|
|
|
|
if (theme) {
|
|
try {
|
|
root.setAttribute("data-theme", themeId);
|
|
localStorage.setItem("theme", themeId);
|
|
localStorage.setItem("theme-type", theme.type);
|
|
|
|
window.dispatchEvent(
|
|
new CustomEvent("themechange", {
|
|
detail: { theme: themeId, type: theme.type },
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
console.error("❌ Error applying theme:", error);
|
|
}
|
|
} else {
|
|
console.warn(`⚠️ Theme not found: ${themeId}, falling back to light theme`);
|
|
applyTheme("light");
|
|
}
|
|
};
|
|
|
|
export const getSavedTheme = () => {
|
|
try {
|
|
return localStorage.getItem("theme") || "light";
|
|
} catch (error) {
|
|
console.error("Error reading theme from localStorage:", error);
|
|
return "light";
|
|
}
|
|
};
|
|
|
|
export const initializeTheme = () => {
|
|
const savedTheme = getSavedTheme();
|
|
|
|
const themeExists = themes.some((t) => t.id === savedTheme);
|
|
const themeToApply = themeExists ? savedTheme : "light";
|
|
|
|
applyTheme(themeToApply);
|
|
return themeToApply;
|
|
};
|
|
|
|
export const getCurrentTheme = () => {
|
|
return document.documentElement.getAttribute("data-theme") || "light";
|
|
};
|
|
|
|
export const getCurrentThemeType = () => {
|
|
const currentTheme = getCurrentTheme();
|
|
const theme = themes.find((t) => t.id === currentTheme);
|
|
return theme ? theme.type : "light";
|
|
};
|
|
|
|
export const toggleDarkLight = () => {
|
|
const currentTheme = getCurrentTheme();
|
|
const currentThemeData = themes.find((t) => t.id === currentTheme);
|
|
|
|
if (currentThemeData) {
|
|
const oppositeThemes = themes.filter(
|
|
(t) => t.type !== currentThemeData.type,
|
|
);
|
|
if (oppositeThemes.length > 0) {
|
|
applyTheme(oppositeThemes[0].id);
|
|
return oppositeThemes[0].id;
|
|
}
|
|
}
|
|
|
|
const newTheme = currentTheme === "light" ? "dark" : "light";
|
|
applyTheme(newTheme);
|
|
return newTheme;
|
|
};
|
|
|
|
export const getNextTheme = () => {
|
|
const currentTheme = getCurrentTheme();
|
|
const currentIndex = themes.findIndex((t) => t.id === currentTheme);
|
|
const nextIndex = (currentIndex + 1) % themes.length;
|
|
return themes[nextIndex].id;
|
|
};
|
|
|
|
export const applySystemTheme = () => {
|
|
if (
|
|
window.matchMedia &&
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
) {
|
|
applyTheme("dark");
|
|
} else {
|
|
applyTheme("light");
|
|
}
|
|
};
|
|
|
|
export const watchSystemTheme = () => {
|
|
if (window.matchMedia) {
|
|
window
|
|
.matchMedia("(prefers-color-scheme: dark)")
|
|
.addEventListener("change", (e) => {
|
|
if (e.matches) {
|
|
applyTheme("dark");
|
|
} else {
|
|
applyTheme("light");
|
|
}
|
|
});
|
|
}
|
|
};
|