React styled-components shared styles

Viewed 607

I have a question about both directory structure and the technique of sharing styles when using styled-components in react.

I have a Project and Task page. They both contain different information, but they are displayed in kinda the same way.

Example:

const Foo = styled.div`
  margin: 30px !important;
  border: 1px solid black;
  border-radius: 30px;
  overflow: hidden;
  min-width: 700px;
  min-height: 800px;
`;

This is a styled component that I would use as a parent div for both of them. So I can do create const Task = styled.div and const Project = styled.div and copy this style to each of them (they are in different folders of course). But then if I want to change something, this becomes painful, because I have to make changes in multiple places.

My directory structure is as follows:

  • src
    • components
      • Navbar
        • index.js
        • Navbar.tsx
        • styles.tsx
    • containers
      • Task
      • Project

Task and Project also contain 3 files, like Navbar. So here are my questions:

  1. Where do I define a shared style like Foo? Is it src/components/shared, src/components/shared/styles or maybe src/shared/stylees?
  2. No matter where I put it, how should I define this shared style? Because I can think of two options:

Option 1:

Create a styled.div like I've shown above and just use it as it is, so for example:

const Project = () => {
  return <Foo>{content}</Foo>
}

Option 2:

Create a css instance (?) like this:

const Foo = css`
  margin: 30px !important;
  border: 1px solid black;
  border-radius: 30px;
  overflow: hidden;
  min-width: 700px;
  min-height: 800px;
`

And then use it like this (so I would define a new styled component for Task and Project and include this style I defined):

const StyledProject = styled.div`
  ${Foo}
`

const Project = () => {
  return <StyledProject>{content}</StyledProject>
}

styled-components docs show how to define styled components for a current component that I am working on. I also found some conventions about that and I chose the index.js/<component_name>.tsx/styles.tsx trio, but there are many more. However, I couldn't really find docs/article about what to do with shared styles like this.

Do you guys know the way, or maybe you can share your particular approach?

1 Answers

For me, when I think about shared styles I think about why are the styles being shared. Do my two components appear similar because they are actually variations of a higher level component, and if so, what is that component?

For example, perhaps both Task and Project are supposed to look like "cards". In this case, I'd argue that what we have is actually the beginning of a new component called Card which will encapsulate the shared styling and just be another component.

const Project = () => {
    return <Card>{content}</Card>
}

In other words, instead of thinking about sharing styles, I prefer thinking about sharing components. Mentally it's the difference between making things look like cards and, in some sense, printing content onto cards.

Besides fitting organically within the structure you already have, it's also flexible in that cards can eventually become more structured without duplication at the usage sites.

So to answer your questions more specifically:

  1. I suppose I'd make a component in src/components/NameOfComponent
  2. And I would make the standard trio of files (index.js, NameOfComponent.tsx, and styles.tsx), though if at first the component is as simple as a single styled div, I might bypass styles.tsx and put the styled-components definition directly into NameOfComponent.tsx.

When it comes to frontend development, there never is one right way to do things, just a collection of generally good practices. So what I wrote above is also not the one-right-way, but my opinion having worked on different projects.

Related