Nate Green

UX Designer

Figma form components for MRI's design system

MRI Software

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.

Some examples of inconsistencies that we'd see in UI design reviews

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

Components were structured such that a form could be fully linked to the Figma library, without needing to break from the main components.

Spacing was built into the component structure, so mockups and prototypes could be pixel-perfect with minimal designer effort.

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.

In-field labels made forms look more modern and clean, in some ways, but ultimately we found them to be hard to retrofit into our designs.

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

Validation styles were applied in different-but-similar ways to each form control.

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.

Radio button lists can be configured from Figma's properties panel, allowing for a lot of customization without detaching the component.

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.

Figma's multiple selection and find/replace features came in very handy when creating hundreds of variants for MRI's library components.

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.