Search code examples
reactjstypescriptstyled-components

Override a Styled Component


I've created a Button component in my React app using TS and Styled Components. For simplicity, here are the styles:

const Button = styled.div`
    background: #fff;
    width: 100px;
    border-radius: 4px;
`

In a separate page, I'm using this button, but want to change the background color and the width. I assumed I could create my SecondaryButton with the following styles.

const SecondaryButton = styled(Button)`
    width: 40px;
    background: red;
`

I've imported the Button component into my second file, so it's accessible. The SecondaryButton is correctly inheriting all of the Button styles, but the overridden styles aren't applying or even showing in the browser console.

How can I extend a styled component and add new styles to it? I'd like to avoid creating an additional component for this one-time use.

Styled-Components v6.1.6

React v18.2.0


Solution

  • You need to pass a className prop to the parent component before you can properly override the styling. Example:

    Button.tsx

    interface IProps extends ButtonHTMLAttributes<HTMLButtonElement> {
       className?: string;
       children?: React.ReactNode;
       onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
    }
    
    export default function Button({ ...props }: IProps) {
      const { className, children, onClick } = props;
    
      return (
        <ButtonWrapper
          className={className}
          onClick={onClick}
        >
          {children}
        </ButtonWrapper>
      );
    }
    
    const ButtonWrapper = styled.div`
      //css goes here
    `;
    
    

    HomePage.tsx

    import Button from 'Button';
    
    */.../*
    return(
      <SecondaryButton />
    )
    
    const SecondaryButton = styled(Button)`
      //new CSS
    `
    

    Reference: https://styled-components.com/docs/advanced#styling-normal-react-components

    If you use the styled(MyComponent) notation and MyComponent does not render the passed-in className prop, then no styles will be applied. To avoid this issue, make sure your component attaches the passed-in className to a DOM node: