How to use Material UI Themes and Dark Mode

H
andrewgbliss
7 months ago

This article will cover how to use Material UI Themes and setup a Dark Mode

. . .

Github repo

https://github.com/EntryLevelDeveloperTraining/todos

Theme Provider

Material UI gives us a way to set theming variables and options in a provider component. Similar to context in the last article. When we wrap our components in their Provider it will automatically apply styles, and colors.

So let's create a Theme component that can do this all for us.

import React, { useState } from "react";
import { createMuiTheme } from "@material-ui/core/styles";
import { ThemeProvider } from "@material-ui/styles";
import { CssBaseline } from "@material-ui/core";
import purple from "@material-ui/core/colors/purple";
import green from "@material-ui/core/colors/green";

const theme = createMuiTheme({
  palette: {
    type: "light",
    primary: purple,
    secondary: green,
  },
});

const themeDark = createMuiTheme({
  palette: {
    type: "dark",
    primary: purple,
    secondary: green,
  },
});

const Theme = (props) => {
  const { children, darkMode } = props;
  const defaultTheme = darkMode ? themeDark : theme;
  return (
    <ThemeProvider theme={defaultTheme}>
      <CssBaseline />
      {children}
    </ThemeProvider>
  );
};

export const withTheme = (Component) => {
  return (props) => {
    const [darkMode, setDarkMode] = useState(false);
    return (
      <Theme darkMode={darkMode}>
        <Component {...props} darkMode={darkMode} setDarkMode={setDarkMode} />
      </Theme>
    );
  };
};

In this code example we setup two separate themes with their own colors. One light theme and one dark theme. Then we use a state variable to control when to show dark mode.

Updating the App component

Now we have a Theme component we can use that around the whole app.

import React from "react";
import Grid from "@material-ui/core/Grid";
import { makeStyles } from "@material-ui/core";
import Paper from "@material-ui/core/Paper";
import Todos from "../Todos/Todos";
import { useTheme } from "@material-ui/core/styles";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { withTheme } from "../Theme/Theme";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Switch from "@material-ui/core/Switch";

const useStyles = makeStyles((theme) => ({
  root: {
    width: "100%",
    height: "100%",
    [theme.breakpoints.down("xs")]: {
      paddingTop: theme.spacing(2),
    },
  },
}));

function App(props) {
  const { darkMode, setDarkMode } = props;
  const classes = useStyles();
  const theme = useTheme();
  const matches = useMediaQuery(theme.breakpoints.down("xs"));
  return (
    <Grid
      className={classes.root}
      container
      justify="center"
      alignItems={matches ? "flex-start" : "center"}
    >
      <Grid item>
        <Paper elevation={8}>
          <Todos />
        </Paper>
        <FormControlLabel
          control={
            <Switch
              checked={darkMode}
              onChange={() => setDarkMode(!darkMode)}
            />
          }
          label="Dark Mode"
        />
      </Grid>
    </Grid>
  );
}

export default withTheme(App);

Just bring in the Theme component and wrap in around the App component in App.js. Also we create a Switch component from Material UI to switch Dark mode on or off.

Conclusion

Material UI theming is a very powerful way to control how your application looks and feels. You can easily override colors, and default values to give your application a unique look.


H
andrewgbliss
7 months ago