How to extend component style in styled-components

Viewed 209

I have a basic ElipseDetail component that looks like the image below

enter image description here

<ElipseDetail text="1.07" />

When I am using the component everything works as expected.

But now I want to reuse the component in another place but add an extension to the Text component style

How can I achieve that with styled-components and reuse the component but change the Text which is a child?

import React, { ReactElement } from "react";
import styled from "styled-components";

interface Props {
  text: string;
  children?: React.ReactNode;
}


export const Container = styled.div`
  padding: 4px 12px;
  border-radius: 30px;
  background-color: #eaeef2;
  display: inline-block;
`;

export const Text = styled.p`
  font-size: 12.5px;
  font-weight: normal;
  font-stretch: normal;
  font-style: normal;
  letter-spacing: 0.63px;
  color: #687c97;
`;


export default function ElipseDetail({ text, children }: Props): ReactElement {
  return (
    <Container>
      <Text>{text}</Text>
      {children}
    </Container>
  );
}

2 Answers

Since ElipseDetails is not a styled component, but calls to a styled one, you can do something like:

function ElipseDetail({ text, children }: Props): ReactElement {
  return (
    <Container>
      <Text>{text}</Text>
      {children}
    </Container>
  );
}

ElipseDetail.Styled = Container;

export default ElipseDetail

And then, in a different component, you can change it like so:


const StyledElipseDetail = styled(ElipseDetail.Styled)`
  ${Text} {
    //
  }
`;

...

return <StyledElipseDetailed>...</StyledElipseDetail>

PS - I have taken this approach from an older question of mine which I found quite useful.

I would suggest to create a container and if Text is in that container then add different properties. & here means this class name so it evaluates to Text so when text would be in ElipseContainer then it will behave in different way depending on your use case. Here if it's wrapped with ElipseContainer then colour of Text is green and it's red otherwise. Here is sandbox link : sandobx

const ElipseContainer = styled.div``;

const Text = styled.p`
  color: red;

  ${ElipseContainer} & {
    color: green;
  }
`;

 const App =() =>   
      <ElipseContainer>
        <ElipseDetail text="word2" />
      </ElipseContainer>
Related