Open shjacobs303 opened 2 months ago
I battled this issue this morning...
What I did to resolve in the interim:
colorSchemeSelector
to be class
in `next.config
- cssVariables: true,
+ cssVariables: {
+ colorSchemeSelector: "class"
+ },
toggle()
the class on root/html element
const ToggleColorScheme = () => {
const handleClick = () => {
document.documentElement.classList.toggle("dark");
};
return (
<Button onClick={handleClick} color="primary" variant="contained">
Toggle color scheme
</Button>
);
};
getSelector
in next.config
as it seems superfluous...PS
Add suppressHydrationWarning
to your html and body tags to avoid hydration errors in console
This at least gets it to toggle but it loses system preference. Would really like to have an opinionated way to allow system preference, but then to select an override if desired.
And like other frameworks, be able to avoid the first time load flicker while not causing all routes to become dynamic by using async in the root layout.
@shjacobs303 Pigment does not have a built-in way to handle system preferences yet. Meanwhile, you can use https://github.com/pacocoursey/next-themes for Next.js
next-themes looks to be ideal, I can see you're planning to add some examples using V6. I can wait and follow your pattern, looking forward to it.
As @samuelgoldenbaum has stated, if you are using createTheme
from @mui/material
, that's the way to go to have manual toggle of theme which will give you dark
and light
classes.
As for the system preference, there's no built-in way right now. It's either manual or system, not both.
But you can use a bit of JS with manual classes to achieve it. A reference snippet -
const matcher = window.matchMedia('(prefers-color-scheme: dark)');
if (matcher.matches) {
document.documentElement.classList.remove('light');
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
document.documentElement.classList.add('light');
}
matcher.addEventListener('change', event => {
const newColorScheme = event.matches ? "dark" : "light";
document.documentElement.classList.remove('light', 'dark');
document.documentElement.classList.add(newColorScheme);
});
Steps to reproduce
Link to live example: (required) codesandbox
Steps:
.theme-${colorScheme}
: ":root" to the theme fileCurrent behavior
adds class="theme-light" or "theme-dark" Color scheme does not change after button click ### Expected behavior adds class="theme-light" or "theme-dark" Color scheme changes on button click ### Context I'm trying to use mui v6 with pigment css with the ability to select a particular color scheme, overriding the system defaults. You'll also notice I had to comment out a Grid component in the codesandbox example. The nextjs pigment css example does not currently render with
``` Replicated in Chrome System: OS: Linux 6.1 Ubuntu 20.04.6 LTS (Focal Fossa) Binaries: Node: 20.12.1 - /home/codespace/nvm/current/bin/node npm: 10.5.0 - /home/codespace/nvm/current/bin/npm pnpm: 8.15.6 - /home/codespace/nvm/current/bin/pnpm Browsers: Chrome: Not Found npmPackages: @emotion/react: 11.13.3 @emotion/styled: 11.13.0 @mui/core-downloads-tracker: 6.0.2 @mui/material: 6.0.2 => 6.0.2 @mui/material-pigment-css: 6.0.2 => 6.0.2 @mui/private-theming: 6.0.2 @mui/styled-engine: 6.0.2 @mui/system: 6.0.2 @mui/types: 7.2.16 @mui/utils: 6.0.2 @pigment-css/nextjs-plugin: latest => 0.0.22 @pigment-css/react: 0.0.21 @pigment-css/unplugin: 0.0.22 @types/react: latest => 18.3.4 react: latest => 18.3.1 react-dom: latest => 18.3.1 typescript: latest => 5.5.4 ```npx @mui/envinfo