2

As an example, let's say I've a component that can take in props like this:

const testComponent = (props: {isBold: boolean}) => {
   if(props.isBold)
     return <strong><div>hello</div></strong>
   return <div>hello</div>
    
}

In this case, my example component that can take in props and the result depends on the props given to it.

Now, if I extend this component in styled-components, how can I pass my props into the base component? The idea is something like this:

const styledTestComponent = styled(testComponent({isBold: true}))`
    width: 100%;
    opacity: 0.5
    /* etc etc... */
`

Well, obviously not going to work. This part will fail: styled(testComponent({isBold: true}))

But the idea is that what I want to do is to use CSS to style a particular instance of a component. So in that case, I will need to pass a pre-defined props to the base component, testComponent.

How can I achieve this?

Update:

I've come up with a quick example to illustrate the issue. The code below attempts to style a react component MyCustomImage as a styled-component StyledMyCustomImage. When this is run, you can see that StyledMyCustomImage does render itself as MyCustomImage. However, the CSS styles are not applied.

const MyCustomImage = props => (
  <img
    src={`https://dummyimage.com/${props.width}x${props.height}/619639/000000`}
  />
);

const StyledMyCustomImage = styled(MyCustomImage)`
  border: 2px dotted red;
`;

function App() {
  return (
    <div className="App">
      <h3>Test passing props from styled component to base component</h3>
      <StyledMyCustomImage width="600" height="400" />
    </div>
  );
}

I've created a sandbox for this demo: https://codesandbox.io/s/k21462vjr5

Update 2:

Oh! Thanks to @SteveHolgado's answer, I've gotten it to work! I didn't know styled component will pass the CSS as a prop to its base component! Here's the code after adding in the class name for future reference:

const MyCustomImage = props => (
  <img
    src={`https://dummyimage.com/${props.width}x${props.height}/619639/000000`}
    className={props.className}
  />
);

const StyledMyCustomImage = styled(MyCustomImage)`
  border: 2px dotted red;
`;

The sadnbox of the working demo: https://codesandbox.io/s/j4mk0n8xkw

Community
  • 1
  • 1
Carven
  • 14,988
  • 29
  • 118
  • 161

2 Answers2

4

Try this, it should work

const StyledTestComponent = styled(testComponent)`
    width: 100%;
    opacity: 0.5
    /* etc etc... */
`

and pass the prop to instance in this way.

<StyledTestComponent isBold />

Feedbacks are welcome. I have not checked it working, but feels it will work

Note: I checked and it's working. Should work for you.

simbathesailor
  • 3,681
  • 2
  • 19
  • 30
  • I just tried it out. While the props do get passed on, the styles in StyledTestComponent doesn't get applied. In fact, when I view the source of the page, those styles are not on the page at all. – Carven Oct 28 '18 at 08:33
  • I've updated my question with an example to illustrate my problem. – Carven Oct 31 '18 at 09:24
2

When you use the styled function like that, your wrapped component will get passed a prop called className, which you need to apply to the element that you want the styles to affect:

const testComponent = (props) => {
  return <div className={props.className}>hello</div>
}

You will have access to all props in your styles, which you can use like this:

const styledTestComponent = styled(testComponent)`
  width: 100%;
  opacity: 0.5;
  font-weight: ${props => props.isBold ? "bold" : "normal"};

  /* etc etc... */
`
Steve Holgado
  • 11,508
  • 3
  • 24
  • 32
  • Thank you! I've gotten it to work now! I've also updated my question with your answer in my example code. – Carven Oct 31 '18 at 09:31
  • Just a heads up @Carven you shouldn't put the answers inside the question and leave the answers on the page as it confuses the users. – Jamie Hutber Jun 15 '21 at 16:31