From bb72909dd5948c8857a0c928b19971eb4af2a637 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Sat, 31 Jan 2026 20:12:27 +0700 Subject: [PATCH] feat: Add comprehensive reference documentation for Pencil design skill, detailing its build system, code conversion, file format, and atomic design principles. --- .agent/skills/pencil-design/SKILL.md | 1143 ++++------------- .../pencil-design/references/ATOMIC_DESIGN.md | 565 ++++++++ .../pencil-design/references/BUILD_SYSTEM.md | 424 ++++++ .../references/CODE_CONVERSION.md | 616 +++++++++ .../pencil-design/references/FILE_FORMAT.md | 425 ++++++ 5 files changed, 2256 insertions(+), 917 deletions(-) create mode 100644 .agent/skills/pencil-design/references/ATOMIC_DESIGN.md create mode 100644 .agent/skills/pencil-design/references/BUILD_SYSTEM.md create mode 100644 .agent/skills/pencil-design/references/CODE_CONVERSION.md create mode 100644 .agent/skills/pencil-design/references/FILE_FORMAT.md diff --git a/.agent/skills/pencil-design/SKILL.md b/.agent/skills/pencil-design/SKILL.md index 52316712..52764678 100644 --- a/.agent/skills/pencil-design/SKILL.md +++ b/.agent/skills/pencil-design/SKILL.md @@ -10,938 +10,220 @@ metadata: # Pencil Design Tool / Công cụ thiết kế Pencil -## 1. Tổng Quan / Overview +## When to Use This Skill / Khi Nào Sử Dụng -[Pencil](https://pencil.evolus.vn/) là công cụ thiết kế UI/UX mã nguồn mở. File project có extension `.pen` lưu dưới định dạng JSON. +Use this skill when: +- Reading and analyzing `.pen` design files / Đọc và phân tích file `.pen` +- Extracting design content and tokens / Trích xuất nội dung và design tokens +- Converting Pencil designs to code / Chuyển đổi thiết kế sang code +- Building component libraries / Xây dựng thư viện components +- Organizing enterprise UI Kits with Atomic Design / Tổ chức UI Kits doanh nghiệp +- Working with modular design systems / Làm việc với hệ thống thiết kế module -**Khả năng Agent với file .pen:** -- ✅ Đọc và phân tích cấu trúc design +## Core Concepts / Khái Niệm Cốt Lõi + +### What is Pencil / Pencil là gì + +[Pencil](https://pencil.evolus.vn/) is an open-source UI/UX design tool. Project files have `.pen` extension and are stored as JSON. + +**Agent capabilities with .pen files:** +- ✅ Read and analyze design structure - ✅ Extract content (text, colors, images) -- ✅ Convert sang HTML/CSS/React/Blazor -- ✅ Hiểu component system và design tokens -- ❌ Render preview (cần Pencil app) -- ❌ Chỉnh sửa trực tiếp trong app +- ✅ Convert to HTML/CSS/React/Blazor +- ✅ Understand component system and design tokens +- ❌ Render preview (requires Pencil app) +- ❌ Edit directly in app -## 2. File Format / Định dạng file - -### 2.1 Cấu trúc JSON +### File Structure / Cấu trúc File ```json { "version": "2.6", - "children": [ /* Page frames và components */ ], + "children": [ /* Pages and components */ ], "variables": { /* Design tokens */ } } ``` -### 2.2 Element Types +**Key elements:** +- `children`: Page frames and components +- `variables`: Design tokens (colors, spacing, typography) +- `reusable: true`: Marks reusable components -| Type | Mô tả | Properties chính | -|------|-------|------------------| -| `frame` | Container, layout | `width`, `height`, `fill`, `layout`, `gap`, `padding` | -| `text` | Text element | `content`, `fontSize`, `fontFamily`, `fontWeight`, `fill` | -| `rectangle` | Shape | `width`, `height`, `fill`, `cornerRadius` | -| `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) | +### Design Tokens / Design Tokens -### 2.3 Layout Properties - -```json -{ - "layout": "vertical", // vertical | horizontal | none - "gap": 16, // spacing between children - "padding": [16, 24], // [vertical, horizontal] hoặc single value - "justifyContent": "center", // start | center | end | space_between - "alignItems": "center" // start | center | end -} -``` - -### 2.4 Size Properties - -```json -{ - "width": 400, // fixed pixels - "width": "fill_container", // 100% của parent - "height": 200 -} -``` - -## 3. Design Tokens / Variables - -Design tokens được định nghĩa trong `variables` object: +Variables stored in `variables` object: ```json "variables": { "bg-page": { "type": "color", "value": "#0A0A0B" }, "text-primary": { "type": "color", "value": "#FFFFFF" }, - "orange-primary": { "type": "color", "value": "#FF5C00" } + "orange-primary": { "type": "color", "value": "#FF5C00" }, + "space-4": { "type": "number", "value": 16 } } ``` -**Sử dụng trong elements:** +**Usage in elements:** ```json "fill": "$bg-page", -"fill": "$text-primary" +"fontSize": "$text-lg" ``` -### 3.1 Common Token Categories - -| Category | Prefix | Examples | -|----------|--------|----------| -| Background | `bg-` | `$bg-page`, `$bg-surface`, `$bg-elevated` | -| Text | `text-` | `$text-primary`, `$text-secondary`, `$text-tertiary` | -| Border | `border-` | `$border-default`, `$border-subtle` | -| Brand | `{color}-` | `$orange-primary`, `$green-success` | - -## 4. Component System - -### 4.1 Reusable Components - -Components có `reusable: true` có thể được tham chiếu lại: +### Component System / Hệ thống Component +**Reusable components:** ```json { "type": "frame", - "id": "tmKtl", - "name": "Component/Button/Primary", + "id": "btn_001", + "name": "Button/Primary", "reusable": true, "children": [...] } ``` -### 4.2 Component Instances (Refs) - -**Internal refs (same file):** +**Component instances (refs):** ```json { "type": "ref", - "ref": "tmKtl", // ID của component gốc - "name": "myButton", - "descendants": { // Override properties - "q7oNn": { // Child element ID - "content": "Click Me" // Override content + "ref": "btn_001", + "descendants": { + "label_id": { + "content": "Submit" } } } ``` -**External refs (cross-file, using build system):** +**External component references (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 + "component": "ui-kit#Button/Primary", + "overrides": { ... } } ``` > [!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. +> `component_ref` is processed by the build system and converted to `ref` during build. -## 5. Build System +### Atomic Design Architecture / Kiến trúc Atomic Design -### 5.1 Configuration File +For enterprise-scale UI Kits (50+ components), organize with Atomic Design: -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 +``` +src/ +├── foundations/ +│ └── design-tokens.pen # Colors, typography, spacing +├── atoms/ # Buttons, inputs, badges +├── molecules/ # Form fields, search bars +├── organisms/ # Cards, navigation, headers +└── pages/ # Complete pages +``` + +**Benefits:** +- ✅ Industry standard (Figma, Material Design) +- ✅ Maximum scalability +- ✅ Team collaboration +- ✅ Small, focused files (<500 lines each) + +**Naming convention:** +``` +{Level}/{Component}/{Variant}/{State} + +Examples: +- Atom/Button/Primary/Default +- Atom/Button/Primary/Hover +- Molecule/FormField/Text/Default +- Organism/Card/Feature/Default +``` + +## Key Patterns / Mẫu Chính + +### Reading .pen Files + +```javascript +import fs from 'fs'; + +// Read file +const data = JSON.parse(fs.readFileSync('design.pen', 'utf-8')); + +// Get design tokens +const tokens = data.variables; + +// Get main page +const mainPage = data.children[0]; + +// Find sections +const sections = mainPage.children; +``` + +### Extracting Content + +```javascript +// Find all text elements +function extractAllText(element, texts = []) { + if (element.type === 'text') { + texts.push(element.content); } + if (element.children) { + element.children.forEach(child => extractAllText(child, texts)); + } + return texts; +} + +const allText = extractAllText(mainPage); +``` + +### Converting to CSS Variables + +```javascript +// Generate CSS from design tokens +function generateCSSTokens(variables) { + const cssVars = Object.entries(variables) + .map(([key, value]) => { + if (value.type === 'color') return ` --${key}: ${value.value};`; + if (value.type === 'number') return ` --${key}: ${value.value}px;`; + return ` --${key}: ${value.value};`; + }) + .join('\n'); + + return `:root {\n${cssVars}\n}`; } ``` -### 5.2 Build Script +### Build System Usage -The build system (`scripts/build.py`) supports two modes: - -#### Monolithic Build ⭐ (Recommended) -Merges all pages + component library into one file: +**Monolithic build (recommended):** ```bash python3 scripts/build.py --monolithic # or python3 scripts/build.py -m -# Custom output -python3 scripts/build.py -m --output myDesign.pen +# Output: tPOS.pen (all pages + components in one file) ``` -**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: +**Standard build:** ```bash python3 scripts/build.py + +# Output: build/ directory with individual files ``` -**Output:** -- Directory: `build/` -- Files: Separate `.pen` files with injected components -- Use case: Development workflow, testing component refs +### Atomic Design Extraction -### 5.3 Build Process +For large UI Kits, extract to Atomic Design structure: -**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 -2. Parse JSON structure -3. Identify main page frame (thường là child lớn nhất) -4. Extract sections dựa trên "name" property -5. List design tokens từ "variables" -``` - -### 6.2 Extract Content - -```markdown -1. Tìm tất cả elements có type "text" -2. Collect "content" property -3. Group theo parent frame (section) -4. Export dạng structured text hoặc JSON -``` - -### 6.3 Design to Code Conversion - -**Step 1: Analyze Structure** -```markdown -- Identify layout (vertical/horizontal) -- Map padding và gap values -- Extract color tokens -``` - -**Step 2: Convert Elements** - -| Pencil | HTML/CSS | React | Blazor | -|--------|----------|-------|--------| -| `frame` layout:vertical | `
` flex-direction:column | `
` | `
` | -| `frame` layout:horizontal | `
` flex-direction:row | | | -| `text` | `

