Skip to content

Instantly share code, notes, and snippets.

@garethpbk
Created December 20, 2018 20:20
Show Gist options
  • Save garethpbk/4880b3f5840b84a233a9cbd4924f745e to your computer and use it in GitHub Desktop.
Save garethpbk/4880b3f5840b84a233a9cbd4924f745e to your computer and use it in GitHub Desktop.

Helping Out Your styled-components Theme

One of the most popular CSS-in-JS solutions out there is styled-components, and one of its killer features is the ability to easily create themes for your React applications. There are many ways to work with themes, and in this article I'll share my method that revolves around creating reusable helper functions to simplify the process and reduce the amount of code involved in styling. We'll also touch on using the polished library to add some pizzazz and further functionality to a styled-components theme.

My motivation for this pattern was to achieve the same ease that Sass and Stylus offer for writing functional CSS; I believe that the combination of styled-components and polished comes really close.

Project Setup

Set up a new create-react-app project and add the dependencies (or add to an existing project) - go ahead and delete everything except App.js and index.js in /src:

https://gist.github.com/d915fd437ca520243d894a4eccc25402

styled-components themes work with the Context API via a <ThemeProvider /> component. In index.js, import the component and theme and wrap <App />:

https://gist.github.com/6dbd004ad9d4482ec1295363cab28b02

<ThemeProvider /> takes one prop, an object calledtheme; create thetheme.js` file that was imported and set up the values:

https://gist.github.com/50b0201f1c940ff26e11109cce8c3a16

Let's use our theme colors and sizes in <App /> in a styled component:

https://gist.github.com/24ecfe9fad17ee23d61b091ac6200930

Hm. The syntax is kind of...bulky - we have the use the name of the property of the property of the theme object of the props each time. How can we simplify this?

Functions to the rescue! Let's create some reuseable helpers functions to make it easier to access theme values. In theme.js:

https://gist.github.com/72f9f4a7c879591d70a4a81a105f994e

Now we can import and use this function anytime we need a color in a styled component:

https://gist.github.com/f324e9932e46bed117f1991aad747c36

Let's do the same for sizes:

https://gist.github.com/e67298094c999a5415b483029048a294

https://gist.github.com/5cc218b82c2b221ca297783e931d0670

title

Alright, maybe it's not that much less code right now, but this pattern really shines when you're dealing with complex themes and nested theme objects. It puts the power of JavaScript functions in your hands for managing theme styling.

Lastly let's use some polished features via helper functions in theme.js:

https://gist.github.com/edf0fc83dcaf8f2bfe38b1efd50211a3

In <App /> let's use this on a new styled component:

https://gist.github.com/64e70d82d8ba351b7e7903c39fce7486

If you've used Sass's lighten feature, this should feel familiar.

Why can't we just import lighten directly into the component? Try it - ${lighten(getColor('secondary'), '0.2')} - it isn't parsed correctly. Keeping it in the theme means it's only imported from polished once, and doesn't rely on having direct access to getColor in the component.

One more - let's utilize the rgba feature from polished for easily controllable text shadows:

https://gist.github.com/402311ba23a9959739b6177fce16eb93

rgba automatically converts hex values to rgb values (exactly like the Sass function of the same name). This is great because it means we don't have to re-declare color values in different formats; the availability of default parameters is also a nice tool for setting base values. Add to <Content />:

https://gist.github.com/81da74a4ebf1b138e98732c17a73b9b5

content

That wraps up my method of theming styled-components; functions make for a powerful, infinitely expandable system. In the example project you'll also find a simple grid component created with breakpoint values in the theme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment