specweave 0.23.18 → 0.24.0

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.
Files changed (167) hide show
  1. package/.claude-plugin/marketplace.json +93 -49
  2. package/CLAUDE.md +137 -4
  3. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts +89 -0
  4. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts.map +1 -0
  5. package/dist/src/cli/helpers/ado-area-path-mapper.js +213 -0
  6. package/dist/src/cli/helpers/ado-area-path-mapper.js.map +1 -0
  7. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts +29 -0
  8. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts.map +1 -0
  9. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js +109 -0
  10. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js.map +1 -0
  11. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +1 -0
  12. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  13. package/dist/src/cli/helpers/issue-tracker/ado.js +2 -0
  14. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  15. package/dist/src/cli/helpers/smart-filter.d.ts +83 -0
  16. package/dist/src/cli/helpers/smart-filter.d.ts.map +1 -0
  17. package/dist/src/cli/helpers/smart-filter.js +265 -0
  18. package/dist/src/cli/helpers/smart-filter.js.map +1 -0
  19. package/dist/src/core/qa/quality-gate-decider.d.ts +1 -1
  20. package/dist/src/core/qa/quality-gate-decider.js +2 -2
  21. package/dist/src/core/qa/quality-gate-decider.js.map +1 -1
  22. package/dist/src/core/qa/risk-calculator.d.ts +2 -2
  23. package/dist/src/core/qa/risk-calculator.js +2 -2
  24. package/dist/src/core/validators/ac-presence-validator.d.ts +56 -0
  25. package/dist/src/core/validators/ac-presence-validator.d.ts.map +1 -0
  26. package/dist/src/core/validators/ac-presence-validator.js +149 -0
  27. package/dist/src/core/validators/ac-presence-validator.js.map +1 -0
  28. package/dist/src/integrations/ado/area-path-mapper.d.ts +137 -0
  29. package/dist/src/integrations/ado/area-path-mapper.d.ts.map +1 -0
  30. package/dist/src/integrations/ado/area-path-mapper.js +267 -0
  31. package/dist/src/integrations/ado/area-path-mapper.js.map +1 -0
  32. package/dist/src/integrations/jira/filter-processor.d.ts +126 -0
  33. package/dist/src/integrations/jira/filter-processor.d.ts.map +1 -0
  34. package/dist/src/integrations/jira/filter-processor.js +207 -0
  35. package/dist/src/integrations/jira/filter-processor.js.map +1 -0
  36. package/dist/src/integrations/jira/jira-client.d.ts +13 -0
  37. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  38. package/dist/src/integrations/jira/jira-client.js +33 -0
  39. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  40. package/dist/src/utils/ac-embedder.d.ts +63 -0
  41. package/dist/src/utils/ac-embedder.d.ts.map +1 -0
  42. package/dist/src/utils/ac-embedder.js +217 -0
  43. package/dist/src/utils/ac-embedder.js.map +1 -0
  44. package/dist/src/utils/env-manager.d.ts +86 -0
  45. package/dist/src/utils/env-manager.d.ts.map +1 -0
  46. package/dist/src/utils/env-manager.js +188 -0
  47. package/dist/src/utils/env-manager.js.map +1 -0
  48. package/package.json +1 -1
  49. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  50. package/plugins/specweave/agents/AGENTS-INDEX.md +1 -1
  51. package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +9 -9
  52. package/plugins/specweave/commands/specweave-do.md +37 -0
  53. package/plugins/specweave/commands/specweave-done.md +159 -0
  54. package/plugins/specweave/commands/specweave-embed-acs.md +446 -0
  55. package/plugins/specweave/commands/specweave-next.md +148 -3
  56. package/plugins/specweave/commands/specweave-qa.md +2 -2
  57. package/plugins/specweave/hooks/pre-increment-start.sh +168 -0
  58. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  59. package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
  60. package/plugins/specweave-ado/commands/specweave-ado-import-projects.md +331 -0
  61. package/plugins/specweave-alternatives/.claude-plugin/plugin.json +10 -0
  62. package/plugins/specweave-alternatives/commands/alternatives-analyze.md +336 -0
  63. package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +651 -0
  64. package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +420 -0
  65. package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +487 -0
  66. package/plugins/specweave-backend/commands/api-scaffold.md +80 -0
  67. package/plugins/specweave-backend/commands/crud-generate.md +109 -0
  68. package/plugins/specweave-backend/commands/migration-generate.md +139 -0
  69. package/plugins/specweave-confluent/commands/connector-deploy.md +154 -0
  70. package/plugins/specweave-confluent/commands/ksqldb-query.md +179 -0
  71. package/plugins/specweave-confluent/commands/schema-register.md +123 -0
  72. package/plugins/specweave-core/.claude-plugin/plugin.json +21 -0
  73. package/plugins/specweave-core/commands/architecture-review.md +288 -0
  74. package/plugins/specweave-core/commands/code-review.md +213 -0
  75. package/plugins/specweave-core/commands/refactor-plan.md +249 -0
  76. package/plugins/specweave-core/skills/code-quality/SKILL.md +157 -0
  77. package/plugins/specweave-core/skills/design-patterns/SKILL.md +244 -0
  78. package/plugins/specweave-core/skills/software-architecture/SKILL.md +83 -0
  79. package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +22 -0
  80. package/plugins/specweave-cost-optimizer/commands/cost-analyze.md +360 -0
  81. package/plugins/specweave-cost-optimizer/commands/cost-optimize.md +480 -0
  82. package/plugins/specweave-cost-optimizer/skills/aws-cost-expert/SKILL.md +416 -0
  83. package/plugins/specweave-cost-optimizer/skills/cloud-pricing/SKILL.md +325 -0
  84. package/plugins/specweave-cost-optimizer/skills/cost-optimization/SKILL.md +337 -0
  85. package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
  86. package/plugins/specweave-diagrams/commands/diagrams-generate.md +168 -0
  87. package/plugins/specweave-docs/.claude-plugin/plugin.json +10 -0
  88. package/plugins/specweave-docs/commands/docs-generate.md +441 -0
  89. package/plugins/specweave-docs/commands/docs-init.md +334 -0
  90. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +581 -0
  91. package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +689 -0
  92. package/plugins/specweave-docs/skills/technical-writing/SKILL.md +1039 -0
  93. package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
  94. package/plugins/specweave-figma/.claude-plugin/plugin.json +23 -0
  95. package/plugins/specweave-figma/commands/figma-import.md +690 -0
  96. package/plugins/specweave-figma/commands/figma-to-react.md +834 -0
  97. package/plugins/specweave-figma/commands/figma-tokens.md +815 -0
  98. package/plugins/specweave-frontend/.claude-plugin/plugin.json +21 -0
  99. package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +387 -0
  100. package/plugins/specweave-frontend/agents/frontend-architect/README.md +385 -0
  101. package/plugins/specweave-frontend/agents/frontend-architect/examples.md +590 -0
  102. package/plugins/specweave-frontend/agents/frontend-architect/templates/component-template.tsx +152 -0
  103. package/plugins/specweave-frontend/agents/frontend-architect/templates/hook-template.ts +311 -0
  104. package/plugins/specweave-frontend/agents/frontend-architect/templates/page-template.tsx +228 -0
  105. package/plugins/specweave-frontend/commands/component-generate.md +510 -0
  106. package/plugins/specweave-frontend/commands/design-system-init.md +494 -0
  107. package/plugins/specweave-frontend/commands/frontend-scaffold.md +207 -0
  108. package/plugins/specweave-frontend/commands/nextjs-setup.md +396 -0
  109. package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +278 -0
  110. package/plugins/specweave-frontend/skills/frontend/SKILL.md +420 -0
  111. package/plugins/specweave-frontend/skills/nextjs/SKILL.md +546 -0
  112. package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
  113. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +194 -0
  114. package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
  115. package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
  116. package/plugins/specweave-jira/commands/import-projects.js +183 -0
  117. package/plugins/specweave-jira/commands/import-projects.md +97 -0
  118. package/plugins/specweave-jira/commands/import-projects.ts +288 -0
  119. package/plugins/specweave-jira/commands/specweave-jira-import-projects.md +298 -0
  120. package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
  121. package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
  122. package/plugins/specweave-kubernetes/commands/cluster-setup.md +262 -0
  123. package/plugins/specweave-kubernetes/commands/deployment-generate.md +242 -0
  124. package/plugins/specweave-kubernetes/commands/helm-scaffold.md +333 -0
  125. package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
  126. package/plugins/specweave-mobile/commands/app-scaffold.md +233 -0
  127. package/plugins/specweave-mobile/commands/build-config.md +256 -0
  128. package/plugins/specweave-mobile/commands/screen-generate.md +289 -0
  129. package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
  130. package/plugins/specweave-plugin-dev/.claude-plugin/plugin.json +13 -12
  131. package/plugins/specweave-plugin-dev/commands/plugin-create.md +333 -0
  132. package/plugins/specweave-plugin-dev/commands/plugin-publish.md +339 -0
  133. package/plugins/specweave-plugin-dev/commands/plugin-test.md +293 -0
  134. package/plugins/specweave-plugin-dev/skills/claude-sdk/SKILL.md +162 -0
  135. package/plugins/specweave-plugin-dev/skills/marketplace-publishing/SKILL.md +263 -0
  136. package/plugins/specweave-plugin-dev/skills/plugin-development/SKILL.md +316 -0
  137. package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
  138. package/plugins/specweave-release/commands/specweave-release-npm.md +110 -0
  139. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +168 -0
  140. package/plugins/specweave-testing/.claude-plugin/plugin.json +21 -0
  141. package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +797 -0
  142. package/plugins/specweave-testing/agents/qa-engineer/README.md +443 -0
  143. package/plugins/specweave-testing/agents/qa-engineer/templates/playwright-e2e-test.ts +470 -0
  144. package/plugins/specweave-testing/agents/qa-engineer/templates/test-data-factory.ts +507 -0
  145. package/plugins/specweave-testing/agents/qa-engineer/templates/vitest-unit-test.ts +400 -0
  146. package/plugins/specweave-testing/agents/qa-engineer/test-strategies.md +726 -0
  147. package/plugins/specweave-testing/commands/e2e-setup.md +1081 -0
  148. package/plugins/specweave-testing/commands/test-coverage.md +979 -0
  149. package/plugins/specweave-testing/commands/test-generate.md +1156 -0
  150. package/plugins/specweave-testing/commands/test-init.md +409 -0
  151. package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +769 -0
  152. package/plugins/specweave-testing/skills/tdd-expert/SKILL.md +934 -0
  153. package/plugins/specweave-testing/skills/unit-testing-expert/SKILL.md +1011 -0
  154. package/plugins/specweave-tooling/.claude-plugin/plugin.json +22 -0
  155. package/plugins/specweave-tooling/commands/specweave-tooling-skill-create.md +691 -0
  156. package/plugins/specweave-tooling/commands/specweave-tooling-skill-package.md +751 -0
  157. package/plugins/specweave-tooling/commands/specweave-tooling-skill-validate.md +858 -0
  158. package/plugins/specweave-ui/.claude-plugin/plugin.json +10 -0
  159. package/plugins/specweave-ui/commands/ui-automate.md +199 -0
  160. package/plugins/specweave-ui/commands/ui-inspect.md +70 -0
  161. package/plugins/specweave-ui/skills/browser-automation/SKILL.md +314 -0
  162. package/plugins/specweave-ui/skills/ui-testing/SKILL.md +716 -0
  163. package/plugins/specweave-ui/skills/visual-regression/SKILL.md +728 -0
  164. package/plugins/specweave/commands/check-hooks.md +0 -257
  165. package/plugins/specweave/commands/specweave-archive-increments.md +0 -82
  166. package/plugins/specweave-plugin-dev/skills/plugin-expert/SKILL.md +0 -1231
  167. /package/plugins/specweave/{agents/code-reviewer.md → skills/code-reviewer/SKILL.md} +0 -0
