Search code examples
javascriptreactjsecmascript-6styled-components

How does this Nested Javascript Template Literal with Arrow work?


The Code Below has been taken from Styled Components example.

FULL CODE :
import styled, { css } from 'styled-components'

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;

  ${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `};
`

QUESTION :

The thing that I am trying to understand is how does the following template literal evaluation work?

CODE :
${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `};
  1. Is this expression inside the litreal returning a string to the upper string litreal defined by the backtick?
  2. How does the => function work inside the template literal?
  3. Hows does the evaulation of conditionals work here? Does it return a true/false or it evaluates to last statements return function if true?

Solution

  • There is a lot of fancy ES6 syntax here. I will break it down line by line.

    The first couple lines,

    background: transparent;
    border-radius: 3px;
    border: 2px solid palevioletred;
    color: palevioletred;
    margin: 0 1em;
    padding: 0.25em 1em;
    

    are just basic CSS to apply to the element. Then, we have a ${} which lets us use a JS object inside the template literal. Here, the code uses arrow functions, => which is very similar to a anonymous function. These are all equivelant:

    () => {
    // do things
    }
    function () {
    // do things
    }
    () => /* do a single line expression and return */
    

    So in the interpolation, the code is just making a function. In Styled Components, a interpolation with a function means some CSS that is dependent on the component arguments, so you could specify arguments like color, font, background-preset, etc...

    Then, what the && operator does is that it can be thought of as a shorthand "if". From MDN:

    More generally, the operator returns the value of the first falsy operand encountered when evaluating from left to right, or the value of the last operand if they are all truthy.

    So if props.primary is true, then it will return the CSS,

    background: palevioletred;
    color: white;
    

    but if it is not then it will return whatever props.primary is. In the example, props.primary is true or undefined. When undefined, it returns undefined. Quoting from the styled components docs:

    Speaking of which, during flattening, styled-components ignores interpolations that evaluate to undefined, null, false, or an empty string (""), which means you're free to use short-circuit evaluation to conditionally add CSS rules.

    So when it returns undefined styled components will just ignore it.