mirror of
https://github.com/domfelipe/mika-agent-assist.git
synced 2026-08-07 20:16:42 +00:00
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
|
|
|
|
type Theme = "light" | "dark";
|
|
type ThemeContextValue = {
|
|
theme: Theme;
|
|
setTheme: (t: Theme) => void;
|
|
toggleTheme: () => void;
|
|
};
|
|
|
|
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
const STORAGE_KEY = "mika-theme";
|
|
|
|
function applyTheme(theme: Theme) {
|
|
if (typeof document === "undefined") return;
|
|
const root = document.documentElement;
|
|
if (theme === "dark") root.classList.add("dark");
|
|
else root.classList.remove("dark");
|
|
root.style.colorScheme = theme;
|
|
}
|
|
|
|
function getInitialTheme(): Theme {
|
|
if (typeof window === "undefined") return "light";
|
|
try {
|
|
const stored = window.localStorage.getItem(STORAGE_KEY);
|
|
if (stored === "light" || stored === "dark") return stored;
|
|
} catch {}
|
|
if (window.matchMedia?.("(prefers-color-scheme: dark)").matches) return "dark";
|
|
return "light";
|
|
}
|
|
|
|
export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
const [theme, setThemeState] = useState<Theme>("light");
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const t = getInitialTheme();
|
|
setThemeState(t);
|
|
applyTheme(t);
|
|
setMounted(true);
|
|
}, []);
|
|
|
|
const setTheme = (t: Theme) => {
|
|
setThemeState(t);
|
|
applyTheme(t);
|
|
try {
|
|
window.localStorage.setItem(STORAGE_KEY, t);
|
|
} catch {}
|
|
};
|
|
|
|
const toggleTheme = () => setTheme(theme === "dark" ? "light" : "dark");
|
|
|
|
return (
|
|
<ThemeContext.Provider value={{ theme, setTheme, toggleTheme }}>
|
|
<div style={{ visibility: mounted ? "visible" : "visible" }}>{children}</div>
|
|
</ThemeContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useTheme() {
|
|
const ctx = useContext(ThemeContext);
|
|
if (!ctx) throw new Error("useTheme deve ser usado dentro de ThemeProvider");
|
|
return ctx;
|
|
}
|