Skip to content Skip to sidebar Skip to footer

Emotion Css-in-js - How To Add Conditional Css Based On Component Props?

I'd like to have a component, styled with Emotion, that takes props that ultimately control the styling. For example, consider a GridCol component that has various props that chang

Solution 1:

This is a great question. First, avoid this pattern.

constGridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};
`

In this example, a new styled component is created on every render which is terrible for performance.

Any expression, or interpolation, can be a function. This function will receive 2 arguments: props and context

constGridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
`

As for the size prop in your example, I would use the following pattern.

import { css } from'emotion'constsizePartial = (props) => typeof props.size === 'string' ?
  css`width: 10%;` :
  css`@media screen and (min-width: 500px) {
      width: 20%;
   }


   @media screen and (min-width: 800px) {
      width: 30%;
   }


   @media screen and (min-width: 1100px) {
      width: 40%;
   }
 `

You can then use the partial just like any other function that occurs in an expression.

constGridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
  ${sizePartial};
`

This is an extremely powerful pattern that can be used to compose reusable dynamic styles across your project.

If you are interested in other libraries that leverage this pattern check out https://github.com/emotion-js/facepaint and https://github.com/jxnblk/styled-system

Solution 2:

If you are looking for a way to implement conditional styles with Emotion's css prop, you can do something like this:

import { css } from'@emotion/core';

conststyles = ({ isSelected }) => css`border: solid 1px black;
  border-radius: 10px;
  padding: 16px;
  cursor: pointer;
  ${isSelected === true &&
  `
    background-color: #413F42;
    color: white;
  `}
`;

constConditionalComponent = () => {
  const [isSelected, setIsSelected] = useState(false);
  return (
    <divcss={styles({isSelected })} onClick={() => setIsSelected(!isSelected)}>
      Click here to change styles.
    </div>
  );
};

More details on this here: https://seanconnolly.dev/emotion-conditionals

Solution 3:

Emotion has a helper called cx that provides functionality similar to the popular classnames library. You can use this to write conditionals more easily:

import { cx, css } from'@emotion/css'const cls1 = css`font-size: 20px;
  background: green;
`const foo = trueconst bar = falseconstSomeComponentWithProp = ({ foo }) => (
  <divclassName={cx(
      { [cls1]:foo === 'bar' },
    )}
  />
);

(Adapted from the linked docs)

Post a Comment for "Emotion Css-in-js - How To Add Conditional Css Based On Component Props?"