@relipa/ai-flow-kit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,207 +1,399 @@
1
- ---
2
- name: figma-to-component
3
- description: Read designs from Figma and generate React/Next.js/Vue components following project conventions. Supports specific frame URLs and entire pages.
4
- keywords: figma, design, component, ui, generate, react, nextjs, vue, frontend
5
- ---
6
-
7
- # Figma to Component
8
-
9
- ## When to use
10
-
11
- - Received a Figma link from a designer and need to generate a component
12
- - Designer has approved the UI, developer starts implementation
13
- - Need to ensure pixel-perfect matching with the design
14
-
15
- ---
16
-
17
- ## Process
18
-
19
- ### Step 1: Identify input
20
-
21
- Receive one of the following from the user:
22
- - Figma URL frame: `https://www.figma.com/design/<fileKey>/...?node-id=<nodeId>`
23
- - Figma URL file: `https://www.figma.com/design/<fileKey>/...`
24
- - Node description: "UserCard component in file ABC"
25
-
26
- Extract `fileKey` and `nodeId` from the URL.
27
-
28
- ### Step 2: Read design via Figma MCP
29
-
30
- Use Figma MCP tools to fetch design information:
31
-
32
- ```
33
- 1. Get node info: figma_get_file_nodes(fileKey, nodeIds=[nodeId])
34
- 2. Get styles: figma_get_file_styles(fileKey)
35
- 3. Get components: figma_get_file_components(fileKey) if needed
36
- 4. Export image if visual reference needed: figma_get_image(fileKey, nodeId)
37
- ```
38
-
39
- Analyze the output to extract:
40
- - **Layout**: flexbox direction, gap, padding, alignment
41
- - **Sizing**: width/height (fixed vs fill vs hug)
42
- - **Colors**: fills, strokes → map to Tailwind colors if available
43
- - **Typography**: font-size, font-weight, line-height, letter-spacing → map to Tailwind text classes
44
- - **Spacing**: padding, margin, gap → map to Tailwind spacing scale
45
- - **Border**: radius, width, color → map to Tailwind border classes
46
- - **Shadow**: box-shadow map to Tailwind shadow classes
47
- - **States**: hover, focus, disabled, active (if variants present)
48
- - **Responsive**: breakpoints if multiple frames present
49
-
50
- ### Step 3: Map Figma tokens → Tailwind / CSS
51
-
52
- **Color mapping:**
53
- ```
54
- Figma hex #3B82F6 Tailwind blue-500
55
- Figma hex #EF4444 → Tailwind red-500
56
- Figma rgba(0,0,0,0.5) Tailwind black/50
57
- No Tailwind match use arbitrary value [#hexcode]
58
- ```
59
-
60
- **Spacing mapping (8px grid):**
61
- ```
62
- 4px → p-1 / gap-1
63
- 8px → p-2 / gap-2
64
- 12px p-3 / gap-3
65
- 16px p-4 / gap-4
66
- 24px → p-6 / gap-6
67
- 32px p-8 / gap-8
68
- No match → arbitrary value [20px]
69
- ```
70
-
71
- **Typography mapping:**
72
- ```
73
- text-xs: 12px
74
- text-sm: 14px
75
- text-base: 16px
76
- text-lg: 18px
77
- text-xl: 20px
78
- text-2xl: 24px
79
- text-3xl: 30px
80
- font-normal: 400
81
- font-medium: 500
82
- font-semibold: 600
83
- font-bold: 700
84
- ```
85
-
86
- ### Step 4: Generate component
87
-
88
- **Framework detection** — check the project's CLAUDE.md to determine the framework:
89
- - `reactjs` / `nextjs` → generate `.tsx` with React conventions
90
- - `vue-nuxt` generate `.vue` with Vue 3 Composition API
91
-
92
- #### React/Next.js component template:
93
-
94
- ```tsx
95
- interface [ComponentName]Props {
96
- // Props extracted from Figma variants or dynamic content slots
97
- className?: string;
98
- }
99
-
100
- export const [ComponentName] = ({ className }: [ComponentName]Props) => {
101
- return (
102
- <div className={cn(
103
- // Layout classes
104
- // Sizing classes
105
- // Color classes
106
- // Typography classes (if text node)
107
- className
108
- )}>
109
- {/* Child nodes rendered recursively */}
110
- </div>
111
- );
112
- };
113
- ```
114
-
115
- #### Vue 3 component template:
116
-
117
- ```vue
118
- <script setup lang="ts">
119
- interface Props {
120
- // Props extracted from Figma variants
121
- class?: string;
122
- }
123
-
124
- const props = withDefaults(defineProps<Props>(), {});
125
- </script>
126
-
127
- <template>
128
- <div :class="cn(
129
- // Layout classes
130
- // Sizing classes
131
- // Color classes
132
- props.class
133
- )">
134
- <!-- Child nodes -->
135
- </div>
136
- </template>
137
- ```
138
-
139
- ### Step 5: Handle interactive states
140
-
141
- If Figma has variants (Default, Hover, Disabled, Active):
142
-
143
- ```tsx
144
- // Map variants into props + conditional classes
145
- interface ButtonProps {
146
- variant?: 'primary' | 'secondary' | 'outline';
147
- size?: 'sm' | 'md' | 'lg';
148
- disabled?: boolean;
149
- }
150
-
151
- const variantClasses = {
152
- primary: 'bg-blue-600 text-white hover:bg-blue-700',
153
- secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
154
- outline: 'border border-gray-300 hover:bg-gray-50',
155
- };
156
- ```
157
-
158
- ### Step 6: Verify and output
159
-
160
- After generation, verify:
161
-
162
- - [ ] Layout matches Figma (flex direction, alignment, gap)
163
- - [ ] Colors mapping correct (or use arbitrary values if no Tailwind match)
164
- - [ ] Typography correct (size, weight, line-height)
165
- - [ ] Spacing correct (padding, margin, gap)
166
- - [ ] Component has `className` prop for external overrides
167
- - [ ] Use `cn()` helper for conditional/mergeable classes
168
- - [ ] Responsive if Figma has mobile frames
169
- - [ ] Props typed with TypeScript interface
170
-
171
- ---
172
-
173
- ## Output format
174
-
175
- Always output in order:
176
-
177
- 1. **Design Summary** (brief): layout structure, color palette, typography scale
178
- 2. **Component file** with full code
179
- 3. **Usage example**:
180
- ```tsx
181
- <ComponentName variant="primary" className="mt-4" />
182
- ```
183
- 4. **Notes** if anything cannot be mapped 100% accurately from Figma
184
-
185
- ---
186
-
187
- ## Rules
188
-
189
- - **Do not hardcode** hex colors directly into className if a Tailwind equivalent exists
190
- - **Always use** `cn()` (clsx + twMerge) to merge classes
191
- - **No new CSS imports** — use Tailwind utilities only
192
- - **Responsive** if Figma only has 1 breakpoint, default to mobile-first design
193
- - **Accessibility** — add `aria-label`, `role`, `alt` for interactive and image elements
194
- - **Image** — use `next/image` for Next.js, `<img>` for React, add `alt` from Figma layer name
195
- - **Icon** — if Figma uses SVG icons, extract SVG or map to lucide-react / heroicons
196
-
197
- ---
198
-
199
- ## Trigger Example Commands
200
-
201
- ```
202
- Read Figma and generate component: https://www.figma.com/design/xxxxx/App?node-id=123-456
203
-
204
- Generate UserCard component from Figma frame node-id=123-456
205
-
206
- Implement UI from this Figma link following my project: [URL]
207
- ```
1
+ ---
2
+ name: figma-to-component
3
+ description: Read designs from Figma and generate React/Next.js App Router/Vue/Angular components following project conventions. Supports specific frame URLs and entire pages.
4
+ keywords: figma, design, component, ui, generate, react, nextjs, nextjs-app-router, vue, angular, frontend
5
+ ---
6
+
7
+ # Figma to Component
8
+
9
+ ## When to use
10
+
11
+ - Received a Figma link from a designer and need to generate a component
12
+ - Designer has approved the UI, developer starts implementation
13
+ - Need to ensure pixel-perfect matching with the design
14
+
15
+ ---
16
+
17
+ ## Step 0: Verify Figma MCP is available
18
+
19
+ Before doing anything, confirm the Figma MCP server is connected in this session:
20
+
21
+ - The tool `mcp__figma__get_figma_data` (and `mcp__figma__download_figma_images`) must be available.
22
+ - If it is **not** available, STOP and tell the developer:
23
+ > Figma MCP not connected. Run `aiflow init -a figma` (REST API token) or
24
+ > `aiflow init -a figma-desktop` (Figma Desktop), then restart the session.
25
+
26
+ Do not guess design values from the URL — without the MCP server the skill cannot read the design.
27
+
28
+ ---
29
+
30
+ ## Process
31
+
32
+ ### Step 1: Identify input
33
+
34
+ Receive one of the following from the user:
35
+ - Figma URL frame: `https://www.figma.com/design/<fileKey>/...?node-id=<nodeId>`
36
+ - Figma URL file: `https://www.figma.com/design/<fileKey>/...`
37
+ - Node description: "UserCard component in file ABC"
38
+
39
+ Extract `fileKey` and `nodeId` from the URL.
40
+
41
+ ### Step 2: Read design via Figma MCP
42
+
43
+ Use Figma MCP tools to fetch design information:
44
+
45
+ ```
46
+ 1. Get node info, styles, and components in one call:
47
+ get_figma_data(fileKey, nodeId, depth=2)
48
+
49
+ 2. Export image if visual reference needed:
50
+ download_figma_images(fileKey, nodes=[{ nodeId, fileName }], localPath)
51
+ ```
52
+
53
+ Note: `get_figma_data` returns layout, fills, strokes, typography, and component
54
+ definitions in a single response. No separate style or component fetch is needed.
55
+
56
+ Analyze the output to extract:
57
+ - **Layout**: flexbox direction, gap, padding, alignment
58
+ - **Sizing**: width/height (fixed vs fill vs hug)
59
+ - **Colors**: fills, strokes → map to project CSS tokens / Tailwind colors if available
60
+ - **Typography**: font-size, font-weight, line-height, letter-spacing
61
+ - **Spacing**: padding, margin, gap
62
+ - **Border**: radius, width, color
63
+ - **Shadow**: box-shadow
64
+ - **States**: hover, focus, disabled, active (if variants present)
65
+ - **Responsive**: breakpoints if multiple frames present
66
+
67
+ ### Step 2.5: Image Detection & Export
68
+
69
+ After receiving node data from Step 2, scan the entire node tree to detect image nodes:
70
+
71
+ **Detect image nodes:**
72
+ - Node has a `fills` array containing at least 1 fill with `type === "IMAGE"` → this is an image node
73
+ - Node is a frame/group containing many complex layers (icon, illustration, banner) that cannot be recreated with CSS → needs image export
74
+ - Node has `type === "VECTOR"` or `type === "BOOLEAN_OPERATION"` → always export as SVG/PNG
75
+
76
+ **Export images via MCP:**
77
+
78
+ For each detected image node, call MCP tool `download_figma_images`:
79
+
80
+ ```
81
+ download_figma_images({
82
+ fileKey: "<fileKey>",
83
+ nodes: [
84
+ { nodeId: "<nodeId>", fileName: "<layerName-nodeId>.png" }
85
+ ],
86
+ localPath: "public/assets/figma/"
87
+ })
88
+ ```
89
+
90
+ - `localPath` defaults to `public/assets/figma/` (relative to the project root)
91
+ - `fileName` follows the pattern: `<layer name in lowercase, spaces replaced with ->-<nodeId>.png`
92
+ - Example: layer "Banner Top" with nodeId "123-456" → `banner-top-123-456.png`
93
+ - If MCP does not support `download_figma_images`, get the image URL via `get_figma_data`, then notify DEV to download manually and place in `public/assets/figma/`
94
+
95
+ **Record the result:**
96
+
97
+ After export, save the mapping for use in Step 4:
98
+
99
+ ```
100
+ imageMap = {
101
+ "123-456": "public/assets/figma/banner-top-123-456.png",
102
+ "789-012": "public/assets/figma/icon-star-789-012.png"
103
+ }
104
+ ```
105
+
106
+ ### Step 3: Detect CSS tooling, then map Figma tokens
107
+
108
+ **Detect the project's styling approach first** (do not assume Tailwind):
109
+
110
+ 1. `tailwind.config.*` present → **Tailwind** — map to utility classes; extend `tailwind.config` with design tokens when a value has no built-in match
111
+ 2. `*.module.css` / `*.module.scss` files present → **CSS Modules** — emit a co-located `.module.css` and reference `styles.x`
112
+ 3. `styled-components` / `@emotion` in `package.json` → **CSS-in-JS** — emit styled components
113
+ 4. None of the above → **vanilla CSS** — emit a co-located `.css` file with CSS custom properties
114
+
115
+ **Design tokens:** prefer mapping Figma Styles/Variables to existing project tokens
116
+ (Tailwind theme keys or CSS custom properties) instead of hardcoding hex/px values.
117
+ Only fall back to an arbitrary value when no token matches.
118
+
119
+ **Tailwind reference mappings** (when Tailwind is the detected tooling):
120
+
121
+ ```
122
+ Color: #3B82F6 → blue-500 · #EF4444 → red-500 · rgba(0,0,0,0.5) → black/50
123
+ no match → arbitrary value [#hexcode]
124
+ Spacing: 4→p-1/gap-1 · 8→p-2 · 12→p-3 · 16→p-4 · 24→p-6 · 32→p-8 (8px grid)
125
+ no match → arbitrary value [20px]
126
+ Type: 12→text-xs · 14→text-sm · 16→text-base · 18→text-lg · 20→text-xl · 24→text-2xl · 30→text-3xl
127
+ 400→font-normal · 500→font-medium · 600→font-semibold · 700→font-bold
128
+ ```
129
+
130
+ ### Step 4: Generate component
131
+
132
+ **Framework detection** — check in this order:
133
+
134
+ 1. Read project's `CLAUDE.md` for framework identifier:
135
+ - `nextjs-app-router` → Next.js App Router (Server/Client Components)
136
+ - `reactjs` / `nextjs` → React / Next.js Pages Router `.tsx`
137
+ - `vue-nuxt` → Vue 3 `.vue` with Composition API
138
+ - `angular` → Angular `@Component` class
139
+ 2. Scan project files if CLAUDE.md is ambiguous:
140
+ - `app/` directory present → `nextjs-app-router`
141
+ - `angular.json` present `angular`
142
+ - `nuxt.config.*` present → `vue-nuxt`
143
+ 3. Fallback → `nextjs` (React Pages Router)
144
+
145
+ **Image node rendering rule:**
146
+
147
+ Before rendering each node, check `imageMap` from Step 2.5:
148
+ - If `nodeId` is in `imageMap` → render using `<img>` (React/Vue) or `<Image>` (Next.js), do NOT use CSS `background-image`
149
+ - If not in `imageMap` → render normally using div + styling classes
150
+
151
+ React/Next.js template for image node:
152
+ ```tsx
153
+ {/* Image node — exported from Figma */}
154
+ <img
155
+ src="/assets/figma/<fileName>.png"
156
+ alt="<layer name from Figma>"
157
+ width={<width from Figma>}
158
+ height={<height from Figma>}
159
+ className="<sizing classes if needed>"
160
+ />
161
+ ```
162
+
163
+ Next.js with `next/image`:
164
+ ```tsx
165
+ import Image from 'next/image';
166
+ <Image
167
+ src="/assets/figma/<fileName>.png"
168
+ alt="<layer name from Figma>"
169
+ width={<width from Figma>}
170
+ height={<height from Figma>}
171
+ />
172
+ ```
173
+
174
+ Vue 3 template for image node:
175
+ ```vue
176
+ <img
177
+ src="/assets/figma/<fileName>.png"
178
+ :alt="'<layer name from Figma>'"
179
+ :width="<width from Figma>"
180
+ :height="<height from Figma>"
181
+ />
182
+ ```
183
+
184
+ #### React/Next.js component template:
185
+
186
+ ```tsx
187
+ interface [ComponentName]Props {
188
+ // Props extracted from Figma variants or dynamic content slots
189
+ className?: string;
190
+ }
191
+
192
+ export const [ComponentName] = ({ className }: [ComponentName]Props) => {
193
+ return (
194
+ <div className={cn(
195
+ // Layout classes
196
+ // Sizing classes
197
+ // Color classes
198
+ // Typography classes (if text node)
199
+ className
200
+ )}>
201
+ {/* Child nodes rendered recursively */}
202
+ </div>
203
+ );
204
+ };
205
+ ```
206
+
207
+ #### Next.js App Router component template:
208
+
209
+ Default to **Server Component**. Add `'use client'` only when the design has
210
+ interactive states (hover effects, click handlers, form inputs, modals).
211
+
212
+ ```tsx
213
+ // Server Component — no interactivity (default)
214
+ interface [ComponentName]Props {
215
+ className?: string;
216
+ }
217
+
218
+ export default async function [ComponentName]({ className }: [ComponentName]Props) {
219
+ return (
220
+ <div className={cn(
221
+ // Layout classes
222
+ // Sizing classes
223
+ // Color classes
224
+ className
225
+ )}>
226
+ {/* Child nodes */}
227
+ </div>
228
+ );
229
+ }
230
+ ```
231
+
232
+ ```tsx
233
+ // Client Component — has onClick / useState / useEffect
234
+ 'use client'
235
+
236
+ import { useState } from 'react'
237
+
238
+ interface [ComponentName]Props {
239
+ className?: string;
240
+ }
241
+
242
+ export function [ComponentName]({ className }: [ComponentName]Props) {
243
+ return (
244
+ <div className={cn(
245
+ // Layout classes
246
+ // Sizing classes
247
+ // Color classes
248
+ className
249
+ )}>
250
+ {/* Child nodes */}
251
+ </div>
252
+ );
253
+ }
254
+ ```
255
+
256
+ File path: `app/components/[ComponentName].tsx` or `components/[ComponentName].tsx`
257
+
258
+ #### Vue 3 component template:
259
+
260
+ ```vue
261
+ <script setup lang="ts">
262
+ interface Props {
263
+ // Props extracted from Figma variants
264
+ class?: string;
265
+ }
266
+
267
+ const props = withDefaults(defineProps<Props>(), {});
268
+ </script>
269
+
270
+ <template>
271
+ <div :class="cn(
272
+ // Layout classes
273
+ // Sizing classes
274
+ // Color classes
275
+ props.class
276
+ )">
277
+ <!-- Child nodes -->
278
+ </div>
279
+ </template>
280
+ ```
281
+
282
+ #### Angular component template:
283
+
284
+ Use Tailwind classes if `tailwind.config.*` exists in the project root.
285
+ Otherwise use `styles` array with CSS-in-component.
286
+
287
+ ```typescript
288
+ import { Component, Input } from '@angular/core';
289
+ import { CommonModule } from '@angular/common';
290
+
291
+ @Component({
292
+ selector: 'app-[component-name]',
293
+ standalone: true,
294
+ imports: [CommonModule],
295
+ template: `
296
+ <div [class]="hostClasses">
297
+ <!-- Child nodes -->
298
+ </div>
299
+ `,
300
+ styles: []
301
+ })
302
+ export class [ComponentName]Component {
303
+ @Input() className = '';
304
+
305
+ get hostClasses(): string {
306
+ return [
307
+ // Layout classes
308
+ // Sizing classes
309
+ // Color classes
310
+ this.className
311
+ ].filter(Boolean).join(' ');
312
+ }
313
+ }
314
+ ```
315
+
316
+ ### Step 5: Handle interactive states
317
+
318
+ If Figma has variants (Default, Hover, Disabled, Active):
319
+
320
+ ```tsx
321
+ // Map variants into props + conditional classes
322
+ interface ButtonProps {
323
+ variant?: 'primary' | 'secondary' | 'outline';
324
+ size?: 'sm' | 'md' | 'lg';
325
+ disabled?: boolean;
326
+ }
327
+
328
+ const variantClasses = {
329
+ primary: 'bg-blue-600 text-white hover:bg-blue-700',
330
+ secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
331
+ outline: 'border border-gray-300 hover:bg-gray-50',
332
+ };
333
+ ```
334
+
335
+ ### Step 6: Verify and output
336
+
337
+ After generation, verify:
338
+
339
+ - [ ] Layout matches Figma (flex direction, alignment, gap)
340
+ - [ ] Colors mapping correct (project tokens, or arbitrary values if no match)
341
+ - [ ] Typography correct (size, weight, line-height)
342
+ - [ ] Spacing correct (padding, margin, gap)
343
+ - [ ] Component has `className` prop for external overrides
344
+ - [ ] Conditional/mergeable classes use the project's helper (`cn()` for Tailwind)
345
+ - [ ] Responsive if Figma has mobile frames
346
+ - [ ] Props typed with TypeScript interface
347
+ - [ ] Image nodes use `<img>` / `<Image>` (do not use CSS `background-image`)
348
+ - [ ] Image files exist in `public/assets/figma/` before submitting code
349
+
350
+ ---
351
+
352
+ ## Output format
353
+
354
+ Always output in order:
355
+
356
+ 1. **Design Summary** (brief): layout structure, color palette, typography scale
357
+ 2. **Component file** with full code
358
+ 3. **Usage example**:
359
+ ```tsx
360
+ <ComponentName variant="primary" className="mt-4" />
361
+ ```
362
+ 4. **Notes** if anything cannot be mapped 100% accurately from Figma
363
+
364
+ ---
365
+
366
+ ## Rules
367
+
368
+ - **Detect styling tooling first** — do not assume Tailwind; honour CSS Modules / styled-components / vanilla CSS when detected
369
+ - **Prefer design tokens** — map Figma Styles/Variables to project tokens; only hardcode a value when no token matches
370
+ - **Always use** the project's class-merge helper (`cn()` = clsx + twMerge for Tailwind)
371
+ - **Responsive** — if Figma only has 1 breakpoint, default to mobile-first design
372
+ - **Accessibility** — add `aria-label`, `role`, `alt` for interactive and image elements
373
+ - **Image** — detect image fills in Figma node data, export via `download_figma_images` MCP, save to `public/assets/figma/`. Use `<Image>` (Next.js) or `<img>` (React/Vue) with `src` pointing to the exported file. Do NOT use CSS `background-image` for image nodes.
374
+ - **Icon** — if Figma uses SVG icons, extract SVG or map to lucide-react / heroicons
375
+
376
+ ---
377
+
378
+ ## Troubleshooting
379
+
380
+ | Symptom | Cause | Fix |
381
+ |---------|-------|-----|
382
+ | `mcp__figma__get_figma_data` not available | Figma MCP server not connected | Run `aiflow init -a figma` or `-a figma-desktop`, restart session |
383
+ | `403 Forbidden` / token rejected | PAT invalid or wrong header | Re-issue a `figd_...` token; `init` sends `X-Figma-Token` (not `Bearer`) |
384
+ | Tool call hangs / times out | Large node tree (`depth` too high) | Lower `depth` (e.g. `depth=1`), target a specific `nodeId` not the whole file |
385
+ | `404` on node | Wrong `fileKey`/`nodeId` | Re-copy the frame URL; node-id uses `-` in URL but `:` in API |
386
+ | Empty fills / no styles | Node is a component instance | Fetch the main component, or increase `depth` |
387
+ | `download_figma_images` unsupported | Older MCP preset | Get image URL via `get_figma_data`, download manually to `public/assets/figma/` |
388
+
389
+ ---
390
+
391
+ ## Trigger Example Commands
392
+
393
+ ```
394
+ Read Figma and generate component: https://www.figma.com/design/xxxxx/App?node-id=123-456
395
+
396
+ Generate UserCard component from Figma frame node-id=123-456
397
+
398
+ Implement UI from this Figma link following my project: [URL]
399
+ ```