React and Styled Components Theming (Typescript Edition)

Creating high scale theming in React with Styled Components and TypeScript

styled compoents typescript
Copyright from Google Images

TL;DR: We are gonna create light and dark theme in react app with thought of scaleability using typescript.

Github source: https://github.com/ShonP/Theming-Practices

Live Project: https://ecstatic-albattani-06b63c.netlify.app/

react typescript styled components

Motivation: Using react typescript with styled components might be a challenge also theming it self is not that easy when talking about scale and bigger applications.

So today we will create a small react application that can be the base structure of any app that using styled components and typescript. So without any further words let’s get some code done.

Creating our app:

Create our project by using the following

npx create-react-app my-app — template typescript

I cleaned up a bit and this will be our final src folder structure

Let’s start by defining our theme interface (that later will be accessible by any styled components we will create)

Creating our theme interface:

Let’s create the file shared/theme/styled.d.ts

I defined here the default theme that any styled components we will create would have the access to it (https://styled-components.com/docs/api#typescript)

Creating our common theme:

Those are common properties for both our light and dark theme. (Font Sizes, Palette, Fonts, Paddings and Margins)

Creating a GlobalStyles:

The Global style will later change our application background-color and color while switching between themes, we will see it in action later.

Creating our Dark and Light themes:

For this example in light theme the background is black and the text color is white, and in the dark theme its the opposite.

Defining our themes options:

Last step of defining our themes would be defining which themes are available in our application. So I’ll create a file named themes.ts

Hurray! We created our themes, now we need to create a context that we will be able to change the theme whenever we want wherever we want.

Creating the theme context:

The context will hold the current theme that our application use and a function to change it. Currently I set the default to light and changeTheme function doing nothing. We need to connect it to react and we will use it by working with react hooks.

Creating our useTheming hook:

Let’s talk about useTheming, it receive the default theme of the application (if not passed its just light) then creating state for it to hold our theme and a changeTheme function to change it. Later we will pass it to the context to hold a single source of function and theme.

The second function is to use the context which holds the theme and the function to change the theme. We will see it in action soon.

Wrapping it up into our Application Root:

As you see we provide to the ThemeContext our themingValue which is the function and the current theme being hold in our state.

Also we provide to the StyledComponents ThemeProvider the currentTheme.

Creating a Dummy Button component:

Just a fancy/ugly Button using our theme.

Wrapping it all up and finally creating our page:

The button call the toggle function (it could be a select with options of themes, here it’s just two themes so it’s easy to swap between them)

We also get the currentTheme from the useThemeContext so we know what theme we are currently at.

Why did it help me?

  • From here you can expand your theme without worrying about someone from your team not adding a property to the other theme because it won’t compile(thanks to typescript).
  • Using it from any styled components with auto-complete from vs-code .
Example of the auto-complete
  • Expanding the common theme will cause both of the themes to inherit it without maintaining the files.
  • Readability and maintenance of your code.
  • A hook(useThemeContext) that you can use anywhere from your app, it means you can change the theme from whatever page/component you can think of.
  • Extending to more themes and not only light/dark by just inheriting the interface.

There might be more advantages that I take as granted but maybe for you guys it’s enormous.

That’s it so far,

Thanks for reading!

Full Stack Engineer passionate about Front End and technology.