Feature/theme toggle#26
Merged
Merged
Conversation
Adds a ThemePreference store field (default 'system'), a cycle button in the AppShell topbar (system → light → dark → system) and bridges the preference to <html data-theme=…>. CSS now applies the light palette either via the OS prefers-color-scheme media query or via data-theme=light, and falls through to dark defaults when data-theme=dark or unset on a dark-preferring OS. useColorScheme mirrors the same priority so the Konva canvas colors stay in sync. Locale keys (themeToggle, themeSystem, themeLight, themeDark) added in all 32 locales.
The system mode added complexity (3-state cycle, conditional CSS
fallbacks, separate handling in useColorScheme) for a niche benefit
nobody really sees: tracking the OS auto-switching schedule. Most
modern label tools just take the OS preference once and let the user
override.
Now the store stamps the initial theme from prefers-color-scheme on
first load and treats it as a stored preference afterwards. The toggle
is a 2-state button (Sun/Moon) that flips between light and dark and
shows the destination as its tooltip. CSS only carries the
data-theme=light override; data-theme=dark falls through to the dark
defaults. useColorScheme is now a one-liner.
Removes themeSystem locale key and rewrites themeLight/themeDark to
action-oriented strings ('Light theme' / 'Helles Design'). Adds a
matchMedia stub to the test setup since the store now reads it at
import time.
The 'system' theme value only existed on a feature branch that was never merged, so no production localStorage carries it. The catch-all 'not light/dark → delete' clause is also redundant: zustand-persist already falls back to the initializer default when a field is missing or invalid. Removing both keeps migrateLegacy focused on real shipped schema changes.
There was a problem hiding this comment.
Code Review
This pull request introduces a theme toggle system that allows users to switch between light and dark modes, with the preference persisted in the label store and synchronized to the DOM. The changes include new UI components, updated hooks, and extensive localization support. Feedback identifies a potential runtime error in environments where window is undefined, a risk of Flash of Unstyled Content (FOUC) caused by the removal of CSS media queries, and a limitation in the persistence logic that prevents the application from tracking system theme changes after the initial load.
Inline script in index.html reads the persisted theme (or falls back to prefers-color-scheme on first ever load) and stamps data-theme on <html> synchronously before React mounts. Removes the dark→light flash that light-theme users would otherwise see while the AppShell bridge effect is still queueing. Wrapped in try/catch so a malformed cache entry just falls through to the dark default — no chance of a blank page from the inline script.
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.
No description provided.