How to add multiple styles based on property with styled-components?

Viewed 7043

In CSS/LESS I would do this:

.button {
    &:active, .active {
        background-color: #393939;
        border-color: #2F2F2F;
        box-shadow: inset 0 0 0 1px #3D3D3D,
            inset 0 2px 0 #323232;

    }
}

Where :active is the style for my button when it's being clicked, and .active is the class I would add to the button when it's active (for toggle-able button).

With styled-components I presently have this:

import styled from 'styled-components';

export default styled.button`
    width: 32px;
    height: 32px;
    border-radius: 5px;
    background-color: #535353;
    border: 1px solid transparent;
    cursor: pointer;
    outline: none;
    padding: 4px;

    &:active, /* what to do here?? */ {
        background-color: #393939;
        border-color: #2F2F2F;
        box-shadow: inset 0 0 0 1px #3D3D3D,
            inset 0 2px 0 #323232;

    }
`

But I don't know how to re-use all those :active styles based on some property. I know I can access the prop with ${props => prop.active}, but I don't know how to re-use that block of styles without repeating all those styles again.

How would I do this?

2 Answers

If you want to share some styles you could simply move it into a variable that you use in both places:

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

const activeStyles = `
   background-color: #393939;
    border-color: #2F2F2F;
    box-shadow: inset 0 0 0 1px #3D3D3D,
        inset 0 2px 0 #323232;
`

export default styled.button`
  width: 32px;
  height: 32px;
  border-radius: 5px;
  background-color: #535353;
  border: 1px solid transparent;
  cursor: pointer;
  outline: none;
  padding: 4px;

  &:active {
    ${activeStyles}
  }

  ${props => props.active ? css`${activeStyles}` : ''}
`

Instead of using template literals you can do this:

const Heading = styled.div([], props => ({
  backgroundColor: 'red',

  ...(props.isOpen && {
    backgroundColor: 'blue', 
    color: 'white',
    // ...some other styles
  })
}));
Related