From e33b11458c8d4934bca364da76444fe2dd1ade90 Mon Sep 17 00:00:00 2001 From: william Date: Tue, 22 Sep 2026 15:08:09 +0200 Subject: [PATCH] =?UTF-8?q?Bande=20de=20pages=20:=20un=20seul=20carr=C3=A9?= =?UTF-8?q?=20visible=20(la=20page=20active),=20les=20fl=C3=A8ches=20chang?= =?UTF-8?q?ent=20de=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remplace le bandeau scrollable multi-cartes par un vrai carrousel une-page-à-la-fois : un seul carré affiché (la page active), les grandes flèches ‹/› aux extrémités changent directement la page affichée (au lieu de juste faire défiler la vue). Les petites flèches ←/→ au-dessus du carré restent pour réordonner la page active parmi ses sœurs, sans changer l'affichage — distinctes des flèches de navigation. Co-Authored-By: Claude Sonnet 5 --- static/document/document-editor.css | 42 +++++++------ static/document/js/document-editor.js | 78 +++++++++++++++--------- templates/document/document_edit.html | 88 ++++++++++++++------------- 3 files changed, 117 insertions(+), 91 deletions(-) diff --git a/static/document/document-editor.css b/static/document/document-editor.css index 97d10129..26501599 100644 --- a/static/document/document-editor.css +++ b/static/document/document-editor.css @@ -1165,22 +1165,20 @@ img.docImage { /* ---- Section "Pages" du panneau GAUCHE (retour utilisateur du 21/09/2026 : "une section qui s'ajoute dans le panneau de gauche pour ajouter une page et naviguer entre elles", à la place de l'ex- - catégorie "Mise en page"/formes libres, supprimée) — un bandeau - HORIZONTAL défilant à hauteur FIXE (retour utilisateur du 21/09/2026 : - "ce système n'est pas bien il faut un système de slide horizontale" — - une liste verticale grandissait sans limite avec beaucoup de pages), - toujours visible en tête du panneau. Cartes texte (pas de vignette - visuelle). ---- */ + catégorie "Mise en page"/formes libres, supprimée) — un CARROUSEL + une-page-à-la-fois (retour utilisateur du 22/09/2026 : "un seul carré + page visible, les flèches ne servent pas qu'à naviguer mais aussi à + changer de page") : un seul carré = la page ACTIVE, hauteur fixe quel + que soit le nombre de pages. Carte texte (pas de vignette visuelle). ---- */ .docPageSection { display: flex; flex-direction: column; gap: 8px; } -/* Bandeau : flèches précédent/suivant AUX EXTRÉMITÉS (retour utilisateur - du 21/09/2026 : "affiche les flèches ... en plus", donc en supplément - des ←/→ par carte, qui eux réordonnent) — font défiler la VUE de la - bande, jamais la page active. */ +/* ‹/› CHANGENT la page affichée (voir forgeDocBindPageStripNav) — à ne + pas confondre avec les petites flèches ←/→ DANS la carte, qui elles + réordonnent la page active parmi ses sœurs sans changer l'affichage. */ .docPageStrip { display: flex; align-items: center; @@ -1190,7 +1188,7 @@ img.docImage { .docPageStripNav { flex-shrink: 0; width: 22px; - height: 72px; + height: 84px; border: 1px solid var(--doc-border); border-radius: 6px; background: var(--doc-card); @@ -1202,19 +1200,21 @@ img.docImage { justify-content: center; } -.docPageStripNav:hover { +.docPageStripNav:hover:not(:disabled) { border-color: var(--doc-accent); color: var(--doc-text); } +.docPageStripNav:disabled { + opacity: 0.3; + cursor: default; +} + .docPageList { flex: 1; min-width: 0; display: flex; - flex-direction: row; - gap: 6px; - overflow: auto hidden; - padding-bottom: 4px; + justify-content: center; } .docPageListItem { @@ -1222,9 +1222,8 @@ img.docImage { flex-direction: column; align-items: center; gap: 4px; - flex-shrink: 0; - width: 72px; - padding: 4px; + width: 88px; + padding: 6px; border: 1px solid var(--doc-border); border-radius: 8px; background: var(--doc-card); @@ -1336,6 +1335,11 @@ img.docImage { color: var(--doc-text); } +.docPageListCounter { + font-size: 10px; + color: var(--doc-muted); +} + /* ---- RIGHT SIDEBAR : Propriétés ---- */ .docField { display: flex; diff --git a/static/document/js/document-editor.js b/static/document/js/document-editor.js index e3fd56fe..325a1891 100644 --- a/static/document/js/document-editor.js +++ b/static/document/js/document-editor.js @@ -592,36 +592,40 @@ function forgeDocRenderPageList() { const container = document.getElementById('docPageList'); if (!container) return; const pages = forgeDocOrderedPages(); - // div + role="button" ici, jamais - + +
${index + 1}
${forgeDocEscapeHtml(p.title)} + ${index + 1} / ${pages.length} - `).join(''); + `; - container.querySelectorAll('.docPageListItem[data-page-id]').forEach((item) => { - item.addEventListener('click', (e) => { - if (e.target.closest('.docPageListActions')) return; - forgeDocSwitchPage(Number(item.dataset.pageId)); - }); - item.addEventListener('keydown', (e) => { - if (e.key !== 'Enter' && e.key !== ' ') return; - e.preventDefault(); - forgeDocSwitchPage(Number(item.dataset.pageId)); - }); + const item = container.querySelector('.docPageListItem[data-page-id]'); + item.addEventListener('click', (e) => { + if (e.target.closest('.docPageListActions')) return; + forgeDocSwitchPage(Number(item.dataset.pageId)); + }); + item.addEventListener('keydown', (e) => { + if (e.key !== 'Enter' && e.key !== ' ') return; + e.preventDefault(); + forgeDocSwitchPage(Number(item.dataset.pageId)); }); container.querySelectorAll('.docPageListMove').forEach((btn) => { btn.addEventListener('click', (e) => { @@ -642,21 +646,35 @@ function forgeDocRenderPageList() { }); }); container.querySelectorAll('.docPageListTitle').forEach(forgeDocApplyTitleMarquee); + + const prevBtn = document.getElementById('docPageStripPrev'); + const nextBtn = document.getElementById('docPageStripNext'); + if (prevBtn) prevBtn.disabled = index <= 0; + if (nextBtn) nextBtn.disabled = index >= pages.length - 1; + const addBtn = document.getElementById('docPageListAdd'); if (addBtn) addBtn.onclick = () => forgeDocAddPage(); } function forgeDocBindPageStripNav() { - const container = document.getElementById('docPageList'); const prevBtn = document.getElementById('docPageStripPrev'); const nextBtn = document.getElementById('docPageStripNext'); - if (!container || !prevBtn || !nextBtn) return; - // Fait défiler la VUE de la bande (pas la page active — retour - // utilisateur du 21/09/2026 : "affiche les flèches ... en plus", donc - // une navigation visuelle distincte des ←/→ par carte qui, eux, - // réordonnent). Défilement d'environ une carte + son espacement. - prevBtn.addEventListener('click', () => container.scrollBy({ left: -110, behavior: 'smooth' })); - nextBtn.addEventListener('click', () => container.scrollBy({ left: 110, behavior: 'smooth' })); + if (!prevBtn || !nextBtn) return; + // Les flèches ‹/› CHANGENT la page affichée (retour utilisateur du + // 22/09/2026 : "les flèches ne servent pas qu'à naviguer mais aussi à + // changer de page") — lecture dynamique de l'ordre courant à chaque + // clic (même principe que forgeDocBindPageNavPill), jamais un index + // figé au moment du binding. + prevBtn.addEventListener('click', () => { + const pages = forgeDocOrderedPages(); + const index = pages.findIndex((p) => p.id === window.forgeDocState.activePageId); + if (index > 0) forgeDocSwitchPage(pages[index - 1].id); + }); + nextBtn.addEventListener('click', () => { + const pages = forgeDocOrderedPages(); + const index = pages.findIndex((p) => p.id === window.forgeDocState.activePageId); + if (index < pages.length - 1) forgeDocSwitchPage(pages[index + 1].id); + }); } function forgeDocBindPageNavPill() { diff --git a/templates/document/document_edit.html b/templates/document/document_edit.html index 14365da1..b068f785 100644 --- a/templates/document/document_edit.html +++ b/templates/document/document_edit.html @@ -101,54 +101,58 @@ + aria-label="Page précédente" + title="Page précédente">‹
- {% for page in pages %} -
- {# //NOSONAR Web:S6819,Web:MouseEventWithoutKeyboardEquivalentCheck - div+role=button - volontaire : la rangée contient de vrais - - - -
-
{{ loop.index }}
- {{ page.title }} + {# active_page est toujours pages[0] au chargement initial (voir + routes/document/document_edit.py) — index 0 fixe, jamais recalculé + ici ; un changement de page ensuite est entièrement géré côté + client par forgeDocRenderPageList, qui recalcule le VRAI index. #} + {% set active_index = 0 %} +
+ {# //NOSONAR Web:S6819,Web:MouseEventWithoutKeyboardEquivalentCheck - div+role=button + volontaire : la rangée contient de vrais + + +
- {% endfor %} +
{{ active_index + 1 }}
+ {{ active_page.title }} + {{ active_index + 1 }} / {{ pages|length }} +
+ aria-label="Page suivante" + title="Page suivante">›