Search code examples
reactjsstyled-components

Styled components - How do I create a style that inherits a component and is able to send props to the parent?


As an example (not real, but works the same way), I have two components, one (the parent) has the styles and calls a function in one of them:

Component 1

import { callFunctionToResolve } from 'resolver';
import styled from 'styled-components';

const Styled = {
  Component1: styled.div`
    background-color: ${({ backgroundColor }) => callFunctionToResolve(backgroundColor};
    color: ${({ textColor })};
    // ...
  `
};

const Component1 = ({ children, styles }) => {
  const { backgroundColor, textColor } = styles;

  return (
    <Styled.Component1
      backgroundColor={backgroundColor}
      textColor={textColor}
    >
      {children}
   </Styled.Component1>
  );
};

And now I have my Component 2 which has the exact same css's as Component 1, but changes div to something else, adds a display property, and will also receive the styles props.

import { Component1 } from 'component1';
import styled from 'styled-components';

const Styled = {
  Component2: styled(Component1)`
    display: block;
    font-size: 24px;
  `
};

const Component2 = ({ children, styles }) => (
  <Styled.Component2
    as={'header'}
    styles={styles}
  >
    {children}
  </Styled.Component2>
);

The problem is that Component1 isn't receiving the Component2 props. What is the best way to do this?

Note that more components will inherit from Component1.

Link to sandbox: https://codesandbox.io/s/rough-sound-ufeg0?fontsize=14&hidenavigation=1&theme=dark


Solution

  • Add className prop in order to apply injected styles and remove the as prop as it overrides.

    You can't use as and styled(Component) together.

    const Component1 = ({ className, children, styles }) => {
      const { backgroundColor, textColor } = styles;
    
      return (
        <Styled.Component1
          className={className}
          backgroundColor={backgroundColor}
          textColor={textColor}
        >
          {children}
        </Styled.Component1>
      );
    };
    
    const Component2 = ({ children, styles, className }) => (
      <Styled.Component2 className={className} styles={styles}>
        {children}
      </Styled.Component2>
    );
    

    Edit unruffled-proskuriakova-gmrmt