Material UI Theme Switcher for React

Submitted on May 27, 2020, 6:32 a.m.

Here's a short post on how to create a Material-UI theme switcher for React - using React.createContext. This is based on Praveen's excellent post here... https://techinscribed.com/building-react-app-using-material-ui-with-support-for-multiple-switchable-themes/

When we're done - you should see the following React app with a simple theme toggle switcher.

Screenshot of dark theme with text

First we'll create two themes: normal.js and dark.js, and place them in a themes directory below src.

1import { createMuiTheme } from '@material-ui/core/styles'
2import { red } from '@material-ui/core/colors'
3
4// Normal or default theme
5const theme = createMuiTheme({
6 palette: {
7 primary: {
8 main: '#556cd6',
9 },
10 secondary: {
11 main: '#cc4444',
12 },
13 error: {
14 main: red.A400,
15 },
16 background: {
17 default: '#f5f5f5',
18 },
19 titleBar: {
20 main: '#eeeeee',
21 contrastText: '#222222',
22 },
23 },
24})
25
26export default theme
1import { createMuiTheme } from '@material-ui/core/styles'
2import { red } from '@material-ui/core/colors'
3
4// Dark theme
5const theme = createMuiTheme({
6 palette: {
7 type: 'dark',
8 primary: {
9 main: '#26292C',
10 light: 'rgb(81, 91, 95)',
11 dark: 'rgb(26, 35, 39)',
12 contrastText: '#ffffff',
13 },
14 secondary: {
15 main: '#FFB74D',
16 light: 'rgb(255, 197, 112)',
17 dark: 'rgb(200, 147, 89)',
18 contrastText: 'rgba(0, 0, 0, 0.87)',
19 },
20 titleBar: {
21 main: '#555555',
22 contrastText: '#ffffff',
23 },
24 error: {
25 main: red.A400,
26 },
27 },
28})
29
30export default theme

And then a simple theme switcher component - base.js also placed in the themes directory.

1import normal from './normal'
2import dark from './dark'
3
4const themes = {
5 normal,
6 dark,
7}
8
9export default function getTheme(theme) {
10 return themes[theme]
11}

And now we'll create our CustomThemeProvider and React Context - CustomThemeProvider.js - also placed in the themes directory.

1Code snippetLanguage <not set> apache bash css coffeescript dart dockerfile dust gherkin go haml handlebars ini json java javascript less makefile markdown nginx php perl powershell puppet python ruby scss sql twig typescript xml yaml
2
3Code content*
4
5OK
6
7Cancel
8
9
10 const contextValue = {
11 currentTheme: themeName,
12 setTheme: setThemeName,
13 }
14
15 return (
16 <CustomThemeContext.Provider value={contextValue}>
17 <ThemeProvider theme={theme}>{children}</ThemeProvider>
18 </CustomThemeContext.Provider>
19 )
20}
21
22export default CustomThemeProvider

Here's how this looks in index.js...

1import React from 'react'
2import ReactDOM from 'react-dom'
3import CssBaseline from '@material-ui/core/CssBaseline'
4import App from './App'
5import CustomThemeProvider from './themes/CustomThemeProvider'
6
7ReactDOM.render(
8 <CustomThemeProvider>
9 {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
10 <CssBaseline />
11 <App />
12 </CustomThemeProvider>,
13 document.querySelector('#root'),
14)

And then using the context in our App.js component...

1export default function App() {
2 const classes = useStyles()
3 const { currentTheme, setTheme } = useContext(CustomThemeContext)
4 const isDark = Boolean(currentTheme === 'dark')
5
6 const handleThemeChange = (event) => {
7 const { checked } = event.target
8 if (checked) {
9 setTheme('dark')
10 } else {
11 setTheme('normal')
12 }
13 }
14...

The entire source for this as a working 'Create React App'-based repository, including the AppBar and Toggle controls can be found here...

https://github.com/infonomic/material-ui-theme-switcher

Here are a few additional links to theme and color related resources and tools that help in creating custom Material-based themes for Material-UI

  1. https://material-ui.com/customization/default-theme/
  2. https://material-ui.com/customization/color/
  3. https://material.io/design/color/the-color-system.html#color-usage-and-palettes
  4. https://material.io/resources/color/#!/?view.left=0&view.right=0
  5. https://react-theming.github.io/create-mui-theme/

Enjoy!