DEV Community

MANOJ AP
MANOJ AP

Posted on

Create Mui Dark Mode switch using React Context

Material UI or MUI is one word for all UI needs in Reactjs. It is well documented and easy to use. I really enjoyed it.
In this post I would like to demonstrate how to create dark-mode switcher using the React Context and Material UI switch component.

Context

please use these posts to learn more about Context and the basic step required.

Our context setup with look like the following

//context/themeContext.js
 import React from 'react';

export const ThemeContext = React.createContext({
    theme: 'dark',
    setTheme: () => { }
  })


 //app.js or _app.js

import React, { useState } from 'react'; 
import { ThemeContext } from '../context/themeContext';


function MyApp({ Component, pageProps }) {
  const [theme, setTheme] = useState("light")
  const value = { theme, setTheme };


  return (

      <ThemeContext.Provider value={value}   >
        <Component {...pageProps} />
      </ThemeContext.Provider>

  );
}
Enter fullscreen mode Exit fullscreen mode

Theme Switcher

A MUI customized switch can be used to create a theme switcher. We also need to access the context using the useContext hook. The code will look like the following.

The complete switch snippet can be obtained from Material UI switch documentation page.

import * as React from 'react';
import clsx from 'clsx';
import { styled } from '@mui/system';
import { useSwitch } from '@mui/core/SwitchUnstyled';
import { Tooltip } from '@mui/material';
import { ThemeContext } from '../context/themeContext';
 ...
function MUISwitch(props) {
  const { theme, setTheme } = React.useContext(ThemeContext)
  const { getInputProps, checked, disabled, focusVisible } = useSwitch(props);
  const stateClasses = {
    checked,
    disabled,
    focusVisible,
  };
  var mode = {

  };


  React.useEffect(() => {
    const mode = stateClasses.checked ? 'dark' : 'light'
    setTheme(mode)
  }, [stateClasses])
  return (
    <Tooltip title="Theme switcher">
      <SwitchRoot className={clsx(stateClasses)} >
        <SwitchTrack>
          <SwitchThumb className={clsx(stateClasses)} />
        </SwitchTrack>
        <SwitchInput {...getInputProps()} aria-label="Demo switch" />
      </SwitchRoot>
    </Tooltip>

  );
}

export default function UseSwitchesCustom() {
  return <MUISwitch defaultChecked />;
}
Enter fullscreen mode Exit fullscreen mode

Tracking changes

In order observe changes in state of the switch component , we can use useEffect and the stateClass. Note that there is no event handler attached to the component.

Implement the Theme

The theme can be implemented as you wish, one of the suggested way is to create a component to implement the theme and wrap other components inside it. Such a component can be .

import React from 'react'
import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
import { ThemeContext } from '../context/themeContext';

export default function BaseTheme(props) {
    const { theme, setTheme } = React.useContext(ThemeContext)
    const theme1 = createTheme(
        {
            palette:
                { mode: theme }
        }
    );

    console.log('Current Theme - ' + JSON.stringify(theme));
    return (
        <div>
            <ThemeProvider theme={theme1} >
                {props.children}
            </ThemeProvider>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Read more react posts On My blog

Discussion (0)