MAISON CODE .
/ Design Systems · Figma · Tailwind · Architecture

Jetons de conception : combler le fossé entre Figma et la production

Le codage en dur des valeurs HEX est une dette technique. Comment créer un système de conception multiplateforme à l'aide de jetons JSON et d'un dictionnaire de styles.

AB
Alex B.
Jetons de conception : combler le fossé entre Figma et la production

« Pouvez-vous changer le bleu principal en un bleu légèrement plus foncé ? » Dans une base de code existante, cette demande coûte 5 000 €. Pourquoi? Parce que #3b82f6 est codé en dur dans 400 fichiers CSS, 20 fichiers JS et 5 modèles HTML. Dans une base de code moderne, cette requête coûte 0 €. Vous mettez à jour le Design Token dans Figma et il se propage automatiquement sur iOS, Android et Web.

Pourquoi Maison Code en parle

Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.

Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.

Que sont les jetons de conception ?

Les jetons de conception sont les « atomes » du design visuel. Il s’agit de paires clé-valeur indépendantes de la plate-forme.

  • Héritage : couleur : #000000;
  • Jeton : couleur : var(--color-foreground);

La hiérarchie des jetons

Nous ne nous contentons pas de tout aplatir. Nous utilisons une hiérarchie à 3 niveaux pour garantir la signification sémantique.

1. Jetons primitifs (mondiaux)

Valeurs brutes. Ils ne doivent jamais être utilisés directement dans l’interface utilisateur.

  • bleu-500 : #3b82f6
  • gris-900 : #111827
  • espaceur-4 : 16px

2. Jetons sémantiques (alias) : axés sur un objectif.

  • couleur-primaire : {bleu-500}
  • color-surface : {gray-900} (Crucial pour le Mode sombre)
  • espacement-carte-padding : {spacer-4}

3. Jetons de composants (spécifiques)

Remplacements basés sur le contexte.

  • bouton-bg-primaire : {couleur-primaire}
  • card-bg : {couleur-surface}
  • input-border-error : {color-destructive}

Le workflow : de Figma au code

Nous traitons Figma comme la « source de vérité » pour le design, tout comme nous traitons Git comme la source de vérité pour le code. Nous utilisons la fonctionnalité Variables de Figma combinée avec le plugin “Tokens Studio”.

Étape 1 : Exporter des jetons

Nous exportons tokens.json. Ce fichier est la seule source de vérité.

{
  "mondial": {
    "couleurs": {
       "bleu": { "500": { "valeur": "#3b82f6" } }
    }
  },
  "sémantique": {
    "primary": { "value": "{colors.blue.500}" },
    "on-primary": { "value": "{colors.white}" }
  }
}

Étape 2 : Transformations (Dictionnaire de styles)

JSON est inutile sur iOS (Swift) ou Android (XML). Nous utilisons Style Dictionary (par Amazon) pour transformer le JSON en artefacts spécifiques à la plate-forme. Le pipeline de build (« npm run build:tokens ») ressemble à ceci :

graph LR
    Figma[Variables Figma] -->|Plugin| JSON[jetons.json]
    JSON -->|CI/CD| SD[Dictionnaire de styles]
    
    SD -->|Transformer| CSS[Variables CSS]
    SD -->|Transformer| TS[Configuration Tailwind]
    SD -->|Transformer| Swift[Couleur.swift]
    SD -->|Transformer| XML[couleurs.xml]

Étape 3 : Consommation en cas de vent arrière

Pour notre vitrine Headless (construite avec Atomic Design), nous mappons ces jetons sur Tailwind CSS. Dans tailwind.config.js, nous ne codons pas les valeurs en dur. Nous lisons les artefacts de construction.

// tailwind.config.js
const tokens = require('./build/tokens.js');

module.exports = {
  thème : {
    couleurs : {
      primaire : 'var(--color-primary)', // Mappe vers la variable CSS
      arrière-plan : 'var(--color-background)',
    },
    prolonger : {
      borderRadius : jetons.radius,
      fontFamily : tokens.typography,
      espacement : tokens.spacing
    }
  }
}

Cela signifie que nous n’écrivons jamais class="bg-[#3b82f6]". Nous écrivons class="bg-primary". Si la marque devient Red, nous changeons le jeton « primaire » -> « rouge-500 » dans Figma. L’ensemble du site est mis à jour instantanément lors du déploiement.

Architecture du mode sombre

Le mode sombre ne consiste pas à « inverser les couleurs ». Il s’agit de l’échange de jetons. Nous définissons une carte « claire » et une carte « sombre ». Ils partagent les mêmes noms sémantiques (« —color-background »), mais pointent vers des primitives différentes.

Implémentation CSS

:racine {
  /* Par défaut (Clair) */
  --color-background: var(--white);
  --color-text: var(--noir);
  --color-border: var(--gray-200);
}

[data-theme="dark"] {
  /* Remplacer */
  --color-background: var(--noir);
  --color-texte : var(--white);
  --color-border: var(--gray-800);
}