`, `

`-`

`, `` | | | -| `icon_font` | `` | `` | `` | - -**Step 3: Apply Styles** -```css -/* Map Pencil properties to CSS */ -gap: 16px /* gap: 16 */ -padding: 24px 32px /* padding: [24, 32] */ -border-radius: 10px /* cornerRadius: 10 */ -background: linear-gradient /* fill.type: "gradient" */ -``` - -### 6.4 Design System Extraction - -```markdown -1. Extract all "variables" as CSS custom properties -2. Convert to: - - CSS Variables (:root) - - Tailwind config - - SCSS variables - - Design tokens JSON -``` - -**Output Example:** -```css -:root { - --bg-page: #0A0A0B; - --text-primary: #FFFFFF; - --orange-primary: #FF5C00; -} -``` - -### 6.5 Build and Deploy Workflow - -**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 -├── Header/NavBar -├── Hero Section -├── Features Section -├── Pricing Section -├── CTA Section -└── Footer -``` - -### 7.2 Component Naming Convention - -Atomic Design uses strict hierarchical naming: - -``` -{AtomicLevel}/{Component}/{Variant}/{State} -``` - -**Examples:** - -**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 - -### 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.5 Atomic Design Architecture - -**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 - -#### Design Tokens Foundation - -**design-tokens.pen should contain:** - -```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} - } -} -``` - -#### Atomic Design Extraction Workflow - -**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 +# Create structure +mkdir -p src/foundations src/atoms src/molecules src/organisms -# 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)" +# Run extraction script (see references/ATOMIC_DESIGN.md) +python3 scripts/extract-atomic.py ``` -**Step 2: Create Atomic Structure** -```bash -mkdir -p src/foundations src/atoms src/molecules src/organisms src/pages -``` +## Common Mistakes / Lỗi Thường Gặp -**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" -3. **Extract tokens trước** - Hiểu color palette trước khi convert -4. **Map components** - List ra reusable components trước -5. **Check file size** - Nếu > 300KB, consider splitting - -### 8.2 Khi convert sang code - -1. **Mobile-first** - Responsive breakpoints -2. **Semantic HTML** - `
`, `
`, `
`, `