Refactoring the Button Component

A behind-the-scenes look at how I reduced Edifire UI's button component from 432 variants to just 32 using parametric logic, slot-based design, and Figma properties. This case study explores the thinking, tooling, and cleanup strategy behind a scalable, token-driven system built solo and made for open source.

Code for a button component

Overview

Overview

Edifire UI is a personal, token-driven design system built solo with the purposeful goal of becoming fully open source. The button—undoubtedly the most frequently utilized component in any comprehensive UI kit—was one of the foundational elements I first tackled. Built initially with a meticulous mindset of “account for everything,” its variant list gradually ballooned into an overwhelming 432 combinations spanning various states, sizes, colors, icon placements, tones, hierarchies, and theme modes. What originally began as a display of thoroughness and care slowly morphed into a stifling maintenance burden, and the button eventually became the perfect, necessary test case for transitioning toward a more disciplined, scalable, and manageable approach.

How i reduced my button variants from 432 to 32 in My Solo Design System - Edifire UI


When I started building Edifire, a personal design system built from the ground up with a vision to become open source, I thought I was being thorough. Thoughtful, even. After all, what’s a design system without a button component that can handle every edge case and visual preference imaginable?

I created states for hover, focus, disabled, and loading. I accounted for size variations, different icon placements, tones, hierarchies based on importance.

It seemed comprehensive at first, just a simple frame with a label. Maybe an icon. Maybe two. Then came sizes. Colors. States. Icon alignments. Theme modes. Before I knew it, my tidy component panel had morphed into a scrollable mess of 432 button variants.

It was chaos… but it was my chaos.

How i reduced my button variants from 432 to 32 in My Solo Design System - Edifire UI


When I started building Edifire, a personal design system built from the ground up with a vision to become open source, I thought I was being thorough. Thoughtful, even. After all, what’s a design system without a button component that can handle every edge case and visual preference imaginable?

I created states for hover, focus, disabled, and loading. I accounted for size variations, different icon placements, tones, hierarchies based on importance.

It seemed comprehensive at first, just a simple frame with a label. Maybe an icon. Maybe two. Then came sizes. Colors. States. Icon alignments. Theme modes. Before I knew it, my tidy component panel had morphed into a scrollable mess of 432 button variants.

It was chaos… but it was my chaos.

Setting the scene

Edifire UI started as a personal project, to build a scalable, visually balanced design system I could reuse across side projects and eventually release for others to use. I wanted it to be minimal, flexible, and fully tokenized.

The button, being the most frequently used component in any UI kit, was naturally one of the first elements I tackled. I approached it with a mindset of “account for everything.” And that’s exactly what I did. I over-accounted.


When it broke: When Flexibility Becomes Fatigue

This wasn’t a visual failure. Nothing was broken, misaligned, or technically wrong. But something felt heavy. My build-up felt bloated.

I wasn’t getting error messages. I wasn’t struggling to make the component work. What I was struggling with was the mental load of navigating it. I had unknowingly recreated one of the most common and least discussed problems in design systems: Variant Overload.

In Figma, the component panel had become a scroll-fest. Every time I needed a simple button, I found myself buried in nested menus and 5-syllable variant names. It was like trying to order a coffee and being handed a menu with 400+ combinations, each with a slightly different name.

Even though Figma handled it just fine, I wasn’t.
The bigger insight? Component overload is a quiet killer in many design systems.


The inspiration

I came across a talk by the Uber design systems team. They were walking through how they reduced their badge component from dozens of rigid variants to just a few highly dynamic configurations, by switching to a parametric design model.

Their badge could take on any shape, tone, or status, without bloating the variant list. It used just a handful of props like tone, size, icon, and message, powered by tokens and context-aware logic. It was simple, smart, and scalable.
This stuck with me.

So when I looked back at my own button, I began to see it not as a static set of visual options, but as a parametric system waiting to be unlocked. That mindset that shift from how it looks to how it behaves, became the catalyst for rethinking everything.


Inspired by Uber’s “Parametric Components” approach

Watch here: https://youtu.be/-z9JX8Lz5lI?si=9l5XZCbpWZF0OQee

In this talk, Uber shares how they reduced the badge component by switching from permutations to parametric controls using tokens and props.

