Flux de travail autonome Figma vers React
Aperçu
Cette compétence orchestre le pipeline complet de conversion de maquettes Figma en applications React prêtes pour la production. Elle extrait les systèmes de design (couleurs, typographie, espacements, effets) de Figma, les transforme en configuration Tailwind CSS et propriétés CSS personnalisées, puis génère des composants React TypeScript fonctionnels qui reproduisent fidèlement le design source.
Le flux de travail opère en quatre phases : découverte interactive, structure TDD, exécution autonome et livraison vérifiée. Le résultat est un ensemble de composants React, de pages et d'un système de jetons de design prêts à être intégrés dans des projets Next.js, Vite ou Remix — vérifiés au niveau du pixel près par rapport à la source Figma.
Principes fondamentaux :
- Le TDD est obligatoire — les tests sont écrits avant les composants, jamais après
- Chaque composant est un composant TypeScript fonctionnel avec des interfaces de props explicites
- Tout le style utilise des classes utilitaires Tailwind basées sur les jetons de design de Figma
- Pas de valeurs de couleur codées en dur, de tailles de police ou d'espacements — tout référence le système de jetons
- Les images utilisent des importations appropriées ou des références au répertoire public, jamais de chemins cassés
- La sortie est adaptée au framework (Next.js App Router, Vite SPA, routes Remix)
- Vérification pixel par pixel — boucle de différence automatisée avec pixelmatch, pas de comparaison manuelle
- Conscient du type d'application — les extensions Chrome, les PWA et les applications web reçoivent chacune des stratégies de test appropriées
Quand l'utiliser
Utilisez cette compétence lorsque :
- Vous convertissez un fichier de design Figma en application React
- Vous extrayez un système de design de Figma vers une configuration Tailwind
- Vous générez une bibliothèque de composants à partir d'ensembles de composants Figma
- Vous reconstruisez une interface utilisateur existante à partir d'une refonte Figma
- Vous démarrez un nouveau projet React à partir d'un prototype Figma
Phrases déclencheuses :
- "Convertis ce design Figma en React"
- "Génère des composants React à partir de Figma"
- "Extrais les jetons de design de Figma"
- "Construis une application React à partir de ce fichier Figma"
- "Figma vers Next.js"
- "Figma vers Vite"
Phase 1 : Découverte (Interactive)
Cette phase nécessite une saisie utilisateur. Ne procédez pas de manière autonome tant que l'utilisateur n'a pas confirmé le plan.
Vérification d'intégration du pipeline
Avant de poser des questions, vérifiez si des artefacts en amont existent :
1. Vérifiez : .claude/plans/build-spec.json
→ S'il existe : IGNOREZ toutes les questions de découverte. Chargez directement le spec.
→ Journalisez : "build-spec.json trouvé à partir de figma-intake — découverte ignorée"
2. Vérifiez : src/styles/design-tokens.lock.json
→ S'il existe : IGNOREZ l'extraction de jetons dans la Phase 2. Utilisez les valeurs du fichier de verrouillage.
→ Journalisez : "design-tokens.lock.json trouvé — utilisation des valeurs de jetons verrouillées"
Si build-spec.json existe, passez directement à la Phase 2 avec le framework, les composants et les options du spec préchargés.
Étape 1.1 : Recueillir le contexte Figma
Utilisez le MCP Figma pour inspecter le fichier de design.
1. get_metadata — Nom du fichier, pages, dernière modification, nombre de composants
2. get_variable_defs — Jetons de design (couleurs, typographie, espacements, effets)
3. get_design_context — Structure de mise en page, hiérarchie des composants, paramètres de mise en page automatique
4. get_screenshot — Référence visuelle pour chaque page/cadre
Étape 1.2 : Extraire les jetons de design
Mappez les variables et styles Figma vers une structure de jetons :
Jetons de design
├── Couleurs
│ ├── Primitives (bleu-500, gris-100, etc.)
│ ├── Sémantiques (primaire, secondaire, destructif, atténué)
│ └── Spécifiques aux composants (carte-fond, bouton-primaire, entrée-bordure)
├── Typographie
│ ├── Familles de polices (avec piles de secours)
│ ├── Tailles de police (échelle : xs à 5xl)
│ ├── Poids de police
│ ├── Hauteurs de ligne
│ └── Espacement des lettres
├── Espacement
│ ├── Unité de base
│ └── Échelle (0,5 à 96)
├── Rayon de bordure
│ ├── Échelle (sm, md, lg, xl, complet)
│ └── Remplacements spécifiques aux composants
├── Ombres / Effets
│ ├── Ombres de boîte (sm, md, lg, xl)
│ └── Ombres portées
└── Points de rupture
└── Mobile, tablette, bureau, large
Étape 1.3 : Examiner les composants
Identifiez tous les composants Figma et mappez-les à des composants React :
| Composant Figma | Composant React | Catégorie |
|---|---|---|
| Button/Primary | <Button variant="primary"> | Primitives |
| Card | <Card> | Conteneurs |
| Navigation/Header | <Header> | Mise en page |
| Section Hero | <HeroSection> | Sections |
| Input/Text | <Input type="text"> | Formulaires |
Étape 1.4 : Confirmer la cible de sortie
Demandez à l'utilisateur de confirmer :
- Framework : Next.js (App Router), Next.js (Pages Router), Vite ou Remix
- Approche de style : Tailwind CSS (par défaut), CSS Modules ou styled-components
- Base de la bibliothèque de composants : shadcn/ui, Radix UI, Headless UI ou aucun
- Gestion d'état : État React, Zustand, Jotai ou aucun
- Répertoire de sortie : par exemple,
src/components/,app/, etc.
Présentez l'inventaire des composants et le résumé des jetons pour approbation par l'utilisateur avant de continuer.
Phase 2 : Exécution (Autonome)
Une fois que l'utilisateur a approuvé le plan de découverte, procédez de manière autonome à travers toutes les étapes.
Contrainte du fichier de verrouillage des jetons
Si src/styles/design-tokens.lock.json existe, TOUT le code généré DOIT référencer les valeurs du fichier de verrouillage :
- Couleurs : Utilisez les classes Tailwood mappées dans le fichier de verrouillage, jamais des valeurs hexadécimales approximatives
- Typographie : Utilisez les familles de polices, tailles et poids exacts du fichier de verrouillage
- Espacement : Utilisez les valeurs de l'échelle d'espacement du fichier de verrouillage
- Contenu textuel : Utilisez les chaînes exactes de
lockfile.textContent
N'approchez jamais et ne devinez jamais les valeurs lorsqu'un fichier de verrouillage existe. Si une valeur ne se trouve pas dans le fichier de verrouillage, ajoutez-la d'abord au fichier de verrouillage, puis référencez-la.
Porte de tests d'abord (OBLIGATOIRE)
Le TDD est appliqué. La mise en œuvre du composant NE DOIT PAS commencer tant que les fichiers de test n'existent pas. Il s'agit d'une porte stricte, pas d'une suggestion.
AVANT d'écrire toute mise en œuvre de composant :
1. Exécutez : ./scripts/verify-test-coverage.sh
→ Si code de sortie 1 : ARRÊTEZ. Invoquez d'abord la compétence tdd-from-figma.
→ Si code de sortie 0 : Passez à la mise en œuvre.
2. Pour chaque composant à générer :
a. EXIGENCE : src/components/**/{NomDuComposant}.test.tsx existe
→ Si manquant : ARRÊTEZ. Écrivez d'abord le test (invoquez tdd-from-figma).
→ Ce n'est pas facultatif. Aucun composant n'est livré sans tests préexistants.
b. Lisez le fichier de test pour comprendre le comportement attendu
c. La mise en œuvre DOIT faire passer tous les tests
d. Exécutez : pnpm vitest run {fichier-de-test} après avoir écrit le composant
e. Si le test échoue : corrigez le composant, PAS le test
3. Après que tous les composants d'un lot sont écrits :
→ Exécutez : pnpm vitest run --reporter=verbose
→ TOUS les tests doivent réussir (phase Verte) avant de continuer
→ Si un échoue : corrigez les composants jusqu'à ce qu'ils soient verts. Ne passez pas à la Phase 3.
4. Vérifiez que la couverture de test atteint le seuil :
→ Exécutez : pnpm vitest run --coverage
→ Doit atteindre : pipeline.config.json → tdd.coverageThreshold (par défaut : 80%)
Pourquoi cette porte existe : Les tests codent des valeurs exactes du fichier de verrouillage (contenu textuel, rôles ARIA, structure des composants). Sans tests pré-écrits, il n'y a aucun mécanisme pour vérifier que la mise en œuvre correspond au design. Les tests sont le contrat entre le design Figma et le code React.
Étape 2.1 : Générer la configuration Tailwind
Créez ou étendez tailwind.config.ts avec les jetons extraits :
// tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
content: ["./src/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}"],
theme: {
extend: {
colors: {
// Jetons sémantiques mappés à partir des variables Figma
primary: {
DEFAULT: "var(--color-primary)",
foreground: "var(--color-primary-foreground)",
// ... échelle complète
},
// ... tous les jetons de couleur
},
fontFamily: {
sans: ["var(--font-sans)", "system-ui", "sans-serif"],
heading: ["var(--font-heading)", "system-ui", "sans-serif"],
},
fontSize: {
// Mappé à partir des styles de typographie Figma
},
spacing: {
// Mappé à partir des variables d'espacement Figma
},
borderRadius: {
// Mappé à partir des jetons de rayon de bordure Figma
},
boxShadow: {
// Mappé à partir des styles d'effet Figma
},
},
},
plugins: [],
};
export default config;
Générez un fichier CSS compagnon avec des propriétés personnalisées :
/* src/styles/tokens.css */
:root {
/* Couleurs - Primitives */
--color-blue-500: #3b82f6;
/* ... */
/* Couleurs - Sémantiques */
--color-primary: var(--color-blue-500);
--color-primary-foreground: #ffffff;
/* ... */
/* Typographie */
--font-sans: "Inter", system-ui, sans-serif;
--font-heading: "Plus Jakarta Sans", system-ui, sans-serif;
/* ... */
}
Étape 2.2 : Générer les composants React
Pour chaque composant identifié dans la Phase 1, générez :
Structure de fichier par composant :
src/components/
├── ui/
│ ├── button.tsx # Composants primitifs
│ ├── input.tsx
│ ├── card.tsx
│ └── ...
├── layout/
│ ├── header.tsx # Composants de mise en page
│ ├── footer.tsx
│ └── ...
├── sections/
│ ├── hero-section.tsx # Sections de page
│ ├── features-grid.tsx
│ └── ...
└── pages/ # Compositions de page complètes (ou app/ pour Next.js)
├── home-page.tsx
└── ...
Modèle de composant :
// src/components/ui/button.tsx
import { type ButtonHTMLAttributes, forwardRef } from "react";
import { cn } from "@/lib/utils";
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary" | "outline" | "ghost";
size?: "sm" | "md" | "lg";
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = "primary", size = "md", ...props }, ref) => {
return (
<button
ref={ref}
className={cn(
"inline-flex items-center justify-center rounded-md font-medium transition-colors",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
"disabled:pointer-events-none disabled:opacity-50",
{
"bg-primary text-primary-foreground hover:bg-primary/90": variant === "primary",
"bg-secondary text-secondary-foreground hover:bg-secondary/90": variant === "secondary",
"border border-input bg-transparent hover:bg-accent": variant === "outline",
"hover:bg-accent hover:text-accent-foreground": variant === "ghost",
},
{
"h-8 px-3 text-sm": size === "sm",
"h-10 px-4 text-sm": size === "md",
"h-12 px-6 text-base": size === "lg",
},
className
)}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, type ButtonProps };
Règles pour la génération de composants :
- Tous les composants sont fonctionnels avec
forwardReflorsque approprié - Chaque composant a une
interfaceTypeScript explicite pour les props - Tout le style utilise des classes Tailwind référençant les valeurs des jetons
- Les composants acceptent une prop
classNamepour la composition - Utilisez l'utilitaire
cn()(clsx + tailwind-merge) pour la fusion de classes - Incluez des attributs ARIA appropriés pour les éléments interactifs
- Exportez à la fois le composant et son type de props
Étape 2.3 : Générer les compositions de page
Composez les composants de section en pages complètes correspondant aux cadres Figma :
// app/page.tsx (Next.js App Router)
import { Header } from "@/components/layout/header";
import { HeroSection } from "@/components/sections/hero-section";
import { FeaturesGrid } from "@/components/sections/features-grid";
import { Footer } from "@/components/layout/footer";
export default function HomePage() {
return (
<div className="flex min-h-screen flex-col">
<Header />
<main className="flex-1">
<HeroSection />
<FeaturesGrid />
</main>
<Footer />
</div>
);
}
Étape 2.4 : Gérer les images et les ressources
Pour les images statiques de Figma :
// Next.js - utilisez next/image
import Image from "next/image";
import heroImage from "@/assets/images/hero.webp";
<Image src={heroImage} alt="Illustration héroïque" width={1200} height={600} priority />
// Vite - utilisez des importations standard
import heroImage from "@/assets/images/hero.webp";
<img src={heroImage} alt="Illustration héroïque" width={1200} height={600} loading="eager" />
Règles :
- Exportez les images de Figma en 1x et 2x pour la rétine
- Utilisez le format WebP avec un repli JPEG/PNG
- Placez dans
public/images/ousrc/assets/images/ - Chaque
<img>doit avoir un attributaltsignificatif - Les images au-dessus de la ligne de flottaison utilisent
priority(Next.js) ouloading="eager" - Les images en dessous de la ligne de flottaison utilisent
loading="lazy"
Étape 2.5 : Générer les fichiers utilitaires
src/lib/
├── utils.ts # Aide cn(), formateurs
└── fonts.ts # Chargement de polices (Next.js : next/font, Vite : @fontsource)
Étape 2.6 : Exécuter les tests (si les fichiers de test existent)
Après avoir généré tous les composants, si des fichiers de test ont été écrits par tdd-from-figma :
pnpm vitest run --reporter=verbose
Si les tests échouent : Corrigez la mise en œuvre du composant pour correspondre aux attentes du test. Les tests sont authentiques — ils codent les valeurs exactes du fichier de verrouillage. Ne modifiez pas les tests pour qu'ils correspondent à la mise en œuvre.
Itérez jusqu'à ce que tous les tests réussissent (phase Verte du TDD).
Étape 2.7 : Générer les histoires Storybook (Non-Bloquant)
Une fois les composants construits et leurs tests unitaires réussis, générez automatiquement les histoires Storybook et la documentation MDX. Invoquez la compétence storybook-story-generation (ou exécutez le script directement). C'est la Phase 4.5 du pipeline et elle est non-bloquante — un échec à ce stade enregistre un avertissement et le pipeline continue.
# Génère .stories.tsx + .mdx pour chaque composant (ignore ceux qui ont déjà des histoires)
./scripts/generate-stories.sh
# Prévisualisation sans écriture, ou régénération forcée
…