🧬 Component Lifecycle — Create, Audit & Fix
Complete lifecycle for design system components: from design analysis → token creation → documentation → validation → audit → batch fix.
How to Use This Skill
This skill is organized in 3 layers:
- This file (SKILL.md) — Standards, workflow, audit. Read this first.
- references/ — Deep-dive rules and templates. Read only what's relevant.
- Automated scripts — Run
audit-components.jsfor machine-checkable completeness.
Quick navigation:
| You want to... | Read... |
|---|---|
| Create a new component | Create Workflow (steps 1–7) |
| Understand token categories | Eight Categories |
| Audit existing components | Audit & Fix |
| Fix naming/state issues | references/token-naming-states.md |
| Fix layout/slots | references/layout-slots-tiers.md |
| Fix divider/button patterns | references/patterns-dividers.md |
| Design analysis template | references/design-analysis.md |
| Token JSON authoring guide | references/token-authoring.md |
Pre-read Requirements
Before creating a NEW component, read these skills first:
| Skill | What to read | Why |
|---|---|---|
token-governance |
SKILL.md — tier permissions, reference chain, §8 Gap Report | Ensures tokens reference correct tier |
style-scaling |
SKILL.md §Design Intent Extraction | Only if component has brand/density requirements |
ux-research |
SKILL.md §6 Typography + §7 A11y + §5 Component | MANDATORY — font-size minimums, ARIA, focus, keyboard, interaction states |
⚠️ UX Quick Reference — Apply these rules DURING coding, not after:
Rule Requirement Token T1 Interactive/body text ≥ 14px desktop, ≥ 16px mobile --font-size-smminimumT10 Module title = 16px semibold --font-size-base+--font-weight-semiboldT11 Overlay title = 18px semibold --font-size-lg+--font-weight-semiboldB7 Every overlay closes on Escape key JS keydownhandlerF1 Focus ring uses token, never hide outline :focus-visible+var(--ring)F3 Modal/overlay traps focus + Escape close JS focus trap H1 Every action → visual feedback ≤ 100ms CSS transitionS1 No hardcoded px/rem for spacing calc(var(--spacing) * N)or semanticvar(--comp-padding-*)M1 Respect prefers-reduced-motion@mediaquery
🚫 PRE-CODE GATE — Mandatory Token Resolution
RULE: KHÔNG ĐƯỢC viết code (inline style, CSS, HTML) cho bất kỳ component nào khi chưa hoàn thành bảng resolution bên dưới. Copy bảng này vào response TRƯỚC KHI code.
🔒 TOKEN RESOLUTION TABLE — {component name}
═══════════════════════════════════════════════════
□ Label font-size:
UX tier = _________ (§6.1: Body/Label/Caption?)
UX range = _________ px (e.g. Caption = 11-12px)
Token chosen = var(--_________)
Token actual value = _____ px
In UX range? ☐ YES ☐ NO → pick another token
□ Label line-height:
UX rule = T3: _________ (e.g. caption = 1.4-1.5)
Token = var(--font-leading-_________)
□ Icon size:
Spec = ___ px
Token = var(--icon-___)
□ Gap (icon → label):
S2 check: multiple of 4px? ☐ YES ☐ NO
Token = var(--spacing-___) = ___ px
□ Container height:
Spec = ___ px (source: _________)
Token = var(--spacing-___) = ___ px
□ Touch target:
R3: ≥ 44×44px? ☐ YES → min-width/min-height = 44px
□ Indicator/pill:
Size = ___ × ___ px (source: _________)
Radius = var(--radius-___)
bg/fg pair: bg = var(--___), fg = var(--___)
☐ ALL rows resolved → proceed to code
☐ ANY row fails → fix token choice, DO NOT change spec
⚠️ Direction of truth:
UX Research → Spec → Token → Code. Nếu token value nằm ngoài UX range → CHỌN TOKEN KHÁC, KHÔNG sửa spec.
1. Eight Categories
Every component MUST cover these 8 token categories (≥7/8 = enterprise-grade):
| # | Category | Required Tokens | Source |
|---|---|---|---|
| 1 | Container | height, padding, radius, border-width | MD3 |
| 2 | Content | font-size, font-weight | MD3 |
| 3 | Icon | icon-size, gap (N/A nếu không có icon) | MD3 |
| 4 | Enabled | bg + fg pairs per variant (shadcn pattern) | shadcn |
| 5 | Hover | color.hover → {state-layer.hover} |
MD3 state layer |
| 6 | Disabled | disabled-bg → {base.muted}, disabled-fg → {base.muted-foreground} |
MD3 |
| 7 | Focus | focus-ring → {focus.ring-color} |
shadcn + Apple |
| 8 | Transition | transition → {duration.fast-2} {easing.standard} |
MD3 motion |
2. Token Naming Convention
{component}.{element}.{property}[.{variant}]
✅ button.height.sm, button.color.primary-bg, button.transition
❌ button.custom-height, button.#3B82F6
📖 Full naming rules, title size conventions, and bg/fg pair details: references/token-naming-states.md
3. Critical Rules (Quick Reference)
bg/fg Pair Rule (shadcn)
📖 Full rules: references/token-naming-states.md §3
Every color variant MUST have a paired bg + fg:
"primary-bg": { "$value": "{base.primary}" },
"primary-fg": { "$value": "{base.primary-foreground}" }
In CSS/HTML: Any element with background: var(--primary) MUST also set color: var(--primary-foreground). Applies to classes, inline styles, and pseudo-elements.
Slot Anatomy (Header / Body / Footer)
📖 Full rules: references/layout-slots-tiers.md §1
Container-level components MUST use generic .slot-header / .slot-body / .slot-footer classes:
<!-- ✅ CORRECT -->
<div class="container-module slotted">
<div class="slot-header">...</div>
<div class="slot-body">...</div>
<div class="slot-footer">...</div>
</div>
<!-- ❌ WRONG — custom per-component slots -->
<div class="card">
<div class="card-header">...</div>
</div>
Button Pairing (Action Group Hierarchy)
📖 Full rules: references/patterns-dividers.md §1
| Main Action (CTA) | Counter Action | Example |
|---|---|---|
primary (Filled) |
outline |
Submit ↔ Cancel |
destructive (Filled) |
outline |
Delete ↔ Cancel |
Divider Rules
📖 Full rules: references/patterns-dividers.md §2
Priority: SPACING > DIVIDER > BORDER. Always try spacing tokens first.
Top 3 rules:
- D1: Spacing first — divider is last resort
- D2: Max 2 consecutive full-width dividers in viewport
- D9: No divider inside card — use spacing or subtle bg shift
4. Component Priority Tiers
| Priority | Components |
|---|---|
| P1 — Showcase | button, card, input, select, checkbox, radio, switch, tabs, dialog, modal, toast, alert, badge, avatar, tooltip |
| P2 — Extended | table, pagination, progress, slider, stepper, breadcrumb, skeleton, spinner, divider, drawer |
| P3 — Advanced | date-picker, tag-input, toggle-group, empty-state, search |
5. What to Learn From Each System
| MD3 | shadcn | Apple HIG |
|---|---|---|
| Component anatomy, state layers, 3-tier tokens, density, motion | bg/fg pairs, --ring, CSS var theming, .dark class | Focus standards, semantic colors, a11y, spring motion |
Create Workflow
// turbo-all
Step 1: Check Existence
Verify the component doesn't already exist:
## Check ATOMIC-MAPPING.md for existing entry
findstr /i "{component-name}" "design-system\components md\ATOMIC-MAPPING.md"
→ If it exists, STOP. Use Audit & Fix instead.
Step 2: Design Analysis (5-Part Output)
📖 Full template and examples: references/design-analysis.md
Perform a thorough analysis BEFORE creating any token JSON:
| Part | Question to Answer |
|---|---|
| 🎨 Design Intent | What role does this component serve? What variants and states? |
| 🔗 Token Mapping | Map every visual property → existing design system token |
| 📐 Layout Mapping | Identify layout tier tokens needed (comp-radius, comp-padding-*) |
| ✅ Compliance Check | Are all needed primitives available? |
| ⚠️ Gap Report | If tokens are missing → propose using token-governance §8 Gap Report → ASK User |
CRITICAL: Only proceed to Step 3 when the User has approved all gaps (if any).
Step 3: Add Component to ATOMIC-MAPPING.md
File: design-system/components md/ATOMIC-MAPPING.md
Add a new ### {component-name} section answering 4 questions:
| Q | What to specify |
|---|---|
| UI Layer | Ground / Card / Surface — determines bg/fg token |
| Density Tier | Page / Section / Group / Comp — determines spacing/radius |
| Variant Colors | List all bg/fg pairs per variant |
| Elevation | Shadow level + z-index tier |
⚠️ NO component token JSON files. Components map DIRECTLY to semantic tokens. See existing entries in ATOMIC-MAPPING.md for patterns.
Step 4: Create Component Documentation
File: design-system/components md/{name}.md
Include: description, variants, states, token mapping, usage guidelines, anti-patterns.
Step 4b: Add Slot Map + Code Connect Entry (MANDATORY — ENF-6)
⚠️ GATE: Component is NOT complete without Figma Slot mapping.
- Check
knowledge/slot-manifest.jsonfor existing slot definitions - Read
knowledge/slot-convention.md— CSS naming rules (structural.slot-*vs BEM__) - Add
## Slot Map (Figma ↔ Code)section to the component.md— seeapp-bar.mdfor format:- Table: Figma Slot |
data-slot| CSS Class | Required | Accepts - HTML skeleton with
data-slotattributes
- Table: Figma Slot |
- Add entry to
design-system/code-connect/code-connect.config.json:slots: map Figma slot names → data-slot valuestemplate: HTML code snippet with{SlotName}placeholders
- Add typed interface to
design-system/code-connect/slot-api.d.ts:- Export
{Component}Slotsinterface with JSDocdata-slotcomments
- Export
- Add preferred instances to
design-system/code-connect/preferred-instances.json:- Map each slot → recommended Figma component instances
- If component has NEW slots not in
slot-manifest.json:- Add slot definitions to
slot-manifest.jsonFIRST - Then update spec + Code Connect config + API types + preferred instances
- Add slot definitions to
Step 5: Sync & Validate (Full Pipeline)
node design-system/scripts/pipeline/run-pipeline.js --all
Chạy unified pipeline: sync → build-docs → review CSS → verify output → drift check → audit components. Xem
run-pipeline.js --helpđể biết thêm options (--from=N,--only=1,3,--auto).
Step 6: Add Preview Entry (MANDATORY)
⚠️ GATE: Component is NOT complete until it has a live preview in docs.
File: design-system/scripts/docs/component-previews.js
- Add a new key matching the component slug (e.g.,
'transaction-item') - Write HTML template using DS tokens — NO hardcoded px/colors
- Use
icon()helper for all icons (Lucide SVG, no text emoji) - Include hover states (
onmouseover), focus (tabindex), disabled states - All spacing →
var(--spacing-*)orcalc(var(--spacing) * N) - All sizing →
calc(var(--spacing) * N), NEVER raw40px,48px - All colors →
var(--semantic-token)pairs (bg + fg) - All easing →
var(--easing-standard), NEVER rawease
## Verify preview renders in docs
node design-system/scripts/docs/build-docs.js
## Check output: "{N}/52 components have live previews"
## If your component is missing → FIX before proceeding
Step 7: Audit CSS Class Definition (MANDATORY)
⚠️ GATE: If the component has a CSS class (in
preview-extras.cssorcomponents.css), audit it.
Check every CSS rule for:
| Check | Pattern to find | Fix |
|---|---|---|
| Hardcoded position | top: Npx; left: Npx |
Use display: grid; place-content: center or calc() |
| Hardcoded easing | ease, ease-in-out |
var(--easing-standard) |
| Hardcoded duration | 150ms, 200ms |
var(--duration-fast-1) etc. |
| Hardcoded size | 40px, 48px |
calc(var(--spacing) * N) |
| Missing bg/fg pair | background: var(--primary) without color: |
Add color: var(--primary-foreground) |
::after/::before positioning |
position: absolute + px offsets |
Prefer grid/flex centering |
## Quick check for hardcodes in preview CSS
Select-String '\d+px' design-system/scripts/docs/template/preview-extras.css | Where-Object { $_ -notmatch 'spacing|radius|border-width|shadow|0px' }
Audit & Fix Workflow
Commands
## Audit all components — completeness report
node design-system/scripts/pipeline/audit-components.js
## Audit + generate fix plan
node design-system/scripts/pipeline/audit-components.js --fix-plan
## Generate visual previews (after creating/fixing components)
node design-system/scripts/docs/component-previews.js
When to Batch Fix vs Manual Fix
| Gap Size | Action |
|---|---|
| 1-2 components, ≤3 tokens missing | Fix manually per token JSON file |
| ≥3 components or ≥5 tokens missing | Manual batch fix by pattern |
| Entire category missing (e.g., all missing hover) | Batch fix by category |
Batch Fix Rule: Fix ALL components with the same category gap at once.
❌ Fix button hover → deploy → fix card hover → ...
✅ Collect ALL missing hover → fix ALL → validate → deploy
MANDATORY after batch-fix: Run
node design-system/scripts/pipeline/run-pipeline.js --allto validate (or/post-change).
Anti-patterns
| ❌ Don't | ✅ Do | Why |
|---|---|---|
| Jump straight to CSS | Create tokens first → sync generates CSS | Token-first ensures traceability |
| Hardcode any values | Reference primitives/shared tokens | Hardcodes cause design drift |
| Skip design analysis | Complete all 5 parts before token creation | Analysis prevents rework |
| Add primitives without asking | Propose via Gap Report → get User approval | Primitives affect the entire system |
| Create component with <7 categories | Cover all 8 (or justify N/A) | Incomplete = accessibility gaps |
| Fix 1 component at a time | Batch fix by category | Minimizes review cycles |
card-header custom class |
Use .slot-header generic slot |
Slot consistency |
btn-ghost next to btn-primary |
Use btn-outline as counter |
Button hierarchy |
| Hardcode font-size in title | Use --font-size-base / --font-size-lg |
Typography tokens |
| Fix CSS before fixing tokens | Fix tokens → sync → CSS auto-updates | Source of truth is JSON |
| Fix 1 file, skip blast radius | Grep cùng pattern toàn project trước khi done | Cùng violation ở nhiều file |
| Sửa spec cho match token sai | Chọn token khác cho match UX spec | UX Research → Spec → Token → Code, KHÔNG BAO GIỜ ngược |
| Chọn token theo tên | Resolve actual px, cross-check vs UX range | "2xs" sounds small ≠ compliant |
| Skip preview entry | Add to component-previews.js + rebuild docs |
Component without preview = not shipped |
| Skip CSS class audit | Audit preview-extras.css + components.css for hardcodes |
top: 1px; left: 5px breaks on density scale |
Use position: absolute + px for centering |
Use display: grid; place-content: center |
Grid centering is density-proof |
Use raw ease in transition |
Use var(--easing-standard) |
Easing must be overridable per style |
Decision Points
| Situation | Action |
|---|---|
| Component already exists | STOP → audit with Audit & Fix |
| Missing primitives found | Use token-governance §8 Gap Report → ASK User |
| Brand/density requirements | Read style-scaling Design Intent Extraction first |
| Fewer than 7/8 categories | DO NOT proceed — complete the missing categories |
| User rejects gap proposals | Redesign component to use existing tokens only |
Project Paths
| Item | Path |
|---|---|
| Atomic mapping | design-system/components md/ATOMIC-MAPPING.md |
| Component docs | design-system/components md/{name}.md |
| Sync script | design-system/scripts/pipeline/sync-tokens.js |
| Build script | design-system/scripts/docs/build-docs.js |
| Preview script | design-system/scripts/docs/component-previews.js |
| Audit script | design-system/scripts/pipeline/audit-components.js |
| Preview output | docs/components/{name}/ |
Reference Files
| File | Contents | Read when... |
|---|---|---|
| token-naming-states.md | Naming convention, title sizes, bg/fg pairs, state layers, semantic colors | Creating tokens, fixing naming, auditing bg/fg |
| layout-slots-tiers.md | Slot anatomy, slot classes, density scaling, layout tiers, flex control rules | Building containers, fixing layout, mapping tiers |
| patterns-dividers.md | Button pairing, divider rules (9 rules), decision matrices | Fixing action groups, divider audit, content separation |
| design-analysis.md | 5-part analysis template, examples, output format | Starting design analysis (Step 2) |
| token-authoring.md | Token JSON structure, category checklist, naming patterns | Creating token files (Step 3) |