Implement Dark/Light Theme Toggle with Persistence and Accessibility#38
Conversation
…nd accessibility Co-authored-by: rezwana-karim <126201034+rezwana-karim@users.noreply.github.com>
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive dark/light theme toggle system for the CodeStorm Hub website, replacing a previously disabled theme button with a fully functional theming solution. The implementation uses React Context API for state management, localStorage for persistence, and CSS custom properties for styling.
Key changes:
- Created a centralized theme management system with React Context
- Refactored existing theme hook to use the new context provider
- Updated CSS to use class-based theming instead of media queries
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/lib/theme-context.tsx |
New theme context provider with state management, persistence, and DOM manipulation |
src/hooks/use-theme.ts |
Simplified hook that delegates to the theme context |
src/app/layout.tsx |
Wrapped application with ThemeProvider for global theme access |
src/app/globals.css |
Converted from media query-based to class-based theming with enhanced dark mode support |
| setMounted(true) | ||
|
|
||
| // Check for stored theme preference or default to system preference | ||
| const stored = localStorage.getItem('theme') as Theme | null |
There was a problem hiding this comment.
The type assertion as Theme | null is unsafe. If localStorage contains an invalid theme value, the type assertion will succeed but the runtime check will fail. Consider using type guards or removing the assertion and relying only on the runtime validation.
| const stored = localStorage.getItem('theme') as Theme | null | |
| const stored = localStorage.getItem('theme') |
| useEffect(() => { | ||
| setMounted(true) | ||
|
|
||
| // Check for stored theme preference or default to system preference | ||
| const stored = localStorage.getItem('theme') as Theme | null | ||
| if (stored && (stored === 'light' || stored === 'dark')) { | ||
| setThemeState(stored) | ||
| applyTheme(stored) | ||
| } else { | ||
| // Check system preference | ||
| const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches | ||
| const systemTheme: Theme = prefersDark ? 'dark' : 'light' | ||
| setThemeState(systemTheme) | ||
| applyTheme(systemTheme) | ||
| } | ||
| }, []) |
There was a problem hiding this comment.
The localStorage.getItem() and window.matchMedia() calls should be wrapped in try-catch blocks to handle potential SecurityError exceptions in environments where these APIs are restricted (e.g., sandboxed iframes, private browsing modes).
This PR implements a fully functional dark/light theme switcher that resolves the disabled theme toggle button and adds complete theming support to the CodeStorm Hub website.
Problem
The theme toggle button in the header was previously disabled and non-functional, lacking the necessary infrastructure for theme management, persistence, and accessibility compliance.
Solution
Implemented a comprehensive theme system using React Context API with the following key components:
Theme Context Provider (
src/lib/theme-context.tsx)toggleTheme,setTheme, andmountedstate for proper hydrationEnhanced CSS Variables (
src/app/globals.css).dark)Layout Integration (
src/app/layout.tsx)ThemeProviderfor global theme accessHook Simplification (
src/hooks/use-theme.ts)Features
Screenshots
Light Theme
Dark Theme
Technical Details
The implementation follows React best practices and Next.js patterns:
mountedstate to prevent flash of unstyled contentTesting
The theme toggle button is now fully enabled and provides a polished dark/light mode experience for all users.
Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.