turash/bugulma/frontend/contexts/ThemeContext.tsx
Damir Mukimov 6347f42e20
Consolidate repositories: Remove nested frontend .git and merge into main repository
- Remove nested git repository from bugulma/frontend/.git
- Add all frontend files to main repository tracking
- Convert from separate frontend/backend repos to unified monorepo
- Preserve all frontend code and development history as tracked files
- Eliminate nested repository complexity for simpler development workflow

This creates a proper monorepo structure with frontend and backend
coexisting in the same repository for easier development and deployment.
2025-11-25 06:02:57 +01:00

74 lines
1.8 KiB
TypeScript

import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
type Theme = 'dark' | 'light';
type ThemeProviderProps = {
// FIX: Made children optional to handle cases where the type checker doesn't correctly infer JSX children.
children?: ReactNode;
defaultTheme?: Theme;
storageKey?: string;
};
type ThemeProviderState = {
theme: Theme;
setTheme: (theme: Theme) => void;
};
const initialState: ThemeProviderState = {
theme: 'light',
setTheme: () => null,
};
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
export function ThemeProvider({
children,
defaultTheme = 'light',
storageKey = 'ui-theme',
}: ThemeProviderProps) {
const [theme, setTheme] = useState<Theme>(() => {
try {
const item = window.localStorage.getItem(storageKey);
if (item) {
return item as Theme;
}
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
return prefersDark ? 'dark' : 'light';
} catch {
return defaultTheme;
}
});
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove('light', 'dark');
root.classList.add(theme);
try {
window.localStorage.setItem(storageKey, theme);
} catch (e) {
console.error('Failed to save theme to localStorage', e);
}
}, [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;
};