Files
_Assistant_Lead_Tech/knowledge/frontend/patterns/design-tokens.md
MaksTinyWorkshop 9b7af9f1b0 Refonte Structure
2026-03-25 08:34:19 +01:00

6.8 KiB

Frontend — Patterns : Design Tokens

Extrait de la base de connaissance Lead_tech. Voir knowledge/frontend/patterns/README.md pour l'index complet.


Pattern : Design Tokens natifs TypeScript (Expo / React Native)

Synthèse

  • Objectif : centraliser les tokens de design sans librairie externe (NativeBase, Tamagui), typés et barrel-exportés.
  • Contexte : app Expo / React Native avec un système de design à maintenir.
  • Quand l'utiliser : dès le début d'un projet mobile, avant les premiers composants.
  • Quand l'éviter : si une librairie UI opinionée est déjà choisie et gère ses propres tokens.

Analyse

  • Avantages :
    • aucune dépendance externe, zéro configuration magique
    • autocomplétion TypeScript exacte via as const + types dérivés
    • facile à migrer vers un design system plus élaboré ultérieurement
  • Limites / vigilance :
    • les fichiers TTF doivent être présents dans assets/fonts/ — Google Fonts ne peut pas être téléchargé automatiquement, documenter comme pré-requis dans la story
    • ne pas réutiliser les tokens spacing pour les dimensions de composants (voir risques)

Validation

  • Validé le : 19-03-2026
  • Contexte technique : Expo SDK 52+ / React Native / TypeScript — app-alexandrie story 0.1

Implémentation (exemple minimal)

// apps/mobile/src/theme/colors.ts
export const colors = {
  primary: '#2563EB',
  error: '#DC2626',
  // ...
} as const;
export type ColorToken = keyof typeof colors;

// apps/mobile/src/theme/spacing.ts
export const spacing = { xs: 4, sm: 8, md: 12, base: 16, lg: 24 } as const;
export type SpacingToken = keyof typeof spacing;

// apps/mobile/src/theme/index.ts (barrel export)
export * from './colors';
export * from './spacing';
export * from './typography';
export * from './shadows';

Checklist

  • Tous les tokens as const pour inférence exacte
  • Pas de Context React — constantes TypeScript pures
  • Types dérivés (ColorToken = keyof typeof colors) pour l'autocomplétion
  • useFonts dans _layout.tsx avec guard !fontsLoaded
  • Fichiers TTF présents dans assets/fonts/ et documentés dans la story

Pattern : Token typography par usage sémantique (React Native)

Synthèse

  • Objectif : éviter les mauvais usages de tokens typography visuellement proches mais sémantiquement distincts.
  • Contexte : fichier typography.ts dans un design system React Native.
  • Quand l'utiliser : dès que deux tokens partagent la même taille mais un poids différent.
  • Quand l'éviter : jamais — les tokens typography doivent toujours refléter l'usage, pas l'apparence.

Analyse

  • Avantages :
    • prévient les "approximations" de tokens en code review
    • changement de style d'usage spécifique sans régression globale
  • Limites / vigilance :
    • en review : chercher les usages sans fontWeight explicite — c'est souvent le signe que le mauvais token a été choisi

Validation

  • Validé le : 19-03-2026
  • Contexte technique : React Native / TypeScript — app-alexandrie story 0.4

Implémentation

// Bon : nommé par usage sémantique
listItemTitle: { fontSize: 12, fontWeight: '600' },  // titre d'un item de liste
caption: { fontSize: 12, fontWeight: '500' },         // info secondaire, hints

// Mauvais : nommé par apparence
mediumText12: { fontSize: 12, fontWeight: '500' },    // ambigu, réutilisé à tort

Règle : caption (Medium) ≠ listItemTitle (SemiBold) même si la taille est identique. Ne jamais piocher un token "par approximation".


Pattern : Export des styles de composant pour réutilisation partielle (React Native)

Synthèse

  • Objectif : partager les dimensions et formes d'un composant UI vers des éléments custom qui en dérivent, sans dupliquer les valeurs.
  • Contexte : app React Native où des screens construisent des éléments qui doivent être "au gabarit" d'un composant existant.
  • Quand l'utiliser : bouton custom OAuth, container calqué sur un composant de base, etc.
  • Quand l'éviter : si l'écart visuel est intentionnel — dans ce cas, une constante locale est plus claire.

Analyse

  • Avantages :
    • zéro drift silencieux : si les dimensions du composant changent, tous les éléments dérivés suivent
    • tests de styles possibles en dehors du composant
  • Limites / vigilance :
    • à n'utiliser que pour des éléments vraiment dérivés, pas comme contournement de design system

Validation

  • Validé le : 19-03-2026
  • Contexte technique : React Native / StyleSheet — app-alexandrie story 0.3

Implémentation

// Button.tsx
export const buttonStyles = StyleSheet.create({
  base: { borderRadius: 20, height: 57 },
  primary: { backgroundColor: colors.primary },
});
export function Button(...) { ... }

// login.tsx — bouton OAuth au gabarit du Button
import { buttonStyles } from '@/components/ui/Button';
<TouchableOpacity style={[buttonStyles.base, styles.facebookButton]} />

Pattern : Tests de styles React Native sans renderer JSX

Synthèse

  • Objectif : tester les tokens et styles de composants React Native dans un environnement Jest testEnvironment: node sans renderer JSX.
  • Contexte : config Jest avec transform: { '^.+\\.ts$': 'ts-jest' } — les .tsx ne sont pas transformés.
  • Quand l'utiliser : tokens de thème, logique pure, valeurs de style exportées.
  • Quand l'éviter : rendu conditionnel (styles dynamiques inline) — nécessite @testing-library/react-native.

Analyse

  • Avantages :
    • teste que le composant utilise les bons tokens, pas seulement que les tokens ont des valeurs
    • détecte les régressions de style sans renderer
    • rapide, aucune config Jest supplémentaire
  • Limites / vigilance :
    • ne teste pas le style calculé au runtime (style conditionnel dynamique)

Validation

  • Validé le : 19-03-2026
  • Contexte technique : React Native / Jest / ts-jest — app-alexandrie story 0.2

Implémentation

// Button.tsx — exporter le StyleSheet avec un nom préfixé
export const buttonStyles = StyleSheet.create({
  base: { borderRadius: 20, height: 57 },
  primary: { backgroundColor: colors.primary },
});
export function Button(...) { ... }

// ui-components.spec.ts — importer et vérifier les tokens
import { buttonStyles } from './Button';
import { colors } from '@/theme';

it('variante primary utilise colors.primary', () => {
  expect(buttonStyles.primary.backgroundColor).toBe(colors.primary);
});

Deux niveaux de tests UI recommandés

  1. .spec.ts (node) : tokens, valeurs, logique pure
  2. .spec.tsx (config séparée avec renderer) : rendu visuel, interactions