Advanced Usage of Styled Components for your React App - Part 3

Advanced Usage of Styled Components for your React App - Part 3

This post continues the topic about Advanced Usage of Styled Components and covers animation, styling the existing component and attaching additional props (yes you can do that too).

Styling existing Component

Using method styled it is possible to style not only your own components, but also imported ones (third party components). This is very useful feature. It is possible to style:

  1. Another styled component
  2. Another non-styled third-party component

Styling another Styled Component

Let's say we want to create buttons for our application and we want them to have pretty much same style, except for minor differences. If we would like to do same in another language (for example C#), we would create interface Button with the main features and then other buttons would inherit from it. Pretty much same is happening here.

We create a functional component Button and define styles using styled method:

export const Button = styled.button`
  background: #0d2728;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  -webkit-appearance: none;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-family: sans-serif;
  font-weight: 700;
  height: 45px;
  margin: auto;
  opacity: 0.5;
  width: 35%;
`

Now we want to make a button with different background colour only, but with all other styles kept. First we import Button component to our file:

import {Button} from "Button.styles.js"

Now we can style it as a usual component. Remember, that new styles will have higher specificity over old styles:

export const LoginButton = styled(Button)`
background-color: red;`

Styling non-styled third-party Component

The styled method works perfectly on any third-party component, as long as they attach the passed className prop to a DOM element. Lets say you create Link component (react-router-dom's Link fo example) for your application:

export const Link = ({ className, children }) => (
  <a className={className}>
    {children}
  </a>
);

Now you want it to be styled so it would be not so boring:

export const FunnyLink = styled(Link)`
  color: palevioletred;
  font-weight: bold;`

When we use them in our app, they would be 2 different links:

import {Link, FunnyLink} from "Link.styles.js"

const App = ()=>{
return(
   <div>
     <Link>I am boring link </Link><br/>
     <FunnyLink>I am very funny link </FunnyLink> 
  </div>
  )
}

Simple as that :) Now let's explore one more important feature

Adding Additional Props

The official docs say, that to avoid unnecessary wrappers that just pass on some props to the rendered component, or element, you can use the .attrs constructor. It allows you to attach additional props (or "attributes") to a component. When do we even need that? Let's explore.

We have our styled Button component and we know that by default it has type="submit"right? What if we want to change the type for one of the buttons to type="button"? We can do that using .attrs constructor.

import styled from 'styled-components';
export const Button = styled.button.attrs(props => ({
  type: props.type || 'button'

}))`

Every Button component will now have type="button" as default.

The rule of thumb is to use .attrs when you want every instance of a styled component to have that prop, and pass props directly when every instance needs a different one -Styled Components Docs

Animation

The final feature I want to explore as a final part is animation. We can use the animation on any element using keyframes helper. Let's animate our Button :)

First we create keyframes:

const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
`;

Than we use it in the animation property:

export const Button = styled.button`
  background: #0d2728;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  -webkit-appearance: none;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-family: sans-serif;
  font-weight: 700;
  height: 45px;
  margin: auto;
  opacity: 0.5;
  width: 35%;
  animation: ${rotate} 2s linear infinite;`

That is amazing! Enjoy the animation and code here

Thank you for reading my blog. Feel free to connect on LinkedIn or Twitter :)

Buy Me a Coffee at ko-fi.com