Use Cases (Mis à jour: 03/06/2026)

Design tokens avec Claude Code : de Figma aux variables CSS, Tailwind et React

Implémentez des design tokens avec Claude Code, Style Dictionary, variables CSS, Tailwind et React.

Design tokens avec Claude Code : de Figma aux variables CSS, Tailwind et React

Les design tokens sont un contrat de changement UI

Les design tokens stockent les décisions de design sous forme de données nommées : couleurs, espacements, typographie, rayons, ombres et états. Au lieu de répéter #2563eb, 16px ou 0.5rem dans plusieurs composants, on place la source de vérité dans tokens.json, puis on génère des variables CSS, une configuration Tailwind et du code utilisable par les composants.

Claude Code est utile parce que ce travail est vérifiable. Il peut lire le CSS existant, repérer les valeurs codées en dur, proposer des noms sémantiques, modifier les composants, lancer la génération et résumer le diff. Le prompt vague “rends l’interface cohérente” produit souvent trop de changements. Un bon prompt précise les fichiers, les composants concernés, les règles de contraste et les commandes à exécuter.

Pour compléter, consultez le guide design system avec Claude Code et l’accessibilité avec Claude Code. Les références officielles à garder sous la main sont Design Tokens Format Module 2025.10, Claude Code docs, Figma Variables plugin API, Tailwind theme docs, Style Dictionary, MDN sur les propriétés personnalisées CSS et WCAG sur le contraste.

Raw tokens et semantic tokens

Un raw token décrit la matière première : color.blue.600, space.4, font.size.base. Un semantic token décrit l’intention : color.action.primary.bg, color.text.muted, color.surface.default. Un component token décrit une règle locale, par exemple button.primary.paddingX.

TypeExempleUtilisation
Rawcolor.blue.600Palette, échelle d’espacement, typographie
Semanticcolor.action.primary.bgSens produit, thème, mode sombre
Componentbutton.primary.paddingXException stable d’un composant

Commencez avec raw et semantic. Si un bouton consomme directement color.blue.600, un changement de marque peut laisser un nom faux. Avec color.action.primary.bg, la valeur peut changer sans perdre l’intention.

Transformer une Figma-like spec en contrat de code

Figma Variables est utile, mais Claude Code doit recevoir un handoff vérifiable, pas un export de noms brut. Une Figma-like spec précise le fichier source, les modes, le changement demandé, les composants touchés et les règles de revue. Cela réduit le risk de copier Blue / 600 dans React alors que le produit a besoin de color.action.primary.bg.

{
  "figmaSource": {
    "file": "Marketing UI Kit",
    "collection": "Brand v2",
    "modes": ["light", "dark"]
  },
  "changeRequest": {
    "type": "replace-token",
    "from": "color.blue.600",
    "to": "color.action.primary.bg",
    "components": ["Button", "Link", "Card"]
  },
  "reviewRules": [
    "Do not use raw color tokens in component CSS.",
    "Keep focus and hover tokens explicit.",
    "List affected use case and pitfall before editing files."
  ]
}

Demandez d’abord à Claude Code une table d’impact. Ce workflow évite un pitfall courant : un seul token peut modifier les boutons, liens, cartes et focus outlines.

Un tokens.json exécutable

Créez tokens/tokens.json :

