@discourser/design-system 0.22.2 → 0.22.4
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.
- package/dist/figma-codex.json +2 -2
- package/docs/CSS_USAGE.md +235 -0
- package/docs/FIGMA_MAKE_SETUP.md +339 -0
- package/docs/GUIDELINES_REVIEW.md +728 -0
- package/docs/MAINTAINER_CHECKLIST.md +265 -0
- package/docs/TESTING_QUICK_REFERENCE.md +159 -0
- package/docs/TESTING_TOKENS.md +340 -0
- package/docs/active-stories/README.md +29 -0
- package/docs/active-stories/STORY-006a-figma-translation-foundations.md +324 -0
- package/docs/active-stories/STORY-006b-figma-translation-components.md +201 -0
- package/docs/active-stories/STORY-006c-figma-translation-layout-extension.md +258 -0
- package/docs/active-stories/STORY-008-kai-sidecar-fragments.md +137 -0
- package/docs/active-stories/STORY-011-verify-translation-docs.md +182 -0
- package/docs/archive/ARCHITECTURE-discourser-design-system.md +448 -0
- package/docs/claude-feed-back/ARCHITECTURE_DIAGRAM.md +243 -0
- package/docs/claude-feed-back/STYLING_VERIFICATION.md +89 -0
- package/docs/claude-feed-back/TEST_RESULTS.md +182 -0
- package/docs/context-share/ELEVATION_FIX_PLAN.md +903 -0
- package/docs/context-share/STORY-001-VALIDATION-PASSED.md +192 -0
- package/docs/context-share/STORY-002-IMPLEMENTATION-COMPLETE.md +161 -0
- package/docs/context-share/STORYBOOK_MCP_STRATEGY.md +867 -0
- package/docs/context-share/TESTING_GAPS_FILLED.md +353 -0
- package/docs/context-share/TOKEN_TESTING_SUMMARY.md +388 -0
- package/docs/context-share/code-connect-prompt.md +90 -0
- package/docs/context-share/dds-autonomous-pipeline.md +765 -0
- package/docs/context-share/fix-checkbox-radio-tokens.md +145 -0
- package/docs/context-share/icon-component-prompt.md +154 -0
- package/docs/context-share/icons/Audience.svg +3 -0
- package/docs/context-share/icons/AudioSpeaker.svg +3 -0
- package/docs/context-share/icons/BookmarkPlus.svg +3 -0
- package/docs/context-share/icons/ClipBoard.svg +8 -0
- package/docs/context-share/icons/DiscourserLogo.svg +4 -0
- package/docs/context-share/icons/ExitStudio.svg +4 -0
- package/docs/context-share/icons/Microphone.svg +5 -0
- package/docs/context-share/icons/NotebookPen.svg +3 -0
- package/docs/context-share/icons/PausePlay.svg +5 -0
- package/docs/context-share/icons/Play.svg +4 -0
- package/docs/context-share/icons/Record.svg +6 -0
- package/docs/context-share/icons/RepeatQuestion.svg +3 -0
- package/docs/context-share/icons/ScrollText.svg +3 -0
- package/docs/context-share/icons/Sparkles.svg +3 -0
- package/docs/context-share/icons/Speech.svg +3 -0
- package/docs/context-share/icons/StopPlay.svg +4 -0
- package/docs/context-share/icons/Timer.svg +3 -0
- package/docs/context-share/icons/UserProfile.svg +3 -0
- package/docs/context-share/m3-token-pipeline-audit.md +125 -0
- package/docs/context-share/storybook-mcp-kai-agent-revised-summary.md +211 -0
- package/docs/discourser-design-system-prd.md +3698 -0
- package/docs/figma-captures/01-typography.png +0 -0
- package/docs/figma-captures/02-button-iconbutton.png +0 -0
- package/docs/figma-captures/03-form-inputs.png +0 -0
- package/docs/figma-captures/04-form-controls.png +0 -0
- package/docs/figma-captures/05-data-display.png +0 -0
- package/docs/figma-captures/06-feedback.png +0 -0
- package/docs/figma-captures/07-overlays.png +0 -0
- package/docs/figma-captures/08-navigation-layout.png +0 -0
- package/docs/figma-captures/09-custom-components.png +0 -0
- package/docs/figma-captures/10-scenario-queue.png +0 -0
- package/docs/figma-captures/11-icon-library.png +0 -0
- package/docs/figma-make-docs/01-understanding-templates.md +235 -0
- package/docs/figma-make-docs/02-prerequisites.md +266 -0
- package/docs/figma-make-docs/03-creating-template.md +306 -0
- package/docs/figma-make-docs/04-adding-guidelines.md +448 -0
- package/docs/figma-make-docs/05-example-starter-code.md +590 -0
- package/docs/figma-make-docs/06-publishing-template.md +417 -0
- package/docs/figma-make-docs/07-maintenance.md +536 -0
- package/docs/figma-make-docs/08-faq.md +490 -0
- package/docs/figma-make-docs/README.md +95 -0
- package/docs/material-theme.json +418 -0
- package/docs/plans/2026-03-12-figma-token-export-rewrite.md +504 -0
- package/docs/plans/2026-03-12-step7-panda-token-resolution-design.md +119 -0
- package/docs/plans/2026-03-12-step7-panda-token-resolution.md +993 -0
- package/docs/token-name-mapping.json +850 -0
- package/docs/token-name-mapping.md +251 -0
- package/package.json +3 -2
|
@@ -0,0 +1,765 @@
|
|
|
1
|
+
# DDS Code to Canvas + Code Connect — Autonomous Pipeline
|
|
2
|
+
|
|
3
|
+
> **IMPORTANT**: Execute ALL phases sequentially without stopping to ask for confirmation. Do NOT pause to ask "should I proceed?" or "would you like me to continue?" — just keep going. If a phase fails verification, fix it and retry before moving to the next phase. Only stop if you hit 3 consecutive failures on the same step.
|
|
4
|
+
|
|
5
|
+
> **CONTEXT**: Phase 1 (adding ScenarioQueue to the FullCatalog) was already completed and verified in a prior session. This pipeline covers Phase 2 (Code to Canvas) and Phase 3 (Code Connect setup).
|
|
6
|
+
|
|
7
|
+
> **FIGMA TOKEN**: Available in `.env` file as `FIGMA_ACCESS_TOKEN`. Load it with `source .env` or `export $(cat .env | xargs)` if needed for CLI commands.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Pre-Flight Checks
|
|
12
|
+
|
|
13
|
+
Before starting any phase, verify the environment is ready. Do all of these first:
|
|
14
|
+
|
|
15
|
+
### A. Verify Figma MCP is connected
|
|
16
|
+
|
|
17
|
+
Check that the Figma desktop MCP tools are available. You should have access to tools like `get_design_context`, `get_metadata`, `get_screenshot`, and importantly **write tools** for creating frames on the canvas. If the Figma MCP tools are not available, STOP and report that the Figma desktop MCP server is not connected — the user needs to enable it in Figma Dev Mode.
|
|
18
|
+
|
|
19
|
+
### B. Verify Storybook is running
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:6006 || echo "NOT_RUNNING"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If not running:
|
|
26
|
+
```bash
|
|
27
|
+
pnpm storybook &
|
|
28
|
+
sleep 15
|
|
29
|
+
# Verify it's up
|
|
30
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:6006
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### C. Verify Phase 1 is complete
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Check that ScenarioQueue is in the catalog
|
|
37
|
+
grep -c "ScenarioQueue" stories/ComponentCatalog.stories.tsx
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Should return a number > 0. If it returns 0, something went wrong with the prior session — but do NOT redo Phase 1, just note it and proceed.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Phase 2: Code to Canvas — Push FullCatalog to Figma
|
|
45
|
+
|
|
46
|
+
**Goal**: Capture the rendered FullCatalog from Storybook and push each section into the Figma file as editable frames.
|
|
47
|
+
|
|
48
|
+
**Target Figma file**: `https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm/V2-Discourser-FigmaLoop?node-id=0-1`
|
|
49
|
+
**File key**: `ua4LYtQHXt2lhHlCsSpdBm`
|
|
50
|
+
|
|
51
|
+
### 2A. Understand the catalog sections
|
|
52
|
+
|
|
53
|
+
The FullCatalog at `http://localhost:6006/?path=/story/design-system-component-catalog--full-catalog` contains these sections (in order):
|
|
54
|
+
|
|
55
|
+
1. **Typography** — Header component, 11 sizes
|
|
56
|
+
2. **Button & IconButton** — 6 variants × 7 sizes × 5 color palettes, states, ButtonGroup
|
|
57
|
+
3. **Form Inputs** — Input, InputGroup, Textarea
|
|
58
|
+
4. **Form Controls** — RadioGroup, Checkbox, Switch, Select, Slider
|
|
59
|
+
5. **Data Display** — Card, Badge, Avatar, Progress, Skeleton
|
|
60
|
+
6. **Feedback** — Spinner, CloseButton, Toast triggers, loading states
|
|
61
|
+
7. **Overlays** — Dialog, Drawer, Popover, Tooltip
|
|
62
|
+
8. **Navigation & Layout** — Breadcrumb, Accordion, Tabs, Stepper
|
|
63
|
+
9. **Custom Components** — ContentCard, NavigationMenu, ScenarioSettings, Stepper with content
|
|
64
|
+
10. **ScenarioQueue** — Full queue component, individual ScenarioCards
|
|
65
|
+
11. **Icon Library** — All 9 DDS icons
|
|
66
|
+
|
|
67
|
+
### 2B. Capture and push to Figma
|
|
68
|
+
|
|
69
|
+
Use the browser/devtools MCP to navigate to the Storybook FullCatalog URL at 1440px viewport width. Then use the Figma MCP write tools to push the captured UI into the target Figma file.
|
|
70
|
+
|
|
71
|
+
**Approach — for each section:**
|
|
72
|
+
1. Use the browser MCP to navigate to the FullCatalog story
|
|
73
|
+
2. Scroll to the section, take a screenshot or capture the rendered state
|
|
74
|
+
3. Use the Figma MCP to create a new frame on the canvas for that section
|
|
75
|
+
4. Name each frame clearly: `DDS / Typography`, `DDS / Button & IconButton`, `DDS / Form Inputs`, etc.
|
|
76
|
+
|
|
77
|
+
If the Figma MCP provides a "capture from browser" or "code to canvas" tool, use that directly — it will produce higher fidelity editable layers rather than rasterized screenshots.
|
|
78
|
+
|
|
79
|
+
If you cannot find write tools on the Figma MCP (only read tools are available), then:
|
|
80
|
+
- Document which tools ARE available
|
|
81
|
+
- Take screenshots of each section via browser MCP
|
|
82
|
+
- Save them to `docs/figma-captures/` as PNG files for manual import
|
|
83
|
+
- Report this in the summary and move on to Phase 3
|
|
84
|
+
|
|
85
|
+
### 2C. Verify Phase 2
|
|
86
|
+
|
|
87
|
+
Use `get_metadata` on the Figma file (node `0-1`) to confirm frames were created. List them by name.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Phase 3: Code Connect Setup
|
|
92
|
+
|
|
93
|
+
**Goal**: Set up Figma Code Connect so that Figma Dev Mode shows correct DDS React imports and usage examples when inspecting components.
|
|
94
|
+
|
|
95
|
+
### 3A. Install Code Connect
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pnpm add -D @figma/code-connect
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3B. Create `figma.config.json` at project root
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"codeConnect": {
|
|
106
|
+
"parser": "react",
|
|
107
|
+
"include": ["src/components/**/*.figma.tsx"],
|
|
108
|
+
"importPaths": {
|
|
109
|
+
"src/components/*": "@discourser/design-system"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3C. Create `.figma.tsx` annotation files
|
|
116
|
+
|
|
117
|
+
Create one `.figma.tsx` file per component. These map Figma components to real code. The `figmaNodeUrl` values use the file URL as a base — they'll be refined once components exist as Figma component nodes.
|
|
118
|
+
|
|
119
|
+
**Base URL for all**: `https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm`
|
|
120
|
+
|
|
121
|
+
Create ALL of the following files. Do not skip any. Do not stop to ask if you should continue.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
#### `src/components/Button.figma.tsx`
|
|
126
|
+
```tsx
|
|
127
|
+
import figma from '@figma/code-connect'
|
|
128
|
+
import { Button } from './Button'
|
|
129
|
+
|
|
130
|
+
figma.connect(Button, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
131
|
+
props: {
|
|
132
|
+
variant: figma.enum('Variant', {
|
|
133
|
+
Solid: 'solid', Elevated: 'elevated', Surface: 'surface',
|
|
134
|
+
Subtle: 'subtle', Outline: 'outline', Plain: 'plain',
|
|
135
|
+
}),
|
|
136
|
+
colorPalette: figma.enum('Color Palette', {
|
|
137
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
138
|
+
Neutral: 'neutral', Error: 'error',
|
|
139
|
+
}),
|
|
140
|
+
size: figma.enum('Size', {
|
|
141
|
+
'2xs': '2xs', xs: 'xs', sm: 'sm', md: 'md', lg: 'lg', xl: 'xl', '2xl': '2xl',
|
|
142
|
+
}),
|
|
143
|
+
disabled: figma.boolean('Disabled'),
|
|
144
|
+
loading: figma.boolean('Loading'),
|
|
145
|
+
label: figma.string('Label'),
|
|
146
|
+
},
|
|
147
|
+
example: ({ variant, colorPalette, size, disabled, loading, label }) => (
|
|
148
|
+
<Button variant={variant} colorPalette={colorPalette} size={size} disabled={disabled} loading={loading}>
|
|
149
|
+
{label}
|
|
150
|
+
</Button>
|
|
151
|
+
),
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### `src/components/IconButton.figma.tsx`
|
|
156
|
+
```tsx
|
|
157
|
+
import figma from '@figma/code-connect'
|
|
158
|
+
import { IconButton } from './IconButton'
|
|
159
|
+
|
|
160
|
+
figma.connect(IconButton, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
161
|
+
props: {
|
|
162
|
+
variant: figma.enum('Variant', {
|
|
163
|
+
Solid: 'solid', Elevated: 'elevated', Surface: 'surface',
|
|
164
|
+
Subtle: 'subtle', Outline: 'outline', Plain: 'plain',
|
|
165
|
+
}),
|
|
166
|
+
colorPalette: figma.enum('Color Palette', {
|
|
167
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
168
|
+
Neutral: 'neutral', Error: 'error',
|
|
169
|
+
}),
|
|
170
|
+
size: figma.enum('Size', {
|
|
171
|
+
'2xs': '2xs', xs: 'xs', sm: 'sm', md: 'md', lg: 'lg', xl: 'xl', '2xl': '2xl',
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
example: ({ variant, colorPalette, size }) => (
|
|
175
|
+
<IconButton variant={variant} colorPalette={colorPalette} size={size} aria-label="Action">
|
|
176
|
+
{/* icon */}
|
|
177
|
+
</IconButton>
|
|
178
|
+
),
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `src/components/Input.figma.tsx`
|
|
183
|
+
```tsx
|
|
184
|
+
import figma from '@figma/code-connect'
|
|
185
|
+
import { Input } from './Input'
|
|
186
|
+
|
|
187
|
+
figma.connect(Input, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
188
|
+
props: {
|
|
189
|
+
size: figma.enum('Size', { sm: 'sm', md: 'md', lg: 'lg', xl: 'xl', '2xl': '2xl' }),
|
|
190
|
+
disabled: figma.boolean('Disabled'),
|
|
191
|
+
placeholder: figma.string('Placeholder'),
|
|
192
|
+
},
|
|
193
|
+
example: ({ size, disabled, placeholder }) => (
|
|
194
|
+
<Input size={size} disabled={disabled} placeholder={placeholder} />
|
|
195
|
+
),
|
|
196
|
+
})
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### `src/components/Textarea.figma.tsx`
|
|
200
|
+
```tsx
|
|
201
|
+
import figma from '@figma/code-connect'
|
|
202
|
+
import { Textarea } from './Textarea'
|
|
203
|
+
|
|
204
|
+
figma.connect(Textarea, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
205
|
+
props: {
|
|
206
|
+
disabled: figma.boolean('Disabled'),
|
|
207
|
+
placeholder: figma.string('Placeholder'),
|
|
208
|
+
},
|
|
209
|
+
example: ({ disabled, placeholder }) => (
|
|
210
|
+
<Textarea disabled={disabled} placeholder={placeholder} rows={3} />
|
|
211
|
+
),
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### `src/components/Header.figma.tsx`
|
|
216
|
+
```tsx
|
|
217
|
+
import figma from '@figma/code-connect'
|
|
218
|
+
import { Header } from './Header'
|
|
219
|
+
|
|
220
|
+
figma.connect(Header, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
221
|
+
props: {
|
|
222
|
+
size: figma.enum('Size', {
|
|
223
|
+
'7xl': '7xl', '6xl': '6xl', '5xl': '5xl', '4xl': '4xl',
|
|
224
|
+
'3xl': '3xl', '2xl': '2xl', xl: 'xl', lg: 'lg',
|
|
225
|
+
md: 'md', sm: 'sm', xs: 'xs',
|
|
226
|
+
}),
|
|
227
|
+
children: figma.string('Text'),
|
|
228
|
+
},
|
|
229
|
+
example: ({ size, children }) => <Header size={size}>{children}</Header>,
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### `src/components/Badge.figma.tsx`
|
|
234
|
+
```tsx
|
|
235
|
+
import figma from '@figma/code-connect'
|
|
236
|
+
import { Badge } from './Badge'
|
|
237
|
+
|
|
238
|
+
figma.connect(Badge, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
239
|
+
props: {
|
|
240
|
+
variant: figma.enum('Variant', { Solid: 'solid', Subtle: 'subtle', Outline: 'outline' }),
|
|
241
|
+
colorPalette: figma.enum('Color Palette', {
|
|
242
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
243
|
+
Neutral: 'neutral', Error: 'error',
|
|
244
|
+
}),
|
|
245
|
+
size: figma.enum('Size', { sm: 'sm', md: 'md', lg: 'lg', xl: 'xl' }),
|
|
246
|
+
label: figma.string('Label'),
|
|
247
|
+
},
|
|
248
|
+
example: ({ variant, colorPalette, size, label }) => (
|
|
249
|
+
<Badge variant={variant} colorPalette={colorPalette} size={size}>{label}</Badge>
|
|
250
|
+
),
|
|
251
|
+
})
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### `src/components/Spinner.figma.tsx`
|
|
255
|
+
```tsx
|
|
256
|
+
import figma from '@figma/code-connect'
|
|
257
|
+
import { Spinner } from './Spinner'
|
|
258
|
+
|
|
259
|
+
figma.connect(Spinner, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
260
|
+
props: {
|
|
261
|
+
size: figma.enum('Size', { xs: 'xs', sm: 'sm', md: 'md', lg: 'lg', xl: 'xl' }),
|
|
262
|
+
colorPalette: figma.enum('Color Palette', {
|
|
263
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
264
|
+
Neutral: 'neutral', Error: 'error',
|
|
265
|
+
}),
|
|
266
|
+
},
|
|
267
|
+
example: ({ size, colorPalette }) => <Spinner size={size} colorPalette={colorPalette} />,
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### `src/components/Card.figma.tsx`
|
|
272
|
+
```tsx
|
|
273
|
+
import figma from '@figma/code-connect'
|
|
274
|
+
import * as Card from './Card'
|
|
275
|
+
|
|
276
|
+
figma.connect(Card.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
277
|
+
props: {
|
|
278
|
+
variant: figma.enum('Variant', { Elevated: 'elevated', Outline: 'outline', Subtle: 'subtle' }),
|
|
279
|
+
},
|
|
280
|
+
example: ({ variant }) => (
|
|
281
|
+
<Card.Root variant={variant}>
|
|
282
|
+
<Card.Header>
|
|
283
|
+
<Card.Title>Title</Card.Title>
|
|
284
|
+
<Card.Description>Description</Card.Description>
|
|
285
|
+
</Card.Header>
|
|
286
|
+
<Card.Body>Content</Card.Body>
|
|
287
|
+
<Card.Footer>Footer</Card.Footer>
|
|
288
|
+
</Card.Root>
|
|
289
|
+
),
|
|
290
|
+
})
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### `src/components/Checkbox.figma.tsx`
|
|
294
|
+
```tsx
|
|
295
|
+
import figma from '@figma/code-connect'
|
|
296
|
+
import * as Checkbox from './Checkbox'
|
|
297
|
+
|
|
298
|
+
figma.connect(Checkbox.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
299
|
+
props: {
|
|
300
|
+
colorPalette: figma.enum('Color Palette', {
|
|
301
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
302
|
+
Neutral: 'neutral', Error: 'error',
|
|
303
|
+
}),
|
|
304
|
+
disabled: figma.boolean('Disabled'),
|
|
305
|
+
label: figma.string('Label'),
|
|
306
|
+
},
|
|
307
|
+
example: ({ colorPalette, disabled, label }) => (
|
|
308
|
+
<Checkbox.Root colorPalette={colorPalette} disabled={disabled}>
|
|
309
|
+
<Checkbox.Control><Checkbox.Indicator /></Checkbox.Control>
|
|
310
|
+
<Checkbox.Label>{label}</Checkbox.Label>
|
|
311
|
+
<Checkbox.HiddenInput />
|
|
312
|
+
</Checkbox.Root>
|
|
313
|
+
),
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
#### `src/components/Switch.figma.tsx`
|
|
318
|
+
```tsx
|
|
319
|
+
import figma from '@figma/code-connect'
|
|
320
|
+
import * as Switch from './Switch'
|
|
321
|
+
|
|
322
|
+
figma.connect(Switch.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
323
|
+
props: {
|
|
324
|
+
colorPalette: figma.enum('Color Palette', {
|
|
325
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
326
|
+
Neutral: 'neutral', Error: 'error',
|
|
327
|
+
}),
|
|
328
|
+
disabled: figma.boolean('Disabled'),
|
|
329
|
+
label: figma.string('Label'),
|
|
330
|
+
},
|
|
331
|
+
example: ({ colorPalette, disabled, label }) => (
|
|
332
|
+
<Switch.Root colorPalette={colorPalette} disabled={disabled}>
|
|
333
|
+
<Switch.Control><Switch.Thumb /></Switch.Control>
|
|
334
|
+
<Switch.Label>{label}</Switch.Label>
|
|
335
|
+
<Switch.HiddenInput />
|
|
336
|
+
</Switch.Root>
|
|
337
|
+
),
|
|
338
|
+
})
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### `src/components/Tabs.figma.tsx`
|
|
342
|
+
```tsx
|
|
343
|
+
import figma from '@figma/code-connect'
|
|
344
|
+
import * as Tabs from './Tabs'
|
|
345
|
+
|
|
346
|
+
figma.connect(Tabs.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
347
|
+
example: () => (
|
|
348
|
+
<Tabs.Root defaultValue="tab1">
|
|
349
|
+
<Tabs.List>
|
|
350
|
+
<Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
|
|
351
|
+
<Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
|
|
352
|
+
<Tabs.Indicator />
|
|
353
|
+
</Tabs.List>
|
|
354
|
+
<Tabs.Content value="tab1">Content 1</Tabs.Content>
|
|
355
|
+
<Tabs.Content value="tab2">Content 2</Tabs.Content>
|
|
356
|
+
</Tabs.Root>
|
|
357
|
+
),
|
|
358
|
+
})
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
#### `src/components/Accordion.figma.tsx`
|
|
362
|
+
```tsx
|
|
363
|
+
import figma from '@figma/code-connect'
|
|
364
|
+
import * as Accordion from './Accordion'
|
|
365
|
+
|
|
366
|
+
figma.connect(Accordion.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
367
|
+
example: () => (
|
|
368
|
+
<Accordion.Root collapsible>
|
|
369
|
+
<Accordion.Item value="item-1">
|
|
370
|
+
<Accordion.ItemTrigger>
|
|
371
|
+
<span>Trigger</span>
|
|
372
|
+
<Accordion.ItemIndicator />
|
|
373
|
+
</Accordion.ItemTrigger>
|
|
374
|
+
<Accordion.ItemContent>Content</Accordion.ItemContent>
|
|
375
|
+
</Accordion.Item>
|
|
376
|
+
</Accordion.Root>
|
|
377
|
+
),
|
|
378
|
+
})
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
#### `src/components/Dialog.figma.tsx`
|
|
382
|
+
```tsx
|
|
383
|
+
import figma from '@figma/code-connect'
|
|
384
|
+
import * as Dialog from './Dialog'
|
|
385
|
+
|
|
386
|
+
figma.connect(Dialog.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
387
|
+
example: () => (
|
|
388
|
+
<Dialog.Root>
|
|
389
|
+
<Dialog.Trigger asChild><button>Open</button></Dialog.Trigger>
|
|
390
|
+
<Dialog.Backdrop />
|
|
391
|
+
<Dialog.Positioner>
|
|
392
|
+
<Dialog.Content>
|
|
393
|
+
<Dialog.Header>
|
|
394
|
+
<Dialog.Title>Title</Dialog.Title>
|
|
395
|
+
<Dialog.CloseTrigger />
|
|
396
|
+
</Dialog.Header>
|
|
397
|
+
<Dialog.Body>Content</Dialog.Body>
|
|
398
|
+
</Dialog.Content>
|
|
399
|
+
</Dialog.Positioner>
|
|
400
|
+
</Dialog.Root>
|
|
401
|
+
),
|
|
402
|
+
})
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### `src/components/Drawer.figma.tsx`
|
|
406
|
+
```tsx
|
|
407
|
+
import figma from '@figma/code-connect'
|
|
408
|
+
import * as Drawer from './Drawer'
|
|
409
|
+
|
|
410
|
+
figma.connect(Drawer.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
411
|
+
example: () => (
|
|
412
|
+
<Drawer.Root>
|
|
413
|
+
<Drawer.Trigger asChild><button>Open</button></Drawer.Trigger>
|
|
414
|
+
<Drawer.Backdrop />
|
|
415
|
+
<Drawer.Positioner>
|
|
416
|
+
<Drawer.Content>
|
|
417
|
+
<Drawer.Header>
|
|
418
|
+
<Drawer.Title>Title</Drawer.Title>
|
|
419
|
+
<Drawer.CloseTrigger />
|
|
420
|
+
</Drawer.Header>
|
|
421
|
+
<Drawer.Body>Content</Drawer.Body>
|
|
422
|
+
</Drawer.Content>
|
|
423
|
+
</Drawer.Positioner>
|
|
424
|
+
</Drawer.Root>
|
|
425
|
+
),
|
|
426
|
+
})
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### `src/components/Select.figma.tsx`
|
|
430
|
+
```tsx
|
|
431
|
+
import figma from '@figma/code-connect'
|
|
432
|
+
import * as Select from './Select'
|
|
433
|
+
|
|
434
|
+
figma.connect(Select.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
435
|
+
example: () => (
|
|
436
|
+
<Select.Root collection={collection}>
|
|
437
|
+
<Select.Label>Label</Select.Label>
|
|
438
|
+
<Select.Control>
|
|
439
|
+
<Select.Trigger>
|
|
440
|
+
<Select.ValueText placeholder="Select..." />
|
|
441
|
+
<Select.Indicator />
|
|
442
|
+
</Select.Trigger>
|
|
443
|
+
</Select.Control>
|
|
444
|
+
<Select.Positioner>
|
|
445
|
+
<Select.Content>
|
|
446
|
+
<Select.ItemGroup>
|
|
447
|
+
<Select.Item item={item}>
|
|
448
|
+
<Select.ItemText>{item.label}</Select.ItemText>
|
|
449
|
+
</Select.Item>
|
|
450
|
+
</Select.ItemGroup>
|
|
451
|
+
</Select.Content>
|
|
452
|
+
</Select.Positioner>
|
|
453
|
+
<Select.HiddenSelect />
|
|
454
|
+
</Select.Root>
|
|
455
|
+
),
|
|
456
|
+
})
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
#### `src/components/Slider.figma.tsx`
|
|
460
|
+
```tsx
|
|
461
|
+
import figma from '@figma/code-connect'
|
|
462
|
+
import * as Slider from './Slider'
|
|
463
|
+
|
|
464
|
+
figma.connect(Slider.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
465
|
+
props: {
|
|
466
|
+
colorPalette: figma.enum('Color Palette', {
|
|
467
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
468
|
+
Neutral: 'neutral', Error: 'error',
|
|
469
|
+
}),
|
|
470
|
+
},
|
|
471
|
+
example: ({ colorPalette }) => (
|
|
472
|
+
<Slider.Root colorPalette={colorPalette}>
|
|
473
|
+
<Slider.Label>Label</Slider.Label>
|
|
474
|
+
<Slider.ValueText />
|
|
475
|
+
<Slider.Control>
|
|
476
|
+
<Slider.Track><Slider.Range /></Slider.Track>
|
|
477
|
+
<Slider.Thumb index={0}><Slider.HiddenInput /></Slider.Thumb>
|
|
478
|
+
</Slider.Control>
|
|
479
|
+
</Slider.Root>
|
|
480
|
+
),
|
|
481
|
+
})
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### `src/components/RadioGroup.figma.tsx`
|
|
485
|
+
```tsx
|
|
486
|
+
import figma from '@figma/code-connect'
|
|
487
|
+
import * as RadioGroup from './RadioGroup'
|
|
488
|
+
|
|
489
|
+
figma.connect(RadioGroup.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
490
|
+
props: {
|
|
491
|
+
colorPalette: figma.enum('Color Palette', {
|
|
492
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary',
|
|
493
|
+
Neutral: 'neutral', Error: 'error',
|
|
494
|
+
}),
|
|
495
|
+
},
|
|
496
|
+
example: ({ colorPalette }) => (
|
|
497
|
+
<RadioGroup.Root colorPalette={colorPalette}>
|
|
498
|
+
<RadioGroup.Item value="option">
|
|
499
|
+
<RadioGroup.ItemControl />
|
|
500
|
+
<RadioGroup.ItemText>Option</RadioGroup.ItemText>
|
|
501
|
+
<RadioGroup.ItemHiddenInput />
|
|
502
|
+
</RadioGroup.Item>
|
|
503
|
+
</RadioGroup.Root>
|
|
504
|
+
),
|
|
505
|
+
})
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### `src/components/Avatar.figma.tsx`
|
|
509
|
+
```tsx
|
|
510
|
+
import figma from '@figma/code-connect'
|
|
511
|
+
import * as Avatar from './Avatar'
|
|
512
|
+
|
|
513
|
+
figma.connect(Avatar.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
514
|
+
props: {
|
|
515
|
+
size: figma.enum('Size', { xs: 'xs', sm: 'sm', md: 'md', lg: 'lg', xl: 'xl', '2xl': '2xl' }),
|
|
516
|
+
},
|
|
517
|
+
example: ({ size }) => (
|
|
518
|
+
<Avatar.Root size={size}>
|
|
519
|
+
<Avatar.Image src="avatar.jpg" alt="User" />
|
|
520
|
+
<Avatar.Fallback name="User Name" />
|
|
521
|
+
</Avatar.Root>
|
|
522
|
+
),
|
|
523
|
+
})
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
#### `src/components/Progress.figma.tsx`
|
|
527
|
+
```tsx
|
|
528
|
+
import figma from '@figma/code-connect'
|
|
529
|
+
import * as Progress from './Progress'
|
|
530
|
+
|
|
531
|
+
figma.connect(Progress.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
532
|
+
props: {
|
|
533
|
+
colorPalette: figma.enum('Color Palette', {
|
|
534
|
+
Primary: 'primary', Secondary: 'secondary', Tertiary: 'tertiary', Error: 'error',
|
|
535
|
+
}),
|
|
536
|
+
},
|
|
537
|
+
example: ({ colorPalette }) => (
|
|
538
|
+
<Progress.Root value={50} colorPalette={colorPalette}>
|
|
539
|
+
<Progress.Label>Label</Progress.Label>
|
|
540
|
+
<Progress.ValueText />
|
|
541
|
+
<Progress.Track><Progress.Range /></Progress.Track>
|
|
542
|
+
</Progress.Root>
|
|
543
|
+
),
|
|
544
|
+
})
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
#### `src/components/Tooltip.figma.tsx`
|
|
548
|
+
```tsx
|
|
549
|
+
import figma from '@figma/code-connect'
|
|
550
|
+
import * as Tooltip from './Tooltip'
|
|
551
|
+
|
|
552
|
+
figma.connect(Tooltip.Tooltip, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
553
|
+
props: {
|
|
554
|
+
content: figma.string('Content'),
|
|
555
|
+
},
|
|
556
|
+
example: ({ content }) => (
|
|
557
|
+
<Tooltip.Tooltip content={content} showArrow>
|
|
558
|
+
<button>Trigger</button>
|
|
559
|
+
</Tooltip.Tooltip>
|
|
560
|
+
),
|
|
561
|
+
})
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
#### `src/components/Popover.figma.tsx`
|
|
565
|
+
```tsx
|
|
566
|
+
import figma from '@figma/code-connect'
|
|
567
|
+
import * as Popover from './Popover'
|
|
568
|
+
|
|
569
|
+
figma.connect(Popover.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
570
|
+
example: () => (
|
|
571
|
+
<Popover.Root>
|
|
572
|
+
<Popover.Trigger asChild><button>Trigger</button></Popover.Trigger>
|
|
573
|
+
<Popover.Positioner>
|
|
574
|
+
<Popover.Content>
|
|
575
|
+
<Popover.Arrow><Popover.ArrowTip /></Popover.Arrow>
|
|
576
|
+
<Popover.Title>Title</Popover.Title>
|
|
577
|
+
<Popover.Description>Description</Popover.Description>
|
|
578
|
+
</Popover.Content>
|
|
579
|
+
</Popover.Positioner>
|
|
580
|
+
</Popover.Root>
|
|
581
|
+
),
|
|
582
|
+
})
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
#### `src/components/Breadcrumb.figma.tsx`
|
|
586
|
+
```tsx
|
|
587
|
+
import figma from '@figma/code-connect'
|
|
588
|
+
import * as Breadcrumb from './Breadcrumb'
|
|
589
|
+
|
|
590
|
+
figma.connect(Breadcrumb.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
591
|
+
example: () => (
|
|
592
|
+
<Breadcrumb.Root>
|
|
593
|
+
<Breadcrumb.List>
|
|
594
|
+
<Breadcrumb.Item>
|
|
595
|
+
<Breadcrumb.Link href="#">Home</Breadcrumb.Link>
|
|
596
|
+
</Breadcrumb.Item>
|
|
597
|
+
<Breadcrumb.Separator />
|
|
598
|
+
<Breadcrumb.Item>
|
|
599
|
+
<Breadcrumb.CurrentLink>Current</Breadcrumb.CurrentLink>
|
|
600
|
+
</Breadcrumb.Item>
|
|
601
|
+
</Breadcrumb.List>
|
|
602
|
+
</Breadcrumb.Root>
|
|
603
|
+
),
|
|
604
|
+
})
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
#### `src/components/ContentCard/ContentCard.figma.tsx`
|
|
608
|
+
```tsx
|
|
609
|
+
import figma from '@figma/code-connect'
|
|
610
|
+
import * as ContentCard from './index'
|
|
611
|
+
|
|
612
|
+
figma.connect(ContentCard.Root, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
613
|
+
props: {
|
|
614
|
+
variant: figma.enum('Variant', { Outline: 'outline', Elevated: 'elevated', Flat: 'flat' }),
|
|
615
|
+
size: figma.enum('Size', { sm: 'sm', md: 'md', lg: 'lg' }),
|
|
616
|
+
},
|
|
617
|
+
example: ({ variant, size }) => (
|
|
618
|
+
<ContentCard.Root variant={variant} size={size}>
|
|
619
|
+
<ContentCard.Header>
|
|
620
|
+
<ContentCard.Title>Title</ContentCard.Title>
|
|
621
|
+
<ContentCard.BadgeBar>badges</ContentCard.BadgeBar>
|
|
622
|
+
</ContentCard.Header>
|
|
623
|
+
<ContentCard.Body>Content</ContentCard.Body>
|
|
624
|
+
<ContentCard.Separator />
|
|
625
|
+
<ContentCard.Section>
|
|
626
|
+
<ContentCard.SectionTitle>Section</ContentCard.SectionTitle>
|
|
627
|
+
<ContentCard.List>
|
|
628
|
+
<ContentCard.ListItem>Item</ContentCard.ListItem>
|
|
629
|
+
</ContentCard.List>
|
|
630
|
+
</ContentCard.Section>
|
|
631
|
+
</ContentCard.Root>
|
|
632
|
+
),
|
|
633
|
+
})
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
#### `src/components/NavigationMenu/NavigationMenu.figma.tsx`
|
|
637
|
+
```tsx
|
|
638
|
+
import figma from '@figma/code-connect'
|
|
639
|
+
import { NavigationMenu } from './index'
|
|
640
|
+
|
|
641
|
+
figma.connect(NavigationMenu, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
642
|
+
example: () => (
|
|
643
|
+
<NavigationMenu
|
|
644
|
+
sections={sections}
|
|
645
|
+
defaultOpenSections={['dashboard']}
|
|
646
|
+
activeHref="/dashboard/progress"
|
|
647
|
+
/>
|
|
648
|
+
),
|
|
649
|
+
})
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
#### `src/components/ScenarioSettings/ScenarioSettings.figma.tsx`
|
|
653
|
+
```tsx
|
|
654
|
+
import figma from '@figma/code-connect'
|
|
655
|
+
import { ScenarioSettings } from './index'
|
|
656
|
+
|
|
657
|
+
figma.connect(ScenarioSettings, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
658
|
+
example: () => (
|
|
659
|
+
<ScenarioSettings
|
|
660
|
+
defaultValue={['duration', 'number-of-questions']}
|
|
661
|
+
defaultDuration="standard"
|
|
662
|
+
defaultQuestionCount="standard"
|
|
663
|
+
/>
|
|
664
|
+
),
|
|
665
|
+
})
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
#### `src/components/ScenarioQueue/ScenarioQueue.figma.tsx`
|
|
669
|
+
```tsx
|
|
670
|
+
import figma from '@figma/code-connect'
|
|
671
|
+
import { ScenarioQueue } from './index'
|
|
672
|
+
|
|
673
|
+
figma.connect(ScenarioQueue, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
674
|
+
example: () => (
|
|
675
|
+
<ScenarioQueue
|
|
676
|
+
scenarios={scenarios}
|
|
677
|
+
onReorder={handleReorder}
|
|
678
|
+
onRequeue={handleRequeue}
|
|
679
|
+
/>
|
|
680
|
+
),
|
|
681
|
+
})
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
#### `src/components/Stepper/Stepper.figma.tsx`
|
|
685
|
+
```tsx
|
|
686
|
+
import figma from '@figma/code-connect'
|
|
687
|
+
import { Stepper } from './index'
|
|
688
|
+
|
|
689
|
+
figma.connect(Stepper, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
690
|
+
props: {
|
|
691
|
+
colorPalette: figma.enum('Color Palette', { Primary: 'primary', Secondary: 'secondary' }),
|
|
692
|
+
},
|
|
693
|
+
example: ({ colorPalette }) => (
|
|
694
|
+
<Stepper
|
|
695
|
+
steps={steps}
|
|
696
|
+
defaultStep={0}
|
|
697
|
+
colorPalette={colorPalette}
|
|
698
|
+
showContent
|
|
699
|
+
showActions
|
|
700
|
+
/>
|
|
701
|
+
),
|
|
702
|
+
})
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
#### `src/components/Skeleton.figma.tsx`
|
|
706
|
+
```tsx
|
|
707
|
+
import figma from '@figma/code-connect'
|
|
708
|
+
import * as Skeleton from './Skeleton'
|
|
709
|
+
|
|
710
|
+
figma.connect(Skeleton.Skeleton, 'https://www.figma.com/design/ua4LYtQHXt2lhHlCsSpdBm', {
|
|
711
|
+
example: () => <Skeleton.Skeleton css={{ h: '4', w: '40', borderRadius: 'md' }} />,
|
|
712
|
+
})
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### 3D. Add npm scripts to package.json
|
|
716
|
+
|
|
717
|
+
Add these two scripts:
|
|
718
|
+
|
|
719
|
+
```json
|
|
720
|
+
"figma:connect": "figma connect publish",
|
|
721
|
+
"figma:connect:dry": "figma connect publish --dry-run"
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
### 3E. Ensure .env is gitignored
|
|
725
|
+
|
|
726
|
+
```bash
|
|
727
|
+
grep -q "^\.env$" .gitignore || echo ".env" >> .gitignore
|
|
728
|
+
grep -q "^\.env\.local$" .gitignore || echo ".env.local" >> .gitignore
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### 3F. Create `.env.example`
|
|
732
|
+
|
|
733
|
+
```
|
|
734
|
+
FIGMA_ACCESS_TOKEN=your-figma-personal-access-token
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### 3G. Verify Phase 3
|
|
738
|
+
|
|
739
|
+
Run the dry-run to check annotations parse:
|
|
740
|
+
|
|
741
|
+
```bash
|
|
742
|
+
source .env
|
|
743
|
+
pnpm figma:connect:dry 2>&1 | head -50
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
This will likely warn about unresolved Figma node URLs (expected — the components don't exist as Figma components yet), but it should NOT show syntax errors. If there are syntax errors in any `.figma.tsx` file, fix them and re-run.
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
## Execution Rules — READ THESE
|
|
751
|
+
|
|
752
|
+
1. **Do NOT stop to ask me anything.** Make reasonable decisions and proceed.
|
|
753
|
+
2. **Do NOT ask "should I proceed to Phase 3?" or "would you like me to continue?"** — just do it.
|
|
754
|
+
3. **If a phase fails**, fix the issue and retry (up to 3 attempts per step).
|
|
755
|
+
4. **If Storybook isn't running**, start it.
|
|
756
|
+
5. **If Figma MCP write tools are not available**, document what IS available, save screenshots to `docs/figma-captures/`, and move on to Phase 3.
|
|
757
|
+
6. **If Code Connect dry-run shows syntax errors**, fix them. If it shows warnings about unresolved URLs, that's expected — move on.
|
|
758
|
+
7. **At the very end**, provide a single summary of what succeeded and what needs manual attention. Format it as a table like:
|
|
759
|
+
|
|
760
|
+
```
|
|
761
|
+
| Phase | Status | Notes |
|
|
762
|
+
|-------|--------|-------|
|
|
763
|
+
| Phase 2 | ✅/❌ | ... |
|
|
764
|
+
| Phase 3 | ✅/❌ | ... |
|
|
765
|
+
```
|