Figma form components for MRI's design system
Previous library iterations
Our design system's Figma libraries evolved alongside Figma itself. Early on, Figma didn't support variants, properties, interactivity within components, or any of that. So at first, we created consistency with a sticker sheet of components that designers could copy and paste from.
However, this meant that much of the form layout process was manual and tedious.
- Designers would vary the spacing between elements, usually because they were "sketching" the UI—but these variations would leak into the final UI mockups.
- Sometimes form controls would be stretched to be taller or shorter than they'd naturally be.
- Nit-picky formatting rules like stroke color, font size/weight of labels, etc. would often be missed, leading to multiple needless revisions.
Building a new library
When Figma released Variants and improved instance swapping behavior, this expanded the possibilities for our library.
I created a prototype structure of components, getting feedback from the UX team along the way. Once the first few components were created, teammates helped to build out components for the rest of the states and variants.
Components used Auto Layout (also a fairly new feature) to create the correct form layout and spacing, without needing to break from the main components.
At first, we supported in-field labels experimentally, drawing inspiration from a UX Movement article. Over time, we found that those kind of forms didn't fit well in our UIs—they made data on condensed screens harder to read, and didn't easily implement our patterns for validation—so we dropped support before they were in widespread use.
Validation pattern
Form validation relied on consistent colors and icons to communicate the status of the form data.
When a form field is invalid, a red error icon shows that there is a problem. (A banner on the page would also indicate that the record couldn't be saved until errors were fixed.)
When errors were cleared, the icon would change to a green checkmark. This pattern was applied across many types of fields—text, numbers, dates, passwords, etc.
Configuring radio button and checkbox lists with variants
One challenge facing designers was that in order to create a list—such as a checkbox list or a group of radio buttons—the instance needed to be detached so that items could be added or deleted.
At first, I created a list with 10-20 items that could be shown and hidden in the layers panel. However, this was a tedious approach that required a lot of drilling down/up in the layer tree in Figma.
With a later iteration, I created properties that would allow designers to choose how many options and how many columns to display. By naming layers cleverly, the number of options could be changed even after overrides to the labels were applied, and they would be moved naturally to their new position without losing overrides.
In the end, we produced hundreds of states and variants for form controls. The up-front work on the library saved us hours of time in product designs, and reduced the friction of nitty-gritty decision making—exactly what a design system is good for.
Next steps
Figma has come a long way. I'd do things a little differently now:
- Variables and component-level prototyping could reduce the configuration needed and bring down the total number of variants that need to be created
- Components wouldn't need to be nested the way we did then—properties can now be bubbled up through parent components, so that would dramatically improve the experience (and make the components more maintainable).
- Instance swap properties can now be used instead of using variants to change the child component.