Theme customizer in Reactjs

12-02-2019    Hari Kondlapudi    Views 1488



Themes bring a whole new aesthetic to any application, they can show the diverse features of a developer.

In this blog, we will mainly concentrate on dark and light themes, which helps an application to change the color of the entire website on a click of a button as per the user’s choice.

We use react-redux to complete this task in this blog, so I suggest you go through some basics in react-redux before you continue with this blog.

Npm Need To Install

        1.npm i prop-types

First, we create a ReducerProps.js file to track our theme className, which we will later use throughout the application

import PropTypes from 'prop-types';
   const{  string,bool,shape,func }=PropTypes;
 export const ThemeProps=shape({
       className:string,
  })

Now, we import ThemeProps from the file we just created and we also import PropTypes to establish the functions which are required to be executed.

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { ThemeProps } from '../../../shared/prop-types/ReducerProps';

class ToggleTheme extends PureComponent {
        static propTypes = {
                  theme: ThemeProps.isRequired,
                  changeToDark: PropTypes.func.isRequired,
                  changeToLight: PropTypes.func.isRequired,
           };
           render() {
 const { theme, changeToLight, changeToDark } = this.props;
               return (
                  className="toggle-btn__input"
                  type="checkbox"
                  name="theme_toggle"
                  id="theme_toggle"
                  checked={theme.className==='theme-dark'}
                  onChange={theme.className==='theme-dark'? changeToLight:changeToDark}
        />
        Toggle Dark Theme

         );
      }
}
export default ToggleTheme;

Now let's figure out the onChange functionality in our checkbox input we just created, but before we do that we need two more files that act as our actions and reducers in redux.

First, the actions file which maintains the function to return our type

export const CHANGE_THEME_TO_DARK = 'CHANGE_THEME_TO_DARK';
export const CHANGE_THEME_TO_LIGHT = 'CHANGE_THEME_TO_LIGHT';
export function changeThemeToDark() {
  return {
      type: CHANGE_THEME_TO_DARK,
   };
}
export function changeThemeToLight() {
   return {
        type: CHANGE_THEME_TO_LIGHT,
     };
}

Secondly, the reducer file to perform the actions

import {CHANGE_THEME_TO_DARK, CHANGE_THEME_TO_LIGHT } from '../actions/themeActions';
const initialState = {
      className: 'theme-light',
};
export default function (state = initialState, action) {
switch (action.type) {
     case CHANGE_THEME_TO_DARK:
          return { className: 'theme-dark' };
     case CHANGE_THEME_TO_LIGHT:
          return { className: 'theme-light' };
    default:
return state;
}
}

Now, we have seen the redux functionality and established files, we can understand the on change functionality and how to import and perform these
functions in our class components.

We Import the checkbox input ToggleTheme and the redux actions.

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import ToggleTheme from './ToggleTheme';
import { ThemeProps } from '../../../prop-types/ReducerProps';
import { changeThemeToDark,changeThemeToLight } from '../../../redux/actions/themeActions';

