React styled-components v5 – how to use theme

As you apply css style to many components you will realize that you want to have

  1. consistent style to be applied to your web/mobile application
  2. easy way to change the style depending on some conditions

style-components provides an easy way for that – theme. You can define a theme which could be applied to the app globally.

Define a theme

This could be in separate files if you would like to have multiple themes. In this example, I defined two themes – light and dark – in separate files. I typically place the theme files under components/thems folder.

light.js
const theme = {
  id: 'light',
  primaryColor: '#f8049c',
  secondaryColor: '#fdd54f',
  bodyBackgroundColor: 'white',
  bodyFontColor: 'black'
}

export default theme;
dark.js
const theme = {
  id: 'dark',
  primaryColor: 'black',
  secondaryColor: 'midnightblue',
  bodyBackgroundColor: 'black',
  bodyFontColor: 'white'
}

export default theme;

Use the theme in the theme provider

Import ThemeProvider in styled-components and set the theme in App.js. As you can see in the example below, I am choosing the theme based on the id. The ThemeProvider now injects all the defined properties to all styled components under the App.js

import {ThemeProvider} from 'styled-components';
import LightTheme from 'themes/light';
import DarkTheme from 'themes/dark';


function App() {
    <ThemeProvider theme={{...theme, setTheme: () => {
      setTheme(s => s.id === 'light' ? DarkTheme : LightTheme) 
    }}}>
    
    // other code ...
}

In any styled components under the App.js, you can access the theme now.

const HeaderWrapper = styled.header`
  background-image: linear-gradient(
    to right,
    ${p => p.theme.primaryColor},
    ${p => p.theme.secondaryColor});
  border-bottom: 3px solid ${p => p.theme.secondaryColor};
`;

React Styled Component V5 Basics

Styled component is a very useful and convenient library for react styling. Although there are many other choices (or you don’t even need to use as you can directly apply css) there is a definite advantage such as performance.

Install

Make sure react app is created by running the following command

> npx create-react-app <your app name>

After successful creation, run

> npm install styled-components

Basic Usage

Let’s create a button react component and apply some css. In order to use styled component you just need to choose styled.<component> – in this case I used button but you can use div, h1, span and etc – and apply css styles there.

There is more than just normal css support. You can apply javascript logic in order to decide certain styles based on provided props. As you can see in the example code ‘p’ represents prop.

Styled component also supports bulk styling selection by using css.

// Button.js

import React from 'react';
import styled, {css} from "styled-components";

const ButtonContainer = styled.button`
  color: white;
  background: ${p => p.secondary ? 'black' : '#f8049c'};
  font-weight: bold;

  ${p => p.large ? css`
    padding: 10px;
    border-radius: 5px;
    font-size: 1.5em;
  ` : css`
    padding: 8px;
    border-radius: 4px;
    font-size: 1em;
  `}
  
  box-shadow: none;
  border: one;
  width: 100%;
  display: block;
  white-space: none;

  &:disabled{
    background: #eee;
    color: #666;
  }
`;

function Button(props) {
  return <ButtonContainer {...props}/>
} 

export {Button};

You can also apply global styles so you don’t have to copy code every place.
In order to have global style make sure

  1. import ‘createGlobalStyle’ from styled components
  2. create global style and apply css
  3. render the created component in App
import React from 'react';
import {Button} from 'components/common';
import {createGlobalStyle} from 'styled-components';

const GlobalStyle = createGlobalStyle`
  body {
    background: white;
    min-height: 100vh;
    margin: 0;
    color: black;
    font-family: 'Kaushan Script';
  }
`;


function App() {
  return (
    <>
      <GlobalStyle />
      <h1>App</h1>
      <Button primary>
        Primary Test
      </Button>
      <Button secondary>
        Secondary Test
      </Button>
      <Button large>
        Large Test
      </Button>
    </>
    
  );
}

export default App;