3.6 KiB
#179 — Éditeur tableur : icônes des menus & boutons, fermeture au focus, polish mobile
Statut : 🔵 en cours (2026-10-04) | Effort : 1-2 jours | Impact : 🟡 Références : Roadmap · Changelog · #154 · #155 · #156
1. Constat
La grille (#155), les menus Structure / Mise en forme / Export (#156-A8/A11/A14)
et les boutons du ruban (#154) étaient textuels, et les menus Structure / Mise
en forme / Export restaient ouverts quand le focus les quittait (seul le
menu grille se fermait, au clic extérieur / Échap uniquement).
2. Livré (A1-A4)
A1 — Icônes du menu contextuel de la grille
Chaque entrée de buildContextItems (viewer.js) porte une icône Lucide
(scissors, copy, clipboard-paste, rows/columns, trash-2 danger,
arrow-up/arrow-down, eraser). Rendu dans xlsx/context-menu.js
(<i data-lucide> + <span class="xlsx-menu-label">, label en textContent
— jamais d'HTML injecté), hydraté par safeCreateIcons() (jamais
lucide.createIcons() direct).
A2 — Icônes Structure / Mise en forme / Export + boutons
- Structure :
file-plus,pencil,copy,trash-2(danger),rows,columns; suppressions marquées.xlsx-context-danger. - Mise en forme :
bold/italic/underline,remove-formatting,align-left/center/right,palette/paint-bucket(sélecteurs natifs),type/hash/percent/euro/calendar/pilcrow(formats),combine/ungroup,snowflake/sun(figer/libérer),move-horizontal/move-vertical(largeur/hauteur). - Export :
file-text(MD),code(HTML),printer(impression). - Ruban : bouton Enregistrer (
save+ libellé), onglet « + » (plus),aria-haspopup="menu"/aria-expandedsur les 3 boutons à menu.
A3 — Fermeture à la perte de focus + clavier
trackDismissable(menu, { toggle, onClose })danscontext-menu.js: clic extérieur (le toggle garde ses propres clics),Échap,focusout(vers menu et toggle exemptés), scroll (capture), resize ;dismiss()idempotent qui débranche tout (pas de fuite entre re-rendus).- Menu grille :
focusout+ scroll/resize en plus de l'existant ;enableArrowNav()(↓/↑/Home/End, désactivés sautés), autofocus de la 1ʳᵉ entrée à l'ouverture (preventScroll),:focustoujours visible. - Menus Structure / Mise en forme / Export branchés sur le helper.
A4 — Polish mobile
@media (pointer: coarse): entrées ≥ 44 px, police 0,9 rem.- Menus bornés au viewport (grille :
min(320px, 86vw)+max-height: 80vhscrollable ; structure :min(320px, 92vw); export :86vw). - Le ruban s'enroule déjà (
flex-wrap), l'inspecteur s'empile ≤ 900 px : vérifié sans débordement horizontal à 393 px (E2E projet mobile).
3. Tests
tests/frontend/xlsx-menus.test.mjs(11) : rendu icônes + XSS, autofocus, navigation clavier,Échap/ clic /focusout/ scroll / resize,trackDismissable, icônes du ruban.tests/frontend/xlsx-viewer.test.mjs(+6, 113 total) : icônes et fermetures au niveau viewer réel.tests/e2e/xlsx-viewer.spec.js(+5) : icônes par entrée, fermeture clic/Échap, Structure au focus perdu, Export au clic extérieur, mobile (ruban, 44 px, viewport) — ce dernierskiphors viewport ≤ 768 px.
4. Limites assumées
- Noms d'icônes de la gamme Lucide 0.344.0 (CDN
unpkg) : si le CDN est injoignable, les libellés restent (dégradation texte, jamais de crash). - Pas de nouveaux libellés i18n (icônes +
aria-expandeduniquement).