export default class Customizer extends PureComponent {
      static propTypes = {
               theme: ThemeProps.isRequired,
               changeToDark: PropTypes.func.isRequired,
               changeToLight: PropTypes.func.isRequired
          };
    changeToDark=()=>{
           const {dispatch} = this.props;
          dispatch(changeThemeToDark())
     }
    changeToLight=()=>{
          const {dispatch} = this.props;
          dispatch(changeThemeToLight())
     }

And we created two functions changeToDark and changeToLight to dispatch our redux actions.
Dispatch is a function of the Redux. We use dispatch to dispatch an action. This is the only way to trigger a state change.
Here we send props to our input checkbox to changeToDark or changeToLight.To trigger the dispatch and set the className in the ReducerProps.js to
theme-light or theme-dark

render(){
      const { theme } = this.props;
   return (
      changeToDark={this.changeToDark}
      changeToLight={this.changeToLight}/> 

     )
}
export default(Customizer);

Once you complete all the redux functions now we have to set up the css for your application, it is recommended to start setting up at the beginning of your project, so it isn't too complex.

Firstly, you have to import connect from react-redux. The connect() function connects a React component to a Redux store.

It provides its connected component with the pieces of the data it needs from the store, and the functions it can use to dispatch actions to the store.

And then we have to import withRouter from react-router-dom, withRouter is a higher-order component that will pass the closest route's match, current location, and history props to the wrapped component whenever it renders. simply it connects the component to the router.

import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { ThemeProps } from '../../sidebar/prop-types/ReducerProps';

class Index extends PureComponent {
      static propTypes = {
             theme: ThemeProps.isRequired,
       };
       constructor(props) {
       super(props);
       this.state = {
          }
}
render() {
const { theme } = this.props;
return (    Background color  );
        }
}
export default withRouter(connect(state=>({
theme:state.theme,
}))('common')(Index));

Lastly, we import Theme Props from Reducer props where we store the class name of the theme as ‘theme-light’ or ‘theme-dark’.

As you can see we should always give our outermost div the className as theme.className so that we can control all the className inside the parent div
with it.
As className div-theme is inside the theme.className, we can control and change it through the css.

CSS for Dark-Light Theme

Now let’s look at our scss file set up where we manage our css for light and dark themes, we set up variables for each theme with the same name so that for example on light theme color background in the light will be fetched and vice versa. When the theme.className is theme-light CSS in light $theme will be called and when theme.className is theme-dark CSS in dark $theme will be called.

Always remember to give the variables in two themes with the same names so there is no confusion and as you can see we used @function and @mixin in this file, which we will see how they work in the next slide.

$themes: (
light: (
   colorBackground: white,
   colorBackgroundBody: #f2f4f7,
   colorText:#86c0b6 ,
   colorTextAdditional: #646777,
   logoImg: url(../shared/img/logo/inmedtoryLogo.png),
   colorHover: #fafbfe,
   colorFolderHover: #f0eeee,
   colorBorder: #eff1f5,
   colorIcon: #dddddd,
   imgInvert: invert(0%),
   colorFieldsBorder: #f2f4f7,
   colorBubble: rgba(242, 244, 247, 0.65),
   colorBubbleActive: rgba(234, 238, 255, 0.6),
   colorScrollbar: #B4BFD0,
   colorFitness: #646777,
),
dark: (
  colorBackground: #232329,
  colorBackgroundBody: #2a2a31,
   colorText: #dddddd,
   colorTextAdditional: #999999,
   logoImg: url(../shared/img/logo/logo_dark.svg),
   colorHover: #38373f,
   colorFolderHover: #ffffff1A,
   colorBorder: #333246,
   colorIcon: #605f7b,
    imgInvert: invert(100%),
    colorFieldsBorder: #33333a,
    colorBubble: rgba(68, 79, 97, 0.65),
    colorBubbleActive: rgba(92, 104, 156, 0.6),
    colorScrollbar: #606071,
    colorFitness: #ffffff
)
);

@mixin themify($themes) {
   @each $theme, $map in $themes {
      .theme-#{$theme} & {
            $theme-map: () !global;
   @each $key, $submap in $map {
           $value: map-get(map-get($themes, $theme), '#{$key}');
           $theme-map: map-merge($theme-map, ($key: $value)) !global;
        }
     @content;
      $theme-map: null !global;
      }
    }
}
@function themed($key) {
     @return map-get($theme-map, $key);
}

Once the settings.scss file in set-up we just have to import it to our main.scss file and use @include themify($themes) which will call the @mixin and @function call in our settings file and by themed(variableName) we can access the declared light and dark theme in the settings file make sure the variableName and variables declared in our themes match.

@import 'settings.scss';
.div-theme{
@include themify($themes){
    background-color: themed('background');
    color:theme('color')
   }
}

There is also one more way to declare CSS to change our theme based on className.

   .theme-light .div-theme{
         background-color: white;
         color:black;
   }
   .theme-dark .div-theme{
             background-color: black;
             color:white;
   }

This is more of a simple way to change our theme, as we have given theme.className as a parent div to a div with class name .div-theme we can
control and change the theme in this way.

Although the second way is easier, the primary one is more sophisticated and is recommended to use in large applications for consistency and continuity
reasons.

Conclusion

There are a lot of themes you can accomplish using the method you just saw, we recommend you explore new themes and keep on trying.





Subscribe to Email Updates

Subscribe


Add Comments

Submit Comments

More Blogs


What is Trade Finance Transaction?

Blockchain Technology In Trade Finance Transactions

Hari Kondlapudi        Views 3044
block-chain-transform-your-business

Blockchain to transform your business

Hari Kondlapudi        Views 2448
block-chain-transform-your-business

Localization with React

Hari Kondlapudi        Views 1600

Contact Us

US Address:

Do Systems Inc,
433 Plaza Real, Suite 275
Boca Raton, FL 33432 


India Address:

Jayeesha Software Pvt Ltd
Hitech City Rd, VIP Hills,
Silicon Valley, Madhapur,
Hyderabad, TS 500081


Email: sales@dosystemsinc.com
 

Navigation

Copyright © 2023 Do Systems Inc. All rights reserved. Privacy Policy