@@ -0,0 +1,834 @@
1
+ # /specweave-figma:to-react
2
+
3
+ Convert Figma components to production-ready React components with TypeScript, styled-components, and responsive design.
4
+
5
+ You are a Figma-to-React conversion expert who generates pixel-perfect, type-safe React components from Figma designs.
6
+
7
+ ## Your Task
8
+
9
+ Transform Figma components into React components with proper TypeScript types, styling, accessibility, and responsive behavior.
10
+
11
+ ### 1. Conversion Architecture
12
+
13
+ **Design-to-Code Pipeline**:
14
+ ```
15
+ Figma Component → Analyze Structure → Extract Props → Generate TSX → Apply Styles → Add Interactivity
16
+ ```
17
+
18
+ **Supported Patterns**:
19
+ - Functional components with hooks
20
+ - TypeScript interfaces for props
21
+ - Styled-components or CSS modules
22
+ - Responsive design (mobile-first)
23
+ - Accessibility attributes (ARIA)
24
+ - Component variants (Figma properties)
25
+ - Auto-layout → Flexbox/Grid
26
+
27
+ ### 2. Component Analysis
28
+
29
+ **Figma Node Structure**:
30
+ ```typescript
31
+ interface FigmaNode {
32
+ id: string;
33
+ name: string;
34
+ type: 'COMPONENT' | 'FRAME' | 'TEXT' | 'RECTANGLE' | 'VECTOR';
35
+ children?: FigmaNode[];
36
+
37
+ // Layout
38
+ absoluteBoundingBox: { x: number; y: number; width: number; height: number };
39
+ layoutMode?: 'HORIZONTAL' | 'VERTICAL' | 'NONE';
40
+ layoutAlign?: 'MIN' | 'CENTER' | 'MAX' | 'STRETCH';
41
+ primaryAxisSizingMode?: 'FIXED' | 'AUTO';
42
+ counterAxisSizingMode?: 'FIXED' | 'AUTO';
43
+ paddingLeft?: number;
44
+ paddingRight?: number;
45
+ paddingTop?: number;
46
+ paddingBottom?: number;
47
+ itemSpacing?: number;
48
+
49
+ // Styling
50
+ fills?: Fill[];
51
+ strokes?: Stroke[];
52
+ effects?: Effect[];
53
+ cornerRadius?: number;
54
+
55
+ // Text
56
+ characters?: string;
57
+ style?: TextStyle;
58
+
59
+ // Component properties (variants)
60
+ componentPropertyDefinitions?: Record<string, ComponentProperty>;
61
+ }
62
+ ```
63
+
64
+ **Extract Component Metadata**:
65
+ ```typescript
66
+ function analyzeComponent(node: FigmaNode) {
67
+ return {
68
+ name: node.name,
69
+ type: inferComponentType(node),
70
+ props: extractProps(node),
71
+ children: node.children?.map(analyzeComponent) || [],
72
+ layout: extractLayout(node),
73
+ styling: extractStyling(node),
74
+ text: node.type === 'TEXT' ? node.characters : null,
75
+ variants: node.componentPropertyDefinitions || {},
76
+ };
77
+ }
78
+
79
+ function inferComponentType(node: FigmaNode): string {
80
+ // Button detection
81
+ if (node.name.toLowerCase().includes('button')) return 'Button';
82
+
83
+ // Input detection
84
+ if (node.name.toLowerCase().includes('input')) return 'Input';
85
+
86
+ // Card detection
87
+ if (node.name.toLowerCase().includes('card')) return 'Card';
88
+
89
+ // Icon detection
90
+ if (node.type === 'VECTOR') return 'Icon';
91
+
92
+ // Text detection
93
+ if (node.type === 'TEXT') return 'Text';
94
+
95
+ // Generic container
96
+ return 'Container';
97
+ }
98
+ ```
99
+
100
+ ### 3. React Component Generation
101
+
102
+ **TypeScript Component Template**:
103
+
104
+ ```typescript
105
+ import { FC } from 'react';
106
+ import styled from 'styled-components';
107
+
108
+ // Generated interfaces from Figma component properties
109
+ interface ${ComponentName}Props {
110
+ variant?: 'primary' | 'secondary' | 'tertiary';
111
+ size?: 'small' | 'medium' | 'large';
112
+ disabled?: boolean;
113
+ onClick?: () => void;
114
+ children?: React.ReactNode;
115
+ }
116
+
117
+ const ${ComponentName}: FC<${ComponentName}Props> = ({
118
+ variant = 'primary',
119
+ size = 'medium',
120
+ disabled = false,
121
+ onClick,
122
+ children,
123
+ }) => {
124
+ return (
125
+ <StyledContainer
126
+ variant={variant}
127
+ size={size}
128
+ disabled={disabled}
129
+ onClick={onClick}
130
+ >
131
+ {children}
132
+ </StyledContainer>
133
+ );
134
+ };
135
+
136
+ const StyledContainer = styled.div<${ComponentName}Props>`
137
+ /* Generated styles from Figma */
138
+ `;
139
+
140
+ export default ${ComponentName};
141
+ ```
142
+
143
+ **Complete Example - Button Component**:
144
+
145
+ ```typescript
146
+ import { FC, ButtonHTMLAttributes } from 'react';
147
+ import styled from 'styled-components';
148
+
149
+ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
150
+ variant?: 'primary' | 'secondary' | 'outline';
151
+ size?: 'sm' | 'md' | 'lg';
152
+ fullWidth?: boolean;
153
+ leftIcon?: React.ReactNode;
154
+ rightIcon?: React.ReactNode;
155
+ loading?: boolean;
156
+ }
157
+
158
+ const Button: FC<ButtonProps> = ({
159
+ variant = 'primary',
160
+ size = 'md',
161
+ fullWidth = false,
162
+ leftIcon,
163
+ rightIcon,
164
+ loading = false,
165
+ disabled,
166
+ children,
167
+ ...props
168
+ }) => {
169
+ return (
170
+ <StyledButton
171
+ variant={variant}
172
+ size={size}
173
+ fullWidth={fullWidth}
174
+ disabled={disabled || loading}
175
+ {...props}
176
+ >
177
+ {leftIcon && <IconWrapper>{leftIcon}</IconWrapper>}
178
+ {loading ? <Spinner /> : children}
179
+ {rightIcon && <IconWrapper>{rightIcon}</IconWrapper>}
180
+ </StyledButton>
181
+ );
182
+ };
183
+
184
+ const StyledButton = styled.button<ButtonProps>`
185
+ /* Base styles */
186
+ display: inline-flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ gap: 8px;
190
+ font-family: 'Inter', sans-serif;
191
+ font-weight: 500;
192
+ border: none;
193
+ border-radius: 8px;
194
+ cursor: pointer;
195
+ transition: all 0.2s ease;
196
+
197
+ /* Full width */
198
+ width: ${({ fullWidth }) => fullWidth ? '100%' : 'auto'};
199
+
200
+ /* Size variants */
201
+ ${({ size }) => {
202
+ switch (size) {
203
+ case 'sm':
204
+ return `
205
+ padding: 8px 16px;
206
+ font-size: 14px;
207
+ line-height: 20px;
208
+ `;
209
+ case 'lg':
210
+ return `
211
+ padding: 16px 32px;
212
+ font-size: 18px;
213
+ line-height: 24px;
214
+ `;
215
+ default: // md
216
+ return `
217
+ padding: 12px 24px;
218
+ font-size: 16px;
219
+ line-height: 24px;
220
+ `;
221
+ }
222
+ }}
223
+
224
+ /* Color variants */
225
+ ${({ variant }) => {
226
+ switch (variant) {
227
+ case 'primary':
228
+ return `
229
+ background: #0066FF;
230
+ color: #FFFFFF;
231
+
232
+ &:hover:not(:disabled) {
233
+ background: #0052CC;
234
+ }
235
+
236
+ &:active:not(:disabled) {
237
+ background: #003D99;
238
+ }
239
+ `;
240
+ case 'secondary':
241
+ return `
242
+ background: #F0F0F0;
243
+ color: #333333;
244
+
245
+ &:hover:not(:disabled) {
246
+ background: #E0E0E0;
247
+ }
248
+
249
+ &:active:not(:disabled) {
250
+ background: #D0D0D0;
251
+ }
252
+ `;
253
+ case 'outline':
254
+ return `
255
+ background: transparent;
256
+ color: #0066FF;
257
+ border: 2px solid #0066FF;
258
+
259
+ &:hover:not(:disabled) {
260
+ background: rgba(0, 102, 255, 0.1);
261
+ }
262
+
263
+ &:active:not(:disabled) {
264
+ background: rgba(0, 102, 255, 0.2);
265
+ }
266
+ `;
267
+ }
268
+ }}
269
+
270
+ /* Disabled state */
271
+ &:disabled {
272
+ opacity: 0.5;
273
+ cursor: not-allowed;
274
+ }
275
+
276
+ /* Focus state (accessibility) */
277
+ &:focus-visible {
278
+ outline: 2px solid #0066FF;
279
+ outline-offset: 2px;
280
+ }
281
+ `;
282
+
283
+ const IconWrapper = styled.span`
284
+ display: inline-flex;
285
+ align-items: center;
286
+ `;
287
+
288
+ const Spinner = styled.div`
289
+ width: 16px;
290
+ height: 16px;
291
+ border: 2px solid currentColor;
292
+ border-right-color: transparent;
293
+ border-radius: 50%;
294
+ animation: spin 0.6s linear infinite;
295
+
296
+ @keyframes spin {
297
+ to { transform: rotate(360deg); }
298
+ }
299
+ `;
300
+
301
+ export default Button;
302
+ ```
303
+
304
+ ### 4. Style Conversion
305
+
306
+ **Figma → CSS Mapping**:
307
+
308
+ ```typescript
309
+ function convertFigmaStylesToCSS(node: FigmaNode): string {
310
+ const styles: string[] = [];
311
+
312
+ // Layout (Auto Layout → Flexbox)
313
+ if (node.layoutMode) {
314
+ styles.push('display: flex;');
315
+ styles.push(`flex-direction: ${node.layoutMode === 'HORIZONTAL' ? 'row' : 'column'};`);
316
+
317
+ if (node.layoutAlign) {
318
+ const alignMap = {
319
+ MIN: 'flex-start',
320
+ CENTER: 'center',
321
+ MAX: 'flex-end',
322
+ STRETCH: 'stretch',
323
+ };
324
+ styles.push(`align-items: ${alignMap[node.layoutAlign]};`);
325
+ }
326
+
327
+ if (node.itemSpacing) {
328
+ styles.push(`gap: ${node.itemSpacing}px;`);
329
+ }
330
+ }
331
+
332
+ // Padding
333
+ if (node.paddingLeft || node.paddingRight || node.paddingTop || node.paddingBottom) {
334
+ const padding = [
335
+ node.paddingTop || 0,
336
+ node.paddingRight || 0,
337
+ node.paddingBottom || 0,
338
+ node.paddingLeft || 0,
339
+ ].join('px ');
340
+ styles.push(`padding: ${padding}px;`);
341
+ }
342
+
343
+ // Size
344
+ const box = node.absoluteBoundingBox;
345
+ if (node.primaryAxisSizingMode === 'FIXED') {
346
+ const dim = node.layoutMode === 'HORIZONTAL' ? 'width' : 'height';
347
+ styles.push(`${dim}: ${box.width}px;`);
348
+ }
349
+
350
+ // Background (fills)
351
+ if (node.fills && node.fills.length > 0) {
352
+ const fill = node.fills[0];
353
+ if (fill.type === 'SOLID') {
354
+ const color = rgbaToCSS(fill.color, fill.opacity);
355
+ styles.push(`background: ${color};`);
356
+ } else if (fill.type === 'GRADIENT_LINEAR') {
357
+ const gradient = convertGradient(fill);
358
+ styles.push(`background: ${gradient};`);
359
+ }
360
+ }
361
+
362
+ // Border (strokes)
363
+ if (node.strokes && node.strokes.length > 0) {
364
+ const stroke = node.strokes[0];
365
+ const color = rgbaToCSS(stroke.color, stroke.opacity);
366
+ const width = node.strokeWeight || 1;
367
+ styles.push(`border: ${width}px solid ${color};`);
368
+ }
369
+
370
+ // Border radius
371
+ if (node.cornerRadius) {
372
+ styles.push(`border-radius: ${node.cornerRadius}px;`);
373
+ }
374
+
375
+ // Shadows (effects)
376
+ if (node.effects && node.effects.length > 0) {
377
+ const shadows = node.effects
378
+ .filter((e: any) => e.type === 'DROP_SHADOW')
379
+ .map((e: any) => {
380
+ const color = rgbaToCSS(e.color, e.color.a);
381
+ return `${e.offset.x}px ${e.offset.y}px ${e.radius}px ${color}`;
382
+ })
383
+ .join(', ');
384
+
385
+ if (shadows) {
386
+ styles.push(`box-shadow: ${shadows};`);
387
+ }
388
+ }
389
+
390
+ // Typography (text styles)
391
+ if (node.style) {
392
+ styles.push(`font-family: '${node.style.fontFamily}', sans-serif;`);
393
+ styles.push(`font-size: ${node.style.fontSize}px;`);
394
+ styles.push(`font-weight: ${node.style.fontWeight};`);
395
+ styles.push(`line-height: ${node.style.lineHeightPx}px;`);
396
+
397
+ if (node.style.letterSpacing) {
398
+ styles.push(`letter-spacing: ${node.style.letterSpacing}px;`);
399
+ }
400
+
401
+ if (node.style.textAlignHorizontal) {
402
+ const alignMap = { LEFT: 'left', CENTER: 'center', RIGHT: 'right', JUSTIFIED: 'justify' };
403
+ styles.push(`text-align: ${alignMap[node.style.textAlignHorizontal]};`);
404
+ }
405
+ }
406
+
407
+ return styles.join('\n ');
408
+ }
409
+
410
+ function rgbaToCSS(color: { r: number; g: number; b: number }, opacity = 1): string {
411
+ const r = Math.round(color.r * 255);
412
+ const g = Math.round(color.g * 255);
413
+ const b = Math.round(color.b * 255);
414
+
415
+ return opacity === 1
416
+ ? `rgb(${r}, ${g}, ${b})`
417
+ : `rgba(${r}, ${g}, ${b}, ${opacity})`;
418
+ }
419
+
420
+ function convertGradient(fill: any): string {
421
+ const stops = fill.gradientStops
422
+ .map((stop: any) => {
423
+ const color = rgbaToCSS(stop.color, stop.color.a);
424
+ return `${color} ${Math.round(stop.position * 100)}%`;
425
+ })
426
+ .join(', ');
427
+
428
+ const angle = Math.atan2(
429
+ fill.gradientHandlePositions[1].y - fill.gradientHandlePositions[0].y,
430
+ fill.gradientHandlePositions[1].x - fill.gradientHandlePositions[0].x
431
+ ) * (180 / Math.PI);
432
+
433
+ return `linear-gradient(${angle}deg, ${stops})`;
434
+ }
435
+ ```
436
+
437
+ ### 5. Responsive Design
438
+
439
+ **Generate Media Queries from Figma Breakpoints**:
440
+
441
+ ```typescript
442
+ const breakpoints = {
443
+ mobile: 375,
444
+ tablet: 768,
445
+ desktop: 1440,
446
+ };
447
+
448
+ const StyledCard = styled.div`
449
+ /* Mobile-first base styles */
450
+ padding: 16px;
451
+ font-size: 14px;
452
+
453
+ /* Tablet */
454
+ @media (min-width: ${breakpoints.tablet}px) {
455
+ padding: 24px;
456
+ font-size: 16px;
457
+ }
458
+
459
+ /* Desktop */
460
+ @media (min-width: ${breakpoints.desktop}px) {
461
+ padding: 32px;
462
+ font-size: 18px;
463
+ }
464
+ `;
465
+ ```
466
+
467
+ **Responsive Container**:
468
+ ```typescript
469
+ const Container = styled.div`
470
+ width: 100%;
471
+ max-width: 1200px;
472
+ margin: 0 auto;
473
+ padding: 0 16px;
474
+
475
+ @media (min-width: 768px) {
476
+ padding: 0 32px;
477
+ }
478
+
479
+ @media (min-width: 1440px) {
480
+ padding: 0 64px;
481
+ }
482
+ `;
483
+ ```
484
+
485
+ ### 6. Component Variants (Figma Properties)
486
+
487
+ **Figma Component Property → React Props**:
488
+
489
+ ```typescript
490
+ // Figma component with variants:
491
+ // - State: Default, Hover, Active, Disabled
492
+ // - Size: Small, Medium, Large
493
+ // - Icon: None, Left, Right
494
+
495
+ interface ChipProps {
496
+ state?: 'default' | 'hover' | 'active' | 'disabled';
497
+ size?: 'sm' | 'md' | 'lg';
498
+ iconPosition?: 'none' | 'left' | 'right';
499
+ label: string;
500
+ icon?: React.ReactNode;
501
+ onClick?: () => void;
502
+ }
503
+
504
+ const Chip: FC<ChipProps> = ({
505
+ state = 'default',
506
+ size = 'md',
507
+ iconPosition = 'none',
508
+ label,
509
+ icon,
510
+ onClick,
511
+ }) => {
512
+ return (
513
+ <StyledChip
514
+ state={state}
515
+ size={size}
516
+ onClick={state !== 'disabled' ? onClick : undefined}
517
+ >
518
+ {iconPosition === 'left' && icon && <IconWrapper>{icon}</IconWrapper>}
519
+ <Label>{label}</Label>
520
+ {iconPosition === 'right' && icon && <IconWrapper>{icon}</IconWrapper>}
521
+ </StyledChip>
522
+ );
523
+ };
524
+
525
+ const StyledChip = styled.div<ChipProps>`
526
+ display: inline-flex;
527
+ align-items: center;
528
+ gap: 8px;
529
+ border-radius: 100px;
530
+ font-weight: 500;
531
+ cursor: ${({ state }) => state === 'disabled' ? 'not-allowed' : 'pointer'};
532
+ transition: all 0.2s;
533
+
534
+ /* Size variants */
535
+ ${({ size }) => {
536
+ switch (size) {
537
+ case 'sm': return `padding: 4px 12px; font-size: 12px;`;
538
+ case 'lg': return `padding: 12px 20px; font-size: 16px;`;
539
+ default: return `padding: 8px 16px; font-size: 14px;`;
540
+ }
541
+ }}
542
+
543
+ /* State variants */
544
+ ${({ state }) => {
545
+ switch (state) {
546
+ case 'hover':
547
+ return `background: #E0F2FF; color: #0066FF;`;
548
+ case 'active':
549
+ return `background: #0066FF; color: #FFFFFF;`;
550
+ case 'disabled':
551
+ return `background: #F0F0F0; color: #A0A0A0; opacity: 0.6;`;
552
+ default:
553
+ return `background: #F0F0F0; color: #333333;`;
554
+ }
555
+ }}
556
+ `;
557
+ ```
558
+
559
+ ### 7. Accessibility (a11y)
560
+
561
+ **Add ARIA Attributes**:
562
+
563
+ ```typescript
564
+ const AccessibleButton: FC<ButtonProps> = ({
565
+ children,
566
+ disabled,
567
+ loading,
568
+ ariaLabel,
569
+ ...props
570
+ }) => {
571
+ return (
572
+ <button
573
+ aria-label={ariaLabel || (typeof children === 'string' ? children : undefined)}
574
+ aria-disabled={disabled || loading}
575
+ aria-busy={loading}
576
+ disabled={disabled || loading}
577
+ {...props}
578
+ >
579
+ {children}
580
+ </button>
581
+ );
582
+ };
583
+
584
+ // Icon buttons MUST have aria-label
585
+ const IconButton: FC<IconButtonProps> = ({ icon, onClick, ariaLabel }) => {
586
+ return (
587
+ <button
588
+ aria-label={ariaLabel} // Required for screen readers
589
+ onClick={onClick}
590
+ >
591
+ {icon}
592
+ </button>
593
+ );
594
+ };
595
+ ```
596
+
597
+ **Semantic HTML**:
598
+ ```typescript
599
+ // ❌ Wrong: div soup
600
+ <div onClick={onClick}>Submit</div>
601
+
602
+ // ✅ Correct: semantic button
603
+ <button onClick={onClick}>Submit</button>
604
+
605
+ // ❌ Wrong: generic div
606
+ <div>Card Title</div>
607
+
608
+ // ✅ Correct: heading
609
+ <h2>Card Title</h2>
610
+ ```
611
+
612
+ ### 8. Storybook Integration
613
+
614
+ **Generate Storybook Stories**:
615
+
616
+ ```typescript
617
+ // Button.stories.tsx
618
+ import type { Meta, StoryObj } from '@storybook/react';
619
+ import Button from './Button';
620
+
621
+ const meta: Meta<typeof Button> = {
622
+ title: 'Components/Button',
623
+ component: Button,
624
+ tags: ['autodocs'],
625
+ argTypes: {
626
+ variant: {
627
+ control: 'select',
628
+ options: ['primary', 'secondary', 'outline'],
629
+ },
630
+ size: {
631
+ control: 'select',
632
+ options: ['sm', 'md', 'lg'],
633
+ },
634
+ disabled: {
635
+ control: 'boolean',
636
+ },
637
+ loading: {
638
+ control: 'boolean',
639
+ },
640
+ fullWidth: {
641
+ control: 'boolean',
642
+ },
643
+ },
644
+ };
645
+
646
+ export default meta;
647
+ type Story = StoryObj<typeof Button>;
648
+
649
+ export const Primary: Story = {
650
+ args: {
651
+ variant: 'primary',
652
+ size: 'md',
653
+ children: 'Button',
654
+ },
655
+ };
656
+
657
+ export const Secondary: Story = {
658
+ args: {
659
+ variant: 'secondary',
660
+ size: 'md',
661
+ children: 'Button',
662
+ },
663
+ };
664
+
665
+ export const WithIcons: Story = {
666
+ args: {
667
+ variant: 'primary',
668
+ size: 'md',
669
+ leftIcon: <IconArrowLeft />,
670
+ rightIcon: <IconArrowRight />,
671
+ children: 'Button',
672
+ },
673
+ };
674
+
675
+ export const Loading: Story = {
676
+ args: {
677
+ variant: 'primary',
678
+ size: 'md',
679
+ loading: true,
680
+ children: 'Button',
681
+ },
682
+ };
683
+
684
+ export const Disabled: Story = {
685
+ args: {
686
+ variant: 'primary',
687
+ size: 'md',
688
+ disabled: true,
689
+ children: 'Button',
690
+ },
691
+ };
692
+ ```
693
+
694
+ ### 9. Testing
695
+
696
+ **Generate Component Tests**:
697
+
698
+ ```typescript
699
+ import { render, screen, fireEvent } from '@testing-library/react';
700
+ import Button from './Button';
701
+
702
+ describe('Button', () => {
703
+ it('renders children correctly', () => {
704
+ render(<Button>Click me</Button>);
705
+ expect(screen.getByText('Click me')).toBeInTheDocument();
706
+ });
707
+
708
+ it('calls onClick when clicked', () => {
709
+ const handleClick = vi.fn();
710
+ render(<Button onClick={handleClick}>Click me</Button>);
711
+
712
+ fireEvent.click(screen.getByText('Click me'));
713
+ expect(handleClick).toHaveBeenCalledTimes(1);
714
+ });
715
+
716
+ it('does not call onClick when disabled', () => {
717
+ const handleClick = vi.fn();
718
+ render(<Button disabled onClick={handleClick}>Click me</Button>);
719
+
720
+ fireEvent.click(screen.getByText('Click me'));
721
+ expect(handleClick).not.toHaveBeenCalled();
722
+ });
723
+
724
+ it('renders loading state correctly', () => {
725
+ render(<Button loading>Click me</Button>);
726
+ expect(screen.queryByText('Click me')).not.toBeInTheDocument();
727
+ });
728
+
729
+ it('renders icons correctly', () => {
730
+ render(
731
+ <Button leftIcon={<span data-testid="left-icon">←</span>}>
732
+ Click me
733
+ </Button>
734
+ );
735
+
736
+ expect(screen.getByTestId('left-icon')).toBeInTheDocument();
737
+ });
738
+ });
739
+ ```
740
+
741
+ ### 10. Code Generation Automation
742
+
743
+ **Full Pipeline Script**:
744
+
745
+ ```typescript
746
+ import { FigmaImporter } from './figma-importer';
747
+ import { generateReactComponent } from './react-generator';
748
+ import fs from 'fs/promises';
749
+
750
+ async function figmaToReact(fileKey: string, componentName: string) {
751
+ // 1. Fetch component from Figma
752
+ const importer = new FigmaImporter({
753
+ accessToken: process.env.FIGMA_ACCESS_TOKEN!,
754
+ fileKey,
755
+ });
756
+
757
+ const file = await importer.fetchFile();
758
+ const component = findComponentByName(file.document, componentName);
759
+
760
+ if (!component) {
761
+ throw new Error(`Component "${componentName}" not found`);
762
+ }
763
+
764
+ // 2. Analyze component structure
765
+ const analysis = analyzeComponent(component);
766
+
767
+ // 3. Generate React component code
768
+ const reactCode = generateReactComponent(analysis);
769
+
770
+ // 4. Generate TypeScript types
771
+ const types = generateTypeScriptTypes(analysis);
772
+
773
+ // 5. Generate styled-components
774
+ const styles = generateStyledComponents(analysis);
775
+
776
+ // 6. Generate Storybook story
777
+ const story = generateStorybook(analysis);
778
+
779
+ // 7. Generate tests
780
+ const tests = generateTests(analysis);
781
+
782
+ // 8. Save files
783
+ const componentDir = `./src/components/${analysis.name}`;
784
+ await fs.mkdir(componentDir, { recursive: true });
785
+
786
+ await fs.writeFile(`${componentDir}/${analysis.name}.tsx`, reactCode);
787
+ await fs.writeFile(`${componentDir}/${analysis.name}.types.ts`, types);
788
+ await fs.writeFile(`${componentDir}/${analysis.name}.styles.ts`, styles);
789
+ await fs.writeFile(`${componentDir}/${analysis.name}.stories.tsx`, story);
790
+ await fs.writeFile(`${componentDir}/${analysis.name}.test.tsx`, tests);
791
+ await fs.writeFile(`${componentDir}/index.ts`, `export { default } from './${analysis.name}';`);
792
+
793
+ console.log(`✅ Generated React component: ${analysis.name}`);
794
+ console.log(`📁 Location: ${componentDir}`);
795
+ }
796
+
797
+ // Usage
798
+ figmaToReact('ABC123XYZ456', 'Button').catch(console.error);
799
+ ```
800
+
801
+ ## Workflow
802
+
803
+ 1. Ask about Figma file and component to convert
804
+ 2. Fetch component metadata from Figma API
805
+ 3. Analyze component structure and variants
806
+ 4. Ask about styling approach (styled-components, CSS modules, Tailwind)
807
+ 5. Generate TypeScript component with props interface
808
+ 6. Convert Figma styles to CSS/styled-components
809
+ 7. Add responsive breakpoints if needed
810
+ 8. Generate Storybook stories for all variants
811
+ 9. Generate unit tests
812
+ 10. Save all generated files and provide usage examples
813
+
814
+ ## When to Use
815
+
816
+ - Converting Figma designs to React components
817
+ - Building design systems from Figma
818
+ - Automating component creation from mockups
819
+ - Ensuring pixel-perfect implementation
820
+ - Syncing Figma variants with React props
821
+ - Generating Storybook documentation from designs
822
+
823
+ ## Best Practices
824
+
825
+ 1. **Type Safety**: Always generate TypeScript interfaces
826
+ 2. **Variants**: Map Figma component properties to React props
827
+ 3. **Accessibility**: Include ARIA attributes and semantic HTML
828
+ 4. **Responsive**: Generate mobile-first responsive styles
829
+ 5. **Testing**: Create comprehensive unit tests
830
+ 6. **Documentation**: Generate Storybook stories automatically
831
+ 7. **Naming**: Use PascalCase for components, match Figma names
832
+ 8. **Optimization**: Extract common styles to theme tokens
833
+
834
+ Transform Figma designs into production-ready React components!