How to add dual theme to your React App ?
Dual Themes are very common nowadays in websites most commonly the light and dark versions and more and more apps and websites are including this feature. For React apps, the Material UI framework provides very useful functions using multiple themes, and switching between them is quite easy. In this article we will create a simple react app and switch between Dark and Light themes using a Switch component.
Prerequisites
- Knowledge of React Js
- Node and NPM installed in the system
Steps to create React Application And Installing Module:
Step 1: Create a React application using the following command:
npx create-react-app gfg
Step 2: After creating your project folder i.e. gfg, move to it using the following command:
cd gfg
Step 3: After creating the ReactJS application, Install the material-ui modules using the following command:
npm install @material-ui/core
Project Structure:
Example: Demonstrating dual theme in react app.
Javascript
// theme.js import { createMuiTheme, responsiveFontSizes } from "@material-ui/core/styles" ; const lightTheme = responsiveFontSizes( createMuiTheme({ spacing: 4, typography: { fontFamily: [ "Roboto" , "Raleway" , "Open Sans" ].join( "," ), h1: { fontSize: "5rem" , fontFamily: "Raleway" , }, h3: { fontSize: "2.5rem" , fontFamily: "Open Sans" , }, }, palette: { background: { default : "#009900" , //green }, primary: { main: "#009900" , //green }, secondary: { main: "#000000" , //black icons: "#009900" , //white }, text: { primary: "#000000" , //black secondary: "#FFFFFF" , //white }, }, }) ); const darkTheme = responsiveFontSizes( createMuiTheme({ spacing: 4, typography: { fontFamily: [ "Roboto" , "Raleway" , "Open Sans" ].join( "," ), h1: { fontSize: "5rem" , fontFamily: "Raleway" , }, h3: { fontSize: "2.5rem" , fontFamily: "Open Sans" , }, }, palette: { background: { default : "#000000" , //black }, primary: { main: "#FFFFFF" , //white }, secondary: { main: "#FFFFFF" , //white icons: "#FFFFFF" , //white }, text: { primary: "#FFFFFF" , //white secondary: "#FFFFFF" , //white }, }, }) ); export default lightTheme; export { darkTheme }; |
Javascript
// App.js import React, { Component } from "react" ; import "./App.css" ; import CssBaseline from "@material-ui/core/CssBaseline" ; import { ThemeProvider } from "@material-ui/styles" ; import { createMuiTheme } from "@material-ui/core/styles" ; import Container from "@material-ui/core/Container" ; import Typography from "@material-ui/core/Typography" ; import Button from "@material-ui/core/Button" ; import { AppBar, Toolbar } from "@material-ui/core" ; import Switch from "@material-ui/core/Switch" ; import lightTheme, { darkTheme } from "./theme" ; import Grid from "@material-ui/core/Grid" ; import Component1 from "./Component1" ; function App() { // The 'checked' state is for the status of Switch component const [checked, setChecked] = React.useState( false ); // The 'newtheme' state tells if the new theme (i.e, dark theme) // is to be applied or not. const [newtheme, setTheme] = React.useState( false ); function changeTheme() { setTheme(!newtheme); setChecked(!checked); } // Conditional - if newtheme is set to true // then set appliedTheme to dark const appliedTheme = createMuiTheme(newtheme ? darkTheme : lightTheme); return ( <React.Fragment> <ThemeProvider theme={appliedTheme}> <CssBaseline /> <AppBar position= "static" color= "transparent" elevation={0}> <Toolbar> { /* Switch position whenever changed triggers the changeTheme() */ } <Switch checked={checked} onChange={() => { changeTheme(); }} style={{ color: appliedTheme.palette.secondary.icons, }} /> </Toolbar> </AppBar> <Container maxWidth= "sm" > <Typography component= "h1" variant= "h1" align= "center" color= "textPrimary" gutterBottom > Beginner for Beginner </Typography> <br /> <Component1></Component1> <br /> <Grid container direction= "row" justify= "center" spacing={4} > <Grid item> <Button variant= "contained" color= "secondary" > Button 1 </Button> </Grid> <Grid item> <Button variant= "outlined" color= "secondary" > Button 2 </Button> </Grid> </Grid> <br /> </Container> </ThemeProvider> </React.Fragment> ); } export default App; |
Javascript
// Component1.js import React, { Component } from "react" ; import { makeStyles } from "@material-ui/core/styles" ; import { useTheme } from "@material-ui/core/styles" ; import Typography from "@material-ui/core/Typography" ; const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, }, })); export default function Component1() { const theme = useTheme(); const classes = useStyles(theme); return ( <div className={classes.root}> <Typography variant= "h3" align= "center" color= "textPrimary" paragraph > This is a Child Component text. </Typography> </div> ); } |
Step to Run Application: Run the application using the following command from the root directory of the project:
npm start
Output: Now open your browser and go to http://localhost:3000/, you will see the following output: