Files
pos-system/microservices/.agent/skills/pencil-design/references/ATOMIC_DESIGN.md
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

15 KiB

Atomic Design Architecture Reference

Enterprise-scale UI Kit organization using Atomic Design methodology for Pencil.

Overview

Problem: Large monolithic .pen files (5000+ lines) cause:

  • Slow performance (2-3 second load times)
  • Maintenance challenges (duplicate components)
  • Collaboration bottlenecks (merge conflicts)
  • Poor reusability
  • Difficult to scale for enterprise applications

Solution: Atomic Design Hierarchy - Industry standard for enterprise UI Kits

Atomic Design Structure

project-name/
├── src/
│   ├── foundations/
│   │   └── design-tokens.pen           # Design system variables
│   │
│   ├── atoms/                          # Smallest building blocks
│   │   ├── buttons.pen                 # All button variants & states
│   │   ├── inputs.pen                  # Text fields, checkboxes, radio
│   │   ├── badges.pen                  # Badges, chips, pills, tags
│   │   ├── icons.pen                   # Icon library (if custom)
│   │   └── typography.pen              # Headings, body text, labels
│   │
│   ├── molecules/                      # Combinations of atoms
│   │   ├── form-fields.pen             # Label + Input + Error
│   │   ├── search-bar.pen              # Input + Icon + Button
│   │   ├── card-headers.pen            # Icon + Title + Badge
│   │   └── navigation-items.pen        # Icon + Text + Badge
│   │
│   ├── organisms/                      # Complex UI sections
│   │   ├── cards.pen                   # Feature, pricing, step cards
│   │   ├── navigation.pen              # Top nav, sidebar, mobile menu
│   │   ├── headers.pen                 # Page & section headers
│   │   ├── footers.pen                 # Footer variants
│   │   └── forms.pen                   # Complete form layouts
│   │
│   ├── templates/                      # Page layouts (optional)
│   │   ├── dashboard-layout.pen
│   │   ├── landing-layout.pen
│   │   └── auth-layout.pen
│   │
│   └── pages/                          # Complete pages
│       ├── desktop-home.pen
│       ├── mobile-home.pen
│       └── tablet-home.pen
│
├── build/                              # Build output (gitignore)
├── scripts/
│   └── build.py                        # Build script
├── pencil.config.json
└── USAGE_GUIDE.md

Why Atomic Design?

Benefits

  • Industry Standard - Used by Figma, Material Design, Ant Design
  • Maximum Scalability - Easy to add components at any level
  • Clear Hierarchy - Atoms → Molecules → Organisms → Templates → Pages
  • Team Collaboration - Different designers own different atomic levels
  • Reusability - Components compose naturally from smaller pieces
  • Discoverability - Intuitive folder structure for finding components
  • Maintainability - Small, focused files (<500 lines each)
  • Version Control - Minimal merge conflicts with parallel work
  • Enterprise applications with 50+ components
  • Design systems shared across multiple products
  • Teams of 3+ designers working in parallel
  • Long-term maintenance (2+ years)
  • Component documentation & showcases
  • Cross-platform design consistency

Component Naming Convention

Atomic Design uses strict hierarchical naming:

{AtomicLevel}/{Component}/{Variant}/{State}

Atoms (Smallest Building Blocks)

Atom/Button/Primary/Default
Atom/Button/Primary/Hover
Atom/Button/Primary/Disabled
Atom/Button/Secondary/Default
Atom/Badge/Section/Default
Atom/Input/Text/Default
Atom/Input/Text/Error
Atom/Input/Text/Disabled

Molecules (Combinations of Atoms)

Molecule/FormField/Text/Default
Molecule/FormField/Text/WithError
Molecule/SearchBar/Default
Molecule/SearchBar/Focused
Molecule/CardHeader/WithIcon
Molecule/CardHeader/Plain

Organisms (Complex UI Sections)

Organism/Card/Feature/Default
Organism/Card/Pricing/Enterprise
Organism/Navigation/Desktop/Default
Organism/Navigation/Mobile/Collapsed
Organism/Navigation/Mobile/Expanded
Organism/Footer/TwoColumn/Default
Organism/Footer/FourColumn/Default

Naming Rules

  1. Always include atomic level (Atom/Molecule/Organism)
  2. Use PascalCase for all parts
  3. Include variant even if only one exists (use "Default")
  4. Add state for interactive components (Default/Hover/Active/Focus/Disabled/Loading)
  5. Be descriptive - Name should explain purpose without seeing component

Component States & Variants

Interactive Component States

Every interactive component should have states:

Button/Primary/
├── Default        # Resting state
├── Hover          # Mouse over
├── Active         # Pressed/clicked
├── Focus          # Keyboard focus
├── Disabled       # Non-interactive
└── Loading        # Processing state (with spinner)

Implementation Example

