mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
91.86k stars 31.57k forks source link

[system][question] Issues with using useColorScheme with localstorage #42121

Open sawa-ko opened 2 weeks ago

sawa-ko commented 2 weeks ago

Steps to reproduce

Link to live example: https://codesandbox.io/p/github/sawa-ko/nextjs-app-router-mui-bug/main

Steps:

  1. Use nextjs v14 (app folder)
  2. Install mui
  3. Change theme
// change-theme.tsx

'use client';

import Button from "@mui/material/Button";
import { useColorScheme } from "@mui/material/styles";
import { useEffect, useState } from "react";

export default function ChangeTheme() {
  const { mode, setMode } = useColorScheme();
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
  }, [mode, isMounted]);

  if (!isMounted) {
    return null;
  }

  return (
    <Button
      onClick={() => {
        setMode(mode === 'light' ? 'dark' : 'light');
      }}
    >
      {mode === 'light' ? 'Turn dark' : 'Turn light'}
    </Button>
  );
}
// layout.tsx

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter';
import {
  Experimental_CssVarsProvider as CssVarsProvider,
} from '@mui/material/styles';
import theme from "./theme";

import CssBaseline from '@mui/material/CssBaseline';

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" >
      <body className={inter.className}>
        <AppRouterCacheProvider options={{ enableCssLayer: true }}>
            <CssVarsProvider theme={theme}>
              <CssBaseline enableColorScheme={true}  />
              {children}
            </CssVarsProvider>
        </AppRouterCacheProvider>
        </body>
    </html>
  );
}
// theme.tsx

'use client';
import { Roboto } from 'next/font/google';
import {
  experimental_extendTheme as extendTheme,
} from '@mui/material/styles';

import { blue } from '@mui/material/colors';
import { LinkBehavior } from '@/components/link';

const roboto = Roboto({
  weight: ['300', '400', '500', '700'],
  subsets: ['latin'],
  display: 'swap',
});

const theme = extendTheme({
  unstable_strictMode: true,
  colorSchemes: {
    dark: {
      palette: {
        primary: {
          ...blue,
          main: blue[300],
        },
      }
    }
  },
  typography: {
    fontFamily: roboto.style.fontFamily,
  },
  components: {
    MuiLink: {
      defaultProps: {
        component: LinkBehavior,
      },
    },
    MuiButtonBase: {
      defaultProps: {
        LinkComponent: LinkBehavior,
      },
    },
  },
});

export default theme;

Current behavior

Actually I want to change the theme of my application following the migration guide that mui has in its documentation, but something strange happens.

The hook changes the mui-mode property of the localstorage however there are 2 more properties that are also marked as a kind of setting for the color scheme.

image

The strange thing is that when the hook changes that property of the localstorage nothing happens, but if I change the mui-color-scheme-dark property to dark manually then the change happens, can someone explain me how these properties of the localstorage work?

It is necessary to emphasize that I have not created them, mui creates them automatically.

Expected behavior

That when the hook changes the color scheme is actually changed, and that there is an explanation of how these settings work in the documentation because I searched and found nothing.

Context

Change the color scheme.

Your environment

npx @mui/envinfo ``` $ pnpx @mui/envinfo System: OS: Windows 11 10.0.22631 Binaries: Node: 20.12.2 - C:\Program Files\nodejs\node.EXE npm: 10.5.0 - C:\Program Files\nodejs\npm.CMD pnpm: 9.0.6 - C:\Program Files\nodejs\pnpm.CMD Browsers: Chrome: Not Found Edge: Chromium (124.0.2478.51) npmPackages: @emotion/react: ^11.11.4 => 11.11.4 @emotion/styled: ^11.11.5 => 11.11.5 @mui/material: ^5.15.16 => 5.15.16 @mui/material-nextjs: ^5.15.11 => 5.15.11 @types/react: ^18 => 18.3.1 react: ^18 => 18.3.1 react-dom: ^18 => 18.3.1 typescript: ^5 => 5.4.5 ```

I am using microsoft edge in its version: 124.0.2478.80

Search keywords: useColorScheme, mui-color-scheme-dark, mui-color-scheme-light, mui-mode, localstorage scheme, localstorage mui mode

brijeshb42 commented 1 week ago

Can you link a working demo (a Github repo or a Codesandbox/Stackblitz link) ? It'll be easier to debug.

sawa-ko commented 1 week ago

@brijeshb42 I have updated the issue with the link to the bug reproduction.

brijeshb42 commented 1 week ago

@siriwatknp This might be your area of expertise. Seems related to @mui/material-nextjs.