fix(mobile): paginación 2-en-2 con flechas, sin scroll del dedo

- mobile-ui.js: el contenedor se mueve por translateX en pasos de
  ~2 botones en lugar de scrollLeft. Eliminado el botón "Ver todos".
- mobile.css: nuevo .mode-buttons-clip con overflow:hidden para
  bloquear el scroll por gesto. La fila usa width:max-content y
  transition en transform.
- Flechas más grandes (36x40, font 1.7rem) para que sean visibles
  y fáciles de pulsar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SITO 2026-05-09 00:27:39 +02:00
parent 25283c9b1a
commit 10497a6307
2 changed files with 60 additions and 86 deletions

View file

@ -741,45 +741,50 @@ pre, code {
Scroll horizontal con flechas + expand/collapse
============================================================ */
/* Wrapper: flechas + contenedor alineados en fila */
/* Wrapper: flechas + clip alineados en fila */
.mode-buttons-wrap {
display: flex !important;
align-items: center !important;
gap: 4px !important;
gap: 6px !important;
width: 100% !important;
margin-top: 12px !important;
}
/* Contenedor de botones: scroll horizontal, sin wrap */
.mode-buttons-wrap .mode-buttons {
flex: 1 !important;
overflow-x: auto !important;
/* Clip: oculta lo que no cabe, sin scroll de dedo */
.mode-buttons-clip {
flex: 1 1 0 !important;
min-width: 0 !important;
overflow: hidden !important;
position: relative !important;
}
/* Grid/buttons dentro del clip: una sola fila, ancho del contenido */
.mode-buttons-clip > .mode-buttons,
.mode-buttons-clip > .activity-filter-grid {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
scrollbar-width: none !important;
scroll-behavior: smooth !important;
margin-top: 0 !important;
padding-bottom: 4px !important;
}
.mode-buttons-wrap .mode-buttons::-webkit-scrollbar {
display: none !important;
width: max-content !important;
max-width: none !important;
overflow: visible !important;
margin: 0 !important;
padding: 0 !important;
gap: 6px !important;
transition: transform 0.25s ease !important;
will-change: transform !important;
}
/* Cuando está expandido: vuelve a wrap para mostrar todo en grid */
.mode-buttons-wrap.mode-buttons-expanded .mode-buttons {
overflow-x: visible !important;
flex-wrap: wrap !important;
}
/* Flechas de scroll */
/* Flechas de paginación */
.mode-btn-arrow {
flex-shrink: 0 !important;
width: 30px !important;
height: 34px !important;
width: 36px !important;
height: 40px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
border-radius: 8px !important;
font-size: 1.6rem !important;
font-size: 1.7rem !important;
font-weight: 700 !important;
line-height: 1 !important;
cursor: pointer !important;
padding: 0 !important;
@ -838,27 +843,3 @@ pre, code {
font-size: 0.85rem !important;
}
/* Wrapper aplica también al activity-filter-grid */
.mode-buttons-wrap .activity-filter-grid {
flex: 1 1 0 !important;
width: auto !important;
min-width: 0 !important;
overflow-x: auto !important;
flex-wrap: nowrap !important;
scrollbar-width: none !important;
scroll-behavior: smooth !important;
padding-bottom: 4px !important;
}
.mode-buttons-wrap .activity-filter-grid::-webkit-scrollbar {
display: none !important;
}
.mode-buttons-wrap.mode-buttons-expanded .activity-filter-grid {
overflow-x: visible !important;
flex-wrap: wrap !important;
}
/* Asegurar que .mode-buttons dentro del wrap también suelte el width 100% */
.mode-buttons-wrap .mode-buttons {
width: auto !important;
min-width: 0 !important;
}

View file

@ -6,74 +6,67 @@
cnt.dataset.ms = '1';
var items = cnt.querySelectorAll('form, button.filter-btn, a.filter-btn');
var n = items.length;
if (n < 3) return;
if (items.length < 3) return;
// Wrap container with arrows
// Build pager: [arrow-left] [clip > cnt] [arrow-right]
var wrap = document.createElement('div');
wrap.className = 'mode-buttons-wrap';
cnt.parentNode.insertBefore(wrap, cnt);
wrap.appendChild(cnt);
var clip = document.createElement('div');
clip.className = 'mode-buttons-clip';
wrap.appendChild(clip);
clip.appendChild(cnt);
var la = document.createElement('button');
la.type = 'button';
la.className = 'mode-btn-arrow mode-btn-arrow-left';
la.innerHTML = '&#8249;';
la.setAttribute('aria-label', 'Anterior');
wrap.insertBefore(la, clip);
var ra = document.createElement('button');
ra.type = 'button';
ra.className = 'mode-btn-arrow mode-btn-arrow-right';
ra.innerHTML = '&#8250;';
ra.setAttribute('aria-label', 'Siguiente');
wrap.insertBefore(la, cnt);
wrap.appendChild(ra);
function getStep() {
var offset = 0;
function step() {
var btn = cnt.querySelector('button.filter-btn, a.filter-btn, form');
var w = btn ? btn.getBoundingClientRect().width : 90;
if (!w || w < 40) w = 90;
return Math.round((w + 6) * 2);
}
function maxOffset() {
return Math.max(0, cnt.scrollWidth - clip.clientWidth);
}
function apply() {
var max = maxOffset();
if (offset > max) offset = max;
if (offset < 0) offset = 0;
cnt.style.transform = 'translateX(' + (-offset) + 'px)';
var atStart = offset <= 0;
var atEnd = offset >= max - 1;
la.style.opacity = atStart ? '0.25' : '1';
la.style.pointerEvents = atStart ? 'none' : 'auto';
ra.style.opacity = atEnd ? '0.25' : '1';
ra.style.pointerEvents = atEnd ? 'none' : 'auto';
}
la.addEventListener('click', function (e) {
e.preventDefault();
cnt.scrollBy({ left: -getStep(), behavior: 'smooth' });
offset -= step();
apply();
});
ra.addEventListener('click', function (e) {
e.preventDefault();
cnt.scrollBy({ left: getStep(), behavior: 'smooth' });
offset += step();
apply();
});
function syncArrows() {
var atStart = cnt.scrollLeft < 5;
var atEnd = cnt.scrollLeft + cnt.clientWidth >= cnt.scrollWidth - 5;
la.style.opacity = atStart ? '0.2' : '1';
ra.style.opacity = atEnd ? '0.2' : '1';
la.style.pointerEvents = atStart ? 'none' : 'auto';
ra.style.pointerEvents = atEnd ? 'none' : 'auto';
}
cnt.addEventListener('scroll', syncArrows, { passive: true });
setTimeout(syncArrows, 120);
// Expand/collapse toggle for large button groups
if (n > 6) {
var expanded = false;
var xb = document.createElement('button');
xb.type = 'button';
xb.className = 'mode-expand-btn';
xb.textContent = 'Ver todos ▾';
wrap.parentNode.insertBefore(xb, wrap.nextSibling);
xb.addEventListener('click', function (e) {
e.preventDefault();
expanded = !expanded;
cnt.classList.toggle('mode-buttons-expanded', expanded);
wrap.classList.toggle('mode-buttons-expanded', expanded);
xb.textContent = expanded ? 'Ver menos ▴' : 'Ver todos ▾';
setTimeout(syncArrows, 50);
});
}
setTimeout(apply, 120);
window.addEventListener('resize', apply);
});
}