8000 feat: Enhanced theme switcher with system preference detection and tri-state selection by srambach · Pull Request #4639 · patternfly/patternfly-org · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: Enhanced theme switcher with system preference detection and tri-state selection #4639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 16, 2025

Conversation

srambach
Copy link
Member

🎨 Enhanced Theme Switcher Implementation

This PR implements a comprehensive theme switcher that provides users with three choices: System, Light, and Dark themes, with proper persistence and synchronization across the entire application.

✨ Features

  1. 🖥️ Automatic System Preference Detection

    • Detects user's prefers-color-scheme setting automatically
    • Dynamically responds to system theme changes in real-time
    • Defaults to system preference on first visit
  2. 🎯 Tri-State Theme Selection

    • System: Follow user's operating system preference
    • Light: Always use light theme regardless of system setting
    • Dark: Always use dark theme regardless of system setting
  3. 💾 Persistent User Preferences

    • Saves user's theme choice in localStorage
    • Persists across page reloads and browser sessions
    • Gracefully handles missing localStorage (SSR-safe)
  4. 🔄 Perfect Synchronization

    • Single source of truth for theme state
    • Synchronized between header switcher and full-screen examples
    • No more conflicting theme instances

🛠️ Implementation Details

New Shared Theme Hook (useTheme.js)

  • Centralized theme management with React hooks
  • Handles system preference detection and changes
  • Manages localStorage persistence
  • Applies theme classes to document root

Enhanced UI Components

  • Header: Replaced toggle with Select component showing current mode and descriptions
  • Full-screen examples: Consistent Select component with same options
  • Icons: Desktop, Sun, and Moon icons to clearly indicate each mode

Architecture Improvements

  • Moved theme management to SideNavLayout level for single source of truth
  • Eliminated duplicate theme logic between components
  • Props-based state sharing to prevent synchronization issues

🐛 Bug Fixes

  • ✅ Fixed system preference affecting UI when explicit theme is selected
  • ✅ Eliminated need for page reload after theme changes
  • ✅ Resolved theme synchronization issues between components
  • ✅ Improved SSR compatibility with proper client-side hydration

🎭 User Experience

  • Intuitive Selection: Clear labels and descriptions for each theme mode
  • Visual Feedback: Icons immediately show which mode is active
  • Consistent Behavior: Theme choice works identically across all pages
  • Responsive to System: Automatically adapts when user changes OS theme (in System mode)

📦 Files Changed

  • packages/documentation-framework/hooks/useTheme.js (new)
  • packages/documentation-framework/layouts/sideNavLayout/sideNavLayout.js
  • packages/documentation-framework/components/example/example.js

🧪 Testing

This implementation has been tested with:

  • ✅ Manual theme switching between all three modes
  • ✅ System preference changes (OS dark/light mode toggle)
  • ✅ Page re 8000 loads maintaining user preference
  • ✅ Full-screen example synchronization
  • ✅ Browser sessions and localStorage persistence

🎯 Addresses

This implementation builds upon and completes the work started in PR #4367, providing the full tri-state theme selection that was originally requested while fixing the synchronization issues that prevented the earlier implementation from being merged.


Ready for review! 🚀

srambach added 2 commits May 30, 2025 16:53
… theme management

- Added FullScreenThemeSelector component for theme selection with icons.
- Introduced useTheme hook to manage theme state and preferences.
- Replaced previous dark theme switcher with a dropdown for theme selection in HeaderTools and Example components.
- Updated SideNavLayout to utilize the new theme management system.
@patternfly-build
Copy link
Contributor
patternfly-build commented Jun 2, 2025

Copy link
Member
@rebeccaalpert rebeccaalpert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you and your robot friend did a good job. I read through and it seems understandable. I just left a few nitpicky comments about the switches, but you're free to ignore. It won't cause any problems if it's left as-is.

Gotta figure out my back-up plan for when our robot overlords put me out of work. :)

< 8000 div class="">
@andrew-ronaldson
Copy link
Contributor

Can we force the dropdown to show a generic name rather than system? @edonehoo any thoughts on verbiage?
Also can we move it next to the release dropdown so the icon buttons aren't sandwiched

@edonehoo
Copy link
Collaborator
edonehoo commented Jun 2, 2025

I would recommend "System theme", "Light theme", "Dark theme" as the toggle text to reflect what's selected or pre-selected

Or you could just have "Theme" and not show selections in the toggle (like Atlassian does)

@andrew-ronaldson
Copy link
Contributor

Theme may get confusing as we have a distinction between themes and modes. A new Red Hat theme would have light/dark modes.

Copy link
Contributor
@thatblindgeye thatblindgeye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the comment below, one non-blocker I'm noticing is when the page first loads, the "System" default can be seen before updating to the theme selection in local storage (at least when "Light" is the stored theme). It happens really quickly and probably only noticeable if you're looking for it, but if it is something we'd want to take care of a followup issue would be fine (but also if we want to see if astro will handle it we can do that sa well).

@edonehoo
Copy link
Collaborator
edonehoo commented Jun 2, 2025

Good point, could say "Display mode" instead?

If we want to move away from light/dark "theme" and towards "mode", it would be good to reflect that in the code (rather than the vars/methods like useTheme getStoredThemeMode) and the docs consistently. Otherwise, it feels like we're scrambling the language we're using with devs vs designers (and so on, etc)

Copy link
@sg00dwin sg00dwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work Sarah!

@rebeccaalpert rebeccaalpert merged commit 1b05742 into patternfly:main Jun 16, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0