{
  "color": {
    "blue": {
      "50": { "$type": "color", "$value": "#eff6ff" },
      "600": { "$type": "color", "$value": "#2563eb" },
      "700": { "$type": "color", "$value": "#1d4ed8" }
    },
    "slate": {
      "50": { "$type": "color", "$value": "#f8fafc" },
      "100": { "$type": "color", "$value": "#f1f5f9" },
      "700": { "$type": "color", "$value": "#334155" },
      "900": { "$type": "color", "$value": "#0f172a" }
    },
    "white": { "$type": "color", "$value": "#ffffff" },
    "focus": { "$type": "color", "$value": "#f59e0b" },
    "surface": {
      "default": { "$type": "color", "$value": "{color.white}" },
      "muted": { "$type": "color", "$value": "{color.slate.50}" },
      "inverse": { "$type": "color", "$value": "{color.slate.900}" }
    },
    "text": {
      "default": { "$type": "color", "$value": "{color.slate.900}" },
      "muted": { "$type": "color", "$value": "{color.slate.700}" },
      "inverse": { "$type": "color", "$value": "{color.white}" }
    },
    "action": {
      "primary": {
        "bg": { "$type": "color", "$value": "{color.blue.600}" },
        "bgHover": { "$type": "color", "$value": "{color.blue.700}" },
        "text": { "$type": "color", "$value": "{color.white}" }
      }
    }
  },
  "dark": {
    "color": {
      "surface": {
        "default": { "$type": "color", "$value": "{color.slate.900}" },
        "muted": { "$type": "color", "$value": "{color.slate.700}" }
      },
      "text": {
        "default": { "$type": "color", "$value": "{color.white}" },
        "muted": { "$type": "color", "$value": "{color.slate.100}" }
      },
      "action": {
        "primary": {
          "bg": { "$type": "color", "$value": "{color.blue.50}" },
          "bgHover": { "$type": "color", "$value": "{color.white}" },
          "text": { "$type": "color", "$value": "{color.slate.900}" }
        }
      }
    }
  },
  "space": {
    "2": { "$type": "dimension", "$value": "0.5rem" },
    "3": { "$type": "dimension", "$value": "0.75rem" },
    "4": { "$type": "dimension", "$value": "1rem" },
    "6": { "$type": "dimension", "$value": "1.5rem" }
  },
  "font": {
    "size": {
      "sm": { "$type": "dimension", "$value": "0.875rem" },
      "base": { "$type": "dimension", "$value": "1rem" },
      "lg": { "$type": "dimension", "$value": "1.125rem" }
    },
    "weight": {
      "medium": { "$type": "fontWeight", "$value": "500" },
      "bold": { "$type": "fontWeight", "$value": "700" }
    }
  },
  "radius": {
    "md": { "$type": "dimension", "$value": "0.5rem" },
    "lg": { "$type": "dimension", "$value": "0.75rem" }
  },
  "shadow": {
    "button": { "$type": "shadow", "$value": "0 1px 2px rgb(15 23 42 / 0.16)" }
  }
}

Générer les variables CSS

npm install --save-dev style-dictionary

style-dictionary.config.js :

export default {
  source: ["tokens/tokens.json"],
  hooks: {
    formats: {
      "css/variables-with-dark": ({ dictionary }) => {
        const light = dictionary.allTokens
          .filter((token) => !token.path.includes("dark"))
          .map((token) => `  --${token.name}: ${token.value};`)
          .join("\n");

        const dark = dictionary.allTokens
          .filter((token) => token.path[0] === "dark")
          .map((token) => `  --${token.path.slice(1).join("-")}: ${token.value};`)
          .join("\n");

        return `:root {\n${light}\n}\n\n[data-theme="dark"] {\n${dark}\n}\n`;
      }
    }
  },
  platforms: {
    css: {
      transformGroup: "css",
      buildPath: "src/styles/",
      files: [{ destination: "tokens.css", format: "css/variables-with-dark" }]
    }
  }
};

Ajoutez le script :

{
  "scripts": {
    "tokens:build": "style-dictionary build --config style-dictionary.config.js"
  }
}

Sortie CSS attendue :

:root {
  --color-action-primary-bg: #2563eb;
  --color-action-primary-bg-hover: #1d4ed8;
  --color-action-primary-text: #ffffff;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --font-size-base: 1rem;
  --font-weight-bold: 700;
  --radius-md: 0.5rem;
  --shadow-button: 0 1px 2px rgb(15 23 42 / 0.16);
}