Setting the scene

Edifire UI started as a personal project, to build a scalable, visually balanced design system I could reuse across side projects and eventually release for others to use. I wanted it to be minimal, flexible, and fully tokenized.

The button, being the most frequently used component in any UI kit, was naturally one of the first elements I tackled. I approached it with a mindset of “account for everything.” And that’s exactly what I did. I over-accounted.


When it broke: When Flexibility Becomes Fatigue

This wasn’t a visual failure. Nothing was broken, misaligned, or technically wrong. But something felt heavy. My build-up felt bloated.

I wasn’t getting error messages. I wasn’t struggling to make the component work. What I was struggling with was the mental load of navigating it. I had unknowingly recreated one of the most common and least discussed problems in design systems: Variant Overload.

In Figma, the component panel had become a scroll-fest. Every time I needed a simple button, I found myself buried in nested menus and 5-syllable variant names. It was like trying to order a coffee and being handed a menu with 400+ combinations, each with a slightly different name.

Even though Figma handled it just fine, I wasn’t.
The bigger insight? Component overload is a quiet killer in many design systems.


The inspiration

I came across a talk by the Uber design systems team. They were walking through how they reduced their badge component from dozens of rigid variants to just a few highly dynamic configurations, by switching to a parametric design model.

Their badge could take on any shape, tone, or status, without bloating the variant list. It used just a handful of props like tone, size, icon, and message, powered by tokens and context-aware logic. It was simple, smart, and scalable.
This stuck with me.

So when I looked back at my own button, I began to see it not as a static set of visual options, but as a parametric system waiting to be unlocked. That mindset that shift from how it looks to how it behaves, became the catalyst for rethinking everything.


Inspired by Uber’s “Parametric Components” approach

Watch here: https://youtu.be/-z9JX8Lz5lI?si=9l5XZCbpWZF0OQee

In this talk, Uber shares how they reduced the badge component by switching from permutations to parametric controls using tokens and props.

The Audit: Mapping the Mess


I took a step back and mapped every possible combination I had created.

What i did was to map out the anatomy of the buttons including its different sizes, so i can identify what property to turn into a parametric variable.

I tracked the following elements:

  • Button size

  • Font size

  • Font height

  • Spacing between elements

  • Vertical padding

  • Horizontal padding

  • Corner radius


The Audit: Mapping the Mess


I took a step back and mapped every possible combination I had created.

What i did was to map out the anatomy of the buttons including its different sizes, so i can identify what property to turn into a parametric variable.

I tracked the following elements:

  • Button size

  • Font size

  • Font height

  • Spacing between elements

  • Vertical padding

  • Horizontal padding

  • Corner radius


The Rebuild

The Rebuild

This time i approached the button like a developer might approach a component API.

I then broke down the visual and functional aspects into properties that could be toggled and scaled. I created a collection of token variables for the identified properties and then assigned the variables to the button component while maintaining both light and dark mode.

Instead of hundreds of rigid variants, I created one core structure with 32 intelligent configurations. Each decision was driven by 2 questions:

"Will this scale without duplication?"

“Will this reduce mental load for anyone using it, including future me?”

This time i approached the button like a developer might approach a component API.

I then broke down the visual and functional aspects into properties that could be toggled and scaled. I created a collection of token variables for the identified properties and then assigned the variables to the button component while maintaining both light and dark mode.

Instead of hundreds of rigid variants, I created one core structure with 32 intelligent configurations. Each decision was driven by 2 questions:

"Will this scale without duplication?"

“Will this reduce mental load for anyone using it, including future me?”

The Outcome: From Bloat to Brilliance


Reducing 432 variants to 32 wasn’t just about decluttering. It created space—for speed, focus, and consistency.

  • Faster performance in Figma

  • Less chance to reduce or override

  • Easy theming with token hooks

  • Predictable behavior across breakpoints

Now when I need a button, I toggle a few properties.
That’s it. No overly long list of variants and properties, No visual/mental fatigue.

The Outcome: From Bloat to Brilliance


Reducing 432 variants to 32 wasn’t just about decluttering. It created space—for speed, focus, and consistency.

  • Faster performance in Figma

  • Less chance to reduce or override

  • Easy theming with token hooks

  • Predictable behavior across breakpoints

