fix(tableaux): option A — sync barre avec window.scrollX + style orange #82
Abandonne le wrapper overflow-x (incompatible avec position:sticky des en-têtes). La barre contrôle désormais le scroll horizontal de la page via window.scrollTo/scrollX, ce qui préserve le sticky des th. Scrollbar orange 12px, styling webkit + Firefox. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+17
-10
@@ -379,14 +379,29 @@ table.cell-table th {
|
||||
background-color: rgb(255 240 240 / 40%);
|
||||
}
|
||||
|
||||
/* Barre de défilement horizontale miroir, collée en haut */
|
||||
/* Barre de défilement horizontale, collée en haut au-dessus des en-têtes */
|
||||
.marches_table .dt-hscroll {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 11; /* au-dessus des en-têtes sticky */
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
height: 14px;
|
||||
height: 12px;
|
||||
scrollbar-color: orange #e0e0e0;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.marches_table .dt-hscroll::-webkit-scrollbar {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.marches_table .dt-hscroll::-webkit-scrollbar-thumb {
|
||||
background-color: orange;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.marches_table .dt-hscroll::-webkit-scrollbar-track {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.marches_table .dt-hscroll-inner {
|
||||
@@ -397,14 +412,6 @@ table.cell-table th {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Conteneur scrollable horizontal — overflow-y:clip ne crée pas de scroll container vertical */
|
||||
/* donc position:sticky sur th.dash-header reste calé sur la page */
|
||||
.marches_table .dt-scroll-wrapper {
|
||||
overflow-x: auto;
|
||||
overflow-y: clip;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Column Visibility Menu */
|
||||
.column-actions {
|
||||
margin-right: 8px;
|
||||
|
||||
+13
-17
@@ -12,45 +12,41 @@
|
||||
// qui déclencherait rootObs et provoquerait une re-entrée dans setup().
|
||||
wrapper.dataset.hscrollReady = "1";
|
||||
|
||||
// Injecter le conteneur scrollable horizontal autour du conteneur Dash
|
||||
const scrollWrapper = document.createElement("div");
|
||||
scrollWrapper.className = "dt-scroll-wrapper";
|
||||
dashContainer.parentNode.insertBefore(scrollWrapper, dashContainer);
|
||||
scrollWrapper.appendChild(dashContainer);
|
||||
|
||||
// Injecter la barre de défilement en haut, avant le wrapper scrollable
|
||||
const bar = document.createElement("div");
|
||||
bar.className = "dt-hscroll is-hidden";
|
||||
const inner = document.createElement("div");
|
||||
inner.className = "dt-hscroll-inner";
|
||||
bar.appendChild(inner);
|
||||
wrapper.insertBefore(bar, scrollWrapper);
|
||||
wrapper.insertBefore(bar, wrapper.firstChild);
|
||||
|
||||
// syncing évite les boucles dans la même pile d'exécution ; l'affectation de scrollLeft
|
||||
// déclenche l'événement scroll de façon synchrone dans Chromium.
|
||||
// La barre synchronise le scroll horizontal de la page (overflow: visible sur les
|
||||
// conteneurs Dash laisse le scroll se faire au niveau de la page, ce qui permet
|
||||
// aux en-têtes position:sticky de rester calés sur la fenêtre).
|
||||
// syncing évite les boucles dans la même pile d'exécution.
|
||||
let syncing = false;
|
||||
const onBar = () => {
|
||||
if (syncing) return;
|
||||
syncing = true;
|
||||
scrollWrapper.scrollLeft = bar.scrollLeft;
|
||||
window.scrollTo(bar.scrollLeft, window.scrollY);
|
||||
syncing = false;
|
||||
};
|
||||
const onTable = () => {
|
||||
const onPage = () => {
|
||||
if (syncing) return;
|
||||
syncing = true;
|
||||
bar.scrollLeft = scrollWrapper.scrollLeft;
|
||||
bar.scrollLeft = window.scrollX;
|
||||
syncing = false;
|
||||
};
|
||||
bar.addEventListener("scroll", onBar);
|
||||
scrollWrapper.addEventListener("scroll", onTable);
|
||||
// SPA : ce listener est intentionnellement conservé pour toute la durée de vie de la page.
|
||||
window.addEventListener("scroll", onPage);
|
||||
|
||||
const refresh = () => {
|
||||
const total = scrollWrapper.scrollWidth;
|
||||
const visible = scrollWrapper.clientWidth;
|
||||
const total = document.documentElement.scrollWidth;
|
||||
const visible = window.innerWidth;
|
||||
inner.style.width = total + "px";
|
||||
// +1 absorbe les erreurs d'arrondi sous-pixel
|
||||
bar.classList.toggle("is-hidden", total <= visible + 1);
|
||||
bar.scrollLeft = scrollWrapper.scrollLeft;
|
||||
bar.scrollLeft = window.scrollX;
|
||||
};
|
||||
|
||||
// Recalcule quand le tableau change (pagination, tri, filtre, données).
|
||||
|
||||
Reference in New Issue
Block a user