# 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) ```typescript // 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 ```typescript // 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 ```typescript // 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'; ``` ## 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 ```typescript // 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