How to make styled components mixins with props as css property?

Viewed 70

I'm building an app with React and Styled components. I'd like to use mixins inside the styles, and pass a CSS property inside this mixin. I tried like this but it's not working:

const TestMixin = ({ color, property }) => css`
    ${property}: ${color === "blue"
        ? "blue"
        : color === "green"
        ? "green"
        : "red"};

    &:hover {
        ${property}: ${color === "blue"
            ? "red"
            : color === "green"
            ? "blue"
            : "green"};
    }
`

const Container = styled.div`
    background-color: ${TestMixin({
        property: "background-color"
    })};
`

How could I make this work? Thanks!

1 Answers

You can't to pass CSS property as an object key. If you want to create a similar scss mixin you can only pass CSS values to the mixin. To set CSS mixin in Container, just use the mixin without CSS property.

import styled, { css } from 'styled-components';

const TestMixin = ({ color }) => css`
  background-color: ${color === 'blue' ? 'blue' : color === 'green' ? 'green' : 'red'};

  &:hover {
    background-color: ${color === 'blue' ? 'red' : color === 'green' ? 'blue' : 'green'};
  }
`;

const Container = styled.div`
  ${TestMixin({ color: 'blue' })};
  padding: 1rem 2rem;
`;

export const App = () => {
  return <Container>Some text</Container>;
};

Try this solution with Container and container props, it is more flexible and customizable. If you removed the props, the style will not be applied.

import styled, { css } from 'styled-components';

interface Colors {
  color: string;
  hover: string;
}
interface Props {
  bgColor?: Colors;
  borderColor?: Colors;
  textColor?: Colors;
}

const bgMixin = (color: Colors) => css`
  background-color: ${color.color};
  &:hover {
    background-color: ${color.hover};
  }
`;

const borderMixin = (color: Colors) => css`
  border-color: ${color.color};
  &:hover {
    border-color: ${color.hover};
  }
`;
const textMixin = (color: Colors) => css`
  color: ${color.color};
  &:hover {
    color: ${color.hover};
  }
`;

const Container = styled.div<Props>`
  padding: 1rem 2rem;
  ${({ bgColor }) => bgColor && bgMixin(bgColor)}
  ${({ textColor }) => textColor && textMixin(textColor)}

  border-width: 2px;
  border-style: solid;
  ${({ borderColor }) =>
    borderColor
      ? borderMixin(borderColor)
      : css`
          border-color: transparent;
        `}
`;

export const App = () => {
  return (
    <Container
      bgColor={{ color: 'blue', hover: 'red' }}
      borderColor={{ color: 'red', hover: 'blue' }}
      textColor={{ color: 'white', hover: 'black' }}
    >
      Styled Components
    </Container>
  );
};

Edit dazziling-code

Related