DEV Community

Discussion on: How are you using Styled Components?

Collapse
larsejaas profile image
Lars Ejaas

Yeah, I have worked quite a bit with styled components actually. It is hands down my prefered way of styling things in React projects.
It can be a bit difficult to set up with TypeScript and the syntax for variables is a bit verbose - but it works extremely well!

Collapse
larsejaas profile image
Lars Ejaas

I prefer to write the styling in a seperate file and import the components where I need them. I normally use a global style file for some basic styles and then use *.style.ts files for anything else. Futhermore I will set up varous themes in seperate files.
I also tend to seperate stuff like breakpoints, margins, etc. that I use across themes into seperate files. I then import them where needed:

import {
  breakPoints,
  margins,
} from "styles/...";
Enter fullscreen mode Exit fullscreen mode

Regarding variables I tend to use destructuring when refering to props in styling:

background-color: ${({ theme }) => theme.color.backgroundSecondary};
Enter fullscreen mode Exit fullscreen mode

You can also refer to props on the component like this:

type CloseButtonProps = {
  modalType: TmodalType;
};

export const Closebutton = styled.button<CloseByttonProps>`
  position: absolute;
  right: ${(props) => (props.modalType === "search" ? "10px" : "16px")};
  ...
Enter fullscreen mode Exit fullscreen mode
Collapse
marcelxsilva profile image
Marcelo Silva

here you can use, an helper to destructuring props styling.

I use, an helper called getTheme with get from lodash.

export const getTheme = (themeProp: string) => ({ theme }: any): string => get(theme, themeProp);
Enter fullscreen mode Exit fullscreen mode

and can access this value getTheme('backgroundSecondary')

const backgroundSecondary = getTheme('backgroundSecondary')

background-color: ${backgroundSecondary}
Enter fullscreen mode Exit fullscreen mode

In index.js or index.ts of project you can use ThemeProvider from styled-components:

const theme = {
  ...colors,
  ...spacings,
  ...radius,
  ...breakpoints,
};

<ThemeProvider theme={theme}>
...
</ThemeProvider>
Enter fullscreen mode Exit fullscreen mode
Thread Thread
larsejaas profile image
Lars Ejaas

Hmm, I really love this. However, I tried it and couldn't make it work. Do you need a workaround when using several different themes? I am unsure how this would work?

Thread Thread
marcelxsilva profile image
Marcelo Silva

it is necessary to have the ThemeProvider configured at the root of the project. I usually use the routes file as children of the ThemeProvider.

when dealing with different themes, it will depend a lot on how you will inject the settings

Thread Thread
larsejaas profile image
Lars Ejaas

Yeah, that makes sense! But I need to do some rework on the way I implement themes in styled components. Would like to optimize my workflow further, and your idea using lodash is really great, I defininitely need to include this!

Collapse
nitzanhen profile image
Nitzan Hen Author

Thanks!! This is really helpful info, and seems like a good pattern.

Just to make sure I understand correctly, a typical component X's styles would be defined in X.style.ts/X.styles.js? And styles in that file would typically be declared using the tag-specific variants (e.g. styled.div, styled.h1)?

Also, based on your experience, is declaring styled-components styles inside the component file (X.tsx) itself a standard practice? Or do most developers use separate files for them (like you do)?

Lastly, do you perhaps have an example repo (yours or anyone else's) following this pattern? I'd love to have one as a point of reference.

Thanks again!

Thread Thread
larsejaas profile image
Lars Ejaas

Hi Nitzan

I only have an older repo to share, and honestly I would probably refactor the code a bit today, but feel free to take a look at it at: github.com/LarsEjaas/bruce-willis-app

It's a small page/web app - it's live here at bruce-willis.rocks/en

I am unsure that there is a best practice regarding separating code into separate files or not, but I like to do it this way. We use the same approach in the team where I work.

Let's say I am doing an "awesome button"

Then I would create a folder named AwesomeButton in the components folder.

This would contain:

AwesomeButton.tsx for the functional component,
AwesomeButton.styles.ts for the styles,
AwesomeButton.test.tsx for the tests and maybe
Awesome.stories.tsx if you use storybook.

Furthermore I would make an index.ts file where I would export the functional component like this:

export {default} from AwesomeButton.tsx
Enter fullscreen mode Exit fullscreen mode

This way I can import my AwesomeButton component like this inside my project:

import AwesomeButton from 'components/AwesomeButton'
Enter fullscreen mode Exit fullscreen mode

I think this pattern works well for large projects.

Thread Thread
larsejaas profile image
Lars Ejaas

Ahh, missed the part regarding tag-specific variants:

I use both of these:

export const StyledHeadline = styled.h1`
 //...styles
`
Enter fullscreen mode Exit fullscreen mode

and

import UnstyledComponent from 'components/...'

export const StyledComponent = styled(UnstyledComponent)`
  //...styles
`
Enter fullscreen mode Exit fullscreen mode
Thread Thread
nitzanhen profile image
Nitzan Hen Author

Thanks a lot for your detailed response!!!
This will be of great help to me.

Thread Thread
larsejaas profile image
Lars Ejaas

Ahh, you are welcome! Feel free to drop me a message if something is difficult with Styled Components. It can be a bit difficult at first...