# Figma → Component Workflow

Generate UI components directly from Figma designs using the `figma-to-component` skill.

---

## Prerequisites

Choose one adapter based on your setup:

> **Which adapter?** The REST API is rate-limited **per seat** (see [Rate limits](#rate-limits-429)
> below): a View/Collab seat gets only ~6 heavy calls per MONTH — effectively unusable.
> - Token from a **Dev/Full seat** → Option A (REST) works fine with the batched strategy.
> - Only a View/Collab seat, or design-heavy work (many frames, art-heavy exports) →
>   prefer **Option B (Figma Desktop)** — it uses the local app session and consumes no REST quota.

### Option A — REST API (no Desktop required; needs a Dev/Full-seat token)

```bash
ak init -a figma
# Prompts for FIGMA_API_TOKEN
```

Get your token: [figma.com/settings](https://www.figma.com/settings) → Security → Personal access tokens → Create new token (File content: read). Create it from an account with a **Dev or Full seat** — a View/Collab seat's token is capped at ~6 Tier 1 calls/month.

### Option B — Official Figma MCP (requires Figma Desktop app)

```bash
ak init -a figma-desktop
# No token needed — uses Desktop app session
```

Requirements: Figma Desktop app installed and the target file open before invoking the skill.

---

## Getting a Figma Node URL

1. Open your file in Figma (browser or Desktop)
2. Right-click on a frame or component → **Copy link to selection**
3. The URL looks like:
   ```
   https://www.figma.com/design/FILEKEY/FileName?node-id=123-456
   ```
   - `FILEKEY` — the file identifier (between `/design/` and the next `/`)
   - `node-id=123-456` — the specific frame or component to generate

You can also link to the entire file (no `node-id`) to let the skill list available frames.

---

## Trigger the Skill

Paste the Figma URL into Claude Code with a generation request:

```
Generate component from this Figma frame:
https://www.figma.com/design/XXXXX/App?node-id=123-456
```

```
Implement the UserCard UI from Figma:
https://www.figma.com/design/XXXXX/App?node-id=78-910
```

```
Read Figma and generate component following my project conventions:
https://www.figma.com/design/XXXXX/App?node-id=42-0
```

---

## What to Expect

The skill outputs in this order:

1. **Design Summary** — layout structure, color palette, typography scale used in the design
2. **Component file** — complete code for your detected framework (React, Next.js App Router, Vue 3, or Angular)
3. **Usage example** — how to import and use the component
4. **Notes** — anything that couldn't be mapped 1:1 from Figma (custom fonts, unsupported effects, etc.)

**Framework auto-detection order:**
1. Read `CLAUDE.md` for framework identifier (`nextjs-app-router`, `reactjs`, `vue-nuxt`, `angular`)
2. Scan project files (`app/` dir → App Router, `angular.json` → Angular, `nuxt.config.*` → Vue)
3. Fallback → Next.js / React

---

## Figma trong Gate workflow

Khi làm việc theo quy trình 5 Gate (xem `CLAUDE.md`) với ticket liên quan UI, Figma được
nối tự động — không cần gọi skill thủ công:

| Gate | Vai trò Figma |
|------|----------------|
| **1** | `read-study-requirement` dò Figma URL trong ticket (hoặc hỏi DEV một lần), đọc design **một lần** qua MCP, lưu artifact `plan/[ticket-id]/design/` (design-context.md + images/ + nodes.json). |
| **2** | `generate-spec` đọc `design-context.md` → đưa component tree, design tokens, danh sách ảnh vào plan TDD. |
| **3** | `figma-to-component` chạy ở **Gate mode**: dùng lại cache `nodes.json`, copy ảnh sang `public/assets/figma/`, sinh component (không gọi lại MCP). |
| **4** | `review-plan` đối chiếu UI đã code với `design-context.md`. |

**Artifact dùng chung** — nguồn sự thật cho mọi Gate sau Gate 1:

```
plan/[ticket-id]/design/
├── design-context.md   # layout, tokens, component list, image map
├── images/             # ảnh export từ Figma
└── nodes.json          # raw get_figma_data (cache)
```

**Refresh khi design đổi:** gõ "reload figma" → Gate 1 fetch lại, ghi đè `design/`, cập nhật `Fetched`.

**Ticket không liên quan UI** hoặc không có Figma URL → toàn bộ nhánh Figma được bỏ qua.

---

## Review Checklist

After the component is generated, verify:

- [ ] Layout matches Figma (flex direction, alignment, gap)
- [ ] Colors are correct (Tailwind class or arbitrary value)
- [ ] Typography matches (size, weight, line-height)
- [ ] Spacing correct (padding, margin, gap)
- [ ] Interactive states handled (`'use client'` in App Router, variants in React/Vue/Angular)
- [ ] Images use correct component (`next/image` for Next.js, `<img>` for others)
- [ ] `className` / `class` prop exposed for external overrides

---

## Rate limits (429)

Figma rate-limits the REST API by **endpoint tier × plan × seat** (since 2025-11-17).
`get_figma_data` (file/nodes) and image renders share the same **Tier 1** bucket:

| Seat of the token owner | Tier 1 budget (file / nodes / render images) |
|---|---|
| View / Collab | **~6 calls / MONTH** (any plan) |
| Dev / Full — Starter | 10 / min |
| Dev / Full — Professional | 15 / min |
| Dev / Full — Organization+ | 20 / min |

The fills-map endpoint (`/v1/files/:key/images`) is Tier 2 (25-100/min) — the skill prefers it.
Downloading image bytes from the returned S3 URLs costs nothing.

> **Measured on a free personal (Starter) account, 2026-07:** the API returned
> `x-figma-rate-limit-type: low` with `retry-after ≈ 4 days` after only ~4 Tier 1 calls —
> i.e. free accounts behave like the View/Collab monthly bucket, NOT 10/min. On a free
> account, budget ONE batched fetch per design and cache everything; for anything heavier
> use `figma-desktop` or a paid Dev/Full seat.

**Client-side guard:** `ak init` installs a PreToolUse hook
(`.claude/hooks/figma-rate-limit.js`) that throttles every `mcp__figma__*` call to
6 REST-call units per 60s (safe under the 10/min Starter budget; `download_figma_images`
counts as 3 units — it makes up to 3 REST calls internally). It sleeps instead of
failing, so calls are delayed — never dropped. Tune with `FIGMA_RATE_LIMIT_UNITS`
(e.g. `15` on a Professional plan).

**When you hit a 429, read the `Retry-After` header:**

- **≤ 60s** → per-minute bucket. Wait and retry once — this is normal on art-heavy frames.
- **Hours/days, or `X-Figma-Rate-Limit-Type: low`** → per-seat quota. A new token on the same
  account will NOT help. Fix: use a token from a Dev/Full seat, or switch to
  `ak init -a figma-desktop`.

---

## Troubleshooting

| Problem | Fix |
|---|---|
| `get_figma_data` tool not found | Run `ak init -a figma` to configure the MCP |
| "Invalid API token" | Token expired — create a new one at figma.com/settings |
| `429` immediately / every session | Token from a View/Collab seat (~6 calls/month) — see [Rate limits](#rate-limits-429) |
| Wrong node generated | Check the `node-id` in the URL matches your selection in Figma |
| Figma Desktop MCP not responding | Ensure Figma Desktop app is open with the file loaded |
| Component uses wrong framework | Add framework to `CLAUDE.md` (e.g. `nextjs-app-router`) |