// Default state
{
  "type": "frame",
  "id": "BtnPrimary_Default",
  "name": "Atom/Button/Primary/Default",
  "reusable": true,
  "fill": {
    "type": "gradient",
    "colors": [
      {"color": "#FF5C00", "position": 0},
      {"color": "#FF8A4C", "position": 1}
    ]
  }
}

// Hover state - slightly brighter
{
  "type": "frame",
  "id": "BtnPrimary_Hover",
  "name": "Atom/Button/Primary/Hover",
  "reusable": true,
  "fill": {
    "type": "gradient",
    "colors": [
      {"color": "#FF6E1A", "position": 0},
      {"color": "#FF9C66", "position": 1}
    ]
  }
}

// Disabled state - reduced opacity
{
  "type": "frame",
  "id": "BtnPrimary_Disabled",
  "name": "Atom/Button/Primary/Disabled",
  "reusable": true,
  "fill": "#6B6B70",
  "opacity": 0.5
}

Responsive Variants

Organism/Navigation/
├── Desktop/
│   ├── Default        # Full horizontal nav with all items
│   └── Scrolled       # Sticky/collapsed on scroll
├── Tablet/
│   ├── Default        # Hybrid with some collapsed items
│   └── MenuOpen       # Sidebar drawer
└── Mobile/
    ├── Collapsed      # Hamburger icon only
    └── Expanded       # Full-screen menu overlay

Design Tokens Foundation

design-tokens.pen Structure

{
  "version": "2.6",
  "children": [{
    "type": "frame",
    "name": "Design Tokens Reference",
    "layout": "vertical",
    "gap": 20,
    "children": [
      {
        "type": "text",
        "content": "Design System Tokens",
        "fontSize": 32,
        "fill": "$text-primary"
      }
    ]
  }],
  "variables": {
    // Colors - Semantic naming
    "bg-page": {"type": "color", "value": "#0A0A0B"},
    "bg-surface": {"type": "color", "value": "#1A1A1C"},
    "bg-elevated": {"type": "color", "value": "#222225"},
    "text-primary": {"type": "color", "value": "#FFFFFF"},
    "text-secondary": {"type": "color", "value": "#ADADB0"},
    "text-tertiary": {"type": "color", "value": "#8B8B90"},
    "orange-primary": {"type": "color", "value": "#FF5C00"},
    "orange-light": {"type": "color", "value": "#FF8A4C"},
    "border-default": {"type": "color", "value": "#3B3B40"},
    "border-subtle": {"type": "color", "value": "#27272A"},
    
    // Typography
    "font-primary": {"type": "string", "value": "Roboto"},
    "text-xs": {"type": "number", "value": 11},
    "text-sm": {"type": "number", "value": 13},
    "text-base": {"type": "number", "value": 14},
    "text-lg": {"type": "number", "value": 16},
    "text-xl": {"type": "number", "value": 18},
    "text-2xl": {"type": "number", "value": 24},
    "text-3xl": {"type": "number", "value": 32},
    
    // Spacing (8px grid)
    "space-1": {"type": "number", "value": 4},
    "space-2": {"type": "number", "value": 8},
    "space-3": {"type": "number", "value": 12},
    "space-4": {"type": "number", "value": 16},
    "space-5": {"type": "number", "value": 20},
    "space-6": {"type": "number", "value": 24},
    "space-8": {"type": "number", "value": 32},
    "space-10": {"type": "number", "value": 40},
    
    // Border Radius
    "radius-sm": {"type": "number", "value": 6},
    "radius-md": {"type": "number", "value": 10},
    "radius-lg": {"type": "number", "value": 16},
    "radius-full": {"type": "number", "value": 100},
    
    // Breakpoints
    "breakpoint-mobile": {"type": "number", "value": 390},
    "breakpoint-tablet": {"type": "number", "value": 768},
    "breakpoint-desktop": {"type": "number", "value": 1440}
  }
}

Extraction Workflow

Step 1: Audit Components

# Analyze current structure
grep '"name":' tPOS-ui-kit.pen | grep -i "button" > buttons-list.txt
grep '"name":' tPOS-ui-kit.pen | grep -i "badge" > badges-list.txt
grep '"name":' tPOS-ui-kit.pen | grep -i "card" > cards-list.txt

# Count components by category
echo "Buttons: $(grep -c button buttons-list.txt)"
echo "Badges: $(grep -c badge badges-list.txt)"
echo "Cards: $(grep -c card cards-list.txt)"

Step 2: Create Structure

mkdir -p src/foundations src/atoms src/molecules src/organisms src/pages

Step 3: Extract to Atomic Files

The pencil-design skill now includes an automated extraction tool.

# Run the extraction script
python3 scripts/extract-atomic.py

This script will:

  1. Read src/components/tPOS-ui-kit.pen (or configured library)
  2. Extract design tokens to src/foundations/design-tokens.pen
  3. Categorize components into src/atoms, src/molecules, src/organisms
  4. Generate showcase wrappers for each file

