Why we chose Chakra-UI for our design system (part 2)

Yotam Bloom
Melio’s R&D blog

--

In the previous blog (part 1), I talked about what led us to choose Chakra-UI as our design system and we covered possible solutions.

In this part 2, I will detail how to create our own theme using Chakra-UI to build a design system while using detailed examples.

Theme

Chakra-UI offers an easy way to create custom themes. Every theme can be easily customized and it includes components, typography, and foundations. We’ll go over each one of these and show you how I implemented them for our needs.

First thing first, let’s install Chakra-UI in our project:

npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6

Next up we’ll set up the following files and folders:

Basically, what I’m doing is creating an extended theme of the one Chakra-UI has to offer.

This is a partial view of the theme. There are many more extensions that you can make and you can check them out here.

Now, let’s cover each file and build our design system.

Breakpoints

are the way for us to define the responsiveness of our app. Each breakpoint creates a media query behind the scenes, where we can define our responsive style:

A use case example would look something like this:

And if we wanted to make it responsive it will look something like this:

The width will translate to following media queries:

  • Under 440px ➡️ 300px width.
  • Below 768px and above 440px ➡️ 400px width.
  • Above 768px ➡️ 500px width.

This is a really easy way for us to create responsive components. another cool way is to use the breaking points values as so:

This will give a more verbose way to write our responsive component.

Foundations

Most of the theme will be defined in this section.

Borders

In Chakra-UI you can define the borders you want in your app, for example:

Instead of writing this each time:

border: '1px solid'

This will allow us to simply:

<Box border="1px" />

and this property exists in all of Chakra-UI’s components.

Colors

This is where we’ll define our color palette. Note that you can choose any color palette that suits your needs. We chose to use this color naming convention, but you can use a different naming convention (such as: primary or secondary).

Here’s an example. Let’s say you want to have a div with a red background color and give the text a white color:

This is what it will look like:

Behind the scenes, Chakra-UI will use CSS variables to apply the correct colors.

In my opinion, reading JSX in the return and understanding how it looks without having the need to jump to another styled component or a css file gives you a lot more context, faster and makes the code a lot more self-explanatory.

Spacing

The space key allows you to customize the global spacing and sizing scale for your project. By default, these spacing values can be referenced by the padding, margin, and top, left, right, and bottom styles. Chakra-UI offers numeric scaling based on TailwindCSS (link). But we had a need to define spacing in a different way.

As an example, let’s say you want to have a button inside a div and have a margin on the left and on the right. This is how you would do it in Chakra-UI:

In this example mx is a property used to add a margin from the left and right. my gives us a margin at the top and the bottom.

here is the result:

Button with margin

Radius

This is where you’ll define the border-radius sizes. The reasoning behind this is to have a close set of values that you can reuse in the app and design system. You can see the code reference here

Let’s say you want to create a button with a rounded border-radius:

This is what it will look like:

rounded border button

The radius values will mostly be used in our component theming (as you’ll see next).

Layer Styles

This is one of the features I really like about Chakra-UI. Layer style allows you to create layering styles that can be applied to every component. It’s very useful when you want to apply state changes to a component. This is a small code example of one of our layer styles:

Now, let’s say we have a card and that card has a selected state and non-selected state, with layer styles you can use the following code:

This is what the code will output:

example for using layer styles

It’s important to note that layer styles are used for common styles in your system. In our case, the selection border is used on multiple components so it makes sense to add them as layer styles. You can add any styling that you want to components commonly use.

Text Styles

Similar to layer styles, text styles are one of my favorite features in Chakra-UI. The feature allows you to create a list of text styles that are common, a pre-defined font size, font-weight, and a line-height system that works in your app. In this example, we decided to make it verbose and we divided it into 5 groups:

  • Display
  • Heading
  • Body
  • Caption
  • Link
a break down our text styles in our design system

Each group has a few values that we can use and formalize. I will give a short example of our code but note that this is what works for us you can design it in any way you see fit.

The authors of Chakra-UI have a few ideas on how to define your naming system — see here.

What’s so great about this is that you’ll never need to rewrite the font size again. All fonts are pre-defined and our design and dev teams are aligned, meaning we use names, not values both in the code and in our Figma design. Hence, our code will look like this:

This is what it will look like:

text styles example

This code is more readable, allows us to write less code, and has a common language with our design team. This keeps our app styling aligned and we can maintain a system that can be expanded if needed.

The final index.ts files for the foundation folder will look like:

Chakra-UI offers other customizing options (see here).

Components

This is where you can build custom styling for components. Each themeable component you import from Chakra-UI will require you to add a custom theme (see the full list here).

For the purpose of this blog post, I’ll focus on styling a button.

Button

The button is one of the most common components there are. In order for us to customize our button, let’s look at the Chakra-UI code for their default button theme:

The theme is a file that’s composed of:

  • baseStyle
  • variants
  • sizes
  • defaultProps

The base style is the basic shape of your button: how round it'll be, it’s line-height and how it will behave when it’s disabled, hovered, and focused.

Next, let’s define the different button variants. In this example, we use a basic Primary variant, but alternatively, you can add as many variants you want.

This code will allow us to have a few buttons in different sizes:

In this configuration, pay attention to the `apply` property. When you’re defining your theme and want to use the text style that was defined earlier in Chakra-UI, you need to use this syntax.

Now you can define your default props — These will be used as the default values of the button each time you will render a button component.

Now we can export everything and have a custom-styled button:

This theme will give us the following buttons:

Custom Theme button

Let’s say you want to build a custom component that Chakra-UI doesn't have in their component library. You can add it to your theme, the same way we added the button and you’ll need to consume it in a different way. More on that in the third part of this blog post series.

Now, let’s export the button from the components folder in the index.ts file. For each component added we need to also add it to our index.ts file:

Typography

In this section, we can define the typography. It’s important to note that since we based most of our typography on text styles, results in slim typography. With that being said, Chakra-UI has a lot more verbose options that you can check out here.

Next, we’ll build the theme file which is a combination of all the theme files that we built:

The extendTheme accepts 2 parameters.

1. The theme that you defined.

2. The base theme, where we’ll need to tell Chakra-UI which styles we want to keep from the base theme. We used zIndices from the base style because they were aligned with our design system and borders. To exemplify this I used an empty object in order for the base theme not to override it.

Setting up a provider

Next, let’s take the theme file and apply it to Chakra-UI’s provider:

That’s it, now we have a working design system that we can use in our app.

Theme types

Because we created a custom theme, the components may differ from the ones defined in Chakra-UI. For that reason Chakra-UI allows you to run a local CLI that connects to your theme and then generates theme types based on yours. Check out this really cool guide that can give you some inspiration.

In the next part of this blog series (part 3), we’ll take a look at how we built our design system using Chakra-UI’s components which enabled us to wrap and extend our functionalities. We’ll also cover how we handled custom components.

Visit our career website

--

--