✨(frontend) add dark / light / system colour-mode switcher - #2519
✨(frontend) add dark / light / system colour-mode switcher#2519MashdorDev wants to merge 6 commits into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds persisted light, dark, and system color-mode state with system preference resolution. Theme providers hydrate stored preferences, synchronize operating-system changes, and preserve configured brand themes. A pre-hydration document script applies the initial theme class. The new translated Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/frontend/apps/impress/src/components/ThemeSwitch.tsx`:
- Around line 30-42: Update the ThemeSwitch component’s DropdownMenu usage to
remove selectedValues, allowing the single-choice theme options to use radio
semantics via isSelected. Also remove the redundant inner aria-label while
retaining the DropButton label.
In `@src/frontend/apps/impress/src/core/config/ThemeProvider.tsx`:
- Around line 22-35: Prevent the OS color-scheme listener in ThemeProvider from
overriding brand themes: when onChange checks the store, only call
setThemeMode('system') if themeMode is 'system' and the current theme is the
default theme; alternatively update setTheme to synchronize themeMode when
applying a brand theme. Use useCunninghamTheme, onChange, setThemeMode, and
setTheme as references.
- Around line 2-20: ThemeProvider’s mount reconciliation persists the fallback
“system” value and prevents backend brand themes from being applied. Update the
theme handling around useIsomorphicLayoutEffect and useCunninghamTheme so a
missing stored preference applies “system” only in memory without localStorage
persistence, using an internal non-persisting applyThemeMode path; continue
using the persisting setter when getStoredThemeMode() returns an explicit value.
In `@src/frontend/apps/impress/src/pages/_document.tsx`:
- Around line 11-22: Replace the hardcoded 'doc-theme-mode' in THEME_INIT_SCRIPT
with an interpolation of the shared THEME_MODE_STORAGE_KEY constant imported
from useCunninghamTheme.tsx, ensuring the script and hook remain synchronized if
the storage key changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 62d5b6bc-37f0-43ed-8631-3b8edddd06ed
📒 Files selected for processing (10)
CHANGELOG.mdsrc/frontend/apps/impress/src/components/ThemeSwitch.tsxsrc/frontend/apps/impress/src/components/index.tssrc/frontend/apps/impress/src/core/config/ConfigProvider.tsxsrc/frontend/apps/impress/src/core/config/ThemeProvider.tsxsrc/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsxsrc/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsxsrc/frontend/apps/impress/src/features/home/components/HomeHeader.tsxsrc/frontend/apps/impress/src/features/left-panel/components/LeftPanelFooter.tsxsrc/frontend/apps/impress/src/pages/_document.tsx
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx`:
- Around line 25-33: Reformat the explanatory comment above the `.bn-editor`
rule so the referenced selector `.bn-root.bn-editor` remains intact on one line
or is broken clearly without splitting hyphenated class names.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: fa655852-54b1-44ff-b796-f73188c09476
📒 Files selected for processing (2)
src/frontend/apps/impress/src/components/dropdown-menu/DropdownMenu.tsxsrc/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx
77dc653 to
99b9fd5
Compare
|
In case it helps unblock this: the branch no longer merges cleanly onto https://github.com/lucletoffe/docs/tree/darkmode-rebase-main The only conflict was One data point that might be useful: we are running a build of these commits on Two cosmetic things we noticed, neither introduced by this PR:
Feel free to take the rebase or ignore it — just wanted the conflict not to be the thing keeping this stalled. |
Adds a user-facing colour-mode preference on top of the existing Cunningham dark token set: - useCunninghamTheme: themeMode state (light/dark/system) + setThemeMode, persisted to localStorage; system resolves via prefers-color-scheme. - ThemeProvider: applies the stored mode on mount and follows live OS changes while in system mode. - _document: pre-hydration inline script sets the theme class on <html> to avoid a flash of the wrong theme; suppressHydrationWarning on <html>. - ConfigProvider: user mode preference takes precedence over the plain light/dark FRONTEND_THEME default (brand themes still apply). - ThemeSwitch component in the left-panel footer and the home header. - Unit tests for the theme-mode store logic. Signed-off-by: MashdorDev <dorzairi@ymail.com>
- Drive the BlockNote editor (editable + reader) theme from the resolved Cunningham theme so the document canvas is dark in dark mode instead of staying light with unreadable text. - Fade the doc floating bar to the surface background token instead of solid white (the white blur band under the header in dark mode). - ThemeProvider: resolve the default 'system' in memory (new non-persisting applyThemeMode) so an unset preference no longer masks a backend brand theme, and skip the OS-change listener when a brand theme is active. - ThemeSwitch: use radio semantics (drop selectedValues), remove the redundant inner aria-label. - _document: reference the shared THEME_MODE_STORAGE_KEY constant. - Add a test for applyThemeMode not persisting. Signed-off-by: MashdorDev <dorzairi@ymail.com>
The BlockNote editor used its own Mantine surface (distinct from the app background) and the loading skeleton was hardcoded to gray-000 (white), so in dark mode both stood out. Make the editor background transparent so it shares the page background, and paint the skeleton with the surface token. Signed-off-by: MashdorDev <dorzairi@ymail.com>
Setting the BlockNote CSS var lost to BlockNote's own .bn-root[data-color-scheme=dark] rule, so the editor kept Mantine's dark surface. Set the background directly on .bn-root .bn-editor (which outranks BlockNote's .bn-editor rule) so the canvas shares the page background in any theme. Also make the dropdown selected-check use the theme-aware neutral text colour instead of a fixed gray that was invisible on the dark menu. Signed-off-by: MashdorDev <dorzairi@ymail.com>
Nothing painted a background on html, body or the app wrapper, so the browser default white showed through in dark mode while the text tokens switched to the dark ramp. On the pre-login home page that left the heading near-white on white. Reproduced on a 5.4.1 build and on our own instance before this change.
99b9fd5 to
d9be7bb
Compare
|
Thanks Luc. The branch is rebased onto Your check also caught something I had missed, so there is a fifth commit now. Nothing painted a background on Your other two points match what I see and neither comes from this PR: the brand ramp differs because the @virgile-dev the branch is current and CI is green if you want to take a look. |
The chip was a hardcoded gainsboro, so in dark mode it stayed near-white while the content tokens switched to the light ramp, leaving inline code unreadable. Uses the gray tertiary background token instead: #d3d4e0 in default (near-identical to the old value) and #686b6f in dark, which is 4.5:1 against the neutral primary text.
Purpose
Docs already ships a
darkCunningham token set, but there is no way for a user to select it and no following of the OS colour scheme. This adds an in-app dark / light / system colour-mode switcher, which is one of the recurring asks around theming.Proposal
themeMode(light/dark/system) to the theme store, persisted tolocalStoragesystemmode, resolve and follow the OSprefers-color-schemelive_documentsets the theme class on<html>so the correct scheme paints on first frame (no flash), withsuppressHydrationWarningFRONTEND_THEMEbackend default (non-default brand themes likedsfrstill apply)ThemeSwitchcontrol in the left-panel footer (app) and the home header (landing page)The store maps the mode onto the existing Cunningham themes (
light->default,dark->dark), so no new tokens are introduced.External contributions
Thank you for your contribution! 🎉
General requirements
CI requirements
git commit --signoff(DCO compliance)git commit -S)<gitmoji>(type) title description## [Unreleased]section (if noticeable change)AI requirements