Component Modeling

The anatomy and physiology of a component

What is a component model?

A component model defines the architecture required to build a component. A model requires feature data properties, style properties, layout definition, and rules for how the component accepts and handles that data.

Modeling is especially critical when working with dynamic content, authorization permissions, and features that roll out over multiple stages. Component leveling helps separate areas that only use style data, and areas that hold stateful data.

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Does this relate to Atomic Design?

Absolutely — but it’s not the same thing. The model above uses an “atomic” approach, but data isn't always defined within atomic levels.

Atomic Design and this framework are logical approaches to use in tandem.

The role of the designer in component modeling.

Data models aren’t always thought of as a designer’s responsibility, but that couldn’t be further from the truth. Components handle everything rendered to the DOM, and designers must account for how that data needs to be rendered.

Starting to design by modeling a component helps account for all feature rules and data required — and can help identify any holes in the delivered feature requirements.

The role of the engineer in component modeling.

Ultimately, engineers are building components and need complete design requirements. Engineers and designers don’t work in identical workflows and that needs to be accounted for when developing handoff processes.

Engineers often work with design deliveries in the confines of a sprint. This workflow may mean an engineer is only looking at the data required within the context of their assigned ticket and isn’t privy to the full scope of a component’s potential behavior across the product.



Because systems are living ecosystems, component data may be forward-looking, only relevant in specific contexts, and accounts for interactions between a collection of components.

When building components, the delivered component must include all possible data the design system has defined. When an instance of that component is required, engineers can draw from the requirements for the current context.

modeling basics

Modeling walkthrough

I like to use the Button component when illustrating modeling logic because it’s an easy component for almost everyone to understand.

Button architecture from left to right

This is how I built the button component. The structure here shows the leveled breakdown of data definition.

BUTTON/Button Elements/Base/Button Text

  • Text styles. These should reference a token system, or at least, a style library.

BUTTON/Button Elements/Base Buttons

  • All sizes are inherited
  • Content — icons are optional and set here using a boolean component property
  • Spacing — three spacing options (Default, Dense, Hugged) are defined

BUTTON/Button Elements/Semantic

  • Content and Spacing is inherited
  • All button data is accounted for within this level

Logic rules accounted for in this approach

Sizing

In this case, we have 3 sizes which we can name “small, medium, large” at the base level. Once the button is at a contextual level, naming needs to be more specific to the application. For example, buttons may be named “default, small, and large.”

When adding button sizes we don’t have to think of the contextual application when modifying base components. We can add “extra small,” for example. This also allows us to define different contextual rules in different areas of the application. What is “default” in one system level area may be different than another.

Scaling

Sizing is handled by the text’s rem value. The rem value means little on its own, but the value is set with the understanding that sizing rules built in subsequent layers will use sizing values relative to those rem values.

Padding set in a value relative to the text’s rem value means that the padding value only needs to be defined in one place. If the padding value needs to be edited, only one area of the rule needs to be targeted. A system could easily add more button sizes and only need to declare that size in the text size’s value.

Assets panel breakdown

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top-level folder and expand the nested folders to see what the component is comprised of.

primary button component — system level component

In this example, we’re using the Primary Button component. There are 3 sizes, styled states, and the option to have the button span the full width of its container. While it’s possible to exclude full width as a property and control the width behavior when applying the component, adding the property in the button component gives us the ability to identify a clear product rule that we can declare when the component is applied.

properties panel

These are the properties we need to select from when applying the component. We’ll also want to determine the button’s content (icon, icon placement) and whether or not we want the default spacing value or another value we’ve declared a level down. To declare values within the nested component, we just need to click into those layers and set what’s required.

layers and properties

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top level folder and expand the nested folders to see what the component is comprised of.

Levels breakdown

Figma has some amazing features that you can take advantage of to build nested components. While Figma is many organizations’ tools of choice at the moment, the logic behind this approach isn’t confined to any application.

Why is there a need for this much detail?

The system architecture logic behind these requirements is key to building a scalable system that avoids declaring current product patterns and styles within its foundational architecture.

scaling

Scaling always needs to be considered when building systems. A system, by design, needs to be a living ecosystem that can change to meet product and business requirements.

