Dark mode is a complex feature to add - that is if you are not using Chakra UI. Chakra UI comes with built-in support for managing color mode in your apps.
Let's first add the colorModeConfig
to our app and then we'll create a component to toggle the color mode.
Adding config
Recall in the last module we added a custom theme and set the config property. We can set the color mode here by using initialColorMode
and useSystemColorMode
.
// 1. import `extendTheme` function
import { extendTheme, ThemeConfig } from "@chakra-ui/react"
// 2. Add your color mode config
const config = {
initialColorMode: "light", // options are light or dark
useSystemColorMode: false, // options are true or false
}
// 3. extend the theme
const theme = extendTheme({ config })
export default theme
ColorModeScript
To see these changes take effect, we need to add ColorModeScript
to _document.js
.
import { ColorModeScript } from "@chakra-ui/react"
import NextDocument, { Html, Head, Main, NextScript } from "next/document"
import theme from "./theme" // this is the theme.js file we added our custom theme to
export default class Document extends NextDocument {
render() {
return (
<Html lang="en">
<Head />
<body>
<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // <-- add this line!
<Main />
<NextScript />
</body>
</Html>
)
}
}
If you run your app you should see the color mode change coming through! Feel free to change the initialColorMode
and useSystemColorMode
values and see the color mode change!
Creating A Toggle Color Mode Component
This works grest but what if we want the user to be able to toggle the color mode to their preference? We can do this using the useColorMode
hook.
Let's create a simple button that allows the user to change the color mode.
import {
useColorMode,
Button,
} from '@chakra-ui/react'
function DarkModeSwitch() {
const { colorMode, toggleColorMode } = useColorMode()
return (
<Button onClick={toggleColorMode}>
Toggle {colorMode === "light" ? "Dark" : "Light"}
</Button>
)
}
What's Happening in The Code?
- We are importing
useColorMode
andButton
from Chakra UI. - We are using the
useColorMode()
hook to get the current color mode (colorMode
) and a hook to toggle the color mode (toggleColorMode
). - We added a Button component with an
onClick
event to can thetoggleColorMode
. - We are dynamically setting the text based on what the current color mode it.
Import this component anywhere in your app and use it. When you click the button, the color mode will change. Try it out here:
Styling
To style any Chakra UI component for light/dark mode we can use the useColorModeValue
hook. Here is is in action:
const value = useColorModeValue(lightModeValue, darkModeValue) // <- signature
function StyleColorMode() {
const { toggleColorMode } = useColorMode()
const bg = useColorModeValue("red.500", "red.200")
const color = useColorModeValue("white", "gray.800")
return (
<>
<Box mb={4} bg={bg} color={color}>
This box's style will change based on the color mode.
</Box>
<Button size="sm" onClick={toggleColorMode}>
Toggle Mode
</Button>
</>
)
}