theme-provider.tsx - Application Theme Management¶
Purpose¶
The theme-provider.tsx
file provides centralized theme management for the ReViewPoint application, handling light/dark mode switching, theme persistence, and system preference detection. It implements a React context-based theme system with automatic color scheme management.
Key Components¶
ThemeContext Interface¶
interface ThemeContextType {
mode: ThemeMode; // Current theme mode ('light' | 'dark' | 'system')
setMode: (mode: ThemeMode) => void; // Manual theme setter
toggleMode: () => void; // Toggle between light/dark
colors: ThemeColors; // Current color palette
}
Theme Provider Component¶
- Theme Persistence: Automatically saves theme preference to localStorage
- System Detection: Respects user's system color scheme preference
- Color Management: Provides current color palette based on selected theme
- Theme Switching: Supports manual and automatic theme transitions
Theme Modes¶
- Light: Default light theme with bright color palette
- Dark: Dark theme with dimmed color palette optimized for low-light usage
- System: Automatically follows system color scheme preference
Implementation Details¶
Theme Initialization¶
// Priority order for theme detection:
1. localStorage saved preference
2. System color scheme (if enableSystem is true)
3. Default theme (light)
Color Palette Management¶
The provider automatically selects the appropriate color palette:
System Theme Detection¶
// Detects system preference using media query
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
Dependencies¶
Core Dependencies¶
React
- Context API and state management@/logger
- Theme change logging and error tracking
Theme Configuration¶
Usage Examples¶
Basic Theme Provider Setup¶
import { ThemeProvider } from '@/lib/theme/theme-provider';
function App() {
return (
<ThemeProvider defaultTheme="light" enableSystem={true}>
<YourApplication />
</ThemeProvider>
);
}
Using Theme Context¶
import { useTheme } from '@/lib/theme/theme-provider';
function ThemeToggle() {
const { mode, toggleMode, setMode } = useTheme();
return (
<button onClick={toggleMode}>
Current: {mode}
</button>
);
}
Accessing Theme Colors¶
function ThemedComponent() {
const { colors } = useTheme();
return (
<div style={{
backgroundColor: colors.background,
color: colors.foreground
}}>
Themed content
</div>
);
}
Theme Persistence¶
Local Storage Integration¶
- Storage Key:
reviewpoint-theme
- Automatic Saving: Theme changes are immediately persisted
- Cross-Session: Theme preference maintained across browser sessions
Error Handling¶
// Graceful fallback for localStorage issues
try {
localStorage.setItem(THEME_STORAGE_KEY, newMode);
} catch (error) {
logger.warn("Theme persistence failed", error);
// Continue with in-memory theme state
}
System Integration¶
CSS Variables¶
The theme provider updates CSS custom properties for global theme application:
:root {
--background: theme-colors-background;
--foreground: theme-colors-foreground;
--primary: theme-colors-primary;
/* Additional theme variables */
}
Media Query Sync¶
// Listens for system theme changes
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", handleSystemThemeChange);
Configuration Options¶
ThemeProvider Props¶
interface ThemeProviderProps {
children: React.ReactNode;
defaultTheme?: ThemeMode; // Initial theme mode
enableSystem?: boolean; // Enable system preference detection
}
Default Configuration¶
- Default Theme:
light
- System Detection:
enabled
- Storage Persistence:
enabled
Related Files¶
- colors.ts - Theme color definitions and palette configuration
- useTheme.ts - Theme context hook for component usage
- ThemeToggle.tsx - UI component for theme switching
Performance Considerations¶
Theme Switching Optimization¶
- Immediate Updates: Theme changes are applied instantly without flicker
- Minimal Re-renders: Context updates only trigger re-renders for consuming components
- Efficient Storage: localStorage operations are optimized and error-handled
Memory Management¶
- Event Cleanup: Media query listeners are properly cleaned up on unmount
- Lightweight Context: Theme context contains minimal state for optimal performance
Development Notes¶
Adding New Themes¶
- Define new theme colors in
colors.ts
- Update
ThemeMode
type definition - Add theme detection logic in provider
- Update theme switching logic
Theme Testing¶
// Test theme persistence
localStorage.setItem("reviewpoint-theme", "dark");
// Reload page to verify theme restoration
// Test system theme detection
// Change system preference and verify automatic update
Debugging Theme Issues¶
- Check browser console for theme-related logs
- Verify localStorage contains correct theme value
- Ensure CSS custom properties are updated correctly
- Test theme switching across different components