If you work in Figma, you've already been building ◈ interface representatives. Buttons, cards, table cells, nav bars, dropdown menus, etc. You know them well. But they're worth taking a closer look at so we can begin to understand where the "edges" are. These edges are central to an idea that I hope you explore along with me: the idea is that there are "types" of components, and they each suited for doing certain jobs exceptionally well, but no single component can do all the jobs well. My hunch is we've been overburdening our ◈ interface representatives with the jobs of other components.
Designers writ large have already agreed upon 4 types of components and their names: "base components", "slots" or "placeholders", and "annotation components." I am simply proposing there's a few more out there that haven't yet received agreed-upon names and definitions. If you're someone who was excited by the power and utility that base components offered when you first discovered them, I'd especially love your help exploring these additional types.
This post is my examination of a type that we're (seemingly) all already very familiar with: ◈ interface representatives. Acknowledging the context that there are other types beyond them is how I think we discover ◈ interface reps' "edges." Finding edges is how we can establish useful names and definitions. This matters because precise language is a wicked powerful thing. Visa said it best, I think:
As Visa suggests, let's first start with what "component" means before we get to talking about different types.
Figma's documentation defines components this way:
Components are elements you can reuse across your designs. They help to create and manage consistent designs across projects.
You can create components from any layers or objects you've designed. These could be a whole range of things like buttons, icons, layouts, and more
There are two aspects to a component:
1. A main component defines the properties of the component.
2. An instance is a copy of the component you can reuse in your designs. Instances are linked to the main component and receive any updates made to the component.
To me, that first sentences sounds like a really specific job: the job of ◈ interface representatives. They even list a couple: "buttons" and "icons", but they also mention "layouts", and have an "and more" catch all... that's where I think this idea that there are "types" of components comes handy in. The types help us get really clear about the "and more."
If I had to write a definition for "components" that was job-agnostic, it'd go something like this:
A component is a set of rules and decisions whose instances can be updated en mass, swapped with any other instance, nested within other components, and detached from their origin point (the "main" component).
Okay great. Components are settled. Now we can move on to ◈ interface representatives:
◈ Interface reps. take the visual design language of a product's brand and apply it to functional parts of a product, be it a website, mobile app, or software. The name is (purposefully) obvious: these things represent pieces of interface. They're what designers pull out of Figma's asset panel to compose mockups and string together prototypes. They're the "design expression" of what gets referenced by engineers who go on to craft the "code expression" (the real-life components) that get pushed to production.
You might be thinking "Alice, wait, by your definition aren't all components, ◈ interface representatives??" And to that I'd say "no ❤️". For people who are just starting out in Figma or entering the world of component libraries and design systems for the first time, it's likely that every Figma component they encounter and craft themselves is an ◈ interface rep. It's a super practical application of components! It's how Figma defines components! For new folks, interface reps might be are all there is. The value is immediately clear: build a button once, re-use it thousands of times, update these thousands of instances from a single source with high accuracy and low risk in seconds. I bet you could go your whole career as a designer without thinking beyond this type of component and do quite well for yourself.
So why is it important we name and define them?
[certain components are] suited for doing certain jobs exceptionally well, but no single one can do all the jobs well.
I believe pairing a visual symbol with a title helps me remember the definition. Figma does this with ❖ and ◇; you see those glyphs and you know exactly what they mean, without labels! I want to do the same for these types of components.
For ◈ interface reps, I felt like choosing another diamond shape that matched Figma's four-diamond ❖ and empty diamond ◇ was important, because, again, ◈ interface reps are a familiar thing. Their pictogram should also feel familiar. ◈ feels like a midpoint of ❖ and ◇.
⭐️ Your component should have a thoughtfully constructed API. Nathan Curtis has great advice about working with engineers to build a good component API in Figma. A simpler, maybe even reductive, way to put this is: clean up your layers and properties. I get it, it's a tired request, very "parent asking kids to clean their room" vibes, but doing this is helpful for the people using your ◈ interface rep! And tidying layer and property names is just one of twelve ways you can ensure you build an ◈ interface rep that designers are excited to pull from the assets panel because they know it's usable, useful, and trustworthy.
⭐️ If your ◈ interface rep is configurable (as in, there are parts of it that can be shown, hidden, or re-arranged depending on the context of use) reach first for component properties instead of variants to set up and manage those configurations.
⭐️ If your ◈ interface rep is interactive, that's when you should reach for variants to handle things like state, enabled VS disabled, and populated VS empty states. Some folks will combine all these things into one single property called "State", but I prefer to be more specific and use the following property set up:
⭐️ And if you have interactive states, don't forget to set up those prototype connections for those interactions!
⭐️ When possible, name your ◈ interface rep after the HTML tag it will use. If you're familiar with atomic design, this likely only applies to your atoms and some smaller molecules. If you're not familiar with atomic design, you can check out Chapter 2 of Brad Frost's book on the subject to get yourself oriented.
⭐️ Keep your ◈ interface rep in a dedicated component library file (as opposed to a local file).
⭐️ If the ◈ interface rep has any documentation associated with it, take some time to add a link to the ◈ interface rep's documentation field. It's hard to convey just how much people appreciate this! It's well worth the time and tedium of hunting down links.
❌ Storing real content or data in your ◈ interface rep. This might seem like a clever "feed two birds with one scone" thing because you're giving other designers a hint about what sort of content the component may hold.... but I want to gently dissuade you from this idea... because there is another component type specifically for working with content and data! They're called ✎ Content carriers.
Instead ◈ interface reps' text layers should make clear the name of that piece of anatomy: "Label", "Value", "Placeholder", "Title", "Username", "Street address", and in the case of text that needs to use a certain format, such as dates or number values, the text can help guide designers to use the correct format
❌ Not using auto layout. Now, when you're exploring new ideas and concepts, I know some folks work faster without auto layout. They prefer to manually place and re-size their layers. That's awesome, I think experimentation is super appropriate in local files where you're jamming on a new idea, and everyone should feel empowered to work however they're most comfortable!
But as soon as the design of an ◈ interface rep has firmed up and it's ready to add into your component library, take the time to add auto layout. This is what makes components responsive and flexible.
With the do's and don'ts covered I've now suggested a few "edges" to what an interface rep is:
✅ Their job is to represent a part of your product's interface and establish consistency in the product's visual design.
✅ They get employed by designers in local files to create mockups and prototypes.
✅ Experiments and modifications to ◈ interface reps should also happen in local files.
✅ Ideally each ◈ interface reps' main component lives in a library file.
✅ Their architecture and naming should be driven by anatomy and interaction.
✅ They do not hold realistic content, because that's another component's job and mixing up job responsibilities defeats the purpose of defining component types. Instead ◈ interface reps suggest what content will be applied, and help designers follow the content's format if needed.
✅ When they're ready to move out of a local file and into a component library, they make full use of auto layout to be responsive and flexible.
Because no one type of component can do every job successfully, they need to work together to add value to designers' workflows. With this post being specifically about ◈ interface reps, I'll focus on their strengths in pairings with other types of components, or how they become enhanced when paired with another type of component.
✂︎ Placeholders and ◈ Interface reps are friends in the same way bread and butter are: bread can be great on it's own, but really great with some butter spread over it. But consider the reverse: you'd never eat the butter by itself—the butter needs the bread. Right? Okay, so ✂︎ Placeholders are your butter, and your ◈ interface reps are the bread. You'll never use a ✂︎ Placeholder without an ◈ Interface rep.
Here's some examples of where ◈ Interface reps can be supercharged by nesting a ✂︎ Placeholder inside of them:
With the addition of component properties, working with ✂︎ placeholders has gotten easier than ever! Swapping a nested ✂︎ placeholder can now happen from the ◈ Interface rep's properties. This means less deep-clicking, which is an important characteristic of highly usable components.
While ◈ interface reps' final destination is usually a component library, it's in local files where designers spend the most time with them. Local files are where ◈ interface reps' visual design gets experimented with, iterated on, and pressure tested. And the farther and wider your exploration takes you, the more useful ⍚ Bases will become in your journey.
Let's say I'm exploring a new design for an ◈ interface rep that will appear on nearly every page of a website, like article previews on a news site. Let's also say I have full-page mockups of every unique page of this news site. Perhaps I want to explore lots and lots of different visual styles of the ◈ article preview, especially when it comes to the foundational elements of its visual design, like padding and spacing. Using ⍚ Bases will help speed up my process:
The first thing I'd do is pull in and detach an instance of the existing <span class="figma-component">◈ article preview</span> component so I have full control over it. I'd leave smaller molecules and atoms, like icons or buttons, basically any components I'm not iterating on, intact and still connected to their main components. For this scenario maybe I want to explore a lot of different card designs for my <span class="figma-component">◈ article preview</span>. To do this efficiently, I'd set up as many ⍚ Bases as I had ideas I wanted to try for varying designs. I'd also componentize the article preview content inside of a ⎆ Content carrier in case I wanted to change how content was arranged.
After setting up my new local <span class="figma-component">◈ article preview</span> component that is underpinned with my ⍚ Bases, I could add instances of <span class="figma-component">◈ article preview</span> into my full-page mockups and see how they look. Seeing them in the context of a page might inspire me to make further adjustments to the padding of the new card design I'm trying. Since I have ⍚ Bases, I can do that in one place and immediately see the change take affect as the new padding values cascade down to the ◈ interface reps that I added to the full page mockups.
Once I land on a new design for the <span class="figma-component">◈ article preview</span> that I like, I'd go back to its main component in the component library file (which I originally pulled in to detach and experiment off of). From there I'd update it to match the new look that I designed in my local file. The ⍚ Bases would stay behind though! I would not use them in the component library version of <span class="figma-component">◈ article preview</span>The ⍚ Bases were just a tool for me to quickly experiment with visual design.
✎ Content carriers are great to pair with more complicated ◈ interface reps that begin to establish context about the product experience. These ◈ interface reps are often larger molecules, organisms, and page templates.
For example, let's say I have a commonly used newsletter sign-up form on my website. It uses input fields like "First name", "Last name", "Email address", and some checkboxes that allow users to opt-in to categories of newsletter content they want to receive. There's also a success message whose copy is specific to this particular form.
If this form gets used in multiple places on my product or website, it's a good candidate for componentization! To build it I'd need instances of ◈ interface reps such as <span class="figma-component">◈ text input fields</span>, <span class="figma-component">◈ checkboxes</span>, and a <span class="figma-component">◈ button</span> to submit the form. But when I pull those out of the assets panel all their labels would need to be updated: "Input label", "Checkbox label" and "Button label" would get overridden to say "First name", "Last name", "Email address", and "Subscribe." I'd also need to design a success message variant that uses the copy I want for this specific form.
After making all those text overrides, I'd be ready to componentize my form. Once I do so, this form is no longer an ◈ interface rep, because it holds specific copy. It now has content in it. It has become a ✎ Content carrier that relies on nested ◈ interface reps which establish the visual design. And the newly made <span class="figma-component">✎ newsletter sign up</span> component shows us how the ◈ interface reps it's composed of are used in practice.
⍂ Starter kit components are all about speed and convenience. They're very much like meal kit delivery services: you want to cook spaghetti and meatballs in a scratch-made tomato sauce? Then your meal kit likely comes with preportioned pasta, meat, tomatoes, and garlic, all nicely packaged in a cardboard box. Now, you're not going to use the cardboard box in the recipe, right? Right. It's not an ingredient, it's just a container. This is no different than a ⍂ Starter kit component: the top-level parent frame is the cardboard box. Once the "box" (⍂ Starter kit instance) arrives "at your door" (in your local file), you dispose of it (detach and remove the frame). The contents of the box (detached frame that you've done away with) are all your pre-portioned ingredients (instances of ◈ interface reps) ready for you to use!
One practical example of a ⍂ Starter kit is making a kit for a particular type of card.
Let's say I'm designing an e-commerce website. There's a few existing ◈ interface reps that represent products being sold on the site, and they all use a card-like design. I'll call them "product cards." The information on these product card is probably suuuper context dependent. Sometimes a product card needs an "On sale!" badge, sometimes there's a brief written description of the product, sometimes the product maker's logo is visible on the card, sometimes cards can be selected to take bulk-actions on, like "favoriting" or "add to cart", sometimes products are being promoted and need to take up more space, and there are more decorative elements to attract people to click on them. And of course all of these variations need to work responsively, and some elements may change position to work well on smaller devices...
You can see how this will end up requiring a ton of variants and component properties if I tried to cram it all into a single "Product card" ◈ interface rep component. So for this ficticious e-commerce site, I would use a strategy where I have context-dependent product cards as separate components named like so: "Product card / Featured", "Product card / Alternative", "Product card / In-cart." It's likely and they'd share certain properties for contexts that are global, such as an "On sale" boolean toggle.
It's great to have all these product cards built, but when the day comes that the e-commerce site expands to include some new context, like a comparison page, well, it likely needs new product cards that make sense in that context. I could pull in an instance of an existing product card to detach and riff off of, but then I might be missing some pieces because no one product card displays every bit of information. Alternatively, I could drop in and detach instances of all the unique product cards. That would ensure I'd have all the right elements to play with, and great to have references to all these existing components, but it's a lot of work to detach and extract the necessary bits from them.
This is where ⍂ starter kits can come in handy. If I'm charged with designing a new product card I need to balance being consistent with existing product cards, but not constrained by their context-dependent compositions. Keeping consistent requires I make sure I'm including the mainstay information and global characteristics. To do that I need to identify what elements are present across all these permutations of my product cards. And the list might be smaller than you think! For example, these imaginary product cards might only require:
Imaging having all those shared ◈ interface reps (some of which aren't even components, they're just text layers, like the price and the product name) and package them up with some ✍︎ Annotation components that label them as "product card required information", or whatever will communicate "hey, pretty much every product card you design is needs to have these elements."
Then if there are other ◈ interface reps that are only sometimes visible depending on the context... such as:
Well, those ◈ interface reps can come along for the ride too! Again, I'd use an ✍︎ Annotation component to label them as "optional product card information."
All of these ◈ interface reps and text layers and ✍︎ Annotation components will be free-floating on the canvas, wrapped in a single frame called "⍂ Product card starter kit." When I pull this ⍂ kit into my local file I'll detach it so I have full reign over the ◈ interface reps that I choose to use. It's unlikely I'll need all of them. Maybe the star rating ◈ interface rep isn't appropriate for the new product card I'm designing. And since I detached the kit, I'm free to delete it and keep designing! No bloat, baggage, or spelunking my way through the assets panel to find all the right pieces.
✍︎ Annotation components are great to pair with your ◈ interface reps when you need to:
Pairing ◈ interface reps with ✍︎ Annotation components is what can take your ◈ interface reps' documentation from good to great 💪
⎌ Switchboards are game changers for anyone who builds prototypes out of their ◈ interface reps. They allow you to componentize prototype connections! What components did for making it easier to iterate and update visual design, well, ⎌ Switchboards do the same for prototyping. Massive workflow boost.
To demonstrate: say I'm building a prototype to test how discoverable a company's website's careers page is. I want to see the natural path people take to get to the careers page, so my prototype needs to allow folks to roam free rather than follow a predefined, scripted path.
For the design of this site, I'll offer three different ways to get to the careers page:
Since I want my prototype to be as realistic as possible, I'll include screens for every unique page and make them visit-able in the prototype. For this scenario let's say I've already designed ◈ interface reps for the global navigation, footer, and button that will be used in the blog post in my prototype file. Instances of those ◈ interface reps are what will become my ⎌ switchboards.
To make these switchboards, I'll re-componentize them to make them local main components, then draw prototype noodles stemming from the global nav's "Careers" link to the frame acting as my "Careers page" in my prototype. I'll do the same with the "Careers" link in the footer, as well as an instance of a Button whose label reads "Careers at Cool Company."
And that's it! What used to be instances of ◈ interface reps are now ⎌ switchboards! Instead of dropping instances of regular ◈ interface reps on all my screens and drawing dozens and dozens of noodles off of every footer and every global nav on every screen, I can simply use my local ⎌ switchboard components instead. Any time I need a button that takes users to the careers page I use an instance of my "⎌ Button ➡️ Careers page" switchboard and change the label as needed. All the text objects that represent links in my "⎌ Global Nav" switchboard instances all point to the right pages. It's a beautiful combination: ◈ interface reps are handling consistent visual design, and the ⎌ switchboards reduce risk for human error and amount of time needed to stand up a working prototype.
In writing this post I've realized that ◈ interface reps are at the center of it all. The 6 other types of components exist to support them, and they can help us add rules and rigor to how we use ◈ interface reps in local files. As I said at the beginning, I fully believe you could have a wicked successful design career without bothering to think about the different jobs components can do... but when we free up ◈ interface reps' from carrying so much responsibility, we have this huge opportunity to further reduce risk of inconsistency, file bloat, save time, and extend what we're capable of building in Figma. All while using natively supported features and workflows.
For the huge amount of time spent pixel pushing that we've rescued by leaving tools Photoshop behind, we still do quite a bit of it in Figma. I believe exploring and (hopefully) agreeing upon new types of components in Figma will free designers up even further. Working in this way might seem heady and overly complicated, but we can't really know until we try. That's why I'm taking these concepts for a test ride in a ground-up component library build where I build one of my favorite products, YNAB, from scratch in Figma using ◈ interface reps and all these other types of components.
As I said at the beginning, I'd love for this to be a dialogue with the wider community. Don't be shy about getting in my replies on twitter, joining live-streams, or leaving comments on old streams! While I'll consider it a success if I'm the only person who finds all of this useful, it'd be amazing to know if this framework might help others in their design work.
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. Right now I'm averaging 1 post every ~3 months (and trying to pick up my pace).