feat: mobile mode-buttons scroll arrows and expand/collapse
Adds left/right arrow navigation to all .mode-buttons on mobile. Sections with 7+ buttons (Activity, Stats, etc.) also get a Ver todos / Ver menos toggle to expand the full grid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1025f2789d
commit
cb32d0b9ad
4 changed files with 160 additions and 1 deletions
|
|
@ -735,3 +735,68 @@ pre, code {
|
|||
max-width: 100% !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
MODE-BUTTONS MOBILE ENHANCEMENT (mobile-ui.js)
|
||||
Scroll horizontal con flechas + expand/collapse
|
||||
============================================================ */
|
||||
|
||||
/* Wrapper: flechas + contenedor alineados en fila */
|
||||
.mode-buttons-wrap {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 4px !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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
.mode-btn-arrow {
|
||||
flex-shrink: 0 !important;
|
||||
width: 30px !important;
|
||||
height: 34px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 1.6rem !important;
|
||||
line-height: 1 !important;
|
||||
cursor: pointer !important;
|
||||
padding: 0 !important;
|
||||
transition: opacity 0.15s !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
|
||||
/* Botón "Ver todos / Ver menos" */
|
||||
.mode-expand-btn {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
margin-top: 6px !important;
|
||||
padding: 7px 12px !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 0.82rem !important;
|
||||
font-weight: 600 !important;
|
||||
text-align: center !important;
|
||||
cursor: pointer !important;
|
||||
letter-spacing: 0.02em !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,3 +395,17 @@ a.user-link:focus {
|
|||
.mobile-menu-close {
|
||||
color: #FFD700;
|
||||
}
|
||||
|
||||
/* Mode-buttons scroll arrows */
|
||||
.mode-btn-arrow {
|
||||
background-color: #2a2a00;
|
||||
color: #FFD700;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
|
||||
/* Expand/collapse button */
|
||||
.mode-expand-btn {
|
||||
background-color: #1e1e00;
|
||||
color: #FFD700;
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
(function () {
|
||||
function setup() {
|
||||
if (window.innerWidth > 768) return;
|
||||
|
||||
document.querySelectorAll('.mode-buttons:not([data-ms])').forEach(function (cnt) {
|
||||
cnt.dataset.ms = '1';
|
||||
|
||||
var items = cnt.querySelectorAll('form, button.filter-btn, a.filter-btn');
|
||||
var n = items.length;
|
||||
if (n < 3) return;
|
||||
|
||||
// Wrap container with arrows
|
||||
var wrap = document.createElement('div');
|
||||
wrap.className = 'mode-buttons-wrap';
|
||||
cnt.parentNode.insertBefore(wrap, cnt);
|
||||
wrap.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');
|
||||
|
||||
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);
|
||||
|
||||
la.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
cnt.scrollBy({ left: -180, behavior: 'smooth' });
|
||||
});
|
||||
ra.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
cnt.scrollBy({ left: 180, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', setup);
|
||||
} else {
|
||||
setup();
|
||||
}
|
||||
})();
|
||||
|
|
@ -23,7 +23,7 @@ const getUserId = async () => {
|
|||
return userId;
|
||||
};
|
||||
|
||||
const { a, article, br, body, button, details, div, em, footer, form, h1, h2, h3, head, header, hr, html, img, input, label, li, link, main, meta, nav, option, p, pre, section, select, span, summary, table, td, textarea, title, tr, ul, strong, video: videoHyperaxe, audio: audioHyperaxe } = require("../server/node_modules/hyperaxe");
|
||||
const { a, article, br, body, button, details, div, em, footer, form, h1, h2, h3, head, header, hr, html, img, input, label, li, link, main, meta, nav, option, p, pre, script, section, select, span, summary, table, td, textarea, title, tr, ul, strong, video: videoHyperaxe, audio: audioHyperaxe } = require("../server/node_modules/hyperaxe");
|
||||
|
||||
const lodash = require("../server/node_modules/lodash");
|
||||
const markdown = require("./markdown");
|
||||
|
|
@ -682,6 +682,7 @@ const template = (titlePrefix, ...elements) => {
|
|||
link({ rel: "stylesheet", href: "/assets/styles/style.css" }),
|
||||
themeLink,
|
||||
link({ rel: "stylesheet", href: "/assets/styles/mobile.css", media: "(max-width: 768px)" }),
|
||||
script({ src: "/js/mobile-ui.js", defer: true }),
|
||||
link({ rel: "icon", href: "/assets/images/favicon.svg" }),
|
||||
meta({ charset: "utf-8" }),
|
||||
meta({ name: "description", content: i18n.oasisDescription }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue