Search code examples
styled-components

Convert styled-components theme object to style


I have a styled-components theme that I want to dynamically import everything in a specific section.

// example theme
const theme = {
  typography: {
    body: {
      fontSize: "0.875rem",
      fontWeight: 400,
      fontFamily: ["Roboto", "Helvetica", "Arial", "sans-serif"],
      lineHeight: "1.46429em",
      color: "rgba(0, 0, 0, 0.87)",
    }
  }
}

I want to avoid this:

const Section = styled.div`
  font-size: ${theme => theme.typography.body.fontSize},
  font-weight: ${theme => theme.typography.body.fontWeight},
  font-family: ${theme => theme.typography.body.fontFamily},
  line-height: ${theme => theme.typography.body.lineHeight},
  color: ${theme => theme.typography.body.color},
`

This works. This is exactly what I need to do...

import { objToCss } from "styled-components/lib/utils/flatten";

export const Section = styled.div`
  ${props => objToCss(props.theme.typography.body)};
`

...but I am importing styled-components/lib/utils/flatten, which doesn't look like it's part of their "public" API. This can change in the future, so it is risky.

Is there a better way I should be doing this?


Solution

  • You're right, it's not a good idea to use a non exposed API. Since you are in control on when you will update styled-components, it could be a risk that you are willing to take.

    Otherwise, you can use one of the many library that do this job. For example: https://github.com/rofrischmann/css-in-js-utils#cssifyobjectobject

    styled-components already support CSS object well, but you need a function that returns a CSS object. There is an issue here: https://github.com/styled-components/styled-components/issues/1762