跳到主要内容
+

暗黑模式

了解将暗黑模式应用于 Joy UI 应用的不同方法。

Media prefers-color-scheme

创建一个主题,其中 colorSchemeSelector: 'media' 用于使用 @media (prefers-color-scheme) 而不是默认的 data-joy-color-scheme 属性。

import { extendTheme } from '@mui/joy/styles';

const theme = extendTheme({
  colorSchemeSelector: 'media',
});

function App() {
  return <CssVarsProvider theme={theme}>...</CssVarsProvider>;
}

识别系统模式

使用 useColorScheme React Hook 来检查用户的偏好是亮色模式还是暗黑模式

import { useColorScheme } from '@mui/joy/styles';

function SomeComponent() {
  const { mode, systemMode } = useColorScheme();
  console.log(mode); // "system"
  console.log(systemMode); // "light" | "dark" based on the user's preference.
}
计算中…
Enter 键开始编辑

创建模式切换组件

您可以创建一个切换组件,让用户可以选择模式。

在下面的示例中,我们使用了一个 Select 组件,该组件调用 useColorSchemes() Hook 中的 setMode 来处理模式切换。

Enter 键开始编辑

服务端渲染注意事项

避免水合不匹配

确保在页面挂载到客户端时渲染 UI。

这是因为 mode 仅在客户端可用(在服务器端为 undefined)。如果您尝试在客户端挂载之前基于服务器渲染 UI,您将看到水合不匹配错误。

 function ModeToggle() {
   const { mode, setMode } = useColorScheme();
   const [mounted, setMounted] = React.useState(false);

+  React.useEffect(() => {
+    setMounted(true);
+  }, []);
+
+  if (!mounted) {
+    // to avoid layout shift, render a placeholder button
+    return <Button variant="outlined" color="neutral" sx={{ width: 120 }} />;
+  }

   return (
     <Button
       variant="outlined"
       color="neutral"
       onClick={() => setMode(mode === 'dark' ? 'light' : 'dark')}
     >
       {mode === 'dark' ? 'Turn light' : 'Turn dark'}
     </Button>
   );
 };

避免屏幕闪烁

为了防止 UI 闪烁,在主应用程序脚本之前应用 <InitColorSchemeScript />——它因框架而异

Next.js Pages Router

要在 Next.js 项目中使用 Joy UI API,请将以下代码添加到自定义的 pages/_document.js 文件中

import Document, { Html, Head, Main, NextScript } from 'next/document';
import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript';

export default class MyDocument extends Document {
  render() {
    return (
      <Html data-color-scheme="light">
        <Head>...</Head>
        <body>
          <InitColorSchemeScript />
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

Next.js App Router

要在带有 App Router 的 Next.js 项目中使用 Joy UI API,请将以下代码添加到根布局文件中,以防止闪烁

app/layout.js
import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript';
import { CssVarsProvider } from '@mui/joy/styles';
import CssBaseline from '@mui/joy/CssBaseline';

export default function RootLayout(props) {
  return (
    <html lang="en" suppressHydrationWarning={true}>
      <body>
        <InitColorSchemeScript />
        <CssVarsProvider>
          <CssBaseline />
          {props.children}
        </CssVarsProvider>
      </body>
    </html>
  );
}