Now when I need a button, I toggle a few properties.
That’s it. No overly long list of variants and properties, No visual/mental fatigue.

Accessibility


Reducing complexity was the goal, but not at the cost of usability. From the very start, I treated accessibility as a core design input, not a post-cleanup patch. Here’s how it shaped the button rebuild:

Every color token, whether text, or background, was tested to meet WCAG AA contrast standards in both light and dark mode. If it didn’t pass, it didn’t make the cut.

Accessibility


Reducing complexity was the goal, but not at the cost of usability. From the very start, I treated accessibility as a core design input, not a post-cleanup patch. Here’s how it shaped the button rebuild:

Every color token, whether text, or background, was tested to meet WCAG AA contrast standards in both light and dark mode. If it didn’t pass, it didn’t make the cut.

What I Learned


Working alone on Edifire gave me full control, but also full responsibility. I couldn’t rely on team reviews or shared standards. The system had to be resilient by design.

Here’s what this process taught me:

  • A component should feel like a tool, not a trap.

  • Flexibility comes from constraint, not chaos.

  • Designing alone means future you becomes your toughest stakeholder.

  • Component logic is more powerful than visual stacking.

  • Design systems are about decision reduction, not just reusability.

  • Tokens, slots, and props are your best friends.

  • If something starts to look heavy, it's time to refactor.

What I Learned


Working alone on Edifire gave me full control, but also full responsibility. I couldn’t rely on team reviews or shared standards. The system had to be resilient by design.

Here’s what this process taught me:

  • A component should feel like a tool, not a trap.

  • Flexibility comes from constraint, not chaos.

  • Designing alone means future you becomes your toughest stakeholder.

  • Component logic is more powerful than visual stacking.

  • Design systems are about decision reduction, not just reusability.

  • Tokens, slots, and props are your best friends.

  • If something starts to look heavy, it's time to refactor.

What's next


The button refactor was just the first step in shaping Edifire into a system that’s thoughtful, scalable, and genuinely enjoyable to use.

Next, I’m applying the same approach to modals, dropdowns, tabs, and inputs, where logic not layering, leads the design.

Edifire is going open source soon. When it does, it won’t just be a collection of UI parts. Build small. Think in systems. Reduce friction. Leave room to grow.

I’m also focused on bridging the gap between design and development so others can use the system right out of the box. I plan to include the React code snippets of the components in Edifire UI directly into Zeroheight using Figma MCP and Cursor.

What's next


The button refactor was just the first step in shaping Edifire into a system that’s thoughtful, scalable, and genuinely enjoyable to use.

Next, I’m applying the same approach to modals, dropdowns, tabs, and inputs, where logic not layering, leads the design.

Edifire is going open source soon. When it does, it won’t just be a collection of UI parts. Build small. Think in systems. Reduce friction. Leave room to grow.

I’m also focused on bridging the gap between design and development so others can use the system right out of the box. I plan to include the React code snippets of the components in Edifire UI directly into Zeroheight using Figma MCP and Cursor.

Send us a message

Send us a message

Get Quote

Book call

Text us

Get Quote

Book call

Text us

Prefer email?

hello@jayhans.design

hello@jayhans.design

Follow us on

© 2026 Joyce Hanson

© 2026 Joyce Hanson

Designed & built in Framer · Hamburg, DE

Designed & built in Framer · Hamburg, DE

StudioHans®

Premium websites and brands for businesses that'd rather earn customers than chase them. Hamburg → worldwide

STATUS

2 spots — June 2026

Reply within 4 hours

© 2026 StudioHans

Built & forged in 🔥 · Hamburg, DE

StudioHans®

Premium websites and brands for businesses that'd rather earn customers than chase them. Hamburg → worldwide

STATUS

2 spots — June 2026

Reply within 4 hours

© 2026 StudioHans

Built & forged in 🔥 · Hamburg, DE

StudioHans®

Premium websites and brands for businesses that'd rather earn customers than chase them. Hamburg → worldwide

STATUS

2 spots — June 2026

Reply within 4 hours

© 2026 StudioHans

Built & forged in 🔥 · Hamburg, DE