How to use Themes in styled-components
Tags: frontend, react, css, styledcomponents
Published: 2019-11-11 04:05:06

Styled-components is my default `css-in-js` library. I have used other libraries in the past but `styled-components` remains my personal favorite. I love the fact that I can embed and treat styles as if they were components. It gives me the ability to use maximum reusability. Additionally, I can pass props to these and make really cool conditional styles with minimum effort. 

Theming is a great tool to use within front-end applications. It also allows me to write way less code and be more consistent with my styling. By leveraging the theme provider in `styled-components` I only need to write my main styles and rules in one single object and invoke them in any component that is a descendant of that provider. Theme provider achieves this by leveraging the `context API`.

This short guide assumes a basic knowledge of styled-components.

I created a code sandbox with only three files in it, but the Theme pattern I use can be added anywhere within the directory of your application.

Update June 2020: I hosted a small workshop where I show how to add `styled-components` with `ThemeProvider` to a react app. You can checkout the [video here](https://www.youtube.com/watch?v=Acn8BMfPpsY). If you want to skip directly to theme provider, you can jump to minute 26:27.

Given the following structure:

```
|_ public
|_ src
  |_ App.jsx
  |_ index.js
  |_ Theme.jsx // can go in any folder
|_ package.json

```

App.jsx


```jsx
import React from "react";

const App = () => {
  return (
      <div>
        <h1>Hello world!</h1>
        <h2>By the power of styled-components!</h2>
      </div>
  );
};
export default App;

```


To begin with, inside of your react project install styled-components

```js
npm install styled-components
```

After I have set up my initial configuration and installed all my dependencies I usually go ahead and create a `Theme.jsx` component. In this component, I also create the theme object file. You can easily create this within your `App.jsx` component, but I think it is a good separation of concerns to allow it to live in its own file.

First things first, import React from the react dependency, and then we import `ThemeProvider` from the `styled-components` file. Theme provider uses context to provide the properties to its descendants.

```jsx
import React from "react";
import { ThemeProvider } from "styled-components";
```

Theme provider takes in a prop called `theme`, this props takes an object. We can add any property we want our `styled-components` to have access to. You can let your imagination run wild here! It is very powerful.

```jsx
const theme = {
  colors: {
    powderWhite: "#FFFDF9",
    persianGreen: "#06B49A",
    lightBlue: "#AFDBD2",
    onyx: "#36313D"
  },
  fonts: ["sans-serif", "Roboto"],
  fontSizes: {
    small: "1em",
    medium: "2em",
    large: "3em"
  }
}
```

Then, using the render props method we will create a `Theme` component that will render children with all the properties from the Theme provider. Like I mentioned before, the theme provider takes a theme prop. In that prop is where we reference the object we create above.

```jsx
const Theme = ({ children }) => (
  <ThemeProvider theme={theme}>{children}</ThemeProvider>
);
```

Finally, we export the theme.

```jsx
import React from "react";
import { ThemeProvider } from "styled-components";

const theme = {
  colors: {
    powderWhite: "#FFFDF9",
    persianGreen: "#06B49A",
    lightBlue: "#AFDBD2",
    onyx: "#36313D"
  },
  fonts: ["sans-serif", "Roboto"],
  fontSizes: {
    small: "1em",
    medium: "2em",
    large: "3em"
  }
};

const Theme = ({ children }) => (
  <ThemeProvider theme={theme}>{children}</ThemeProvider>
);

export default Theme;

```

Back in our `App.jsx` the component, we now import the theme component that was just created to wrap our entire function. By wrapping our App function, all the descendants of App will have access to the theme object. I usually like to add it to the top level of my project. 

We will also import the styled object. In a nutshell, the way we create styled-components is through this method. This method will give us back an HTML element that is mapped to the components and applies the give CSS styles.

```jsx
import React from "react";
import Theme from "./Theme";
import styled from "styled-components"
const App = () => {
  return (
    <Theme>
      <div>
        <h1>Hello world!</h1>
        <h2>By the power of styled-components!</h2>
      </div>
    </Theme>
  );
};
export default App;

```

Now, let's create some quick styled-components to highlight how we can access the theme within our styles. I also added props to `<Heading>` to illustrate how we can pass prop to our styles and use them to do things like conditionally render a font size, but you can do so much more. As I said, you can use your imagination 😁. You can perform any javascript operation. And because `styled-components` uses template literals, it all feels as if we were writing normal CSS.

```jsx
import React from "react";
import Theme from "./Theme";
import styled from "styled-components";

const Container = styled.div`
  width: 100%;
  border: ${props => `1px solid ${props.theme.colors.onyx}`};
  background-color: ${props => props.theme.colors.lightBlue};
  font-family: ${props => props.theme.fonts[0]};
`;

const Heading = styled.h1`
  font-size: ${({ isHeading, theme: { fontSizes } }) =>
    isHeading ? fontSizes.large : fontSizes.small};
  color: ${({ theme: { colors } }) => colors.persianGreen};
`;

const App = () => {
  return (
    <Theme>
      <Container>
        <Heading isHeading={true}>Hello World</Heading>
        <h2>By the power of styled-components!</h2>
      </Container>
    </Theme>
  );
};
export default App;

```

In the `<Container>` styles I opted out of destructuring in order to show that the concept of theming is possible via the props system. All we are doing is telling our props that we want to access the theme object that lives there. Inside the theme object, we can access any of the keys such as the colors object and reference a specific color (i.e `persianGreen`). 

I personally prefer to destructure my objects such as in `<Heading>`, in my opinion, it looks cleaner and I prefer less repetition of long chaining.

The props object as a whole now contains two main properties, `theme` and `isHeading`, but we can add as many props as we like. A way to great leverage this, is to pass a value from state and tie the style to rendered on state change.

You can start using themes in styled-components really quick as you can see. If you need clarification on any concept from this post, don't hesitate to reach out via comments or spectrum.chat :)!

{% codesandbox fancy-leftpad-4m8rd %}

Thanks for reading!