Media queries & custom props on Styled Components | React | TS

Media queries & custom props on Styled Components | React | TS featured image

Today I'm back to writing after a while without doing it and we come back strong with an article where I will show how to use media queries and custom props inside our Styled Components in React with Typescript, this is a functionality that I needed to implement for a project recently and I think it is positive to share it with the community. So here we go.

Requirements

In this step I will assume that we have a project with React, Typescript and Styled Components configured correctly and I will only show the dependencies that will be used in this tutorial:

yarn add styled-media-query

Create media file on theme folder

We will create a file called media.ts where we will configure the breakpoints.

./src
    ./theme
        ./media.ts
// media.ts import { generateMedia } from 'styled-media-query' // example media queries export const BREAKPOINT_XS = 480 export const BREAKPOINT_SM = 576 export const BREAKPOINT_MD = 768 export const BREAKPOINT_LG = 992 export const BREAKPOINT_XL = 1366 export const BREAKPOINT_XXL = 1600 export const media = generateMedia({ xs: `${BREAKPOINT_XS}px`, sm: `${BREAKPOINT_SM}px`, md: `${BREAKPOINT_MD}px`, lg: `${BREAKPOINT_LG}px`, xl: `${BREAKPOINT_XL}px`, xxl: `${BREAKPOINT_XXL}px` })

Create Example component

We create an Example component where we will use the styled components. In this case we will only use the component called Container in order not to complicate the example too much.

./src
    ./components
        ./Example
            ./index.tsx
// index.tsx import React from 'react' import { Container } from './styles' const Example = () => { return ( <Container> <h3>Example component</h3> </Container> ) } export default Example

Create styles file

We will create a file called styles.ts where our styled components will be, which we will use later inside the Example component.

./src
    ./components
        ./Example
            ./styles.ts
// styles.ts import styled from 'styled-components' import { media } from '../../theme/media' export const Container = styled.div` /* your CSS code */ `

Using media queries on styled components

In this step we will use the breakpoints created earlier for the media queries.

// styles.ts import styled from 'styled-components' import { media } from '../../theme/media' export const Container = styled.div` /* your CSS code for mobile first */ ${media.greaterThan('sm')` /* your CSS code for sm breakpoint */ `}; ${media.greaterThan('md')` /* your CSS code for md breakpoint */ `}; `

Using custom props on styled components

First we must pass the prop and its value in the styled component call.

// index.tsx import React from 'react' import { Container } from './styles' const Example = () => { return ( <Container bgColor="red"> <h3>Example component</h3> </Container> ) } export default Example

We simply do a destructuring and use the prop.

// styles.ts import styled from 'styled-components' import { media } from '../../theme/media' export const Container = styled.div<{ bgColor: string }>` /* Destructuring and use prop */ background-color: ${({ bgColor }) => bgColor}; `

Use the props with the ternary operator

For this case we will use the ternary operator, in case we do not receive a value or received empty value in the prop, we will assign the color #fff.

// styles.ts import styled from 'styled-components' import { media } from '../../theme/media' export const Container = styled.div<{ bgColor: string }>` /* Use ternary operator*/ background-color: ${({ bgColor }) => (bgColor ? bgColor : '#fff')}; `

Using the props into media query

We will create an arrow function and pass the props as a parameter so that we can use it within the function.

// styles.ts import styled from 'styled-components' import { media } from '../../theme/media' export const Container = styled.div<{ bgColor: string }>` ${({ bgColor }) => media.greaterThan('sm')` /* Use bgColor */ background-color: ${bgColor ? bgColor : '#fff'}; `}; `

Thanks for reading me. 😊