Styled-components organization [closed]

Solution 1:

This is what most of my big production applications built with styled-components look like:

src
├── App
│   ├── Header
│   │   ├── Logo.js    
│   │   ├── Title.js   
│   │   ├── Subtitle.js
│   │   └── index.js
│   └── Footer
│       ├── List.js
│       ├── ListItem.js
│       ├── Wrapper.js
│       └── index.js
├── shared
│   ├── Button.js
│   ├── Card.js
│   ├── InfiniteList.js
│   ├── EmojiPicker
│   └── Icons
└── index.js

The App folder contains all the specific components that make up your bigger application. (you might structure that by route in your real app) Each of those bigger components is a folder with an index.js file and a bunch of styled components in individual files.

While I'm building my application and I notice I need a styled component from one bigger component in another bigger component, I drag its file to the shared/ folder, update all the imports and that's it! Over time shared/ becomes an improptu pattern library with all of the components I want/need to reuse throughout my entire app.

Another way that's fairly common is to have style.js files in the component folders which contains all of the styled components of that component. The upside being that you have less files that get in your way, but with the downside that it's harder to notice duplication and moving components into the shared folder is more work.

I personally use the first version more often than not, but that's probably just a matter of taste—try them both and see which one you like more!

Solution 2:

You can also try Atomic Design to structure your app. This way you will be able to reuse your styled components. Based on Atomic Design methodology, you organize your components into atoms, molecules, organisms, pages and templates.

Atom

An atom is native html tag. For example, an Input element can be an Atom

const Input = props => <input {...props} />

Molecules

Group of atoms is a molecule. For example:

const Field = ({ label, ...inputProps }) => (
    <Label>
        {label}
        <Input {...inputProps} />
    </Label>
)

Organisms

Organism is a group of atoms, molecules and/or other organisms. For example:

const Form = (props) => (
    <form {...props}>
        <Field label="Name" type="text" />
        <Field label="Email" type="email" />
    </form>
)

Pages

A page is where you will put mostly organisms. For example:

const HomePage = () => (
    <PageTemplate header={<Header />}>
        <Form />
    </PageTemplate>
)

Templates

A template is a layout to be used on pages. For example:

const PageTemplate = ({ header, children }) => (
    <main>
        {header && <div>{header}</div>}
        {children}
    </main>
)

Github example

There is a React starter project on Github that uses Atomic Design methodology with styled-components integration. Here is the Link.

Solution 3:

The way i am organizing my Project with styled-component is the following:

src
├── Layout
│   ├── Header
│   │   ├── Logo.jsx    
│   │   ├── styled.js
│   │   ├── container.js
│   │   └── index.js
│   └── LeftPanel
│       ├── LeftPanel.jsx
│       ├── styled.js
│       └── index.js
└── index.js

Reasoning:

  • Each folder is a feature.
  • Each file within a folder have a responsability.
    • .jsx represent a presentational component.
    • styled.js are styled components. Manage only how components look. Also any theme related file should be imported here, such as colors,borderStyles, etc.
    • container.js If we are using any state management we should have an artifact connecting our components with that library. In this case Redux.
    • index.js exports whatever is relevant.

The advantage that i see with this approach is that is pretty clear where changes have to be made if you decide to use another CSSinJS library.

Hope it make sense for someone else.

Cheers!