Framework architecture

Identifying which parts of a system can be accounted for in a universal framework simplifies which properties are unique to the product's design system.

Lean

Maintaining a product's system is much simpler when the framework properties are set and tucked away in dedicated sections.

  • Documentation is simpler to define and understand
  • Architecture rules are in place for when new components or variants
  • Designers working from the system aren't required to manipulate areas that could break the system

Component Levels

base

Props apply to all variants of a component.

jump to section
semantic

Boilerplate design system components that aren’t unique to the product.

jump to section

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Does this relate to Atomic Design?

Absolutely — but it’s not the same thing. The model above uses an “atomic” approach, but data isn't always defined within atomic levels.

Atomic Design and this framework are logical approaches to use in tandem.

The role of the designer in component modeling.

Data models aren’t always thought of as a designer’s responsibility, but that couldn’t be further from the truth. Components handle everything rendered to the DOM, and designers must account for how that data needs to be rendered.

Starting to design by modeling a component helps account for all feature rules and data required — and can help identify any holes in the delivered feature requirements.

The role of the engineer in component modeling.

Ultimately, engineers are building components and need complete design requirements. Engineers and designers don’t work in identical workflows and that needs to be accounted for when developing handoff processes.

Engineers often work with design deliveries in the confines of a sprint. This workflow may mean an engineer is only looking at the data required within the context of their assigned ticket and isn’t privy to the full scope of a component’s potential behavior across the product.



Because systems are living ecosystems, component data may be forward-looking, only relevant in specific contexts, and accounts for interactions between a collection of components.

When building components, the delivered component must include all possible data the design system has defined. When an instance of that component is required, engineers can draw from the requirements for the current context.

Assets panel breakdown

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top-level folder and expand the nested folders to see what the component is comprised of.

primary button component — system level component

In this example, we’re using the Primary Button component. There are 3 sizes, styled states, and the option to have the button span the full width of its container. While it’s possible to exclude full width as a property and control the width behavior when applying the component, adding the property in the button component gives us the ability to identify a clear product rule that we can declare when the component is applied.

properties panel

These are the properties we need to select from when applying the component. We’ll also want to determine the button’s content (icon, icon placement) and whether or not we want the default spacing value or another value we’ve declared a level down. To declare values within the nested component, we just need to click into those layers and set what’s required.

layers and properties

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top level folder and expand the nested folders to see what the component is comprised of.

Levels breakdown

Figma has some amazing features that you can take advantage of to build nested components. While Figma is many organizations’ tools of choice at the moment, the logic behind this approach isn’t confined to any application.

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Does this relate to Atomic Design?

Absolutely — but it’s not the same thing. The model above uses an “atomic” approach, but data isn't always defined within atomic levels.

Atomic Design and this framework are logical approaches to use in tandem.

The role of the designer in component modeling.

Data models aren’t always thought of as a designer’s responsibility, but that couldn’t be further from the truth. Components handle everything rendered to the DOM, and designers must account for how that data needs to be rendered.

Starting to design by modeling a component helps account for all feature rules and data required — and can help identify any holes in the delivered feature requirements.

The role of the engineer in component modeling.

Ultimately, engineers are building components and need complete design requirements. Engineers and designers don’t work in identical workflows and that needs to be accounted for when developing handoff processes.

Engineers often work with design deliveries in the confines of a sprint. This workflow may mean an engineer is only looking at the data required within the context of their assigned ticket and isn’t privy to the full scope of a component’s potential behavior across the product.



Because systems are living ecosystems, component data may be forward-looking, only relevant in specific contexts, and accounts for interactions between a collection of components.

When building components, the delivered component must include all possible data the design system has defined. When an instance of that component is required, engineers can draw from the requirements for the current context.

modeling basics

Modeling walkthrough

I like to use the Button component when illustrating modeling logic because it’s an easy component for almost everyone to understand.

Button architecture from left to right

This is how I built the button component. The structure here shows the leveled breakdown of data definition.

BUTTON/Button Elements/Base/Button Text

  • Text styles. These should reference a token system, or at least, a style library.

