The texts in this article were partly composed with the help of artificial intelligence and corrected and revised by us. The following services were used for the generation:
How we use machine learning to create our articlesWhere we Left Off
Previous, we learned how to Create a Component Library for Designers and Developers by implementing a fairly simple button component. In this article we’ll expand on the previously established foundation and display how to handle more extensive components.
To facilitate our desired outcome, we’ll build on some of the ideas presented in Develop design systems with accessibility in mind and implement design tokens to manage the colors and appearance of our components during design and development.
New Requirements
Before we get into the specifics of the design tokens, let’s add to the previous requirements of our button component. In this particular case, the button component should now cover several color variants to convey its possible actions.
Designers Requirements
- Colors
- Brand
- Neutral
- Informative
- Successful
- Cautionary
- Destructive
This additional requirement increases the number of variants of the component to 24. While this is still manageable within Figma using Multi Edit, the creeping complexity necessitates a more structured approach to handling variants and their appearance.
Design Tokens in Figma
Design tokens, or Variables as they’re called in Figma, help us define a consistent design language for our components. To be more precise and flexible in the future, we’ll divide the tokens into two groups: Primitives and Semantics.
Primitives
Primitives serve as the foundation of our design language. They define base colors and other units to built upon. To start, add the desired colors to the Local Variables table. In this example, we’ll use the Tailwind CSS color palette to define the colors.
Semantics
Semantics built on primitives to expose verbose tokens for our layouts, pages, and components. They reference the primitive tokens and act as an interface to populate the components with the colors defined in the design language.
To recap, raw values like #e4e4e7 can be defined as a primitive token like Indigo 600 . This primitive token in turn is referenced by one or more semantic tokens such as Brand . In it’s fullest, this could take the following form:
Semantic Token | Primitive Token | Raw Value | ||
---|---|---|---|---|
Border/Width | ← | 1 | ||
Color/Neutral/Subtle | ← | Primitive/Zinc/200 | ← | #e4e4e7 |
Color/Neutral | ← | Primitive/Zinc/950 | ← | #09090b |
Color/Brand/Subtle | ← | Primitive/Indigo/100 | ← | #e0e7ff |
Color/Brand | ← | Primitive/Indigo/600 | ← | #4f46e5 |
Color/Informative/Subtle | ← | Primitive/Sky/100 | ← | #e0f2fe |
Color/Informative | ← | Primitive/Sky/600 | ← | #0284c7 |
Color/Successful/Subtle | ← | Primitive/Emerald/100 | ← | #d1fae5 |
Color/Successful | ← | Primitive/Emerald/600 | ← | #059669 |
Color/Cautionary/Subtle | ← | Primitive/Amber/100 | ← | #fef3c7 |
Color/Cautionary | ← | Primitive/Amber/600 | ← | #d97706 |
Color/Destructive/Subtle | ← | Primitive/Rose/100 | ← | #ffe4e6 |
Color/Destructive | ← | Primitive/Rose/600 | ← | #e11d48 |
Plugins like variables2css export the defined design tokens in various formats for use in our project. From here on out, we head into the development phase and start by defining the primitives and semantics in CSS.
Design Tokens in Development
Once the design tokens are exported in their respective formats and implemented in the project, we can start using them in our button component to define the colors and their variants. One way to do this is to define the tokens as CSS variables.
To maintain compatibility between design and development, we implement the same separation of tokens and naming conventions. This way, design tokens can be used and kept in sync in both Figma and the project.
Programmatic Components
The rigidity of our design tokens allows us to programmatically generate CSS classes for all colors. Rather than defining classes manually, we rely on SCSS to generate the classes for us and map their values using scoped CSS variables.
Further optimization of style generation and CSS bundle size can be achieved using tools such as PurgeCSS or Tailwind CSS Layers, which automatically remove unused classes and styles and reduce the overhead of programmatically generated classes.
To update the component in question, we define the color property and add SCSS to generate the necessary classes. Then we update the component to use the updated classes and properties, and then its off to update the documentation to match our changes.
Update the Documentation
Properties and their values are automatically added and updated by Storybook’s Autodocs feature. We can also improve the usability of components in Storybook by setting argument types for our component to enhance interactions.
These argument types are part of the meta
object in the story definition and are used to generate the controls for the component in Storybook. This way, we can easily switch between the different color variants of the button component.
Next Article
In the follow up article, we’ll extend the button component by adding states. In particular, we’ll cover interaction states such as :hover
, :focus
, :active
and :disabled
, and how to implement them in combination with our existing colors and variants.
TL;DR
Expand a component library using design tokens for consistent color variants. Implement primitive and semantic tokens in Figma and update Storybook documentation for improved developer and designer collaboration.