Design Systems for Developers
Introduction
Modern front-end development is more complex than it used to be. Developers have to think about building user interfaces that works and adapt to different devices and screen sizes. This has led to thinking about interfaces not as a page but more of a combination of different components. These components that makes up the user interfaces are called the design patterns. Design patterns are reusable pieces of design. With the advent of component based web frameworks like React, Vue and Angular, this has led to more modularities in terms of thinking about user interfaces.
The modularities in design patterns can lead to complexity. This is because it becomes difficult to manage a repository of different design patterns like typography, layout, colors etc to be used across different products in an organization. Also, as the patterns change, it becomes difficult to manage without a system to communicate the changes and how it affects the product.
Why Design Systems?
- Having a design system helps in keeping different part of a UI consistent. Since there are a set of design patterns and guidelines of how they should be used, the UI is always consistent
- Design systems provides an avenue for easy collaboration between designers and developers
- With an efficient design system, it’s easier and faster to make changes to a certain piece of UI
What are design tokens?
Design tokens are a set of variables used for different components and patterns of the design system. They are basically the variable names assigned to design values like typography, color, spacing etc. They are important because they help maintain consistency across different platform of the product. Design tokens can help frontend developers in naming CSS variables. It is the responsibility of both developers and designers to agree on defining the design tokens. Below is a screenshot from the Adobe Spectrum design system showing their design tokens for spacing and their corresponding values.
Building a design system
There are various modern tools for building out a design system. For the designers, they include Adobe XD, Figma, Invision and Sketch. After the design system available to developers. The developers have to build a component library from these design systems. Tools like Fractal, Storybook, Bit.dev and many others provide a modern system for building component libraries. My personal favorite is storybook because it is open-source and it works with modern frontend libraries like React, Vue and angular with little setup. It also provide an easy way to document the components in the component library. The rest of the article shows how storybook can be used to build out React components.
Building component libraries with Storybook
Storybook helps with developing, testing and documenting different parts of the component library that makes up the design system. It can be used to build complex UIs such as a full page or something as simple as a button. The components are designed in isolation before integrating it into the app. It makes development faster and easier since we can focus on a particular component at a time.
Getting Started with Storybook in React
Storybook can easily be used to build React components. It makes the process easier as the components can be built, tested and documented in isolation before integrating with the react app. To add storybook to react, all we need to do is use the storybook CLI to initialize storybook in react. In the root folder of the React app, run the command below
npx sb init
By running the command above, the storybook CLI initializes a new storybook project in the react app. It generates a stories folder in the src directory of the app. Storybook reads every file ending with a .jsx or .tsx as a component. The It also creates a default storybook template in the react app. The default template has three components, Button, Header and Page. It also generates a *.stories.js file for each component.
These files are called story. A story represent the rendered state of a component. A component usually have multiple stories depending on the current state of render. To view the components in storybook, we can run the command below
npm run storybook
This starts the storybook server on a default port which is 6006.
We can see all the components in the stories folder in the sidebar. Under each components, there are subsections, these subsections are the stories which determines the different state the components can have.
Writing a story
Stories are basically React components exported from a file ending with a .stories.js or .stories.ts. A component can have multiple stories depending on the different state we want the component to have.
A story exports a default object which contains the title of the story, the corresponding component and the arguments to the component. The state of the component is controlled by the arguments. In addition to the default object export, a story should also export the different stories that the component should have. The stories are usually bind to the component and the args property are set on each of the stories. Below is an example of stories for a Button component.
From the component above, each of the exported objects (Primary, Large, Secondary and Small) are the stories. Each of them having an args property bounded to the Template(Component). The default export contains the title of the component, the component itself and the argument types. The value of the argument type can be manipulated from the storybook app depending on the type.
There are other storybook concepts like parameters, add-ons and decorators which is beyond the scope of this article. I’ll be writing a more in-depth article focused on storybook.