49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import React, { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
|
|
import { darkTheme, lightTheme } from '../types/theme';
|
|
import type { ThemeColors } from '../types/theme';
|
|
|
|
interface ThemeContextValue {
|
|
isDark: boolean;
|
|
theme: ThemeColors;
|
|
toggleTheme: () => void;
|
|
}
|
|
|
|
const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
|
|
|
|
export const useTheme = (): ThemeContextValue => {
|
|
const context = useContext(ThemeContext);
|
|
if (!context) {
|
|
throw new Error('useTheme must be used within a ThemeProvider');
|
|
}
|
|
return context;
|
|
};
|
|
|
|
interface ThemeProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
|
const [isDark, setIsDark] = useState<boolean>(true);
|
|
const theme = isDark ? darkTheme : lightTheme;
|
|
|
|
const toggleTheme = () => {
|
|
setIsDark((prev) => !prev);
|
|
};
|
|
|
|
// Apply class to document for Tailwind dark mode + body background
|
|
useEffect(() => {
|
|
if (isDark) {
|
|
document.documentElement.classList.add('dark');
|
|
document.body.style.background = '#0a0a12';
|
|
} else {
|
|
document.documentElement.classList.remove('dark');
|
|
document.body.style.background = '#ffffff';
|
|
}
|
|
}, [isDark]);
|
|
|
|
return (
|
|
<ThemeContext.Provider value={{ isDark, theme, toggleTheme }}>
|
|
{children}
|
|
</ThemeContext.Provider>
|
|
);
|
|
}; |