feat: add dark mode with system preference detection#854
feat: add dark mode with system preference detection#854Alain-L wants to merge 8 commits intodalibo:masterfrom
Conversation
|
I gave this PR a quick review. I have he feeling that too many colors are set in our css files. In my opinion, setting the theme theme to Also, the dark mode variables shouldn't be set in the example directory otherwise the colors won't be changed if PEV2 is integrated (ie. used outside the example application). Could you please create a PR with only the playwright e2e tests (and without the husky files) ? I'd be happy to have this integrated sooner. |
e2e/visual.spec.ts
Outdated
| { plan: testPlan.plan, query: testPlan.query, name: testPlan.name } | ||
| ) | ||
|
|
||
| // Wait for plan view to render (has nav-link tabs) |
There was a problem hiding this comment.
The " (has nav-link tabs)" part doesn't seem accurate with th e code below. Let's remove it.
example/src/layouts/MainLayout.vue
Outdated
| @click="toggleTheme" | ||
| :title="theme === 'light' ? 'Switch to dark mode' : 'Switch to light mode'" | ||
| > | ||
| <FontAwesomeIcon :icon="theme === 'light' ? faMoon : faSun" /> |
There was a problem hiding this comment.
In my opinion, this would be better the other way around. ie. the icon should show the current state.
68ce4b0 to
cd6829e
Compare
|
Thanks for the review. I've addressed your points:
The branch has been force-pushed with these changes. Net result: -170 lines of CSS. Happy to adjust anything based on your feedback. |
example/src/composables/useTheme.ts
Outdated
| document.documentElement.setAttribute("data-theme", theme) | ||
| // Bootstrap 5 dark mode | ||
| document.documentElement.setAttribute("data-bs-theme", theme) |
There was a problem hiding this comment.
I think it would be more straight forward to rely on one attribute only: data-bs-theme. I don't see any additional value to have a pev2 custom attribute for that.
Imagine an app integrating PEV2 and using bootstrap. If it already has a theme switch, it wouldn't have to handle the extra specific data-theme value.
There was a problem hiding this comment.
Thanks for the suggestion.
I've made the following changes:
-
Single attribute: Now using only
data-bs-themeinstead of bothdata-themeanddata-bs-theme. Apps integrating pev2 can control the theme using the standard Bootstrap attribute. -
Bootstrap-aligned palette: Replaced custom purple-tinted colors with Bootstrap's neutral grays (#212529, #343a40, etc.) for visual consistency.
-
Semantic classes: Replaced
bg-white/bg-lightwithbg-body/bg-body-tertiarywhich automatically adapt to light/dark mode. Also removedtable-secondaryfrom table headers.
The dark mode now relies almost entirely on Bootstrap's native theming.
2689c6c to
c719be3
Compare
|
Continued simplification: Complete refactor from SCSS variables to Bootstrap CSS vars Replaced all hardcoded SCSS variables ( Result: no need for 3 commits:
For integrators: just set Verified no regression in light mode with Playwright (master vs feature branch comparison). |
|
Excellent work so far. Instead of adding a "master" into branch merge commit, could you please try to rebase your branch instead? I'd prefer we avoid merge commits. |
Replace hardcoded SCSS color variables with Bootstrap CSS variables to enable theme customization (dark mode, high contrast, branding, etc.) - Use semantic classes (bg-body, text-body-secondary, etc.) - Replace $gray-light, $text-color, $line-color with CSS variables - Update hatched background pattern to use --bs-tertiary-bg - Add splitpanes theme overrides - Replace btn-light with btn-outline-secondary in PlanNode
Add theme switcher button in navbar with system preference detection. Theme preference is persisted in localStorage.
8a7d15b to
d23bad7
Compare
Import stackoverflow-dark theme for highlight.js when dark mode is active, scoped to [data-bs-theme="dark"] selector.
d23bad7 to
a93362c
Compare
|
Done! Rebased on master, no merge commit anymore. 3 clean commits:
Build and tests pass (159 tests). |
Replace emoji icons with FontAwesome sun/moon icons for consistency with the rest of the example application.
Replace custom theme implementation with VueUse's useColorMode composable. Reduces code while maintaining the same functionality.
|
Done — switched to FontAwesome icons, VueUse |
- Remove border from node type button (bg-body-tertiary instead of btn-outline-secondary) - Use text-body-tertiary for chevron icon and reserved keywords (on, as, by, using, CTE)
|
You're right, the bordered button was a regression. Applied your suggestions to restore the original look:
|
|
Can you also change the "reserved keywords" color in the grid? |
|
Done — applied to grid as well. |
|
As discussed earlier, here are some possible enhancements (initial refactoring):
|
|
Thanks for your contribution. Integrated in #866 . |
|
Closing in favor of #866 which incorporates this work with additional CSS refactoring. |

Summary
Features
prefers-color-schemeon first visitTechnical details
--bs-body-bg,--bs-body-color,--bs-border-color, etc.)useThemecomposable handles theme state and DOM updatesdata-bs-themeattribute handles 100% of themingstackoverflow-darktheme for highlight.jsFor integrators
Just set
data-bs-theme="dark"on your root element — pev2 adapts automatically.Test plan
Edit 2025-12-24: Updated description to reflect the simplified approach after Pierre's feedback.