2
votes

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

2

2 Answers

4
votes

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.

2
votes

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... */
`