BUTTON/Button Elements/Base Buttons

  • All sizes are inherited
  • Content — icons are optional and set here using a boolean component property
  • Spacing — three spacing options (Default, Dense, Hugged) are defined

BUTTON/Button Elements/Semantic

  • Content and Spacing is inherited
  • All button data is accounted for within this level
Assets panel breakdown

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top-level folder and expand the nested folders to see what the component is comprised of.

primary button component — system level component

In this example, we’re using the Primary Button component. There are 3 sizes, styled states, and the option to have the button span the full width of its container. While it’s possible to exclude full width as a property and control the width behavior when applying the component, adding the property in the button component gives us the ability to identify a clear product rule that we can declare when the component is applied.

properties panel

These are the properties we need to select from when applying the component. We’ll also want to determine the button’s content (icon, icon placement) and whether or not we want the default spacing value or another value we’ve declared a level down. To declare values within the nested component, we just need to click into those layers and set what’s required.

layers and properties

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top level folder and expand the nested folders to see what the component is comprised of.

Why is there a need for this much detail?

The system architecture logic behind these requirements is key to building a scalable system that avoids declaring current product patterns and styles within its foundational architecture.

scaling

Scaling always needs to be considered when building systems. A system, by design, needs to be a living ecosystem that can change to meet product and business requirements.

Framework architecture

Identifying which parts of a system can be accounted for in a universal framework simplifies which properties are unique to the product's design system.

Lean

Maintaining a product's system is much simpler when the framework properties are set and tucked away in dedicated sections.

  • Documentation is simpler to define and understand
  • Architecture rules are in place for when new components or variants
  • Designers working from the system aren't required to manipulate areas that could break the system

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Component Levels

base

Props apply to all variants of a component.

semantic

Boilerplate design system components that aren’t unique to the product.

system

Contextual components that include system patterns and styles

ramp

Style libraries defined for the application. These are based on brand or product standards.

token

Style libraries defined for the application. These are based on brand or product standards.

Does this relate to Atomic Design?

Absolutely — but it’s not the same thing. The model above uses an “atomic” approach, but data isn't always defined within atomic levels.

Atomic Design and this framework are logical approaches to use in tandem.

The role of the designer in component modeling.

Data models aren’t always thought of as a designer’s responsibility, but that couldn’t be further from the truth. Components handle everything rendered to the DOM, and designers must account for how that data needs to be rendered.

Starting to design by modeling a component helps account for all feature rules and data required — and can help identify any holes in the delivered feature requirements.

The role of the engineer in component modeling.

Ultimately, engineers are building components and need complete design requirements. Engineers and designers don’t work in identical workflows and that needs to be accounted for when developing handoff processes.

Engineers often work with design deliveries in the confines of a sprint. This workflow may mean an engineer is only looking at the data required within the context of their assigned ticket and isn’t privy to the full scope of a component’s potential behavior across the product.



Because systems are living ecosystems, component data may be forward-looking, only relevant in specific contexts, and accounts for interactions between a collection of components.

When building components, the delivered component must include all possible data the design system has defined. When an instance of that component is required, engineers can draw from the requirements for the current context.

modeling basics

Modeling walkthrough

I like to use the Button component when illustrating modeling logic because it’s an easy component for almost everyone to understand.

Button architecture from left to right

This is how I built the button component. The structure here shows the leveled breakdown of data definition.

BUTTON/Button Elements/Base/Button Text

  • Text styles. These should reference a token system, or at least, a style library.

BUTTON/Button Elements/Base Buttons

  • All sizes are inherited
  • Content — icons are optional and set here using a boolean component property
  • Spacing — three spacing options (Default, Dense, Hugged) are defined

BUTTON/Button Elements/Semantic

  • Content and Spacing is inherited
  • All button data is accounted for within this level

Logic rules accounted for in this approach

Sizing

In this case, we have 3 sizes which we can name “small, medium, large” at the base level. Once the button is at a contextual level, naming needs to be more specific to the application. For example, buttons may be named “default, small, and large.”

When adding button sizes we don’t have to think of the contextual application when modifying base components. We can add “extra small,” for example. This also allows us to define different contextual rules in different areas of the application. What is “default” in one system level area may be different than another.

