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.

import { createMuiTheme } from '@material-ui/core/styles'
import { red } from '@material-ui/core/colors'
// Normal or default theme
const theme = createMuiTheme({
palette: {
primary: {
main: '#556cd6',
},
secondary: {
main: '#cc4444',
},
error: {
main: red.A400,
},
background: {
default: '#f5f5f5',
},
titleBar: {
main: '#eeeeee',
contrastText: '#222222',
},
},
})
export default theme
import { createMuiTheme } from '@material-ui/core/styles'
import { red } from '@material-ui/core/colors'
// Dark theme
const theme = createMuiTheme({
palette: {
type: 'dark',
primary: {
main: '#26292C',
light: 'rgb(81, 91, 95)',
dark: 'rgb(26, 35, 39)',
contrastText: '#ffffff',
},
secondary: {
main: '#FFB74D',
light: 'rgb(255, 197, 112)',
dark: 'rgb(200, 147, 89)',
contrastText: 'rgba(0, 0, 0, 0.87)',
},
titleBar: {
main: '#555555',
contrastText: '#ffffff',
},
error: {
main: red.A400,
},
},
})
export default theme

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

import normal from './normal'
import dark from './dark'
const themes = {
normal,
dark,
}
export default function getTheme(theme) {
return themes[theme]
}

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

Code 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
Code content*
OK
Cancel
const contextValue = {
currentTheme: themeName,
setTheme: setThemeName,
}
return (
<CustomThemeContext.Provider value={contextValue}>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</CustomThemeContext.Provider>
)
}
export default CustomThemeProvider

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

import React from 'react'
import ReactDOM from 'react-dom'
import CssBaseline from '@material-ui/core/CssBaseline'
import App from './App'
import CustomThemeProvider from './themes/CustomThemeProvider'
ReactDOM.render(
<CustomThemeProvider>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<App />
</CustomThemeProvider>,
document.querySelector('#root'),
)

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

export default function App() {
const classes = useStyles()
const { currentTheme, setTheme } = useContext(CustomThemeContext)
const isDark = Boolean(currentTheme === 'dark')
const handleThemeChange = (event) => {
const { checked } = event.target
if (checked) {
setTheme('dark')
} else {
setTheme('normal')
}
}
...

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!