Files
imprink/ui/src/app/components/theme/ThemeContext.tsx
2025-06-25 15:17:44 +03:00

74 lines
2.0 KiB
TypeScript

'use client';
import React, {
createContext,
useContext,
useState,
useEffect,
ReactNode,
} from 'react';
interface ThemeContextType {
isDarkMode: boolean;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
interface ThemeContextProviderProps {
children: ReactNode;
}
export function ThemeContextProvider({ children }: ThemeContextProviderProps) {
const [isDarkMode, setIsDarkMode] = useState(true);
const [isInitialized, setIsInitialized] = useState(false);
useEffect(() => {
const savedTheme = localStorage.getItem('theme-preference');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const shouldBeDark = savedTheme ? savedTheme === 'dark' : systemPrefersDark;
setIsDarkMode(shouldBeDark);
setIsInitialized(true);
}, []);
useEffect(() => {
if (!isInitialized) return;
const savedTheme = localStorage.getItem('theme-preference');
if (savedTheme) return;
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleChange = (e: MediaQueryListEvent) => {
setIsDarkMode(e.matches);
};
mediaQuery.addEventListener('change', handleChange);
return () => mediaQuery.removeEventListener('change', handleChange);
}, [isInitialized]);
const toggleTheme = () => {
const newTheme = !isDarkMode;
setIsDarkMode(newTheme);
localStorage.setItem('theme-preference', newTheme ? 'dark' : 'light');
};
if (!isInitialized) {
return null;
}
return (
<ThemeContext.Provider value={{ isDarkMode, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme(): ThemeContextType {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeContextProvider');
}
return context;
}