[UI mobile] Socle : nav, popovers et dialogs mobile-natifs #91

Closed
opened 2026-09-07 11:33:58 +02:00 by kyuno · 0 comments
Owner

Résumé

Ticket fondation du chantier "UI mobile & tablette" — dont dépendent tous
les autres tickets ci-dessous. Introduit les quelques composants
vraiment repensés pour mobile (pas juste du CSS resserré sur le DOM
desktop) là où l'audit du chantier a trouvé de vrais problèmes structurels,
plus les breakpoints nommés qui servent de source unique à tout le reste.

Ce chantier en entier (index)

Ce ticket est le socle technique ; les 8 autres, tous planned, couvrent
le reste du périmètre identifié :

  • #83 — Tests Cypress ciblant téléphone et tablette
  • #84 — Redirection vers l'appli + page de téléchargement
  • #85 — La landing page met en avant le téléchargement sur mobile
  • #86 — Onglet "Paramètres d'application"
  • #87 — Popovers flottants → sûrs sur mobile
  • #88 — Grille planning : vue mobile dédiée
  • #89 — Session de cuisine : passe mobile
  • #90 — Liste de courses et catalogue de recettes : renforcement mobile

Contexte

L'app mobile (Capacitor, Android) partage 100% de son code avec le site
web — mêmes routes, mêmes composants, même DOM. Un premier passage
responsive existe (#55) mais s'arrête à la coquille de AppLayout
(sidebar → barre horizontale scrollable sous 640px). Un audit du code (fait
pour ce chantier, pas deviné) trouve que :

  • 8 fichiers .scss sur 28 ont ne serait-ce qu'une règle @media ; 20
    n'en ont aucune.
  • Aucun composant du repo, nulle part, ne branche son JSX/sa structure
    selon la plateforme ou la largeur — chaque adaptation existante est du
    CSS pur sur un DOM identique (main.tsx ne branche que le routeur et le
    stockage du token ; useAppUpdateCheck ne branche qu'un effet de bord,
    jamais du rendu). "Séparer le mobile du web" est donc un pattern
    entièrement nouveau à introduire ici, pas l'extension d'un existant.
  • Deux popovers flottants (panier de restes, calendrier de semaine) et le
    <dialog> générique n'ont aucune gestion dédiée à un petit écran au-delà
    d'un ajustement de marge.

Décision d'architecture (tranchée avec l'utilisateur)

Une seule app/build (pas de apps/mobile séparé) — jugé disproportionné
vu qu'aucune infra de partage (package de hooks/services dédié) n'existe
aujourd'hui pour l'amortir, et vu qu'aucun problème mobile trouvé par
l'audit n'est un problème de logique, seulement de présentation. Les
hooks/services/formulaires/logique métier/client API/i18n restent 100%
partagés sans aucun doublon ; seuls les quelques composants listés
ci-dessous gagnent une variante mobile réelle.

Contenu attendu

  • useIsMobileViewport() (apps/web/src/hooks/ ou lib/) — un seul
    point de vérité pour "faut-il rendre la variante mobile", basé sur
    window.matchMedia, pas un check ponctuel par composant. Zéro précédent
    dans le repo aujourd'hui (vérifié : aucun matchMedia/useMediaQuery
    nulle part) — ce hook devient la référence pour tous les tickets
    suivants qui ont besoin de brancher du JSX (pas juste du CSS) selon la
    largeur.
  • Breakpoints nommés dans apps/web/src/styles/_theme.scss
    (--breakpoint-phone: 640px, --breakpoint-tablet: 1024px) remplaçant
    les nombres magiques dispersés aujourd'hui (640/860/1024 répétés en dur
    dans AppLayout.scss, landing-page.scss, recipes.scss,
    recipe-picker-dialog.scss, planning-page.scss, dialog.scss,
    tours-page.scss) — source unique, réutilisée par le hook ci-dessus, par
    chaque @media existant (à migrer vers var(--breakpoint-*) dans ce
    ticket) et par les tests Cypress de #83.
  • AppLayout : nouvelle nav mobile en barre d'onglets basse (bottom
    tab bar) sous le breakpoint phone, à la place de l'actuelle barre
    horizontale scrollable. Paramètres et compte y deviennent des feuilles
    (voir primitif ci-dessous) plutôt que des popovers flottants ancrés —
    mêmes items de nav (NAV_ITEMS/SETTINGS_ITEMS), même logique de
    routing, juste une présentation différente sous ce breakpoint.
  • Primitif "feuille mobile" (bottom sheet, pleine largeur, tirée depuis
    le bas, fermeture par swipe/tap-outside) réutilisable dans
    apps/web/src/components/ui/ — utilisé par la nav ci-dessus et par #87
    pour les popovers flottants existants.
  • components/ui/dialog.scss : vrai plein-écran (bord à bord, sans
    border-radius, sans marge) sous le breakpoint phone, pas juste la
    marge réduite actuelle (max-width: calc(100vw - var(--space-md))) —
    bénéficie à RecipePickerDialog et tout <dialog> futur sans
    changement par appelant.

Dépendances

Aucune — c'est le point de départ du chantier. #83–#90 en dépendent tous
(directement ou via le hook/primitif/breakpoints introduits ici).

