Implementing Seamless Light and Dark Modes in svgl
The Challenge
Maintaining visual consistency across different user preferences is essential for modern web applications. In the svgl project, we wanted to ensure that our UI components, particularly those handling layers, adapted gracefully to system-level theme changes without sacrificing accessibility or design integrity.
The Approach
To achieve a seamless transition between themes, we implemented a reactive approach that leverages TypeScript state management to toggle visual styles dynamically.
Reactive Theme State
We moved away from hardcoded style values and toward a theme-aware state. By defining a clear interface for our component styles, we can swap between light and dark configurations based on the user's current environment.
type Theme = 'light' | 'dark';
interface LayerStyles {
backgroundColor: string;
borderColor: string;
}
const getLayerStyles = (theme: Theme): LayerStyles => ({
backgroundColor: theme === 'light' ? '#ffffff' : '#1a1a1a',
borderColor: theme === 'light' ? '#e0e0e0' : '#333333',
});
This utility function allows components to resolve their visual properties at runtime, ensuring that colors are computed consistently across the application.
DOM-Level Integration
We hooked into system preference events to allow the application to respond immediately when a user toggles their operating system theme settings:
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => {
const newTheme = e.matches ? 'dark' : 'light';
updateComponentTheme(newTheme);
});
Final Result
By centralizing the theme logic, we achieved a more robust UI that respects user preferences by default. The application now automatically adjusts its layer borders and backgrounds without requiring a page refresh.
Key Takeaway
Never rely on static CSS variables for complex component states. Moving your theme logic into TypeScript interfaces allows you to leverage type safety while maintaining consistent, predictable UI behavior across light and dark modes.
Generated with Gitvlg.com