Theme UI with Storybook: A great way to create a components library

Paweł Ochota
04 August 2020
7 min read

Nowadays, there are a lot of possibilities for styling web applications. We can simply use the CSS, use the capabilities of preprocessors such as SASS, or even style our applications using JavaScript. 

The latter method, also called the CSS-in-JS methodology, has become a very popular option in recent years, especially in the React environment. Many libraries are using this method that helps developers maintain a collection of components. One of these libraries is Theme UI, which integrates well with popular React tools, such as Storybook.

What is Theme UI?

As per Theme UI website: "Theme UI is a library for creating themeable user interfaces based on constraint-based design principles." Constraint-based sounds a bit scary, but there is nothing to be afraid of. The idea is based on a theme object that allows you to control the style of the application and makes it easy to change it later. It is a kind of framework that combines valuable CSS techniques. Together, those allow you to conveniently style web pages, applications and even create component libraries.

Under the hood, the creators have placed solutions such as the sx property. It is a light abstraction built on the top of css property for inline style editing that connects to the theme object. Theme UI also has a built-in database of light components that are sensitive to changes in the theme object. We do not need to use them, but you must know that they have implemented props inspired by Styled-system. It means that they have access to many properties that affect style editing in a more straightforward way than is usually done using CSS.

Finally, we can use, for example, the Emotion library, to wrap the components built into the Theme UI and style them using the Emotion capabilities. By the way, Emotion is also a part of Theme UI, so it is an entirely natural way to use these two libraries together. Sounds pretty flexible, doesn't it?

But wait… what the heck is Storybook?

Storybook is an environment that allows you to create components outside the application in isolation. We don't have to worry about dependencies. Storybook lets you focus on creating beautiful UI for your components. We can create simple elements such as buttons, paragraphs, or form inputs, but also complex components such as carousels, modal windows, etc.

By adding more stories to the components, we create a style guide that can be helpful when adding the same elements in different places in the application. Developers do not have to look for the information they need in the code. Storybook can be generated as a static application and available to all team members from the browser, just like a regular page. It is a handy feature because it also allows the UX team to check if their requirements are accurately transformed into real elements.

Storybook's options can be expanded with the help of add-ons. With their help, it is possible to do visual testing with snapshots and have better control over the responsiveness with the option of resizing the viewport. It is worth spending some time configuring Storybook because it will undoubtedly speed up further work on the project.

Create basic components in Theme UI

I assume that you know how to create a simple application in React (can be generated using CRA) and how to add new components to it. I would like to show you how we can manipulate styles using Theme UI. I will execute all commands on a freshly generated application with create-react-app. Let's start with the installation of the library itself by using the Yarn package manager: 

yarn add theme-ui

Next, we need to define the base theme object. So let's create theme.js file with an example configuration:

For convenience, I will create all files directly in the src directory on the same level. The theme I created contains some basic properties like text colors and defined fonts for body and headings. Now we need to import the theme and use it in a ThemeProvider which will pass it to the rest of the components using the context:

Once the theme has been added, we can start creating the first components. Theme UI recommends using the sx property, so let's use it and create a simple button:

In the example above, the following two lines may seem the strangest:

It is called pragma comment, and this is required for the sx property to be used in normal HTML elements. Inside of the sx property, we can use almost any CSS rules. These can be our custom values, but they can also be elements of the theme, such as secondary and primary colors. However, not all properties are theme-aware. In the example above, I couldn't just write background. I had to use backgroundColor. 

Also, note that we are using camelCase notation to write rules here. All available rules that allow you to use the theme are available in the Theme UI documentation. The possibilities of the sx properties do not end there. For example, we can nest CSS rules (like in SASS), use the styled-system properties, and even write inside media queries. Now let's try the second way of styling and use the components built into the Theme UI. Let's create a simple "hint" component:

This time it is not necessary to add a special pragma comment when we want to use the sx property. Theme UI components convert the sx property rules themselves to the appropriate CSS properties. We can also mix styled-system properties such as "m" for margins and "p" for paddings to style the component faster.

It is also worth mentioning the responsive values. It is a special shorthand syntax for media queries, which allows you to assign specific values to the appropriate breakpoints. The mobile-first approach is used, so we start with the smallest breakpoint and end with the largest. Take a look at an example below:

As you can see, creating styles using Theme UI is very intuitive and has great possibilities.

Let’s play a little bit with Storybook

We already know how to style applications using Theme UI and how to use the properties of this library to make our life easier. It's time to introduce our work to the world, and we will use Storybook for this purpose. Let's start by installing this tool:

The above command will detect that it is dealing with a React application and install the necessary tools. After executing this command, we can see that the .storybook folder has appeared in the project. To be able to use the Theme UI benefits in the Storybook, we have to add the provider in the Storybook configuration. So let's create a preview.js file inside the .storybook folder and put the following code inside:

With this configuration, the Storybook will have no problem loading the theme object. Now we will create a Button.stories.js file right next to Button.js, containing the default button UI:

Now we can run the Storybook and check what our button actually looks like using the command:

yarn storybook

And that's all! We can start creating new elements and stories for them, which together will build a real component library.

Storybook and Theme UI: A world of possibilities

Creating a library of components with a foundation based on Storybook and Theme UI tools can be an enjoyable task. Theme UI provides many ways to style each element of the application, which gives freedom and flexibility to the teams that will use it. However, choosing a specific style path does not affect the very intuitive way to change the theme of the application. So we can mix different techniques, and our applications will still be themeable.

The final result of our work can be presented using a Storybook, which allows you to create components in isolation. It is an excellent tool not only for developers but also for the entire team and stakeholders. They will help us quickly detect potential edge cases, and it will be excellent documentation for them.

If you’d like to know more about styling apps or discuss how we could help your app stand out, we’d love to hear from you. You can also write to us:

You may also like...


Doogie - your health consultant

In the fast-paced world of startups, agility, time-to-market, technical skills, and innovation are all critical factors in building and delivering successful products. At Startup House, ...

Marek Majdak
23 March 2023
3 min read

Introduction to CQRS with NestJS

For many years, most applications have been built using classic N-layer architecture (see below). However, ev...

Michał Cywiński
03 March 2023
17 min read