478 lines
15 KiB
Markdown
478 lines
15 KiB
Markdown
# 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
|
|
|
|
### Recommended For
|
|
|
|
- ✅ 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
|
|
|
|
```json
|
|
// 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
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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.
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```python
|
|
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
|
|
|
|
```python
|
|
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
|
|
|
|
```markdown
|
|
# [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
|
|
|
|
- Back to [Pencil Design Skill](../SKILL.md)
|
|
- [File Format Reference](./FILE_FORMAT.md)
|
|
- [Build System Reference](./BUILD_SYSTEM.md)
|
|
- [Code Conversion Reference](./CODE_CONVERSION.md)
|
|
- [Atomic Design Book by Brad Frost](https://atomicdesign.bradfrost.com/)
|
|
- [Material Design System](https://m3.material.io/)
|
|
- [Figma Design Systems](https://www.figma.com/best-practices/design-systems/)
|