## Résumé Ticket fondation du chantier "UI mobile & tablette" — dont dépendent tous les autres tickets ci-dessous. Introduit les quelques composants *vraiment* repensés pour mobile (pas juste du CSS resserré sur le DOM desktop) là où l'audit du chantier a trouvé de vrais problèmes structurels, plus les breakpoints nommés qui servent de source unique à tout le reste. ## Ce chantier en entier (index) Ce ticket est le socle technique ; les 8 autres, tous `planned`, couvrent le reste du périmètre identifié : - #83 — Tests Cypress ciblant téléphone et tablette - #84 — Redirection vers l'appli + page de téléchargement - #85 — La landing page met en avant le téléchargement sur mobile - #86 — Onglet "Paramètres d'application" - #87 — Popovers flottants → sûrs sur mobile - #88 — Grille planning : vue mobile dédiée - #89 — Session de cuisine : passe mobile - #90 — Liste de courses et catalogue de recettes : renforcement mobile ## Contexte L'app mobile (Capacitor, Android) partage 100% de son code avec le site web — mêmes routes, mêmes composants, même DOM. Un premier passage responsive existe (#55) mais s'arrête à la coquille de `AppLayout` (sidebar → barre horizontale scrollable sous 640px). Un audit du code (fait pour ce chantier, pas deviné) trouve que : - **8 fichiers `.scss` sur 28** ont ne serait-ce qu'une règle `@media` ; 20 n'en ont aucune. - **Aucun composant du repo, nulle part, ne branche son JSX/sa structure** selon la plateforme ou la largeur — chaque adaptation existante est du CSS pur sur un DOM identique (`main.tsx` ne branche que le routeur et le stockage du token ; `useAppUpdateCheck` ne branche qu'un effet de bord, jamais du rendu). "Séparer le mobile du web" est donc un pattern entièrement nouveau à introduire ici, pas l'extension d'un existant. - Deux popovers flottants (panier de restes, calendrier de semaine) et le `<dialog>` générique n'ont aucune gestion dédiée à un petit écran au-delà d'un ajustement de marge. ## Décision d'architecture (tranchée avec l'utilisateur) Une seule app/build (pas de `apps/mobile` séparé) — jugé disproportionné vu qu'aucune infra de partage (package de hooks/services dédié) n'existe aujourd'hui pour l'amortir, et vu qu'aucun problème mobile trouvé par l'audit n'est un problème de *logique*, seulement de *présentation*. Les hooks/services/formulaires/logique métier/client API/i18n restent 100% partagés sans aucun doublon ; seuls les quelques composants listés ci-dessous gagnent une variante mobile réelle. ## Contenu attendu - **`useIsMobileViewport()`** (`apps/web/src/hooks/` ou `lib/`) — un seul point de vérité pour "faut-il rendre la variante mobile", basé sur `window.matchMedia`, pas un check ponctuel par composant. Zéro précédent dans le repo aujourd'hui (vérifié : aucun `matchMedia`/`useMediaQuery` nulle part) — ce hook devient la référence pour tous les tickets suivants qui ont besoin de brancher du JSX (pas juste du CSS) selon la largeur. - **Breakpoints nommés** dans `apps/web/src/styles/_theme.scss` (`--breakpoint-phone: 640px`, `--breakpoint-tablet: 1024px`) remplaçant les nombres magiques dispersés aujourd'hui (640/860/1024 répétés en dur dans `AppLayout.scss`, `landing-page.scss`, `recipes.scss`, `recipe-picker-dialog.scss`, `planning-page.scss`, `dialog.scss`, `tours-page.scss`) — source unique, réutilisée par le hook ci-dessus, par chaque `@media` existant (à migrer vers `var(--breakpoint-*)` dans ce ticket) et par les tests Cypress de #83. - **`AppLayout`** : nouvelle nav mobile en barre d'onglets basse (bottom tab bar) sous le breakpoint phone, à la place de l'actuelle barre horizontale scrollable. Paramètres et compte y deviennent des feuilles (voir primitif ci-dessous) plutôt que des popovers flottants ancrés — mêmes items de nav (`NAV_ITEMS`/`SETTINGS_ITEMS`), même logique de routing, juste une présentation différente sous ce breakpoint. - **Primitif "feuille mobile"** (bottom sheet, pleine largeur, tirée depuis le bas, fermeture par swipe/tap-outside) réutilisable dans `apps/web/src/components/ui/` — utilisé par la nav ci-dessus et par #87 pour les popovers flottants existants. - **`components/ui/dialog.scss`** : vrai plein-écran (bord à bord, sans `border-radius`, sans marge) sous le breakpoint phone, pas juste la marge réduite actuelle (`max-width: calc(100vw - var(--space-md))`) — bénéficie à `RecipePickerDialog` et tout `<dialog>` futur sans changement par appelant. ## Dépendances Aucune — c'est le point de départ du chantier. #83–#90 en dépendent tous (directement ou via le hook/primitif/breakpoints introduits ici).
kyuno added the
enhancement
High
planned
labels 2026-09-07 11:33:58 +02:00
kyuno closed this issue 2026-09-07 12:21:29 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/batchCooking#91
No description provided.