Buttons, checkboxes, tabs, radio buttons, selects, modals, drawers...
All of these components do something when clicked or tapped. But should that “something”, that interaction, always be baked in at the library level?
Quick answer is “it depends on the component...”
And the longer answer... well, let's back up a bit for some perspective. The component library’s whole job is to reduce work for designers. Its purpose is to provide well-built, reliable, reusable bits of interface. So it’s natural to assume that the more the library is responsible for (like on-click interactions), the better life will be for designers!
Figma is not sophisticated enough for that to be true (yet). Let’s use a radio button as an example:
We know that when a user clicks or taps a radio button, it goes from unselected to selected. This is a universal pattern of the web. But that doesn’t mean you should bake that on-click interaction into your <span class="figma-component">❖ Radio button</span> component.
Well, it has no awareness of other radio buttons that will surely neighbor it in a designer’s mockup or prototype. Radio buttons don’t get presented as single options, that would make for poor UX. Instead they get presented in groups, as multiple options.
So what happens if you bake in that click interaction at the library level is you’re giving designers unnatural radio button behavior in their prototypes:
To fix this, the designer must to remove the “on click” interaction on every single instance of <span class="figma-component">❖ Radio button</span>. Not fun, and not a good use of her time. Leaving this issue to fester risks eroading her trust and confidence in the library as a whole. And things like reputation and trust are a big deal in the world of design systems.
Instead of putting your consumers through this, refrain from adding the “on click” interaction on components like radio buttons to begin with! This is a list of everything I discourage folks from adding on-click interactions to.
All these elements have 2 things in common:
But just because they show up in groups, it still makes sense to build a single component for each in your library. That’s how you get consistent styling after all! Don’t despair though, you can still give your library consumers working radios, tabs, pagination, and menu items! But I’ll explain how to do that in a separate blog post.
You’re probably curious about the opposite end of things to: the things you should add on-click interactions to.
There’s also elements that open and close on click! That action is also safe to bake into the individual component at the library level:
And depending on whether you optimize for configuration or composition (or both!) in your library, the element above should have a slot, or swappable chunk of UI, for your consumers. More on that in my blog post about placeholders (a better name for “slots”).
Now, you’ll want to be careful with the following, because often where they open can change based on the trigger element’s placement in the viewport. And sometimes the trigger isn’t consistent! Like tooltips for example. Lots of things can trigger a tooltip: icons, spans, cards, anywhere you can put a link.
That one is pretty safe. Always bake that into the library unless you’re doing something particularly fancy or weird.
In summary, don’t add on click interactions to your radio button, tab, pagination item, breadcrumb item, or menu item for single-select dropdown menus. You’ll just make more work for your consumers. They’ll have to remove those interactions, and then set up ones that are actually appropriate for their prototype. And stay tuned for my blog post on how to deliver “working” versions of all those components I listed for your consumers to save them even more time!
If you'd like to be notified of when I publish a new blog post, joining my newsletter is a great way to keep up. Readers get extra insight behind every post.