Platform / Writing / Creating a Design System Using React Material UI
Frontend

Creating a Design System Using React Material UI

Walks through building a consistent design system on top of React and Material UI. Covers component structure and design tokens as the foundation for a reusable UI library.

Published 2021-06-22

Building a custom design system using Material UI library

Yasas Sri Wickramasinghe

Yasas Sri Wickramasinghe

5 min readJun 22, 2021

\--

Press enter or click to view image in full size

Modern design systems rely heavily on rich UI component libraries. They promote code reusability, enable consistency in design (in and across apps) and speed up overall development.

This article shares how I used React Material UI with Bit open source platform to create a custom design system focused on consistency with high governance.

You can preview each independent components by visiting the Bit collection URL.

https://bit.dev/enlear/react-material-design/

Overview of the design system: https://bit.dev/enlear/react-material-design/

Here, each component in the design system is authored, versioned, and shared individually and not as part of a single monolithic library, that creates countless benefits such as;

Using React Material UI

As we all know React Material UI provides a range of UI components that are ready to use. However, think of a scenario where you want to add a React button component, and you know it supports different attributes. You can have a button with rounded edges, a button with a label, a button with an icon, or even a button in disabled status.

Press enter or click to view image in full size

Different button variants in React Material UI

Consistency Over Flexibility?

Though it’s one of the prime objectives of a UI library to allow customization, if we expose this flexibility to developers, it could adversely affect the consistency of the user interfaces.

But we have the options to restrict this behavior. One approach is to build an abstraction on top of React Material UI components by exposing only a given set of properties.

This what I refer to as wrapping the components.

Following this approach clearly brings control over each UI component props and actions.

High-Level Objectives of the Design System

Besides, there are several objectives I wanted to meet with the design system.

What are the Building Blocks?

For the design system, I’ve developed the following categories to group UI components at different levels.

Then you might wonder why I chose to group them in this way.

Get Yasas Sri Wickramasinghe’s stories in your inbox

Join Medium for free to get updates from this writer.

Remember me for faster sign in

For lower-order components such as UI/Inputs, Layouts, and Surfaces, I’ve followed the same structure as in React Material UI library.

For higher-order components, I’ve introduced Widgets and Pages out of thin air. 🙂

Starting with UI/Inputs

At first, I got stuck on choosing the basic building blocks for the design system. I’ve decided to select a subset of components from React Material UI wrap them to create the Button, Radio, Select and Text field as the foundation. These components you can find under the UI/Inputs, as shown below.

https://bit.dev/enlear/react-material-design/ui/inputs/button/~code/button.tsx

Button component in the design system at bit.dev

For instance, I don’t want developers to make spontaneous decisions on how a button should look or behave, breaking the consistency.

Though the button’s functionality is limited, we can gradually add more functionality having complete control since it’s the only button reused elsewhere in the application. Besides, it also reduces the coupling of React Material UI with higher-order components.

Higher-Order Components

Then, gradually the higher-order components were defined. The below example shows how the product page components look like.

https://bit.dev/enlear/react-material-design/pages/products

Products page component composition in bit.dev

https://bit.dev/enlear/react-material-design/pages/products/~code/products.tsx

Product page code example in bit.dev

Furthermore, to understand its dependencies, let’s look at the complete dependency graph of the products page.

https://bit.dev/enlear/react-material-design/pages/products/~dependencies

Dependency graph of product page component

As you can see, the design system clearly reuses its foundational building blocks, which is a good sign that it’s working.

Theming Support

Typically theming applies to basic UI components. With React Material UI, each component inherits from the default theme. So if we can override that, we can implement custom themes.

That’s precisely the theme provider global overrides supposed to do.

Following are some of the properties we can override by creating a custom theme provider.

https://material-ui.com/customization/theming/#theming

Theme overrides in React Material UI

For example, suppose I override the “primary” property of the palette object inside a custom theme provider. As a result, it directly overrides the color of the button component in the design system.

Press enter or click to view image in full size

Overriding primary color palette in React Material UI

Conclusion

I believe design system should become the norm to bridge the gap between designers and developers to establish consistency in frontend development.

However, in the current design system, I’m still doubtful whether to wrap the React Material UI components or not, which has both ups and downs. If you have a different opinion, please do mention it in the comments below.

Some Final Tips,

Thank you for reading !! 🙂


Originally published on Level Up Coding.