深色模式
了解將深色模式應用於 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 鍵開始編輯
伺服器端渲染注意事項
避免 hydration 不匹配
請確保在頁面於用戶端掛載時渲染 UI。
這是因為 mode
僅在用戶端可用 (在伺服器端為 undefined
)。如果您嘗試在伺服器端渲染 UI,然後才在用戶端掛載,您會看到 hydration 不匹配錯誤。
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>
);
}