Material UI Theme Switcher for React
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.
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 themeconst 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 themeconst 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
- https://material-ui.com/customization/default-theme/
- https://material-ui.com/customization/color/
- https://material.io/design/color/the-color-system.html#color-usage-and-palettes
- https://material.io/resources/color/#!/?view.left=0&view.right=0
- https://react-theming.github.io/create-mui-theme/
Enjoy!