mywork / src /components /layout /ThemeProvider.tsx
DeeCeeXxx's picture
Upload 114 files
e9d5b7d verified
"use client";
import { createContext, useContext, useEffect, useState, ReactNode } from 'react';
type Theme = 'light' | 'dark';
interface ThemeProviderProps {
children: ReactNode;
defaultTheme?: Theme;
storageKey?: string;
}
interface ThemeProviderState {
theme: Theme;
setTheme: (theme: Theme) => void;
}
const initialState: ThemeProviderState = {
theme: 'light', // Default to light if no specific default is provided or found
setTheme: () => null,
};
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export function ThemeProvider({
children,
defaultTheme = 'light',
storageKey = 'anita-deploy-ui-theme', // Specific storage key
}: ThemeProviderProps) {
const [theme, setTheme] = useState<Theme>(() => {
if (typeof window !== 'undefined') {
const storedTheme = localStorage.getItem(storageKey) as Theme | null;
if (storedTheme && (storedTheme === 'light' || storedTheme === 'dark')) {
return storedTheme;
}
// No valid theme in localStorage, check for system preference if defaultTheme is 'system'
// For simplicity now, we'll just use the passed defaultTheme or 'light'
// if (defaultTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// return 'dark';
// }
}
return defaultTheme === 'dark' ? 'dark' : 'light'; // Ensure a valid theme
});
useEffect(() => {
if (typeof window === 'undefined') return;
const root = window.document.documentElement;
root.classList.remove('light', 'dark');
root.classList.add(theme);
localStorage.setItem(storageKey, theme);
}, [theme, storageKey]);
const value = {
theme,
setTheme: (newTheme: Theme) => {
setTheme(newTheme);
},
};
return (
<ThemeProviderContext.Provider value={value}>
{children}
</ThemeProviderContext.Provider>
);
}
export const useTheme = () => {
const context = useContext(ThemeProviderContext);
if (context === undefined) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};