Search code examples
reactjsnext.jsstyled-components

dynamic styled components with mapped data


I'm trying to pull in a JSON of data that looks basically like this inside the json:

"items": [
  {
    "id": "1",
    "title": "data header one",
    "bgColor": "dark",
    "buttonColor": "red",
    "shadow": false,
    "offset": 1,
    "padding": 0,
  },
  {
    "id": "2",
    "title": "data header two",
    "bgColor": "light",
    "buttonColor": "black",
    "shadow": false,
    "offset": 1,
    "padding": 0,
  }
]

And I'm trying to map this data inside a next.js functional component by using map().

I'm struggling to see how to pass the items data such as "padding" or "buttonColor" or "bgColor" back into my styled components outside of the returned render. Is there a way to without using inline styles?

My return is set up like this:

return (
  <>
  {items.map(({id, title, bgColor, buttonColor, shadow, padding}) => {
    return (
    <Cta key={id}>
      <Div>
      {title}
      </Div>
    </Cta>
    )}}
  </>
);

And my styled components is set up like this:

const Cta = styled.div`
  background: ${bgColor};
  h4 {
  font-weight: bold;
  padding: ${padding}px;
  }
`;

I've cut down the code so pay no mind to the data that isn't used.


Solution

  • Here is how you can use object properties for styling:

    import React from "react";
    import styled from "styled-components";
    
    export default function App() {
      const Cta = styled.div`
        background: ${props => props.bgColor};
        h4 {
          color: blue;
          font-weight: bold;
          padding: ${props => props.padding}px;
        }
      `;
    
      const elements = items.map(item => (
        <Cta key={item.id} bgColor={item.buttonColor} padding={item.padding}>
          <h4>Heading</h4>
          {item.title}
        </Cta>
      ));
    
      return <div className="App">{elements}</div>;
    }
    
    const items = [
      {
        id: "1",
        title: "data header one",
        bgColor: "dark",
        buttonColor: "red",
        shadow: false,
        offset: 1,
        padding: 10
      },
      {
        id: "2",
        title: "data header two",
        bgColor: "light",
        buttonColor: "black",
        shadow: false,
        offset: 1,
        padding: 0
      }
    ];
    

    Here you can read more about passing data for styling using component's props: https://styled-components.com/docs/basics#adapting-based-on-props