Étant donné que Tailwind utilise le Nom sémantique, la classe « bg-background » fonctionne dans les deux modes. Il est blanc en mode clair et noir en mode sombre. Aucune classe supplémentaire (dark:bg-black) n’est nécessaire dans vos composants React. Cela réduit considérablement la taille du paquet.

Systèmes multimarques (thème)

Pour les agences gérant plusieurs vitrines (par exemple, GAP, Old Navy, Banana Republic), les systèmes de jetons vous permettent de réutiliser la même base de code React. Vous chargez simplement un autre fichier tokens.css.

  • Espace : primaire = Bleu, rayon = 4px.
  • Old Navy : primaire = Navy, radius = 8px. Le code du composant <Button /> reste identique : <button className="bg-primary round-radius">. Il s’agit d’une « marque blanche » à grande échelle.

Jetons de typographie

Les jetons de design ne sont pas que des couleurs.

  • Taille : text-xl -> 1.25rem
  • Poids : font-bold -> 700
  • Hauteur de la ligne : avance-serrée -> 1,25
  • Espacement des lettres : tracking-wide -> 0,025em

Nous encodons les « Typescales » (Tierce Majeure, Quatrième Parfaite) dans les jetons pour garantir l’harmonie mathématique. Si vous définissez manuellement « font-size : 17px », vous cassez le rythme. Les jetons renforcent le système.

9. Visualisation des jetons : le module complémentaire Storybook

Les jetons sont abstraits. Les développeurs doivent les voir. Nous construisons un module complémentaire Storybook personnalisé qui affiche tous les jetons en direct.

  • Palette de couleurs : grilles d’échantillons de couleurs avec leurs noms de jetons.
  • Échelle de typographie : texte rendu dans chaque taille de police.
  • Ombres : cases affichant les niveaux d’élévation. Cela sert de « documentation vivante ». Si un développeur a besoin d’une couleur, il n’ouvre pas Figma. Ils ouvrent Storybook, recherchent « Primaire » et copient le nom de la classe.

10. Le contexte « Fournisseur de thème »

Dans React, comment changer de thème efficacement ? Ne passez pas d’accessoires. Utilisez les variables CSS + le contexte.

const ThemeContext = createContext({ theme : 'light', toggle : () => {} });

fonction d'exportation ThemeProvider({ enfants }) {
  const [thème, setTheme] = useState('light');
  
  utiliserEffet(() => {
    document.documentElement.dataset.theme = thème ;
  }, [thème]);

  return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider> ;
}

Cela met à jour l’attribut data-theme sur la balise <html>. Les variables CSS sont recalculées instantanément. L’arbre React ne restitue pas (sauf pour le bouton bascule lui-même). Ceci est crucial pour la performance.

11. Maintenance et gouvernance

“Un grand pouvoir implique de grandes responsabilités.” Si un concepteur junior cherche à changer le bleu « principal », il pourrait enfreindre la conformité en matière d’accessibilité dans l’ensemble de l’application. Nous implémentons des CI Checks (Style Dictionary Linting) pour les jetons.

Contrôles automatisés

  1. Vérification du contraste : assurez-vous que le texte « sur principal » a un contraste de 4,5 : 1 par rapport à l’arrière-plan « principal ». Sinon, la construction échoue.
  2. Convention de dénomination : rejetez blue-final-v2. Appliquez « blue-500 ».
  3. Jetons orphelins : avertir si un jeton défini n’est jamais utilisé dans la logique de l’interface utilisateur.

12. Alias de jetons pour l’accessibilité

L’accessibilité ne se limite pas au contraste des couleurs. C’est la préférence de l’utilisateur. Certains utilisateurs ont besoin du « Mode contraste élevé ». Certains utilisateurs ont besoin d’un « mouvement réduit ». Nous mappons les jetons à ces requêtes multimédias. durée de mouvement : { var(--motion-fast) } @media (préfère le mouvement réduit) { --motion-fast : 0 ms ; } La tokenisation du mouvement nous permet de respecter le souhait de l’utilisateur de désactiver globalement les animations, sans réécrire les composants CSS.

13. Jetons mobiles ou Web

iOS utilise des points. Le Web utilise Rem. Android utilise DP. Une exportation naïve échoue. Nous utilisons Style Dictionary Transforms pour gérer les mathématiques. spacing.4 (16px) -> iOS 16pt -> Android 16dp. Nous gérons également les Conventions de dénomination :

  • Web : kebab-case (--color-primary)
  • iOS : camelCase (colorPrimary)
  • Android : snake_case (color_primary) Cela garantit que les développeurs se sentent chez eux sur leur plateforme.

14. Conclusion

Les jetons de conception sont « l’API » entre la conception et l’ingénierie. Ils dissocient la valeur (code hexadécimal) de l’intention (couleur primaire). Pour une Maison où les lignes directrices de la marque sont sacrées, les Design Tokens sont le seul moyen de garantir une fidélité à 100 % sur chaque point de contact numérique. Arrêtez d’écrire du CSS. Commencez à écrire des systèmes.


Engagez nos Architectes.