颜色模式
添加亮色和暗色模式支持
Chakra UI 依赖next-themes
来添加亮色和暗色模式支持。
设置
在大多数情况下,您已经通过 CLI 在 Provider
组件中安装并设置了它。如果没有,您可以手动安装。
npx @chakra-ui/cli snippet add color-mode
该代码片段包含使它感觉与 Chakra v2 类似的 Hooks 和组件。
import {
ColorModeButton,
DarkMode,
LightMode,
useColorMode,
useColorModeValue,
} from "@/components/ui/color-mode"
useColorMode
useColorMode
Hook 返回当前颜色模式以及一个切换颜色模式的函数。
"use client"
import { Button } from "@chakra-ui/react"
import { useColorMode } from "@/components/ui/color-mode"
const Demo = () => {
const { toggleColorMode } = useColorMode()
return (
<Button variant="outline" onClick={toggleColorMode}>
Toggle Mode
</Button>
)
}
在您的应用树中任何地方调用 toggleColorMode
或 setColorMode
都会在亮色和暗色模式之间切换颜色模式,反之亦然。
useColorModeValue
useColorModeValue
Hook 根据当前颜色模式返回一个值。
这是它的签名
const result = useColorModeValue("<light-mode-value>", "<dark-mode-value>")
如果颜色模式为 light
,则返回的值将是亮色模式的值;如果颜色模式为 dark
,则返回暗色模式的值。
此框的样式将根据颜色模式而改变。
"use client"
import { Box, Button, Stack } from "@chakra-ui/react"
import { useColorMode, useColorModeValue } from "@/components/ui/color-mode"
const Demo = () => {
const { toggleColorMode } = useColorMode()
const bg = useColorModeValue("red.500", "red.200")
const color = useColorModeValue("white", "gray.800")
return (
<Stack align="flex-start" gap="4">
<Box p="2" bg={bg} color={color}>
This box's style will change based on the color mode.
</Box>
<Button variant="outline" size="sm" onClick={toggleColorMode}>
Toggle Mode
</Button>
</Stack>
)
}
水合不匹配 (Hydration Mismatch)
在 SSR 中使用 useColorModeValue
或 useColorMode
时,您可能会在页面挂载时注意到水合不匹配。这是因为颜色模式值是在服务器端计算的。
为避免此问题,请使用 ClientOnly
组件包装使用 useColorModeValue
的组件,并在客户端挂载之前渲染一个骨架屏。
"use client"
import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react"
import { useColorMode } from "@/components/ui/color-mode"
import { LuMoon, LuSun } from "react-icons/lu"
const Demo = () => {
const { toggleColorMode, colorMode } = useColorMode()
return (
<ClientOnly fallback={<Skeleton boxSize="8" />}>
<IconButton onClick={toggleColorMode} variant="outline" size="sm">
{colorMode === "light" ? <LuSun /> : <LuMoon />}
</IconButton>
</ClientOnly>
)
}
ColorModeButton
颜色模式代码片段内置了 ColorModeButton
组件,您可以导入它以渲染一个切换颜色模式的图标按钮。
它在服务器端渲染骨架屏,在客户端渲染图标。
import { ColorModeButton } from "@/components/ui/color-mode"
const Demo = () => {
return <ColorModeButton />
}
强制颜色模式
颜色模式代码片段内置了 LightMode
和 DarkMode
组件,您可以导入它们来强制设置颜色模式。
"use client"
import { Button, HStack } from "@chakra-ui/react"
import { DarkMode, LightMode, useColorMode } from "@/components/ui/color-mode"
const Demo = () => {
const { toggleColorMode } = useColorMode()
return (
<HStack>
<LightMode>
<Button size="sm" variant="subtle">
Light Mode Always
</Button>
</LightMode>
<DarkMode>
<Button size="sm" variant="subtle">
Dark Mode Always
</Button>
</DarkMode>
<Button size="sm" variant="subtle" onClick={toggleColorMode}>
Toggle Mode
</Button>
</HStack>
)
}
您可能需要更新 color-mode.tsx
代码片段,因为 LightMode
和 DarkMode
组件是最近才添加到该片段中的。