[data-theme="dark"] {
  --color-surface-default: #0f172a;
  --color-text-default: #ffffff;
  --color-action-primary-bg: #eff6ff;
  --color-action-primary-text: #0f172a;
}

Tailwind et Button React

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{ts,tsx,js,jsx,mdx}"],
  theme: {
    extend: {
      colors: {
        surface: { DEFAULT: "var(--color-surface-default)", muted: "var(--color-surface-muted)" },
        text: { DEFAULT: "var(--color-text-default)", muted: "var(--color-text-muted)", inverse: "var(--color-text-inverse)" },
        action: { primary: "var(--color-action-primary-bg)", "primary-hover": "var(--color-action-primary-bg-hover)" }
      },
      spacing: { 3: "var(--space-3)", 4: "var(--space-4)", 6: "var(--space-6)" },
      borderRadius: { md: "var(--radius-md)", lg: "var(--radius-lg)" },
      boxShadow: { button: "var(--shadow-button)" }
    }
  }
};
import "./Button.css";

type ButtonProps = {
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
};

export function Button({ children, onClick, disabled = false }: ButtonProps) {
  return (
    <button className="Button" onClick={onClick} disabled={disabled}>
      {children}
    </button>
  );
}
.Button {
  background: var(--color-action-primary-bg);
  border: 0;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-button);
  color: var(--color-action-primary-text);
  cursor: pointer;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-bold);
  padding: var(--space-3) var(--space-4);
}

.Button:hover:not(:disabled) {
  background: var(--color-action-primary-bg-hover);
}

.Button:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

.Button:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

Cas d’usage, pièges et revue

Trois cas reviennent souvent. Pour le passage Figma vers code, Claude Code compare l’export avec tokens.json et liste ajouts, suppressions, renommages et composants touchés. Pour le mode sombre, on surcharge les tokens sémantiques surface, text et action au lieu de dupliquer les feuilles de style. Pour un rebranding ou une landing page, la génération évite la dérive des couleurs et des espacements.

Les pièges concrets : créer trop de component tokens dès le départ, nommer par apparence (blueButton) au lieu de l’intention (primaryAction), modifier à la main le fichier tokens.css généré, ou vérifier le contraste trop tard. Pour du texte normal, WCAG AA demande au moins 4,5:1.

Review checklist :

  • tokens/tokens.json est la seule source modifiée ; le CSS généré n’a pas été retouché à la main.
  • Button, Link et Card ont été vérifiés en light, dark, hover, disabled et focus.
  • React et Tailwind consomment des semantic tokens, pas des raw palette tokens.
  • La PR explique Figma-like spec, use case, pitfall, risk et workflow.
  • Le contraste WCAG 2.2 AA a été vérifié pour le texte et les états interactifs.
Design token review task:
- Read tokens/tokens.json, style-dictionary.config.js, src/styles/tokens.css, tailwind.config.js, and src/components/Button.tsx.
- Check that components use semantic tokens, not raw color tokens.
- Verify light and dark theme values for button, surface, and text tokens.
- Flag any generated CSS file that was edited manually.
- Check WCAG 2.2 AA contrast for normal text and button text.
- Suggest the smallest safe diff. Do not rename tokens unless you list every affected component.
- After changes, run npm run tokens:build and the focused component tests.

Conclusion

Un flux solide consiste à maintenir tokens.json, générer les variables CSS avec Style Dictionary, les exposer dans Tailwind, consommer seulement des semantic tokens dans les composants et contrôler drift et contraste dans chaque PR. J’ai vérifié le parcours de l’exemple en générant les variables CSS puis en les branchant sur un Button React. Pour des prompts et checklists réutilisables, consultez les produits ClaudeCodeLab. En production, ajoutez Storybook, axe et une revue visuelle ; pour un déploiement en équipe, consultez la formation et le conseil ClaudeCodeLab.

#Claude Code #design tokens #design system #CSS #UI design
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.