In April of 2021, I was brought on to the design team at Rhino to help turn their fledgling component library into a design system. This article is intended to share the ups and downs, failures and learnings, and the ultimate result of my work (in collaboration with others).
An initial audit
Often the first thing a systems designer must do while onboarding is a full audit of the product. It’s important to find patterns that might not be noticed by product designers in their silos. And it can help prioritize which components would produce the most value by being made reusable, and in our case, being added to Storybook.
The true challenge of my audit at Rhino was the sheer number of components that existed locally within design files. Perhaps a habit left from the days of Sketch, it made it tremendously difficult to find components within designs — even if the pattern existed in staging. However, despite that, I completed a substantial audit of the Portal (our landlord-facing tool) and was able to gather some insights as to which components were sorely needed.
When I joined Rhino, the text styles were already quite well documented and live within the product and in shared-js.
The color styles, however, were a bit confusing — with multiple libraries and no clear intent for use.
I started off by establishing a color system wherein design system colors inherited values from brand colors.
For example —
Brand/100. (Our purple color)
At the request of engineering, we used a system in which we mixed our base colors with black and white to create a library. For example,
Brand/125 is simply
Brand/100 mixed with 25% black (you can achieve this by putting a black square at 25% opacity on top of the purple color).
Although this methodology has its limitations, especially with certain base colors (yellow!), it worked for our needs, and aligned with our engineering goals.
Mistake and learning
Although compromise is crucial, I should have worked with engineering more to establish a naming convention that didn’t codify values. One of the biggest value props of a design system is being able to change the value of
Rhinoto a different color — making global changes easy. Because of the numbers included in our naming, it’s not possible to change anything except the base colors. For example,
Warning/100 could be changed to a different red, but
Warning/4 can’t be edited in isolation.
At a certain point, rather than the simplicity of updating our
Neutral/4 we had to add a
Neutral/6 that was then used in the place of
A couple more tokens
Soon after starting, I also added some tokens for border radii and shadows.
In collaboration with Hunter Bacot, the design system engineer at the time, we decided to focus our efforts on “form components.” Adobe spectrum labels these as “Inputs,” although our “Form” category also included a couple of Actions such as
We immediately went to work on
Date picker — as well as defining the behavior of preformatted inputs.
Establishing patterns for states
Part of this work involved coming up with patterns for how we wanted to handle states across components. For example, our focus state always involves a 2px stroke around the component in our
PALETTE.interaction100 color. Additionally, there can be 2px of padding between the element and the focus indicator, as seen below on the right.
Other patterns established through this work consisted of our use of
PALETTE.neutral25 to indicate disabled states…
The use of our
PALETTE.interaction125 to indicate hover on
and our use of
PALETTE.neutral25 as a default stroke color
Establishing spacing rules for forms
A key challenge to consistency within our product was the vertical spacing between elements within forms.
It’s one thing to all use the same components, it’s another to actually make forms that have the same look and feel.
In order to improve this, I created a series of spacing tokens that could be used by design either as a reference — or directly within their designs. For more information check out my article on spacer tokens here.
Creating documentation for components
At this stage, the maturity of our design system was fairly low, so we didn’t have any sort of buy-in for third-party tools to help with documentation. This meant that our documentation had to live within tools we did have, which in the case of design meant FIGMA!
For a sample of my documentation work within Figma, check out this Figma file.
Improvement in form UX/UI
Our forms saw a lot of improvement over the course of our design system work.
In the above, the most obvious examples are the improvement in:
- Grouping of sections
- Consistent styling of elements
- Decreased overall clutter
- Consistency of vertical spacing
The UX also improved as we improved our focus and hover states ensuring that it is now possible to “Tab” through a form easily and without losing your place.
Usability of the system
While building a design system, it’s always crucial to consider the consumers of the system. In my case, these were the product designers responsible for the landlord portal and the renter portal (as well as myself when working on internal tools).
I ensured that designers were aware of the statuses of all components through a combination of component descriptions within Figma, emojis included in component names in the asset panel, as well as a table or component statuses kept in the product design document and turned into a component (to allow designers to access it without needing to go into the core library file).
A fun side note — the table above is the table I built for the system!
A design system is only ever as good as its adoption. In our case, adoption was not a challenge on the design side — but proved to be more difficult on the engineering side. However, through consistent use of the library within designs on all pods, engineers slowly began seeing the value. Additionally, a JIRA board specifically for design system work was created by my engineering partner JP Pellet — and engineers from other pods began picking up tickets!
Mistake and learning
Early on, I worked too much in isolation. Because of the lack of visibility into what I, and my engineering partner, were doing on the design system front — adoption was weak.
Once we brought the system out into the open, adoption increased quickly!
I blame this on a mix of my own lack of experience with pushing adoption, combined with a remote onboarding that I wasn’t prepared for. Moving forward, I feel more well equipped to handle both!
Status of habitat
Habitat is alive and well and being used consistently by multiple pods at Rhino. It consists of close to 30 reusable components that are fully functional, fully accessible, and can be combined effectively.
This component library has increased consistency within the product and led to a more streamlined design process. Additionally, it has increased efficiency within engineering.
Although I haven’t completed a full ROI calculation using IBM’s pattern efficiency model, early estimates indicate a high ROI. Even with an average pattern efficiency of 33% for the design system as a whole, time savings come in at around $1M/year.
Our form components already show efficiencies between 40–80% depending on how many UIs they appear in, and the estimates for how long they would have taken to design and build as one-offs vs as reusable components. Certain early-stage components have negative ROIs which will be quickly corrected as they are used in more UIs.
For example, our checkbox component, which is used everywhere — shows a 90% pattern efficiency with over 200 hours of design/dev time saved.
There are a number of benefits to the design system that are difficult or impossible to quantify such as:
- Ease of onboarding for designers and devs in the future
- Increased consistency within product
- Increased ease of communication as a common language comes out of having a design system
- Increased focus for product designers to think about problems and not pixels
- Increased speed of ideation