Effective Use of Styled-Components Theme Features

I've been using styled-components(SC) since it was first released. It's my favourite way of building reusable React components and to style them with css-in-js.

One of my favourite features in styled-components is themes! When I was working at Capital On Tap it did allow my team to easily switch the whole UI to match one the company's many partners color scheme and other visual assets or based on a specific campaign we were running at the time.

The way I like to use the theme object in SC is to keep all the basic and reusable UI units in one place - think things like: colors, font sizes, breakpoints, animation timings, font-family, etc.

I'll skip setting up styled-components in your app but it's super easy and you can find all about it here.

Here is an example of how the theme object might look like:

// Theme.js
const theme = {
  colors: {
    beige: '#fcfaf7',
    black: '#000000',
    red: '#ff6060',
    light_red: '#ff6c87',
    yellow: '##fff368',
    dark_gray: '#5a5a5a',
    salmon: '#ff8f72',
  },
  fontSizes: {
    small: '20px',
    medium: '22px',
    large: '32px',
    xl: '38px',
  },
  fonts: ["'Roboto', sans-serif", 'Calibre-Medium'],
  defaultTransitionTime: '350ms',
}

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

export default Theme

After that I tipically create atomic components that use the brand's theme and make my components look consistent when I start building more compelx molecules.

// Heading.js
import styled from 'styled-components'

const Heading = styled.h1`
  font-family: ${props => props.theme.fonts.join(', ')};
  font-size: ${props => props.theme.fontSizes.large};
`

export default Heading
// Button.js
import React from 'react'
import styled from 'styled-components'

const StyledButton = styled.button`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  color: white;
  background: ${props => props.theme.salmon};
`

const Button = ({ children }) => {
  return <StyledButton>{children}</StyledButton>
}

export default Button

And then at a higher level component in your app use the Theme component:

// Layout.js
const Layout = ({ children }) => {
  return (
    <>
      <Theme >
        <Heading>Styled-Components Is Awesome</Heading>
        <Button>Click to change color</Button>
        <main>{children}</main>
        <footer></footer>
      </Theme>
    </>
  )
}

And that is all about you need to start using themes in your app. From here on you can see that if we needed to change themes on the fly we could easily achieve this by storing theme objects in a json file or simply as javascript objects and use a click event or a url query parameter like in htttps://myapp.com?theme=dark to change the theme object passed onto ThemeProvider - after that styled-components takes care of passing down the theme object as a prop to its children.

Hope this helps you building UIs faster, in a more consistent and cleaner fashion.

Happy hacking :)