Create Dark/Light Theme Toggle: React and MUI
This article will show you how to add a dark/light mode to your website so that users can choose what works best for them. We will be building a card which has a switch at the bottom to allow users to toggle between dark and light mode.
Below is what we will be building.
The card toggles between light and dark mode when the user clicks the switch.
Below is the code for that component.
import {useState} from "react"
import {Box, Switch, CardActionArea, CardActions,Card,CardMedia,CardContent,Typography } from "@mui/material"
import {createTheme,ThemeProvider} from "@mui/material"
function App() {
const [mode,setMode]=useState("light")
const darkMode=createTheme({
palette:{
mode:mode
}
})
return (
<ThemeProvider theme={darkMode}>
<Box sx={{display:'flex', justifyContent:"center"}}>
<Card bgcolor={"background.default"} color={'text.primary'} sx={{ maxWidth: 345 }}>
<CardActionArea>
<CardMedia
component="img"
height="140"
image="data:image/jpeg;base64,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"
alt="green iguana"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
The world fastest car
</Typography>
<Typography variant="body2" color="text.secondary">
Moves at speed of light, believe me!
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Switch onChange={()=>setMode(mode==="light"?"dark":"light")}>
</Switch>
</CardActions>
</Card>
</Box>
</ThemeProvider>
);
}
export default App;
Explanation
We first create a mode state and we initially give it a value of 'light'
const [mode,setMode]=useState("light")
We then import createTheme
from @mui/material
createTheme
is a function from mui
and it takes in an object as its parameter.
Inside the object we have access to the palette
object which has the mode.
const darkMode=createTheme({
palette:{
mode:mode
}
})
light mode is the default mode.
We set the value of mode to be equal to the mode state we created.
We also have a Switch
component which toggles the mode state between light and dark when the onChange event happens.
<Switch onChange={()=>setMode(mode==="light"?"dark":"light")}>
</Switch>
We also give the Card
the following props.
bgcolor={"background.default"} color={'text.primary'}
Finally we have to wrap our whole component with the ThemeProvider
as shown below:
<ThemeProvider theme={darkMode}>
//the whole component.
<ThemeProvider/>
Subscribe to my newsletter
Read articles from amschel🦀 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
amschel🦀
amschel🦀
Versatile software engineer. I use Typescript, Node.js and React native. I'm currently on a journey to mastering Rust.