flutter-ui ยท git:20260827.127da4c ยท 2026-08-27 ยท sha256 3b96ce18b6b1124f

flutter-ui git:20260827.127da4cA

Immutable. This exact content never changes and is served at /api/v1/blob/3b96ce18b6b1124f.

---
name: flutter-ui
description: Build Flutter UI from Figma MCP or image input. Scans src for design tokens (colors, sizes, text styles), existing components, and naming conventions before writing a single line of code. Never hard-codes values.
---

# /supergraph:flutter-ui

Build pixel-faithful Flutter UI grounded in the project's own design system.

Announce: "๐ŸŽจ /supergraph:flutter-ui โ€” scanning project design system..."

## Input modes

- **Figma MCP** โ€” user provides a Figma URL or node ID
- **Image** โ€” user provides a screenshot or design image

Figma URL: extract `fileKey` (after `/design/`) and `nodeId` (`node-id` param, replace `-` with `:`).

---

## Step 1 โ€” Scan project design system

### 1a. Locate token files (prefer ripgrep, fallback to codebase-memory)

```bash
# Prefer ripgrep โ€” 10-20x faster than find|xargs grep; single pass covers all token types
rg --type dart --type yaml -l "Color|Colors\.|TextStyle|fontSize|FontWeight|EdgeInsets|Radius|ThemeData|colorScheme" | grep -iE "color|theme|token|palette|constant|style|text|typo|font|dimen|size|spacing|radius" | head -20
# Fallback if rg not available: codebase-memory search_graph(project=CBM_PROJECT, query="Color TextStyle EdgeInsets") or serena get_symbols_overview
find . \( -name "theme" -o -name "themes" \) -type d | head -10
```

### 1b. Extract token registry

Read identified files and extract:
- **Colors**: `grep -n "static.*Color\|Color(" <token_file> | head -40` โ†’ constant name โ†’ hex/Color value
- **Text styles**: `grep -n "TextStyle\|fontSize\|FontWeight" <style_file> | head -40` โ†’ style name โ†’ fontSize + weight + color
- **Spacing/sizing**: `grep -n "static.*double\|const.*= [0-9]" <dimen_file> | head -40` โ†’ constant name โ†’ value
- **Theme**: `grep -n "ThemeData\|colorScheme\|MaterialApp" <theme_file> | head -20` โ†’ determine access pattern (direct class vs `Theme.of(context)`)

### 1c. Find existing reusable widgets

```bash
find . -path "*/widgets/*.dart" -o -path "*/components/*.dart" -o -path "*/common/*.dart" | head -30
```
For each: `grep -n "class \|const \|required \|this\." <widget_file> | head -20` โ€” list as `WidgetName(params) โ†’ path`.

### 1d. Detect state management

```bash
grep -rn "import.*bloc\|import.*riverpod\|import.*provider\|import.*getx\|import.*mobx\|import.*signals" lib/ pubspec.yaml | head -10
```

### 1e. Detect naming & import convention

```bash
find . \( -path "*/lib/screens/*.dart" -o -path "*/lib/pages/*.dart" -o -path "*/lib/features/*.dart" \) | head -1
grep -n "import.*lib/" <reference_file> | head -10
```

---

## Step 2 โ€” Extract design from Figma or image

**Figma:** `mcp__Figma__get_figma_data(fileKey=<key>, nodeId=<nodeId>)` โ†’ extract layout, colors, text, corners, spacing, variants/states, icons.

**Image:** Analyze visually โ€” sections, layout direction, colors โ†’ match to nearest token.

Both: map every color/size/font to the token registry. **If no match โ†’ STOP, ask user before proceeding.**

Variants/interactive states (Figma): if node has variants (Normal/Hover/Disabled/Active) โ†’ map to boolean/enum param on the widget (`isDisabled`, `isActive`). Do NOT generate separate widgets per variant โ€” one widget with conditional styling.

Download custom assets if needed: `mcp__Figma__download_figma_images(...)`. Verify directory declared in `pubspec.yaml` under `flutter.assets:`.

---

## Step 3 โ€” Build token mapping table

| Design value | Token to use | Source |
|---|---|---|
| `#6C63FF` primary bg | `AppColors.primary` | registry |
| `24px bold` heading | `AppTextStyles.heading1` | registry |

**After building full table: any unmapped row โ†’ STOP, resolve with user before Step 4.**

---

## Step 4 โ€” Plan widget tree

Decompose into widget tree before coding. Rules:
- Reuse existing widgets (Step 1c) wherever shape/behavior matches
- Extract sections > 40 lines into private `_WidgetName` classes in same file
- No widget method extraction (`Widget _buildXxx()`) โ€” use classes

---

## Step 5 โ€” Generate code

**Token usage (CRITICAL):** Never hard-code colors, font sizes, spacing, or radius:
```dart
// โœ… color: AppColors.primary  fontSize: AppTextStyles.body.fontSize  padding: EdgeInsets.all(AppSizes.paddingM)
// โŒ color: Color(0xFF6C63FF)  fontSize: 14  padding: EdgeInsets.all(16)
```

**Structure:** One file per screen. File name/location matches Step 1e convention. `const` constructors where possible. No `print()`, no `TODO`.

**Assets:** Material icons โ†’ `Icon(Icons.xxx)`. Custom PNG/SVG โ†’ `flutter_gen` generated class (check existing screens for naming). Asset name format: `snake_case`, prefix `ic_`/`img_`/`bg_`, include state suffix. Verify `pubspec.yaml` declares the asset directory.

**If `flutter_gen` not in `pubspec.yaml`:** propose setup before writing any asset reference:
```yaml
dev_dependencies:
  build_runner:
  flutter_gen_runner:
flutter: { assets: [assets/images/, assets/icons/] }
```
Run `flutter pub get && dart run build_runner build`. Never fall back to `Image.asset(string)` or `SvgPicture.asset(string)`.

**Responsive:** Only add `LayoutBuilder` if design shows multiple form factors. **State:** Use pattern from Step 1d only. `const` constructors for stateless leaf widgets only โ€” omit where widget depends on runtime/reactive state.

---

## Step 6 โ€” Self-verify before handing off

```bash
grep -n "Color(0x\|Color\.from\|Colors\.\|Widget _build\|print(\|TODO" <generated_file>
grep -nE "EdgeInsets\.(all|symmetric|only)\([^A-Z]|fontSize:\s*[0-9]|SizedBox\((height|width):\s*[0-9]" <generated_file>
```

Fix all hits (exception: `Colors.transparent` is allowed). Unfixable โ†’ note and ask user.

---

## Output format

1. Token mapping table (Step 3)
2. Widget tree plan (Step 4 summary)
3. Generated code โ€” full file(s), ready to paste
4. Assets to download (if any)

---

## Hard rules

- NEVER hard-code color, font size, spacing, or radius
- NEVER introduce new design token without user approval
- NEVER use different state management from what src uses
- NEVER extract widget sections as methods โ€” use private classes
- ALWAYS scan src before reading Figma/image
- If registry empty โ†’ stop and ask where design tokens are declared