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:
parent
25283c9b1a
commit
10497a6307
2 changed files with 60 additions and 86 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = '‹';
|
||||
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 = '›';
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue