Sous 768 px, la barre de menus, le ruban et le groupe Recherche sont repliés par défaut : la barre de formule (fx), les onglets et Enregistrer restent visibles et la grille récupère la hauteur d'écran. Un bouton unique (#xlsx-tools-toggle) dans la barre des feuilles déplie/replie l'ensemble (aria-expanded, état actif) ; desktop inchangé. Ergonomie tactile : cibles ≥ 44 px, onglets en défilement horizontal, champs de la barre de formule en 16 px (anti-zoom iOS), barre de formule en 2 lignes quand les outils sont ouverts. Tests : JSDOM xlsx-viewer.test.mjs (+2, 165/165), E2E mobile (repli par défaut, dépliage, no-overflow ruban, cibles 44 px) ; openXlsx() déplie automatiquement ≤ 768 px pour les tests desktop.
82 lines
3.9 KiB
Markdown
82 lines
3.9 KiB
Markdown
# #189 — Tableur : mise en page mobile (barres repliées, grille prioritaire)
|
|
|
|
> **Statut :** ✅ livré (2026-10-08) | **Effort :** 0,5-1 jour | **Impact :** 🟡
|
|
> **Références :** [Roadmap](../ROADMAP.md) · [Changelog](../../CHANGELOG.md) ·
|
|
> [#180](./xlsx-sheetbar-180.md) · [#185](./xlsx-menus-185.md)
|
|
|
|
## 1. Constat
|
|
|
|
Sur mobile, l'empilement `.xlsx-menubar` (10 menus) + `.xlsx-cmdbar`
|
|
(~40 boutons qui s'enroulent sur 4-5 rangées) + `.xlsx-sheetbar` +
|
|
`.xlsx-formula-bar` occupait **plus de 50 % de la hauteur d'écran** : la
|
|
grille, objet premier de l'éditeur, passait après la chrome.
|
|
|
|
## 2. Livré
|
|
|
|
### A1 — Repli par défaut (CSS, ≤ 768 px)
|
|
|
|
Bloc `#189` dans `frontend/style.css` (après les règles `pointer: coarse`) :
|
|
|
|
- `.xlsx-menubar`, `.xlsx-cmdbar`, `.xlsx-find-group` → `display: none` par
|
|
défaut sous 768 px ;
|
|
- `.xlsx-toolbar.xlsx-tools-open …` les réaffiche (état de la classe portée
|
|
par la **barre entière**, donc menubar + ruban + Recherche restent cohérents) ;
|
|
- `.xlsx-formula-bar` reste **toujours visible** (zone Nom + `fx` + champ) et
|
|
passe en `flex-wrap` quand les outils sont ouverts (le groupe Recherche
|
|
réapparaît sur une 2ᵉ ligne) ;
|
|
- `.xlsx-tools-toggle { display: none }` sur desktop : **zéro changement
|
|
visuel hors mobile**.
|
|
|
|
### A2 — Bascule unique (JS)
|
|
|
|
`frontend/js/viewer.js` (`renderXlsxViewer`) :
|
|
|
|
- bouton `#xlsx-tools-toggle` (icône Lucide `menu`, `aria-expanded`,
|
|
`aria-label` i18n `xlsx.tools_toggle`) inséré **en tête de
|
|
`.xlsx-sheetbar`** — donc toujours visible, entre les onglets et Enregistrer ;
|
|
- listener : bascule `.xlsx-tools-open` sur `.xlsx-toolbar`, met à jour
|
|
`aria-expanded` + classe `active`, `safeCreateIcons()` pour l'icône.
|
|
|
|
### A3 — Ergonomie tactile (CSS)
|
|
|
|
- cibles ≥ **44 px** : `.xlsx-toolbar .btn-action`, `.xlsx-menubtn`,
|
|
`.xlsx-tab` / `.xlsx-tab-add` ; à cette taille un groupe du ruban
|
|
(police, nombre…) déborde d'un téléphone : `.xlsx-cmd-group` passe en
|
|
`flex: 0 1 auto; min-width: 0; flex-wrap: wrap` pour s'enrouler au lieu
|
|
de sortir de l'écran (contre-preuve E2E : `scrollWidth - clientWidth ≤ 1`) ;
|
|
- onglets de feuilles : une seule ligne, **défilement horizontal**
|
|
(`overflow-x: auto`, scrollbars masquées) au lieu d'enrouler ;
|
|
- champs de la barre de formule en **16 px** : en dessous, iOS zoome
|
|
automatiquement la page au focus (la « classique » debout de l'UI) ;
|
|
- groupe Recherche masqué avec le ruban pour ne pas écraser le champ de saisie.
|
|
|
|
### A4 — i18n
|
|
|
|
Clé `xlsx.tools_toggle` : FR « Afficher / masquer les barres d'outils » /
|
|
EN « Show / hide toolbars » (parité vérifiée par `tests/test_i18n_parity.py`).
|
|
|
|
## 3. Tests
|
|
|
|
- `tests/frontend/xlsx-viewer.test.mjs` (+2, **165/165**) :
|
|
1. la bascule vit dans la barre des feuilles et flippe correctement
|
|
classe / `aria-expanded` / `active` (aller-retour) ;
|
|
2. `style.css` masque menubar/ruban/Recherche par défaut sous 768 px et les
|
|
réaffiche via `.xlsx-tools-open` (44 px, onglets scrollables, inputs
|
|
16 px présents dans le bloc).
|
|
- `tests/e2e/xlsx-viewer.spec.js` — test mobile réécrit : repli par défaut
|
|
(menubar/ruban cachés, formule + onglets visibles) → dépliage → ruban sans
|
|
débordement horizontal → cibles ≥ 44 px → repli ; `openXlsx()` déplie
|
|
automatiquement sous 768 px pour que les tests « desktop » restent valables
|
|
sur les deux viewports.
|
|
|
|
## 4. Limites assumées
|
|
|
|
- Le repli est piloté par la **largeur** (`max-width: 768px`), pas par
|
|
`pointer: coarse` : une tablette large en mode tactile garde la chrome
|
|
complète (elle a la hauteur pour).
|
|
- Le groupe Recherche n'est accessible sur mobile qu'avec les outils ouverts
|
|
; le reset de tri reste atteignable par la mini-barre de sélection et le
|
|
menu Données (vérifié).
|
|
- Pas de drawer latéral ni de FAB : un seul bouton rétractable suffit à
|
|
l'usage — ajouter un panneau glissant si le retour utilisateur le réclame.
|