Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[material-ui][pigment-css] How to toggle between color modes #43655

Open
shjacobs303 opened this issue Sep 8, 2024 · 5 comments
Open

[material-ui][pigment-css] How to toggle between color modes #43655

shjacobs303 opened this issue Sep 8, 2024 · 5 comments
Assignees
Labels
new feature New feature or request package: pigment-css Specific to @pigment-css/*

Comments

@shjacobs303
Copy link

shjacobs303 commented Sep 8, 2024

Steps to reproduce

Link to live example: (required) codesandbox

Steps:

  1. Deploy https://github.com/mui/material-ui/blob/master/examples/material-ui-pigment-css-nextjs-ts/src/app/page.tsx
  2. Add getSelector: (colorScheme) => colorScheme ? .theme-${colorScheme} : ":root" to the theme file
  3. Add a toggle button with logic like document.documentElement.classList.toggle("theme-light"); from the pigment css documentation

Current 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 Grid/> without changing to a client component.

Your environment

npx @mui/envinfo
   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 

Search keywords: pigment-css v6

@shjacobs303 shjacobs303 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Sep 8, 2024
@zannager zannager added the package: pigment-css Specific to @pigment-css/* label Sep 9, 2024
@samuelgoldenbaum
Copy link

I battled this issue this morning...

What I did to resolve in the interim:

  1. specify colorSchemeSelector to be class in `next.config
-   cssVariables: true,
+   cssVariables: {
+      colorSchemeSelector: "class"
+   },
  1. 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>
  );
};
  1. remove the getSelector in next.config as it seems superfluous...

PS
Add suppressHydrationWarning to your html and body tags to avoid hydration errors in console

sandbox

@shjacobs303
Copy link
Author

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.

@siriwatknp
Copy link
Member

@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

@siriwatknp siriwatknp added new feature New feature or request enhancement This is not a bug, nor a new feature and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer enhancement This is not a bug, nor a new feature labels Sep 10, 2024
@siriwatknp siriwatknp changed the title Can't toggle between color modes using getSelector [material-ui][pigment-css] How to toggle between color modes Sep 10, 2024
@shjacobs303
Copy link
Author

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.

@brijeshb42
Copy link
Contributor

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);
});

@brijeshb42 brijeshb42 moved this from In progress to Backlog in Material UI Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request package: pigment-css Specific to @pigment-css/*
Projects
Status: Backlog
Development

No branches or pull requests

5 participants