Create Dark/Light Theme Toggle: React and MUI

amschel🦀amschel🦀
2 min read

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.

Screenshot (302).png

The card toggles between light and dark mode when the user clicks the switch.

Screenshot (303).png

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/>
0
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.