Scaling

Sizing is handled by the text’s rem value. The rem value means little on its own, but the value is set with the understanding that sizing rules built in subsequent layers will use sizing values relative to those rem values.

Padding set in a value relative to the text’s rem value means that the padding value only needs to be defined in one place. If the padding value needs to be edited, only one area of the rule needs to be targeted. A system could easily add more button sizes and only need to declare that size in the text size’s value.

Levels breakdown

Figma has some amazing features that you can take advantage of to build nested components. While Figma is many organizations’ tools of choice at the moment, the logic behind this approach isn’t confined to any application.

Assets panel breakdown

Slash naming convention lets you nest your component levels into neatly organized folders. You can pull a component from the top-level folder and expand the nested folders to see what the component is comprised of.

primary button component — system level component

In this example, we’re using the Primary Button component. There are 3 sizes, styled states, and the option to have the button span the full width of its container. While it’s possible to exclude full width as a property and control the width behavior when applying the component, adding the property in the button component gives us the ability to identify a clear product rule that we can declare when the component is applied.

properties panel

These are the properties we need to select from when applying the component. We’ll also want to determine the button’s content (icon, icon placement) and whether or not we want the default spacing value or another value we’ve declared a level down. To declare values within the nested component, we just need to click into those layers and set what’s required.

Why is there a need for this much detail?

The system architecture logic behind these requirements is key to building a scalable system that avoids declaring current product patterns and styles within its foundational architecture.

scaling

Scaling always needs to be considered when building systems. A system, by design, needs to be a living ecosystem that can change to meet product and business requirements.

Framework architecture

Identifying which parts of a system can be accounted for in a universal framework simplifies which properties are unique to the product's design system.

Lean

Maintaining a product's system is much simpler when the framework properties are set and tucked away in dedicated sections.

  • Documentation is simpler to define and understand
  • Architecture rules are in place for when new components or variants
  • Designers working from the system aren't required to manipulate areas that could break the system

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Button architecture from left to right

This is how I built the button component. The structure here shows the leveled breakdown of data definition.

BUTTON/Button Elements/Base/Button Text

  • Text styles. These should reference a token system, or at least, a style library.

BUTTON/Button Elements/Base Buttons

  • All sizes are inherited
  • Content — icons are optional and set here using a boolean component property
  • Spacing — three spacing options (Default, Dense, Hugged) are defined

BUTTON/Button Elements/Semantic

  • Content and Spacing is inherited
  • All button data is accounted for within this level

Component Model Framework

This is a model I built to show the levels and corresponding data required to define each component within a system. The nesting organization is fundamental to building scalable components and standardized architecture.

The product level is the result of the model and is the component rendered to the DOM. When modifying features or product UX, the product level is the affected outcome regardless of which level(s) within the model have been modified.

Logic rules accounted for in this approach

Sizing

In this case, we have 3 sizes which we can name “small, medium, large” at the base level. Once the button is at a contextual level, naming needs to be more specific to the application. For example, buttons may be named “default, small, and large.”

When adding button sizes we don’t have to think of the contextual application when modifying base components. We can add “extra small,” for example. This also allows us to define different contextual rules in different areas of the application. What is “default” in one system level area may be different than another.

Scaling

Sizing is handled by the text’s rem value. The rem value means little on its own, but the value is set with the understanding that sizing rules built in subsequent layers will use sizing values relative to those rem values.

Padding set in a value relative to the text’s rem value means that the padding value only needs to be defined in one place. If the padding value needs to be edited, only one area of the rule needs to be targeted. A system could easily add more button sizes and only need to declare that size in the text size’s value.

Levels breakdown

Figma has some amazing features that you can take advantage of to build nested components. While Figma is many organizations’ tools of choice at the moment, the logic behind this approach isn’t confined to any application.

Project Recap

A model provides a consistent approach to follow. Modeling helps to standardize system design and facilitates asynchronous design across a design team.

Having a model as a guide eliminates the cognitive load of needing to think of every component as a unique model. With a model established, we can know the parts of a component that are required before a component is required for our system.