diff --git a/static/document/document-editor.css b/static/document/document-editor.css index 1866b4aa..97d10129 100644 --- a/static/document/document-editor.css +++ b/static/document/document-editor.css @@ -1165,26 +1165,66 @@ 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) — une simple liste - (pas de vignette visuelle), toujours visible en tête du panneau. ---- */ + 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). ---- */ .docPageSection { display: flex; flex-direction: column; gap: 8px; } -.docPageList { +/* 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. */ +.docPageStrip { display: flex; - flex-direction: column; + align-items: center; gap: 4px; } +.docPageStripNav { + flex-shrink: 0; + width: 22px; + height: 72px; + border: 1px solid var(--doc-border); + border-radius: 6px; + background: var(--doc-card); + color: var(--doc-muted); + font-size: 15px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} + +.docPageStripNav:hover { + border-color: var(--doc-accent); + color: var(--doc-text); +} + +.docPageList { + flex: 1; + min-width: 0; + display: flex; + flex-direction: row; + gap: 6px; + overflow: auto hidden; + padding-bottom: 4px; +} + .docPageListItem { display: flex; + flex-direction: column; align-items: center; - justify-content: space-between; - gap: 8px; - padding: 7px 8px; + gap: 4px; + flex-shrink: 0; + width: 72px; + padding: 4px; border: 1px solid var(--doc-border); border-radius: 8px; background: var(--doc-card); @@ -1205,44 +1245,21 @@ img.docImage { outline-offset: 1px; } -.docPageListTitle { - flex: 1; - min-width: 0; - font-size: 12.5px; - font-weight: 600; - color: var(--doc-muted); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.docPageListItem.is-active .docPageListTitle { - color: var(--doc-text); -} - -.docPageListTitle[contenteditable="true"] { - outline: none; - border-bottom: 1px solid var(--doc-accent); - cursor: text; - user-select: text; - color: var(--doc-text); -} - .docPageListActions { display: flex; align-items: center; + justify-content: center; gap: 2px; - flex-shrink: 0; } .docPageListActions button { - width: 20px; - height: 20px; + width: 16px; + height: 16px; border: none; - border-radius: 5px; + border-radius: 4px; background: transparent; color: var(--doc-muted); - font-size: 11px; + font-size: 9px; cursor: pointer; display: flex; align-items: center; @@ -1263,6 +1280,62 @@ img.docImage { color: var(--doc-quiz-danger-border); } +.docPageListSquare { + width: 40px; + height: 40px; + border-radius: 6px; + background: var(--doc-bg-2); + border: 1px solid var(--doc-border); + display: flex; + align-items: center; + justify-content: center; + font-size: 13px; + font-weight: 700; + color: var(--doc-muted); +} + +.docPageListItem.is-active .docPageListSquare { + border-color: var(--doc-accent); + color: var(--doc-accent); +} + +/* Titre SOUS le carré, tronqué, qui défile au survol si tronqué (retour + utilisateur du 21/09/2026) — .has-overflow n'est posé que si le texte + dépasse réellement (voir forgeDocApplyTitleMarquee), jamais un + défilement systématique qui ferait sauter les titres courts. */ +.docPageListTitle { + width: 100%; + overflow: hidden; + white-space: nowrap; +} + +.docPageListTitleText { + display: inline-block; + font-size: 11px; + font-weight: 600; + color: var(--doc-muted); + transition: transform 0.6s ease; +} + +.docPageListItem.is-active .docPageListTitleText { + color: var(--doc-text); +} + +.docPageListTitle.has-overflow:hover .docPageListTitleText { + transform: translateX(calc(-1 * var(--marquee-distance, 0px))); +} + +.docPageListTitle[contenteditable="true"] { + outline: none; + cursor: text; + user-select: text; +} + +.docPageListTitle[contenteditable="true"] .docPageListTitleText { + border-bottom: 1px solid var(--doc-accent); + color: var(--doc-text); +} + /* ---- 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 115d4899..e3fd56fe 100644 --- a/static/document/js/document-editor.js +++ b/static/document/js/document-editor.js @@ -575,6 +575,19 @@ function forgeDocStartRenamingPage(pageId) { titleEl.addEventListener('keydown', onKeydown); } +function forgeDocApplyTitleMarquee(titleEl) { + // "défile au passage de la souris" (retour utilisateur du 21/09/2026) : + // seuls les titres RÉELLEMENT tronqués défilent au survol — mesuré ici + // (scrollWidth vs clientWidth), jamais un défilement systématique qui + // ferait sauter les titres courts sans raison. + const textEl = titleEl.querySelector('.docPageListTitleText'); + const overflow = textEl.scrollWidth - titleEl.clientWidth; + if (overflow > 0) { + titleEl.classList.add('has-overflow'); + titleEl.style.setProperty('--marquee-distance', `${overflow}px`); + } +} + function forgeDocRenderPageList() { const container = document.getElementById('docPageList'); if (!container) return; @@ -588,13 +601,14 @@ function forgeDocRenderPageList() { role="button" tabindex="0" data-page-id="${p.id}"> - ${forgeDocEscapeHtml(p.title)}
- - + +
+
${index + 1}
+ ${forgeDocEscapeHtml(p.title)} `).join(''); @@ -627,10 +641,24 @@ function forgeDocRenderPageList() { forgeDocDeletePage(Number(btn.dataset.pageId)); }); }); + container.querySelectorAll('.docPageListTitle').forEach(forgeDocApplyTitleMarquee); 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' })); +} + function forgeDocBindPageNavPill() { document.getElementById('docPagePrevBtn').addEventListener('click', () => { const pages = forgeDocOrderedPages(); @@ -2755,6 +2783,7 @@ function forgeDocInit() { forgeDocBindKeyboardShortcuts(); forgeDocBindScenarioTreeModal(); forgeDocRenderPageList(); + forgeDocBindPageStripNav(); forgeDocBindPageNavPill(); forgeDocUpdateHistoryButtons(); diff --git a/templates/document/document_edit.html b/templates/document/document_edit.html index 93afba3b..14365da1 100644 --- a/templates/document/document_edit.html +++ b/templates/document/document_edit.html @@ -97,45 +97,58 @@
Pages
-
- {% for page in pages %} -
- {# //NOSONAR Web:S6819,Web:MouseEventWithoutKeyboardEquivalentCheck - div+role=button - volontaire : la rangée contient de vrais - - - +
+ +
+ {% for page in pages %} +
+ {# //NOSONAR Web:S6819,Web:MouseEventWithoutKeyboardEquivalentCheck - div+role=button + volontaire : la rangée contient de vrais + + + +
+
{{ loop.index }}
+ {{ page.title }}
-
- {% endfor %} + {% endfor %} +
+