mirror of
https://github.com/MaksTinyWorkshop/_Assistant_Lead_Tech
synced 2026-04-06 21:41:42 +02:00
Refonte Structure
This commit is contained in:
186
knowledge/frontend/patterns/design-tokens.md
Normal file
186
knowledge/frontend/patterns/design-tokens.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Frontend — Patterns : Design Tokens
|
||||
|
||||
> Extrait de la base de connaissance Lead_tech. Voir `knowledge/frontend/patterns/README.md` pour l'index complet.
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-design-tokens-expo-rn"></a>
|
||||
## 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
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-token-typography-semantique"></a>
|
||||
## 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".
|
||||
|
||||
---
|
||||
|
||||
<a id="pattern-export-styles-composant"></a>
|
||||
## 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';
|
||||
<TouchableOpacity style={[buttonStyles.base, styles.facebookButton]} />
|
||||
```
|
||||
|
||||
<a id="pattern-tests-styles-sans-renderer"></a>
|
||||
## 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
|
||||
Reference in New Issue
Block a user