Developer Friendly Component Design Thumbnail
Component Design for JavaScript Frameworks:
A Designer's Guide to JS-Friendly Components

The history of human-computer interaction and user interface design (graphical user interface, GUI) spans over 70 years. There were only text-based command-line interfaces available when it was initially launched in the early 1960s. We first saw the mouse, windows, icons, and hypertext links when Douglas Engelbart unveiled the "Mother of All Demos.”

Mother of All Demos

Douglas Engelbart using the NLS’s 5-button chord keyset, a standard QWERTY keyboard, and 3-button mouse, around 1968. NMAH Catalog #2015.3073.11.

This marked the start of a lengthy history of user interface design, which was followed by some incredible successes like Xerox PARC’s Alto (’73) and Star (’81), Apple Lisa (’83) and Macintosh (’84), Microsoft Windows (’85). The development of standardized, user-friendly, and reusable interfaces became necessary as a result of all these technical advancements.

Macintosh System 1 GUI

Macintosh System 1 GUI (1984)

When UI became dynamic with Web 2.0 tech in the early 2000s, designers started to create reusable snippets (navigation elements, modals, form elements). This led to emerging design patterns like Yahoo did back in 2006 with Yahoo Design Pattern Library (YUI). Facebook released React in 2013, marking a significant advancement in UI architecture and contributing to the growth of the component ecosystem. Today's digital products are composed of tens of thousands of uniform, scalable, and reusable components. Because it must fit in multiple locations on the interface, designing a small square with an optional checkmark within takes additional planning effort. Since designers and developers co-own modern UI components, we designers need to learn more about their technical implementation.

Placeholder

A decade ago, UI designers relied on Photoshop for interface design. In the 2010s, Sketch emerged as a Mac-exclusive option, though its paid model limited widespread adoption. Many of us started with Adobe XD, which introduced component concepts but lacked robust property management. Tools like InVision, Origami Studio, and Axure RP existed but proved too complex for junior designers.

1. Understanding Components and Properties

I am a tag

Button, Tag, and Icon-Button components

A component is a single, reusable UI element within a product, a building block that can be used repeatedly with different configurations. This concept mirrors both design systems and code architecture.

Component hierarchy follows atomic design principles:

  • Atom: Basic elements (buttons, inputs, icons)
  • Molecules: Simple combinations (search bar = input + button)
  • Organisms: Complex sections (navigation header, product card)
  • Templates: Page-level layouts
  • Pages: Specific instances with real content

Learn more about atomic design principles and how to apply them in your work. Visit the Brad Frost's Atomic Design website for a comprehensive guide.

Common component examples:

  • Buttons: primary, secondary, icon buttons
  • Input fields: text, password, search, textarea
  • Cards: product cards, user cards, content cards
  • Navigation elements: tabs, breadcrumbs, dropdown menus
  • Modals and dialogs: confirmation dialogs, alert modals
  • Form elements: checkboxes, radio buttons, toggles

1.1 The Universal Component Model

Despite syntactic differences, all modern JavaScript frameworks share a common component-based architecture:

  • Props/Properties: Data passed from parent to child components
  • State: Internal component data that triggers re-renders
  • Events: User interactions that trigger functions
  • Composition: Nesting components to build complex UIs

Placeholder

When you design components with these universal concepts in mind, your work translates smoothly across any framework. A well-designed button in Figma becomes an equally well-implemented button in React, Vue, Angular, or Svelte.

1.2 What is a Property?

Properties (props) define a component's identity and characteristics. Consider a car analogy: it has properties like brand, model, year, and passenger capacity where each serves a specific purpose.

Button component with different property configurations

Similarly, a button component might have properties like:

  • label (string) : The button text
  • type (variant) : primary | secondary | tertiary
  • size (variant) : small | medium | large
  • isDisabled (boolean) : Whether the button is interactive
  • isLoading (boolean) : Shows loading spinner
  • startIcon (component instance) : Optional icon before text
  • endIcon (component instance) : Optional icon after text
  • onClick (action) : What happens when clicked

Try Button component properties on the Storybook Playground

These properties map directly to React/Vue/Angular/Svelte props and make components flexible, reusable, and maintainable.

2. The Fundamentals of JS-Friendly Components

