feat: Add build system for external component references and expand documentation on Atomic Design principles and modular architecture.

This commit is contained in:
Ho Ngoc Hai
2026-01-31 19:55:54 +07:00
parent 2099d0469c
commit bd49f4fe3b

View File

@@ -1,11 +1,11 @@
---
name: pencil-design
description: Pencil UI/UX design tool workflows 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)