Add user-controlled dark/light mode toggle#65
Merged
Conversation
Adds a theme preference system allowing users to choose between light mode, dark mode, or system (OS) preference. New `theme` column on users table stores the preference, theme selector appears on account settings page, and a Stimulus controller manages dynamic theme switching. CSS media queries replaced with data-theme attribute selectors for consistent control. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Devise requires current_password for all updates, which causes a re-render with 200 status that Turbo rejects. Custom registrations controller skips password validation when only non-sensitive fields like theme are being changed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The inline flash message script expects toastr as a global, but it was only pinned in the importmap without being imported. This causes a ReferenceError during Turbo page navigations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Turbo replaces the body on navigation but does not update html element attributes. Moving data-theme and the Stimulus controller to body ensures theme is applied after Turbo page transitions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous approach used <%= with a raw string containing quotes, which ERB HTML-escaped to ", causing the attribute value to include literal quote characters. Now uses a simple attribute with ERB value interpolation which avoids the escaping issue. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously the controller only set data-theme when the preference was "system", relying on the server-rendered attribute for explicit dark/light. Now it always applies the correct theme on connect, making it resilient to Turbo body replacements or reconnections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Stimulus controller on <body> wasn't connecting reliably. Replace it with a small inline script that runs immediately when the body is parsed, resolving "system" to the OS preference and listening for real-time OS preference changes. For explicit dark/light, the server-rendered data-theme attribute is used directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The app has three layout files. The theme data-attribute and inline script were only in application.html.erb. Add the same theme logic to home.html.erb and devise.html.erb so dark/light mode works on all pages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the inline theme script to shared/_theme.html.erb and add a theme_preference helper method. All three layouts now use the partial and helper instead of duplicating the theme code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a cycling theme toggle button (light/dark/system) to the home page header, theme API endpoint, and supporting styles. Move theme preference to a shared mutable variable (window.__themePref) so the matchMedia listener stays in sync after client-side toggles without a page reload. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a theme preference system allowing users to choose between light mode, dark mode, or following their system (OS) preference. Users can control this setting on their account settings page, and the theme is persisted in the database.
Changes
themecolumn on users table (defaults to "system") with validation for light/dark/system valuesTesting
bin/rails db:migrate🤖 Generated with Claude Code