Designing components that developers can efficiently implement requires mastering four fundamental principles:

  • Structure & Naming: Using Auto-Layout and meaningful frame names to define HTML structure
  • Properties & Props: Establishing clear, js-friendly component properties
  • Tokenization: Applying design tokens for scalable theming
  • Interaction: Prototyping behaviors and states

Let's explore each principle in depth.

2.1 Structure & Naming

In this section, we'll cover best practices for structuring components using Auto-Layout in Figma and naming conventions that translate seamlessly to HTML/CSS.

2.2 Using Proper Auto-Layout with Frames in Figma

Figma offers two ways to nest objects: Groups and Frames. Groups are the traditional Adobe-style approach, while Frames unlock Figma's powerful Auto-Layout feature.

Placeholder

Auto-Layout in Figma directly corresponds to CSS Flexbox properties. When you configure Auto-Layout settings in Figma, you're essentially defining:

  • display: flex or display: inline-flex
  • flex-direction: row or flex-direction: column
  • justify-content and align-items values
  • gap for spacing between children
  • padding for internal spacing
  • width: auto (hug contents) or width: 100% (fill container)

Placeholder

Learn more about Figma Auto-Layout and how it maps to CSS Flexbox. Visit the Figma Help Center for a comprehensive guide.

Key principle:
Your frame structure defines the HTML structure. Each frame typically becomes an HTML element (most commonly a <div> container, but could be <button>, <section>, <header>, <nav>, or <article> depending on semantic meaning). Therefore, using the minimum necessary frames helps developers create cleaner, more maintainable code.

Best practices:

  • Sketch the structure: Quick sketches help identify necessary containers.
  • Minimize frames: Use as few frames as possible while maintaining proper layout.
  • Use consistent spacing: Apply 4px (0.25rem) or 8px (0.5rem) grid systems using Auto-Layout gap and padding.
  • Set proper sizing: Use "Hug contents" or "Fill container" appropriately.
  • Consider responsive behavior: Think about how the component adapts to different widths.

2.3 Example: Button Component Structure

A simple button needs only one or two frames:

ButtonContainer (Frame with Auto-Layout)
                ├── padding: 12px 24px
                ├── gap: 8px
                ├── direction: horizontal
                ├── align: center
                ├── width: hug contents
                │
                ├── StartIcon (optional, component instance)
                ├── ButtonLabel (text)
                └── EndIcon (optional, component instance)
                

This structure translates directly to HTML/CSS:

/// HTML
                  <button className="button">
                    {/* if startIcon present */}
                    <span>Click me</span>
                    {/* if endIcon present */}
                    </button>
/// CSS
                  .button {
                      display: flex;
                      flex-direction: row;
                      align-items: center;
                      gap: 8px;
                      padding: 12px 24px;
                      width: fit-content;
                    }

2.4 Giving Meaningful Layer Names

Proper layer naming is essential for clear communication between designers and developers. Meaningful names help developers understand the purpose of each frame and how it maps to code. If you wouldn't name a CSS class "Frame 1" or "Group 2", don't use those names in your layers. Instead, use descriptive names that reflect the element's role.

Layer Naming in Figma

Unnamed vs Meaningful Layer Names for a Card Component

Above example shows a card component with poorly named layers (left) versus thoughtfully named layers (right). The meaningful names clarify the structure and purpose of each element, making it easier for developers to implement the design accurately. Even the Figma icons tells the layout direction (horizontal vs vertical) at a glance.

Figma provides AI-powered layer naming if you prefer not to manually label frames. Learn more about using AI to rename layers in Figma.

Benefits of Thoughtful Layer Naming

  • Clarifies HTML structure:Layer names can inform semantic HTML elements and CSS class names.
  • Improves maintainability: Easier to understand and modify components later.
  • Aligns with development patterns: Developers can quickly map design to code.
  • Enhances team communication: Shared vocabulary between design and development.
  • Enables better search: Find components quickly in large Figma files.

Naming Conventions

Follow these guidelines when naming layers:

/// Use clear, descriptive names

🟩 CardImage (not Image1)
🟩 CardTitle (not Text_Layer_2)
🟩 ActionButton (not Button)
🟩 IconWrapper (not Group_23)
🟩 PriceLabel (not Text)
/// Do not use vague, generic names

🟥 Container
🟥 Wrapper
🟥 Group
🟥 Frame #123456
🟥 Text

Do not use Rectangle and Ellipse in Figma since they do not translate to semantic HTML elements. Always use Frames with Auto-Layout for containers. Learn more about Groups vs Frames in Figma.

