Search code examples
cssreactjsstyled-components

Reusable styled components (pseudo element) with logic


I've written some shared style to be used across different components, how can I change the value of left or width based a passed value or boolean logic so the values can be more dynamic?

And if possible, I don't want it passed as a prop in the actual component <bar left="20" />, but rather just within the declared styles.

const shared = css`
  ::after {
    content: '';
    left: 0;
    width: 100%;
    ${(props) => props.beta && 
    `
      top: 0;
    `
  }
`

const foo = styled.div`
  ${shared}
`

const bar = styled.div`
  ${shared}

  ${child} {
     ${shared}
  }
`

Solution

  • you can use a funtion instead:

    const getShared = (props) => css`
      ::after {
        content: '';
        left: ${props.left || '0'};
        width: ${props.width || '100%'};
        ${(otherProps) => otherProps.beta && 
        `
          top: 0;
        `
      }
    `
    
    const foo = styled.div`
      ${(props) => getShared(props)}
    `
    
    const bar = styled.div`
      ${(props) => getShared(props)}
    
      ${child} {
        ${(props) => getShared(props)}
      }
    `
    

    if you want to simply override the shared css here is a simple exemple:

    <div>
          {/* this is a div that uses shared css */}
          <div css={shared}>this is shared css</div>
    
          {/* this is a div that uses shared css in his styling*/}
          <FirstContainer>container extends shared css</FirstContainer>
    
          {/* this is a div that uses shared css in his styling but overrides border color using a prop*/}
          <SecondContainer borderColor="red">container overrriding the shared css</SecondContainer>
     </div>
    

    and here is the styling:

    // this is the shared css
    export const shared = css`
        width: 100px;
        height: 100px;
        border: solid 1px green;
        margin: 40px;
    `
    
    // div using the shared css
    export const FirstContainer = styled.div`
        ${shared}
    `
    
    // div using the shared css but overriding border color
    // props contains all the properties passed to the SecondContainer component (like left in bar component)
    export const SecondContainer = styled.div`
        ${shared}
    
        border-color: ${(props) => props.borderColor}
    `
    

    here is the result :

    enter image description here