Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

This component is an example of Atomic Design composition. The Button molecule is built from smaller atoms (Icon and Label) and receives its behavior and appearance through props.

Imports​

import type { ButtonInterface } from './Button.interface'

Imports the TypeScript interface that defines the props the component accepts.

import { ButtonSizes, ButtonTypes, IconSizes, LabelTypes } from '@/components/_types_'

Imports enums that provide predefined values for button types, sizes, icon sizes, and label types. Using enums prevents invalid values and improves consistency.

import { Icon, Label } from '@/components/atoms'

Imports two atomic components used to build the button.


Component Definition​

const Button = ({ testID, type, size, icon, text, action, disabled }: ButtonInterface) => {

The component receives its properties through destructuring.

Example:

<Button
text="Save"
icon="save"
type={ButtonTypes.PRIMARY}
size={ButtonSizes.MEDIUM}
action={saveData}
/>

Event Handler​

const __handleAction = () => action && action()

Executes the supplied callback if it exists.

Equivalent to:

if (action) {
action()
}

When the button is clicked, this function triggers the action.


Rendering the Icon​

const __renderIcon = () => icon && <Icon icon={icon} />

Conditionally renders an icon.

If:

icon="save"

it produces:

<Icon icon="save" />

If no icon is provided, nothing is rendered.


Rendering the Text​

const __renderText = () => text && <Label text={text} type={LabelTypes.BUTTON} />

Conditionally renders a label.

If:

text="Save"

it produces:

<Label text="Save" type={LabelTypes.BUTTON} />

This keeps text styling centralized inside the Label atom.


Rendering the "Next" Arrow​

const __renderNext = () => {
if (type === ButtonTypes.NEXT) {
return <Icon icon={'arrowRight'} size={IconSizes.LARGE} />
}
}

Adds an arrow icon only when the button type is NEXT.

Example:

<Button
text="Continue"
type={ButtonTypes.NEXT}
/>

Produces:

Continue →

Rendered Markup​

<div
data-testid={testID}
data-object-type={type ?? ButtonTypes.PRIMARY}
data-object-size={size ?? ButtonSizes.MEDIUM}
data-disabled={disabled ? 'true' : 'false'}
className={`Button`}
onClick={() => __handleAction()}
>

data-testid​

Used by testing frameworks:

<div data-testid="button-save">

Allows automated tests to find the element.


data-object-type​

Stores the button type.

Example:

<div data-object-type="primary">

Useful for CSS selectors or debugging.


data-object-size​

Stores the button size.

Example:

<div data-object-size="large">

Allows styling such as:

.Button[data-object-size='large'] {
padding: 1rem 2rem;
}

data-disabled​

Stores disabled state.

Example:

<div data-disabled="true">

className​

className="Button"

Provides the base CSS class.


Click Handler​

onClick={() => __handleAction()}

Calls the action when the button is clicked.

A simpler version would be:

onClick={__handleAction}

Children​

{__renderIcon()}
{__renderText()}
{__renderNext()}

The button is assembled from three optional parts:

  1. Custom icon
  2. Label text
  3. Next-arrow icon

Depending on the props, different combinations appear.


Atomic Design Classification​

ComponentAtomic LevelReason
IconAtomSmallest reusable UI element
LabelAtomSmallest reusable text element
ButtonMoleculeCombines multiple atoms into one interaction

The component demonstrates a core Atomic Design principle: compose larger UI elements from smaller reusable building blocks rather than mixing raw HTML and styling directly into higher-level components.