By combining proper Auto-Layout structure with meaningful layer names, you set developers up for success—enabling them to implement components quickly and accurately. Modern design systems like Material Design (Google), Carbon (IBM), and Atlassian Design System use consistent layer naming to create clarity across hundreds of components.

2.5 Component Properties in Figma

Figma UI Component Properties

Properties of the button component in Figma UI

Component properties (props) are arguably Figma's most powerful feature for creating flexible, functional components that mirror real component behavior. As a designer, If I am going to use an UI element more than once, I always create a component with well-defined properties. This approach not only streamlines my design process but also significantly reduces the development effort required to implement the component. Defining properties is a time investment that pays off in spades.

Figma supports several property types that map directly to JavaScript/TypeScript:

Figma UI Component Properties

Property types available in Figma

Figma PropertyFrontend EquivalentExample Use Case
TextstringButton labels, card titles, descriptions
BooleanbooleanisDisabled, isLoading, hasIcon
Instance SwapComponent instanceIcon components, avatar images
Variantstring enumtype="primary", size="large"

Table 1. Mapping Figma Properties to Frontend Equivalents

Property Naming Best Practices

While naming properties, consider giving meaningful names that convey the purpose of the property. Following front-end conventions can help maintain consistency and clarity and it also reduce the development time. Adding a ? at the end of boolean properties indicates that the property is optional which is a valuable info for the development team.

/// Use descriptive, purposeful names

🟩 cardTitle
🟩 isDisabled
🟩 buttonLabel
🟩 iconStart
🟩 hasEndIcon
🟩 showKebabMenu
/// Do not use vague, generic names

🟥 text1
🟥 disabled
🟥 label
🟥 icon
🟥 end
🟥 menu

Follow frontend conventions

Front-end development is in progress since the early 2000s. Over the years, certain conventions have emerged that enhance code readability and maintainability. Adopting these conventions in your property naming can significantly improve collaboration with developers. As designers, we should strive to speak the same language as our developer counterparts. Here are some key conventions to consider:

  • Use camelCase (e.g., buttonLabel, isDisabled) for property names to align with JavaScript conventions.
  • Prefix boolean properties with is, has, show, or can to indicate their true/false nature.
  • Use specific, clear names (`primaryColor` not `color1`)
  • Indicate optional behavior clearly (`startIcon?` or `iconStart?`)
  • Use consistent naming patterns across all components

Learn more about JavaScript naming conventions and best practices. Visit the W3Schools website for a comprehensive guide.

Framework-Specific Implementation

The same Figma component properties translate naturally across frameworks. Here's how a button component with well-named props looks in different ecosystems:

Figma UI Component Properties

Component property mapping between Figma and code

Above Figma button component properties map directly to props in React, Vue, Angular, and Svelte with minimal adjustments for framework syntax. This consistency reduces cognitive load for developers and help them implement components faster and with fewer errors.

 /// React (TypeScript)

interface ButtonProps {
  label: string;
  size?: 'small' | 'medium' | 'large';
  type?: 'primary' | 'secondary' | 'tertiary';
  isLoading?: boolean;
  isDisabled?: boolean;
  endIcon?: React.ReactNode;
  startIcon?: React.ReactNode;
  onClick?: () => void;
}


// Usage

<Button 
  label="Click me" 
  type="primary" 
  size="medium"
  isDisabled={false}
  startIcon={<WestRoundedIcon />}
  onClick={() => { /* handle click */ }}
/>
                  
 /// Vue 3 (TypeScript)

interface ButtonProps {
  label: string;
  type?: 'primary' | 'secondary' | 'tertiary';
  size?: 'small' | 'medium' | 'large';
  isDisabled?: boolean;
  isLoading?: boolean;
  startIcon?: Component;
  endIcon?: Component;
}


// Usage

<Button 
  label="Click me" 
  type="primary" 
  size="medium"
  :is-disabled="false"
  :start-icon="ArrowLeft"
  @click="handleClick"
/>
                  
 /// Angular (TypeScript)

@Component({
  selector: 'app-button',
  template: ''
})
export class ButtonComponent {
  @Input() label!: string;
  @Input() type?: 'primary' | 'secondary' | 'tertiary' = 'primary';
  @Input() size?: 'small' | 'medium' | 'large' = 'medium';
  @Input() isDisabled?: boolean = false;
  @Input() isLoading?: boolean = false;
  @Input() startIcon?: TemplateRef<any>;
  @Input() endIcon?: TemplateRef<any>;
  @Output() onClick = new EventEmitter<void>();
}