Customization: Edit scripts/extract-atomic.py to adjust categorization logic (regex patterns) if your component names differ.

Step 4: Create Showcase Files

import json
from pathlib import Path

for atomic_dir in ['src/atoms', 'src/molecules', 'src/organisms']:
    for filepath in Path(atomic_dir).glob('*.pen'):
        with open(filepath, 'r') as f:
            data = json.load(f)
        
        # Wrap components in a showcase page
        showcase = {
            'type': 'frame',
            'name': f'{filepath.stem.title()} Showcase',
            'width': 1440,
            'fill': '$bg-page',
            'layout': 'vertical',
            'gap': 80,
            'padding': [80, 120],
            'children': data['children']
        }
        
        data['children'] = [showcase]
        
        with open(filepath, 'w') as f:
            json.dump(data, f, indent=2)
        
        print(f'✅ Added showcase to {filepath}')

Step 5: Validate Structure

import json
import os
from pathlib import Path

required_structure = [
    'src/foundations/design-tokens.pen',
    'src/atoms',
    'src/molecules',
    'src/organisms'
]

for path in required_structure:
    if not os.path.exists(path):
        print(f'❌ Missing: {path}')
    else:
        if path.endswith('.pen'):
            with open(path, 'r') as f:
                data = json.load(f)
            assert 'version' in data
            assert 'variables' in data
            print(f'✅ Valid: {path}')
        else:
            files = list(Path(path).glob('*.pen'))
            print(f'✅ {path}: {len(files)} files')

print('\n🎉 Atomic Design structure validated!')

Best Practices

  1. Foundations First - Design tokens (design-tokens.pen) is single source of truth
  2. Build Bottom-Up - Atoms → Molecules → Organisms → Templates → Pages
  3. Component States - Every interactive component needs ≥3 states (default/hover/disabled)
  4. Naming Consistency - Strict format: {Level}/{Component}/{Variant}/{State}
  5. File Organization - Each atomic level in separate folder (src/atoms/, src/molecules/)
  6. Token Synchronization - Copy variables object from design-tokens.pen to all files
  7. Showcase Pages - Each atomic file needs showcase page to demo components
  8. No Cross-Contamination - Atoms don't reference molecules, molecules don't reference organisms
  9. Reusable Flag - Set "reusable": true for all reusable components
  10. Responsive Variants - Create variants for Desktop/Tablet/Mobile (not breakpoint logic in Pencil)
  11. Documentation - Document component props, states, usage in USAGE_GUIDE.md
  12. Version Control:
    • Commit: src/ (all atomic files)
    • Gitignore: build/ (generated files)
    • Tag releases: v1.0.0 for breaking changes in design tokens
  13. Component Library - Update atomic files before building pages
  14. Validation - Validate JSON structure after extraction
  15. Backup Strategy - Keep original.pen.backup before refactoring to Atomic Design

Usage Guide Template

# [Project] Design System - Atomic Design Structure

## Structure Overview

\`\`\`
src/
├── foundations/
│   └── design-tokens.pen    # Colors, typography, spacing, breakpoints
├── atoms/                   # Smallest building blocks
├── molecules/               # Simple combinations
├── organisms/               # Complex components
└── pages/                   # Complete pages
\`\`\`

## Atomic Levels

### Foundations
- **File**: `design-tokens.pen`
- **Contains**: CSS variables, color palette, typography scale, spacing system
- **Usage**: Copy variables to all component files

### Atoms
- **Examples**: Buttons, inputs, badges, icons, typography
- **Characteristics**: Cannot be broken down further
- **States**: Default, Hover, Active, Disabled

### Molecules
- **Examples**: Form fields, search bars, card headers
- **Characteristics**: Combinations of 2-3 atoms
- **Usage**: Import atoms and compose

### Organisms
- **Examples**: Cards, navigation, headers, footers
- **Characteristics**: Complex sections with multiple molecules
- **Usage**: Complete, reusable UI sections

## Workflow

1. **Update Foundation**: Edit `design-tokens.pen` for colors/typography changes
2. **Build Components**: Edit atomic files with proper naming (Atom/Button/Primary/Default)
3. **Update Library**: Run `python3 scripts/build.py --library` to compile atoms
4. **Compose Up**: Molecules use atoms, organisms use molecules
5. **Test in Pages**: Reference components in page files (from compiled library)
6. **Build Monolith**: Run `python3 scripts/build.py -m` for production output

## Component Naming

\`\`\`
{Level}/{Component}/{Variant}/{State}

Examples:
- Atom/Button/Primary/Default
- Molecule/FormField/Text/WithError
- Organism/Card/Feature/Default
\`\`\`

## Best Practices

1.**Design Tokens First**: Always update foundation before components
2.**Build Up**: Atoms → Molecules → Organisms → Pages
3.**Consistent States**: All interactive components need states
4.**Reusable**: Set `"reusable": true` on all shareable components
5.**Version Control**: Commit src/ files, gitignore build/

Resources