Repository navigation
Générer le thème NativeWind depuis tokens.json et migrer l'app #125
Copy link
Copy link
Closed
Labels
area:mobileapps/mobileapps/mobileprio:P0BloquantBloquantstatus:readySpec complète, prêt à coderSpec complète, prêt à codertype:choreOutillage, infra, processOutillage, infra, process
Milestone
Description
Contexte
Epic : #13
Maquette : sans objet — socle technique ; les valeurs viennent de tokens.json, validé par D-015 et D-016
Direction-Artistique · Accessibilité, règles pour le code · Architecture-Technique · D-015, D-016
Décision d'Ilan du 2026-09-24 : le style de l'app passe à NativeWind, avec un thème généré depuis tokens.json ; StyleSheet reste permis occasionnellement, dans des cas particuliers. Le thème livré par #21 a été recopié à la main (19 couleurs en dur, tailles et graisses différentes de tokens.json) : ce ticket le remplace, et reprend les exigences de D-015 et D-016 restées dans #21, fermé.
Comportement attendu
- Essai d'abord : vérifier que NativeWind fonctionne proprement avec Expo SDK 57 et React Native 0.86 (build de dev iOS et Android, rechargement à chaud, rendu d'un écran). En cas d'échec, commentaire ⛔ sur ce ticket et arrêt : pas de repli silencieux sur
StyleSheet, la décision revient à Ilan. - Une seule source : une copie de
tokens.jsondans le dépôt, tenue identique à celle du wiki par un script de synchronisation. Un générateur en produit le preset Tailwind (couleurs, styles de texte, espacements, rayons, tailles, ombre) et un module TypeScript typé desmappings:placeCategories,filterIcons,badges,moodDotsindexé par clé d'ambiance,uiIcons,darkSurfaces, seuils d'accessibilité. Les fichiers générés portent l'en-tête « généré depuis tokens.json, ne pas modifier ». - Rien que les tokens : le preset remplace la palette et les échelles par défaut de Tailwind, il ne les étend pas. Tokens
mood-*compris ; le point Nature prendfamily-nature(D-016). Aucune valeurdarkgénérée : le thème sombre n'est pas validé. StyleSheet, occasionnellement : permis pour les cas que NativeWind couvre mal, comme les styles animés de Reanimated, les couches de la carte Mapbox ou une valeur calculée à l'exécution. Les valeurs y viennent toujours du thème généré, jamais en dur.tokens.jsonversion 4 (D-023, reprise de Initialiser l'app Expo avec expo-router, onglets, thème et client API #21 fermé) : icônes d'interface du profil et des réglages, pastillesnewetcertified.tokens.jsonversion 5 (D-025, reprise de Initialiser l'app Expo avec expo-router, onglets, thème et client API #21 fermé) : composant Toast (mappings.toast: succès, info, attention, erreur), noms des icônes d'interface dansmappings.uiIcons, couleurs*-on-strong.tokens.jsonversion 6 (D-028) :mappings.accessibility.denseComponentscomplété ; le plafondmaxFontSizeMultiplier={1.3}se pose dans le composant de base de chaque élément de cette liste, jamais écran par écran.tokens.jsonversion 7 (D-029) :surface-strong-raised,radius-sectionetmappings.immersivepour la page immersive du parcours en cours et le mini-lecteur.- Mouvement (D-030, Direction-Artistique › Mouvement) :
tokens.jsonversion 8 ; constantes de mouvement (durées, courbes, ressort des gestes, vibrations) générées depuismappings.motion; « Réduire les animations » (ReduceMotion) géré dans les composants de base. - Police et icônes : Plus Jakarta Sans 400 à 800 (licence OFL) chargée au démarrage, avec les 20 styles de texte de
tokens.json; icônes Phosphor, appelées par leur nom dans les mappings (Extérieur =park). - Composants de base dans
apps/mobile/src/ui:Text(variantes = styles de texte),Icon,Button(primaire, secondaire, Premium encre),Chip(36 px),Badge(Vérifié, Signature, Premium, Privé, depuismappings.badges),MoodDot, pastille d'étape (famille et icône de catégorie, depuismappings.placeCategories),Card(surface et rayon). Les règles d'accessibilité y sont intégrées :maxFontSizeMultiplier={1.3}sur les composants denses, zones tactiles de 44 px, aucune hauteur fixe sur un composant qui contient du texte. Les écrans assemblent ces composants au lieu de styler à partir de rien. - Migration : les six fichiers qui utilisent
StyleSheetaujourd'hui passent à NativeWind et aux composants de base ;apps/mobile/src/theme/index.ts, recopié à la main, disparaît. - Garde-fous en CI, bloquants : un lint refuse les valeurs arbitraires (
text-[15px],bg-[#fff]), les classes inconnues et toute couleur hexadécimale en dur dansapps/mobile/srchors fichiers générés ; un contrôle vérifie que la copie detokens.jsonest identique à celle du wiki et que la régénération ne produit aucun diff.
Critères d'acceptation
- Essai NativeWind concluant sur iOS et Android en build de dev, ou ⛔ commenté sur ce ticket
- La CI échoue si la copie de
tokens.jsondiffère du wiki ou si les fichiers générés ne sont pas à jour - Une classe hors tokens (
bg-blue-500), une valeur arbitraire ou une couleur hexadécimale en dur font échouer le lint - Plus aucune couleur, taille ni police en dur dans
apps/mobile/srchors fichiers générés ;apps/mobile/src/theme/index.tssupprimé - Chaque
StyleSheetrestant relève d'un cas particulier et lit ses valeurs dans le thème généré - Plus Jakarta Sans 400 à 800 chargée et les 20 styles de texte disponibles ; icônes Phosphor par nom de mapping
- Composants de base livrés avec les plafonds 1,3, les zones tactiles de 44 px et sans hauteur fixe sur du texte ; captures à 100 % et 150 % de texte système dans la PR
- Barre d'onglets et accueil existants conformes à Ecrans › E-01 avec les nouveaux composants
- Aucune valeur
darklivrée - Chaque élément de
mappings.accessibility.denseComponentsporte le plafond 1,3 dans son composant de base - Constantes de mouvement générées depuis
mappings.motion, et « Réduire les animations » géré dans les composants de base
Notes techniques
- Relevé du 2026-09-24 sur
main: ni NativeWind ni Tailwind dansapps/mobile;StyleSheet.createdansapp/(tabs)/index.tsx,src/components/Button.tsx,ConsentBanner.tsx,Screen.tsx,StatusMessage.tsxetTabBar.tsx; 19 couleurs en dur dansapps/mobile/src/theme/index.ts; lint danseslint.config.js. - Emplacement suggéré : un paquet
packages/tokensqui garde la copie detokens.jsonet son générateur. Le preset Tailwind servira aussi à l'admin web en v0.6. - Source à synchroniser :
https://raw.githubusercontent.com/wiki/Inprogress-Agency/widoo-app/design/design-system/tokens.json, lisible sans jeton. - Une PR, plusieurs commits sous le plafond de diff : essai et installation, synchronisation et génération, lint et contrôles CI, composants de base, migration des écrans existants.
- La décision NativeWind doit aussi s'inscrire dans la page wiki Architecture-Technique (DESIGN).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:mobileapps/mobileapps/mobileprio:P0BloquantBloquantstatus:readySpec complète, prêt à coderSpec complète, prêt à codertype:choreOutillage, infra, processOutillage, infra, process
Activity
PaulThiberville commentedon Sep 25, 2026
🔨 Démarrage — plan :
Branche
issue/125-nativewind-tokens, une seule PRFixes #125, un commit par étape, chacun sous 400 lignes utiles. Les fichiers générés sont rangés sousgenerated/et ne comptent pas dans le plafond.global.css. Vérification en build de développement sur le simulateur iOS et l'émulateur Android : rendu d'un écran et rechargement à chaud. En cas d'échec : ⛔ ici et arrêt.packages/tokens: copie detokens.json(version 8) et scriptsyncqui la tient identique au wiki (URL raw, sans jeton), avec un mode--check.lightseulement, les 20 styles de texte, les espacements, les rayons, les tailles et l'ombre. Il produit aussi un module TypeScript typé desmappings:placeCategories,filterIcons,badges,moodDotspar clé d'ambiance depackages/shared,uiIcons,darkSurfaces,accessibility,toast,immersive,motion. En-tête « généré depuis tokens.json, ne pas modifier ». Tests Vitest : aucune valeurdark, et chaque clé demoodset deplaceCategoriesa son entrée.text-[15px]), les classes hors preset et les couleurs hexadécimales en dur dansapps/mobile/src;phosphor-react-native) appelées par nom de mapping, composantsTextetIcon.apps/mobile/src/ui:Button(primaire, secondaire, Premium encre),Chip,Badge,MoodDot,StepDot,Card. Ils portent le plafond 1,3 des composants denses, les zones de 44 px, aucune hauteur fixe sur du texte, les constantes de mouvement et la gestion de « Réduire les animations ».StyleSheetpassent aux composants de base, etsrc/theme/index.tsest supprimé. Le test des contrastes est repris sur les couleurs générées.Vérification finale : iOS et Android, captures à 100 % et à 150 % de texte système dans la PR.
PaulThiberville commentedon Sep 25, 2026
✅ Essai NativeWind concluant, sur la branche
issue/125-nativewind-tokens.Versions : NativeWind 4.2.7 (dernière stable), Tailwind CSS 3.4.19, Expo SDK 57.0.24, React Native 0.86.3, Reanimated 4.5.1.
Vérifié en build de développement (
expo run:ios,expo run:android) :className: fond, rayon, espacement, texte, ombre ;Trois points à connaître, pris en compte dans la suite du ticket :
react-native-css-interopdans chaque fichier.react-native-css-interop(0.2.7, la version de NativeWind) doit donc être une dépendance directe de l'app, etbabel-preset-expoune dépendance de développement directe, puisquebabel.config.jsle nomme.Pressableavec unstyleen fonction (({ pressed }) => …) : le style n'est plus appliqué. LeButtonactuel perd son fond bleu. Il passe aux classes dans le même commit que l'installation, pour que l'app ne soit jamais cassée entre deux commits. Pour les autres états d'appui, on utilisera les variantesactive:ou un état React.shadow-tabbarest posée par leboxShadownatif, avec la valeur du thème généré (cas particulierStyleSheetprévu par le ticket) ;mappings.motion, jamais par les classestransition-*ouanimate-*.1 remaining item
feat(mobile): add the Icon base component with the Phosphor icons
chore(mobile): refuse hand-written styles in lint and check tokens in CI
PaulThiberville commentedon Sep 25, 2026
✅ Fermé par #132, fusionnée en rebase and merge le 2026-09-25 (13 commits, tête
3b8ed72).Critères d'acceptation : tous tenus, sauf
denseComponents, accepté en partiel par Paul par délégation d'Ilan. Le détail critère par critère est dans le tableau de la description de la PR ; les captures à 100 % et 150 %, sur iOS et Android, y sont jointes.Reste hors ticket, déposé dans l'Inbox :
tokens.json(donttagpour la chip « Gratuit ») et absence de tailles d'icônes ;packages/shared;PaulThiberville commentedon Sep 25, 2026
Status du Project « Widoo — MVP » : À déployer → Terminés le 2026-09-25, pour ce ticket et pour l'epic #13.
Décision de Paul du 2026-09-25, transmise à MANAGER par la session d'orchestration. L'app mobile n'a pas encore de build de recette (EAS non initialisé), donc aucune vérification en staging n'est possible. La décision repose sur les essais faits sur simulateur iOS et sur émulateur Android. Cette exception à la règle « Terminés après déploiement vérifié en staging » (
CLAUDE.md) vaut pour la partie mobile.IlanAMG commentedon Sep 25, 2026
Livré avant le passage du wiki à
tokens.jsonversion 9 (D-033). La synchronisation de la version 9 est portée par #139.IlanAMG commentedon Sep 25, 2026
D-034 : tokens version 10 (voiles
mappings.immersive:veilrenforcé,textVeil,scrollDarken,photoText;control-borderpour les étoiles non choisies ;mappings.accessibilityde E-07 et E-15 ; budget « ≈ »). Pas de nouveau ticket : la copie du dépôt et le thème sont mis à jour par la PR automatique #144 (action sync-tokens, #139). Utilisation dans l'app : #42 et #64.IlanAMG commentedon Sep 25, 2026
D-035 et D-036 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) : tokens v12 (la synchro automatique doit suffire). Barre d'onglets : l'onglet s'appelle « Parcours » ; aligner le libellé lecteur d'écran qui porte encore « Sorties ».
IlanAMG commentedon Sep 25, 2026
D-038 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) : tokens v13 (error-ink #B42318, error-soft #FDECEA, mappings.planning). La synchro automatique doit suffire.
IlanAMG commentedon Sep 25, 2026
D-039 : tokens v14 (notes d'icônes au format du générateur).
IlanAMG commentedon Sep 25, 2026
D-040 (https://github.com/Inprogress-Agency/widoo-app/wiki/Design-Changelog) : tokens v15 (mappings.premium).
IlanAMG commentedon Sep 25, 2026
Tokens v20 (D-051) : uniquement des clés d'accessibilité et mappings.toast.undo, pas de nouvelle couleur. Suivi dans les composants de base : #174.
IlanAMG commentedon Sep 29, 2026
Tokens v34 (D-072) :
mappings.premium(plans, passTag, routeCard, prix, états).IlanAMG commentedon Sep 29, 2026
Tokens v35 (D-073).
IlanAMG commentedon Sep 29, 2026
Tokens v36 (D-074).