暗黑模式
了解将暗黑模式应用于 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>
);
}