How to work with props in Styled-components

One of the strengths of styled components is adapting styles based on the props. Props in Styled-components can be utilized to make changes, dynamically and conditionally, with JavaScript. You can also use predefined special props to change the override the HTML tags creating.

If you stumble upon this post, I encourage you to have to learn the basics of Styled-components first and then read this post.

Now, let’s see various ways you can use props in Styled-components.

Passing HTML attributes as props in Styled-components

HTML tags have various attributes that you can use to change the behavior of the tag. You can use these HTML attributes in Styled-components just like you use them with regular HTML tags.

let’s create an HTML input

const Input = styled.input`    
     background-color: 'navy';
     color:'white';
     width: fit-content;
`

Let’s say you want a submit button. So, you can pass the “type” and “value” attributes to the Input component as follows. The input HTML tag will convert to a button and you can add an event for the button as well.

<Input type="submit" value="click me" onClick={ ()=>alert("say hello")}/>

An important thing to note here is that you need to make sure the relevant attribute passes to the component. for example, if you create a <li> tag and pass the attribute “type” as a prop to the component, it will not have the same effect as above.

Applying styles dynamically using props in Styled-components

Not only have HTML attributes, but you can also pass custom props and apply styles based on the prop.

In styled components, you need to use a function to access the props as follows.

const MyListItem = styled.li`
    font-size:${ props => props.mainHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.headerStyle }
`;

<MyListItem mainHeader headerStyle="none">Programming languages</MyListItem>
<MyListItem>Java</MyListItem>
<MyListItem>C++</MyListItem>

When I apply the “font-size”, the function is checking if props.mainHeader exists. Based on that, it applies the style.

in the second case, I use the value of the prop to apply the style so that the first item in the list will not have any list styles applied.

You do not need two props for the above case. I used two props for the purpose of code readability. You can achieve the same result with just one prop.

const MyListItem = styled.li`
    font-size:${ props => props.myHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.myHeader }
`;

<MyListItem myHeader="none">Programming languages</MyListItem>
<MyListItem>Java</MyListItem>
<MyListItem>C++</MyListItem>

More on conditional use of props

I have used the conditional ternary operator to apply styles dynamically based on the specific condition. you can also use if-else and switch statements in the styled components.

if-else statements with props in Styled-components.

For the above-styled component, you can apply an if-else statement as follows

const MyListItem = styled.li`
    font-size:${ props => props.mainHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.headerStyle };
    
    font-weight:${ props => {
        if( props.mainHeader ){
            return 'bolder';
        }
        else{
            return 'lighter';
        }
    } 
}`;

<MyListItem mainHeader headerStyle="none">Programming languages</MyListItem>
<MyListItem>Java</MyListItem>
<MyListItem>C++</MyListItem>

switch statement with props in Styled-components.

Similarly, we can apply the switch statement for multiple conditions. I have added the bgColor prop to Styled-components with values as “header”, “java” and “c++”.

const MyListItem = styled.li`
    font-size:${ props => props.mainHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.headerStyle };
 
    background-color: ${ props => {
        switch( props.bgColor ){
            case 'header':
                return 'darkgray';
            case 'java':
                return 'gray';
            default:
                return 'lightgray';
        }
    }};   
`

<MyListItem bgColor="header" mainHeader headerStyle="none">Programming languages</MyListItem>
<MyListItem bgColor="java">Java</MyListItem>
<MyListItem bgColor="c++">C++</MyListItem>

Applying additional props

You can also add props dynamically with the .attr() constructor. You can pass an object to this function with props and values.

const MyListItem = styled.li.attrs( props => ({
    draggable: true, // adding new HTML attribute
    textColor: props.mainHeader ? 'blue': 'green', //adding a new dynamic prop
}))`
    
    color: ${ props => props.textColor }; //appying the dynamic prop
    font-size:${ props => props.mainHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.headerStyle };   
`;


<MyListItem bgColor="header" mainHeader headerStyle="none">Popular programming languages</MyListItem>
<MyListItem secondItem="java">Java</MyListItem>
<MyListItem thirdItem="c++">C++</MyListItem>

The values of the props can be static or dynamic based on a specific condition. If you use only static values, you do not need to use attrs( prop => ({ })) format ( passing function ). You can just pass an object.

const MyListItem = styled.li.attrs({
    draggable: true, 
    textColor: 'green',
})`

Built-in props in styled-components

The Styled-components offers built-in props to apply, adapt or override styles. One of the most commonly used props is the “as” polymorphic prop.

“as” polymorphic prop

This prop is called a polymorphic prop because you can change the HTML element/ tag being rendered while keeping the same styles applied. As you can see in the example below, I have added the “as” polymorphic prop to the first element. This will change <li> tag to a <h1> and to a <a> tag while keeping the same styles.

const MyListItem = styled.li`  
    font-size:${ props => props.mainHeader ? '20px': '12px'};
    text-align:left;
    line-height:20px;
    list-style: ${ props => props.headerStyle };     
`;

<MyListItem as="h1" mainHeader headerStyle="none">Programming languages</MyListItem>
<MyListItem secondItem="java">Java</MyListItem>
<MyListItem thirdItem="c++">C++</MyListItem>
<MyListItem as='a' href="https://www.w3schools.com">learn more</MyListItem>

Final thoughts

The Styled-components is a great use case for using JavaScript tag template literals. It can cut down CSS code by reducing repetitions. It uses JavaScript to make changes and adapt CSS code. In addition, the developers can also use OOP concepts such as inheritance and polymorphism to override and extend styles.

Posted In CSS

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *