feat: Add build system for external component references and expand documentation on Atomic Design principles and modular architecture.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
---
|
||||
name: pencil-design
|
||||
description: Pencil UI/UX design tool workflows và file format. Use for reading .pen files, extracting design content, converting designs to HTML/CSS/React/Blazor code, và understanding component systems.
|
||||
description: Pencil UI/UX design tool workflows, file format parsing, component systems, và Atomic Design Hierarchy cho enterprise UI Kits. Use for reading .pen files, extracting content, converting to code (HTML/CSS/React/Blazor), modular design workflows, và organizing large-scale design systems.
|
||||
compatibility: "Pencil 2.6+, JSON parsing"
|
||||
metadata:
|
||||
author: Velik Ho
|
||||
version: "1.0"
|
||||
references: "pencil.evolus.vn, Pencil GitHub"
|
||||
version: "2.0"
|
||||
references: "pencil.evolus.vn, Pencil GitHub, Atomic Design methodology"
|
||||
---
|
||||
|
||||
# Pencil Design Tool / Công cụ thiết kế Pencil
|
||||
@@ -44,6 +44,7 @@ metadata:
|
||||
| `ellipse` | Circle/Ellipse | `width`, `height`, `fill` |
|
||||
| `icon_font` | Icon (Lucide) | `iconFontName`, `iconFontFamily`, `fill` |
|
||||
| `ref` | Component instance | `ref` (ID), `descendants` (overrides) |
|
||||
| `component_ref` | External component reference | `component` (path), `overrides` (property overrides) |
|
||||
|
||||
### 2.3 Layout Properties
|
||||
|
||||
@@ -112,6 +113,7 @@ Components có `reusable: true` có thể được tham chiếu lại:
|
||||
|
||||
### 4.2 Component Instances (Refs)
|
||||
|
||||
**Internal refs (same file):**
|
||||
```json
|
||||
{
|
||||
"type": "ref",
|
||||
@@ -125,9 +127,116 @@ Components có `reusable: true` có thể được tham chiếu lại:
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Workflows
|
||||
**External refs (cross-file, using build system):**
|
||||
```json
|
||||
{
|
||||
"type": "component_ref",
|
||||
"component": "ui-kit#Button/Primary", // Library#ComponentPath
|
||||
"name": "myButton",
|
||||
"overrides": { // Override properties
|
||||
"q7oNn": {
|
||||
"content": "Click Me"
|
||||
}
|
||||
},
|
||||
"x": 100,
|
||||
"y": 200
|
||||
}
|
||||
```
|
||||
|
||||
### 5.1 Đọc và Phân tích Design
|
||||
> [!NOTE]
|
||||
> `component_ref` is a custom type processed by the build system. It will be converted to a proper `ref` type during build, with the component injected into the file.
|
||||
|
||||
## 5. Build System
|
||||
|
||||
### 5.1 Configuration File
|
||||
|
||||
Create `pencil.config.json` in project root:
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"sourceDir": "src",
|
||||
"buildDir": "build",
|
||||
"componentLibrary": "src/components/ui-kit.pen",
|
||||
"buildOptions": {
|
||||
"minify": false,
|
||||
"validateAfterBuild": true,
|
||||
"preserveComments": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 Build Script
|
||||
|
||||
The build system (`scripts/build.py`) supports two modes:
|
||||
|
||||
#### Monolithic Build ⭐ (Recommended)
|
||||
Merges all pages + component library into one file:
|
||||
```bash
|
||||
python3 scripts/build.py --monolithic
|
||||
# or
|
||||
python3 scripts/build.py -m
|
||||
|
||||
# Custom output
|
||||
python3 scripts/build.py -m --output myDesign.pen
|
||||
```
|
||||
|
||||
**Output:**
|
||||
- File: `tPOS.pen` (project root)
|
||||
- Contains: All pages + component library as separate frames
|
||||
- Size: ~326KB
|
||||
- Use case: Opening complete design, sharing, archiving
|
||||
|
||||
#### Standard Build
|
||||
Builds individual pages with component injection:
|
||||
```bash
|
||||
python3 scripts/build.py
|
||||
```
|
||||
|
||||
**Output:**
|
||||
- Directory: `build/`
|
||||
- Files: Separate `.pen` files with injected components
|
||||
- Use case: Development workflow, testing component refs
|
||||
|
||||
### 5.3 Build Process
|
||||
|
||||
**What the build script does:**
|
||||
1. Loads component library (`ui-kit.pen`)
|
||||
2. Extracts all reusable components and design variables
|
||||
3. Finds all `component_ref` types in page files
|
||||
4. Resolves component paths (e.g., `ui-kit#Button/Primary`)
|
||||
5. Injects component definitions into page files
|
||||
6. Converts `component_ref` → `ref` with proper IDs
|
||||
7. Validates output structure
|
||||
|
||||
**Example transformation:**
|
||||
```json
|
||||
// Before build (in source)
|
||||
{
|
||||
"type": "component_ref",
|
||||
"component": "ui-kit#Button/Primary"
|
||||
}
|
||||
|
||||
// After build (in output)
|
||||
// 1. Component injected at top of children array
|
||||
{
|
||||
"type": "frame",
|
||||
"id": "abc123",
|
||||
"name": "Button/Primary",
|
||||
"reusable": true,
|
||||
"children": [...]
|
||||
}
|
||||
|
||||
// 2. Reference converted
|
||||
{
|
||||
"type": "ref",
|
||||
"ref": "abc123",
|
||||
"descendants": {...}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Workflows
|
||||
|
||||
### 6.1 Đọc và Phân tích Design
|
||||
|
||||
```markdown
|
||||
1. Mở file .pen bằng view_file tool
|
||||
@@ -137,7 +246,7 @@ Components có `reusable: true` có thể được tham chiếu lại:
|
||||
5. List design tokens từ "variables"
|
||||
```
|
||||
|
||||
### 5.2 Extract Content
|
||||
### 6.2 Extract Content
|
||||
|
||||
```markdown
|
||||
1. Tìm tất cả elements có type "text"
|
||||
@@ -146,7 +255,7 @@ Components có `reusable: true` có thể được tham chiếu lại:
|
||||
4. Export dạng structured text hoặc JSON
|
||||
```
|
||||
|
||||
### 5.3 Design to Code Conversion
|
||||
### 6.3 Design to Code Conversion
|
||||
|
||||
**Step 1: Analyze Structure**
|
||||
```markdown
|
||||
@@ -173,7 +282,7 @@ border-radius: 10px /* cornerRadius: 10 */
|
||||
background: linear-gradient /* fill.type: "gradient" */
|
||||
```
|
||||
|
||||
### 5.4 Design System Extraction
|
||||
### 6.4 Design System Extraction
|
||||
|
||||
```markdown
|
||||
1. Extract all "variables" as CSS custom properties
|
||||
@@ -193,9 +302,30 @@ background: linear-gradient /* fill.type: "gradient" */
|
||||
}
|
||||
```
|
||||
|
||||
## 6. Common Patterns
|
||||
### 6.5 Build and Deploy Workflow
|
||||
|
||||
### 6.1 Page Structure
|
||||
**Development cycle:**
|
||||
```markdown
|
||||
1. Design in modular files:
|
||||
- Edit components in `src/components/ui-kit.pen`
|
||||
- Edit pages in `src/pages/*.pen`
|
||||
- Use `component_ref` to reference components
|
||||
|
||||
2. Build for testing:
|
||||
python3 scripts/build.py # Standard build
|
||||
# Open files in build/ to test
|
||||
|
||||
3. Build for production:
|
||||
python3 scripts/build.py -m # Monolithic
|
||||
# Share tPOS.pen with team/clients
|
||||
|
||||
4. Convert to code:
|
||||
# Use agent to convert tPOS.pen to HTML/CSS/React/Blazor
|
||||
```
|
||||
|
||||
## 7. Common Patterns
|
||||
|
||||
### 7.1 Page Structure
|
||||
|
||||
```
|
||||
Page Frame
|
||||
@@ -207,8 +337,9 @@ Page Frame
|
||||
└── Footer
|
||||
```
|
||||
|
||||
### 6.2 Component Naming Convention
|
||||
### 7.2 Component Naming Convention
|
||||
|
||||
**Traditional (Simple Projects):**
|
||||
```
|
||||
Component/{Category}/{Variant}
|
||||
- Component/Button/Primary
|
||||
@@ -217,7 +348,136 @@ Component/{Category}/{Variant}
|
||||
- Component/Card/Pricing
|
||||
```
|
||||
|
||||
### 6.3 Modular Design Architecture (Hybrid Approach)
|
||||
**Atomic Design (Enterprise):**
|
||||
```
|
||||
{AtomicLevel}/{Component}/{Variant}/{State}
|
||||
|
||||
Atoms:
|
||||
- Atom/Button/Primary/Default
|
||||
- Atom/Button/Primary/Hover
|
||||
- Atom/Button/Primary/Disabled
|
||||
- Atom/Badge/Section/Default
|
||||
- Atom/Input/Text/Default
|
||||
- Atom/Input/Text/Error
|
||||
|
||||
Molecules:
|
||||
- Molecule/FormField/Text/Default
|
||||
- Molecule/FormField/Text/WithError
|
||||
- Molecule/SearchBar/Default
|
||||
- Molecule/CardHeader/WithIcon
|
||||
|
||||
Organisms:
|
||||
- Organism/Card/Feature/Default
|
||||
- Organism/Navigation/Desktop/Default
|
||||
- Organism/Navigation/Mobile/Collapsed
|
||||
- Organism/Footer/TwoColumn/Default
|
||||
```
|
||||
|
||||
### 7.3 Component States & Variants
|
||||
|
||||
**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 in Pencil:**
|
||||
```json
|
||||
{
|
||||
"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
|
||||
}
|
||||
```
|
||||
|
||||
### 7.4 Responsive Component Variants
|
||||
|
||||
**Desktop/Tablet/Mobile patterns:**
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
**Breakpoint tokens in design-tokens.pen:**
|
||||
```json
|
||||
"variables": {
|
||||
"breakpoint-mobile": {"type": "number", "value": 390},
|
||||
"breakpoint-tablet": {"type": "number", "value": 768},
|
||||
"breakpoint-desktop": {"type": "number", "value": 1440}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 Project Structure with Build System
|
||||
|
||||
**Recommended structure:**
|
||||
```
|
||||
project-name/
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ └── ui-kit.pen # Component library + design tokens
|
||||
│ └── pages/
|
||||
│ ├── desktop-home.pen # Desktop (1440px)
|
||||
│ ├── mobile-home.pen # Mobile (390px)
|
||||
│ └── tablet-home.pen # Tablet (768px)
|
||||
├── build/ # Standard build output (gitignore)
|
||||
│ ├── desktop-home.pen # With injected components
|
||||
│ └── ...
|
||||
├── scripts/
|
||||
│ └── build.py # Build script
|
||||
├── pencil.config.json # Build configuration
|
||||
├── tPOS.pen # Monolithic build output
|
||||
└── USAGE_GUIDE.md # Documentation
|
||||
```
|
||||
|
||||
### 7.4 Modular Design Architecture (Hybrid Approach)
|
||||
|
||||
**Problem**: Large monolithic `.pen` files (5000+ lines) cause:
|
||||
- ❌ Slow performance (2-3 second load times)
|
||||
@@ -253,7 +513,7 @@ project-name/
|
||||
│ └── footer.pen
|
||||
```
|
||||
|
||||
**Option C: Hybrid** ⭐ (Recommended)
|
||||
**Option C: Hybrid** ⭐ (Recommended for Medium Projects)
|
||||
```
|
||||
project-name/
|
||||
├── components/
|
||||
@@ -265,6 +525,65 @@ project-name/
|
||||
└── USAGE_GUIDE.md # Workflow docs
|
||||
```
|
||||
|
||||
**Option D: Atomic Design Hierarchy** 🏆 (Recommended for Enterprise)
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
**Benefits of Atomic Design:**
|
||||
- ✅ **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
|
||||
|
||||
**When to use Atomic Design:**
|
||||
- ✅ Enterprise applications with 50+ components
|
||||
- ✅ Design system shared across multiple products
|
||||
- ✅ Team of 3+ designers working in parallel
|
||||
- ✅ Long-term maintenance (2+ years)
|
||||
- ✅ Need component documentation & showcases
|
||||
|
||||
#### Component Library Structure
|
||||
|
||||
**ui-kit.pen should contain:**
|
||||
@@ -419,9 +738,272 @@ Components are COPIED, not linked
|
||||
- Prototypes or wireframes
|
||||
- File < 2,000 lines
|
||||
|
||||
## 7. Best Practices
|
||||
#### Atomic Design Extraction Workflow
|
||||
|
||||
### 7.1 Khi đọc .pen files
|
||||
**For large enterprise UI Kits (2,000+ lines), convert to Atomic Design structure:**
|
||||
|
||||
**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 Atomic Structure**
|
||||
```bash
|
||||
mkdir -p src/foundations src/atoms src/molecules src/organisms src/pages
|
||||
```
|
||||
|
||||
**Step 3: Extract to Atomic Files**
|
||||
```python
|
||||
import json
|
||||
import os
|
||||
|
||||
# Read monolithic UI Kit
|
||||
with open('tPOS-ui-kit.pen', 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
variables = data['variables']
|
||||
main_page = data['children'][0] # Component Library page
|
||||
sections = main_page['children'] # All sections
|
||||
|
||||
# 1. Extract design tokens
|
||||
tokens_file = {
|
||||
'version': '2.6',
|
||||
'children': [{
|
||||
'type': 'frame',
|
||||
'name': 'Design Tokens Reference',
|
||||
'layout': 'vertical',
|
||||
'gap': 20,
|
||||
'children': [
|
||||
{
|
||||
'type': 'text',
|
||||
'name': 'Title',
|
||||
'content': 'Design System Tokens',
|
||||
'fontSize': 32,
|
||||
'fill': '$text-primary'
|
||||
}
|
||||
]
|
||||
}],
|
||||
'variables': variables
|
||||
}
|
||||
|
||||
with open('src/foundations/design-tokens.pen', 'w') as f:
|
||||
json.dump(tokens_file, f, indent=2)
|
||||
|
||||
# 2. Categorize components by atomic level
|
||||
atomic_mapping = {
|
||||
'atoms': {
|
||||
'patterns': ['button', 'badge', 'input', 'icon', 'typography', 'chip'],
|
||||
'components': []
|
||||
},
|
||||
'molecules': {
|
||||
'patterns': ['formfield', 'searchbar', 'cardheader'],
|
||||
'components': []
|
||||
},
|
||||
'organisms': {
|
||||
'patterns': ['card', 'navigation', 'header', 'footer', 'form'],
|
||||
'components': []
|
||||
}
|
||||
}
|
||||
|
||||
# Categorize each section
|
||||
for section in sections:
|
||||
section_name = section.get('name', '').lower()
|
||||
|
||||
# Determine atomic level
|
||||
matched = False
|
||||
for level, config in atomic_mapping.items():
|
||||
for pattern in config['patterns']:
|
||||
if pattern in section_name:
|
||||
config['components'].append(section)
|
||||
matched = True
|
||||
break
|
||||
if matched:
|
||||
break
|
||||
|
||||
# 3. Generate atomic files
|
||||
for level, config in atomic_mapping.items():
|
||||
if not config['components']:
|
||||
continue
|
||||
|
||||
# Group by component type
|
||||
grouped = {}
|
||||
for component in config['components']:
|
||||
name = component.get('name', '')
|
||||
# Extract type (e.g., "Buttons & Actions Section" -> "buttons")
|
||||
comp_type = name.lower().split()[0].replace('&', '').strip()
|
||||
|
||||
if comp_type not in grouped:
|
||||
grouped[comp_type] = []
|
||||
grouped[comp_type].append(component)
|
||||
|
||||
# Create file for each type
|
||||
for comp_type, components in grouped.items():
|
||||
output_file = {
|
||||
'version': '2.6',
|
||||
'children': components,
|
||||
'variables': variables
|
||||
}
|
||||
|
||||
filepath = f'src/{level}/{comp_type}.pen'
|
||||
with open(filepath, 'w') as f:
|
||||
json.dump(output_file, f, indent=2)
|
||||
|
||||
print(f'✅ Created {filepath} with {len(components)} sections')
|
||||
|
||||
print(f'\n🎉 Atomic Design structure created!')
|
||||
print(f'📁 Foundations: src/foundations/design-tokens.pen')
|
||||
print(f'⚛️ Atoms: {len(atomic_mapping["atoms"]["components"])} files')
|
||||
print(f'🧬 Molecules: {len(atomic_mapping["molecules"]["components"])} files')
|
||||
print(f'🦠 Organisms: {len(atomic_mapping["organisms"]["components"])} files')
|
||||
```
|
||||
|
||||
**Step 4: Create Showcase Files**
|
||||
|
||||
Each atomic file should have a showcase page:
|
||||
|
||||
```python
|
||||
# Add showcase page to each atomic file
|
||||
import json
|
||||
import os
|
||||
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!')
|
||||
```
|
||||
|
||||
**Step 6: Create Usage Guide**
|
||||
|
||||
Generate `USAGE_GUIDE.md`:
|
||||
|
||||
```markdown
|
||||
# tPOS 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. **Sync Tokens**: Copy `variables` object to all modified component files
|
||||
3. **Build Components**: Edit atomic files with proper naming (Atom/Button/Primary/Default)
|
||||
4. **Compose Up**: Molecules use atoms, organisms use molecules
|
||||
5. **Test in Pages**: Reference components in page files
|
||||
6. **Build**: Run `python3 scripts/build.py -m` for monolithic 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/
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## 8. Best Practices
|
||||
|
||||
### 8.1 Khi đọc .pen files
|
||||
|
||||
1. **Luôn kiểm tra `version`** - Đảm bảo compatibility
|
||||
2. **Tìm page chính** - Thường là frame có name kết thúc bằng "Page"
|
||||
@@ -429,14 +1011,23 @@ Components are COPIED, not linked
|
||||
4. **Map components** - List ra reusable components trước
|
||||
5. **Check file size** - Nếu > 300KB, consider splitting
|
||||
|
||||
### 7.2 Khi convert sang code
|
||||
### 8.2 Khi convert sang code
|
||||
|
||||
1. **Mobile-first** - Responsive breakpoints
|
||||
2. **Semantic HTML** - `<header>`, `<main>`, `<section>`, `<footer>`
|
||||
3. **CSS Variables** - Không hardcode colors
|
||||
4. **Component structure** - Match Pencil component hierarchy
|
||||
|
||||
### 7.3 Khi quản lý modular designs
|
||||
### 8.3 Khi sử dụng build system
|
||||
|
||||
1. **Use component_ref in source files** - Không hardcode components vào pages
|
||||
2. **Build before testing** - Always run build script trước khi mở trong Pencil
|
||||
3. **Monolithic for sharing** - Dùng `-m` mode khi share với người khác
|
||||
4. **Validate after build** - Check output với `jq` hoặc validation script
|
||||
5. **Version control** - Commit source files (`src/`), gitignore `build/`
|
||||
6. **Configuration consistency** - Đảm bảo `pencil.config.json` đúng paths
|
||||
|
||||
### 8.4 Khi quản lý modular designs
|
||||
|
||||
1. **Component Library First** - Always create/update `ui-kit.pen` before pages
|
||||
2. **Consistent Naming** - Use predictable names: `{breakpoint}-{feature}.pen`
|
||||
@@ -446,9 +1037,27 @@ Components are COPIED, not linked
|
||||
6. **Backup Strategy** - Keep `original.pen.backup` before major refactoring
|
||||
7. **Validation Script** - Always validate JSON structure after extraction
|
||||
|
||||
## 8. Common Mistakes / Lỗi Thường Gặp
|
||||
### 8.5 Khi sử dụng Atomic Design (Enterprise)
|
||||
|
||||
### 8.1 Bỏ qua Design Tokens
|
||||
1. **Foundations First** - Design tokens (`design-tokens.pen`) là single source of truth
|
||||
2. **Build Bottom-Up** - Atoms → Molecules → Organisms → Templates → Pages
|
||||
3. **Component States** - Mọi interactive component cần ít nhất 3 states (default/hover/disabled)
|
||||
4. **Naming Consistency** - Strict format: `{Level}/{Component}/{Variant}/{State}`
|
||||
5. **File Organization** - Mỗi atomic level trong riêng folder (`src/atoms/`, `src/molecules/`)
|
||||
6. **Token Synchronization** - Copy `variables` object từ `design-tokens.pen` vào tất cả files
|
||||
7. **Showcase Pages** - Mỗi atomic file cần có showcase page để demo components
|
||||
8. **No Cross-Contamination** - Atoms không reference molecules, molecules không reference organisms
|
||||
9. **Reusable Flag** - Set `"reusable": true` cho tất cả components có thể tái sử dụng
|
||||
10. **Responsive Variants** - Tạo variants riêng cho Desktop/Tablet/Mobile (không dùng breakpoint logic trong Pencil)
|
||||
11. **Documentation** - Document component props, states, usage guidelines trong USAGE_GUIDE.md
|
||||
12. **Version Control Strategy**:
|
||||
- Commit: `src/` (all atomic files)
|
||||
- Gitignore: `build/` (generated files)
|
||||
- Tag releases: `v1.0.0` khi có breaking changes trong design tokens
|
||||
|
||||
## 9. Common Mistakes / Lỗi Thường Gặp
|
||||
|
||||
### 9.1 Bỏ qua Design Tokens
|
||||
|
||||
```css
|
||||
/* ❌ BAD: Hardcoded colors */
|
||||
@@ -458,7 +1067,7 @@ background: #0A0A0B;
|
||||
background: var(--bg-page);
|
||||
```
|
||||
|
||||
### 8.2 Không xử lý Refs
|
||||
### 9.2 Không xử lý Refs
|
||||
|
||||
```javascript
|
||||
// ❌ BAD: Bỏ qua ref elements
|
||||
@@ -471,7 +1080,20 @@ if (element.type === 'ref') {
|
||||
}
|
||||
```
|
||||
|
||||
## 9. Quick Reference / Tham Chiếu Nhanh
|
||||
### 9.3 Quên build trước khi test
|
||||
|
||||
```bash
|
||||
# ❌ BAD: Mở source files trực tiếp
|
||||
open src/pages/desktop-home.pen
|
||||
# → Component refs sẽ không hiển thị
|
||||
|
||||
# ✅ GOOD: Build trước
|
||||
python3 scripts/build.py -m
|
||||
open tPOS.pen
|
||||
# → Tất cả components đã được inject
|
||||
```
|
||||
|
||||
## 10. Quick Reference / Tham Chiếu Nhanh
|
||||
|
||||
| Task | Approach |
|
||||
|------|----------|
|
||||
@@ -480,15 +1102,61 @@ if (element.type === 'ref') {
|
||||
| Get colors | Read `variables` object |
|
||||
| Find components | Filter by `reusable: true` |
|
||||
| Resolve refs | Match `ref` ID to component `id` |
|
||||
| **Split large file** | Use Python script to extract pages by name |
|
||||
| **Create component library** | Extract page with all components + `variables` |
|
||||
| **Validate modular files** | Check `version`, `children`, `variables` in each file |
|
||||
| **Sync design tokens** | Copy `variables` object to all files |
|
||||
| **Build monolithic file** | `python3 scripts/build.py -m` |
|
||||
| **Build standard mode** | `python3 scripts/build.py` |
|
||||
| **Use external component** | Add `component_ref` type in source |
|
||||
| **Validate build output** | `jq empty tPOS.pen && echo "✅ Valid"` |
|
||||
| **Check build contents** | `jq '.children \| length' tPOS.pen` |
|
||||
| **Configure build** | Edit `pencil.config.json` |
|
||||
| **Extract to Atomic Design** | Run Python script in section 7.4 "Atomic Design Extraction" |
|
||||
| **Audit UI Kit size** | `wc -l ui-kit.pen && du -h ui-kit.pen` |
|
||||
| **Count components by category** | `grep '"name":' ui-kit.pen \| grep -i "button" \| wc -l` |
|
||||
| **Sync design tokens** | Copy `variables` from `design-tokens.pen` to all atomic files |
|
||||
| **Create atomic structure** | `mkdir -p src/{foundations,atoms,molecules,organisms,pages}` |
|
||||
| **Validate atomic files** | Python validation script in section 7.4 Step 5 |
|
||||
| **List atomic components** | `find src/atoms -name "*.pen" -type f` |
|
||||
| **Check component states** | `grep '"name": ".*/(Default\|Hover\|Disabled)"' atoms/buttons.pen` |
|
||||
|
||||
## 11. Build System Reference
|
||||
|
||||
### Build Commands
|
||||
```bash
|
||||
# Monolithic build
|
||||
python3 scripts/build.py --monolithic
|
||||
python3 scripts/build.py -m
|
||||
python3 scripts/build.py --mode monolithic
|
||||
|
||||
# Standard build
|
||||
python3 scripts/build.py
|
||||
python3 scripts/build.py --mode standard
|
||||
|
||||
# Custom output
|
||||
python3 scripts/build.py -m --output custom.pen
|
||||
|
||||
# Help
|
||||
python3 scripts/build.py --help
|
||||
```
|
||||
|
||||
### Validation Commands
|
||||
```bash
|
||||
# Validate JSON
|
||||
jq empty tPOS.pen && echo "✅ Valid JSON"
|
||||
|
||||
# Check structure
|
||||
jq '{version, childrenCount: (.children | length)}' tPOS.pen
|
||||
|
||||
# List frame names
|
||||
jq '[.children[].name]' tPOS.pen
|
||||
|
||||
# Extract design tokens
|
||||
jq '.variables' tPOS.pen
|
||||
```
|
||||
|
||||
## Resources / Tài Nguyên
|
||||
|
||||
- [Pencil Official Site](https://pencil.evolus.vn/)
|
||||
- [Pencil GitHub](https://github.com/pencilinc/pencil)
|
||||
- [Workflow: /pencil-build](../../.agent/workflows/pencil-build.md)
|
||||
- [Tailwind Design System](../tailwind-design-system/SKILL.md)
|
||||
- [React UI Components](../react-ui-components/SKILL.md)
|
||||
- [Blazor Theme Patterns](../blazor-theme-patterns/SKILL.md)
|
||||
|
||||
Reference in New Issue
Block a user