// Usage

<app-button 
  label="Click me" 
  type="primary" 
  size="medium"
  [isDisabled]="false"
  [startIcon]="arrowLeftTemplate"
  (onClick)="handleClick()"
/>
                  
 /// Svelte (TypeScript)

<script lang="ts">
  export let label: string;
  export let type: 'primary' | 'secondary' | 'tertiary' = 'primary';
  export let size: 'small' | 'medium' | 'large' = 'medium';
  export let isDisabled: boolean = false;
  export let isLoading: boolean = false;
  export let startIcon: Component | undefined = undefined;
  export let endIcon: Component | undefined = undefined;
</script>


// Usage

<Button 
  label="Click me" 
  type="primary" 
  size="medium"
  isDisabled={false}
  startIcon={ArrowLeft}
  on:click={handleClick}
/>
                  

As we can see, the same well-defined properties in Figma translate cleanly to props in React, Vue, Angular, and Svelte. This consistency not only speeds up development but also reduces the likelihood of miscommunication or errors during implementation. By investing time in defining clear, js-friendly component properties in Figma, we set the stage for a smoother handoff to developers and a more efficient development process overall.

2.6 Tokenization

--color-primary-600--spacing-4--font-family-sans--radius-md

Sample design tokens which point to a color hex value (#0D99FF), spacing in pixels (16px), font family (Space Grotesk), and border radius (8px).

Modern digital products require theme support (light mode, dark mode, high contrast). This necessitates tokenization, using variables instead of hard-coded values. Besides that, using tokens instead of fixed values also enables scalability and consistency across the design system. For example, if your brand color changes, updating a single token updates it everywhere. As designers, we often hear new iteration ideas from stakeholders. Using tokens allows us to implement changes quickly without redesigning every component.

From Hard-Coded Values to Design Tokens

If you are using CSS or CSS-in-JS, design tokens are typically implemented as CSS variables (custom properties). You need to create your own primitive and component tokens. If you want to skip the creating primitive tokens, it's best to use an existing open-source token library like TailwindCSS. Tailwind provides a comprehensive set of design tokens that cover colors, spacing, typography, and more. You can then create component-specific tokens that reference these primitives. For example, a button's primary background color token might reference Tailwind's `--tw-color-blue-600`. Here is an example of how to transition from old way to modern way:

/// Old approach (hard-coded values)

🟥 Color: "#0D99FF" (specific hex value)
🟥 Spacing: "16px" (specific pixel value)
🟥 Font: "Inter" (specific typeface)
🟥 Border radius: "8px" (specific value)
/// Modern approach (design tokens)

🟩 Color: "--color-primary-600" → resolves to "#0D99FF" in light mode, "#3B82F6" in dark mode
🟩 Spacing: "--spacing-4" → resolves to "16px" (or "1rem" in fluid systems)
🟩 Font: "--font-family-sans" → resolves to "Inter, system-ui, sans-serif"
🟩 Border radius: "--radius-md" → resolves to "8px"

Benefits of Tokenization

  • Easy theme switching: Change entire color schemes by swapping variable collections
  • Consistent design: All components reference the same token system, eliminating one-off values
  • Simplified maintenance: Update a token once, change it everywhere
  • Developer alignment: Design tokens map directly to CSS custom properties
  • Accessibility compliance: Manage contrast ratios systematically
  • Brand flexibility: Support white-label products or multi-brand systems

2.7 Implementing Tokens in Figma

Figma's Local Variables feature enables comprehensive tokenization:

2.8 Implementing Tokens in Figma

Our goal was to improve account security with an additional layer of authentication—without creating friction or drop-off in user experience. We needed a solution that served both our individual (B2C) users and our enterprise clients with scalable and customizable options.

Table of Contents

Introduction1. Understanding Components and Properties1.1. The Universal Component Model1.2. What is a Property?2. The Fundamentals of JS-Friendly Components2.1 Structure & Naming2.2 Using Proper Auto-Layout with Frames in Figma2.3 Example: Button Component Structure2.4 Giving Meaningful Layer Names2.5 Component Properties in Figma2.6 Tokenization2.7 Implementing Tokens in Figma