feat(ui): Slider mit Vor-/Zurück-Buttons und Touch/Mouse-Drag für Warengruppen
All checks were successful
Build and Deploy / build (push) Successful in 54s
All checks were successful
Build and Deploy / build (push) Successful in 54s
This commit is contained in:
@@ -154,20 +154,54 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Swipebar Kategorien */
|
||||
.category-swipe-wrapper {
|
||||
/* Interaktiver Slider / Swipe Container */
|
||||
.slider-nav-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 -16px;
|
||||
padding: 0 16px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.slider-arrow {
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--card-border);
|
||||
color: var(--text);
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
z-index: 2;
|
||||
flex-shrink: 0;
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.slider-arrow:hover {
|
||||
background: var(--primary);
|
||||
color: var(--bg);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.category-swipe {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 4px;
|
||||
scroll-behavior: smooth;
|
||||
padding: 6px 8px;
|
||||
scrollbar-width: none;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
flex: 1;
|
||||
cursor: grab;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.category-swipe:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.category-swipe::-webkit-scrollbar {
|
||||
@@ -176,7 +210,7 @@
|
||||
|
||||
.category-pill {
|
||||
flex: 0 0 auto;
|
||||
padding: 8px 16px;
|
||||
padding: 8px 18px;
|
||||
border-radius: 999px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
@@ -185,20 +219,24 @@
|
||||
border: 1px solid var(--card-border);
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
user-select: none;
|
||||
transition: all 0.25s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.category-pill:hover {
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.category-pill.active {
|
||||
background: var(--primary);
|
||||
color: var(--bg);
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 12px var(--primary-glow);
|
||||
box-shadow: 0 0 14px var(--primary-glow);
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@@ -320,11 +358,13 @@
|
||||
<button id="clear-search" class="clear-search">✕</button>
|
||||
</div>
|
||||
|
||||
<!-- Swipebar Warengruppen -->
|
||||
<div class="category-swipe-wrapper">
|
||||
<!-- Warengruppen Slider mit Pfeilen & Touch Drag -->
|
||||
<div class="slider-nav-container">
|
||||
<button id="slide-left" class="slider-arrow" aria-label="Zurück">‹</button>
|
||||
<div id="category-swipe" class="category-swipe">
|
||||
<button class="category-pill active" data-id="all">Alle Artikel</button>
|
||||
</div>
|
||||
<button id="slide-right" class="slider-arrow" aria-label="Weiter">›</button>
|
||||
</div>
|
||||
|
||||
<!-- Getränkeliste -->
|
||||
@@ -351,12 +391,12 @@
|
||||
const data = await res.json();
|
||||
allCategories = data.categories || [];
|
||||
|
||||
// Globale Texte & Theme anwenden
|
||||
if (data.settings) {
|
||||
applySettings(data.settings);
|
||||
}
|
||||
|
||||
renderCategoryPills();
|
||||
initSliderControls();
|
||||
renderMenu();
|
||||
} catch (err) {
|
||||
container.innerHTML = '<div class="card" style="color:#ef4444; text-align:center;">Fehler beim Laden der Speisekarte.</div>';
|
||||
@@ -372,7 +412,6 @@
|
||||
if (s.site_badge) document.getElementById('site-badge').textContent = s.site_badge;
|
||||
if (s.site_footer) document.getElementById('site-footer').textContent = s.site_footer;
|
||||
|
||||
// Theme CSS Variablen dynamisch setzen
|
||||
const root = document.documentElement;
|
||||
if (s.theme_bg) root.style.setProperty('--bg', s.theme_bg);
|
||||
if (s.theme_card_bg) root.style.setProperty('--card-bg', s.theme_card_bg);
|
||||
@@ -399,7 +438,7 @@
|
||||
swipeEl.innerHTML = pillsHtml;
|
||||
|
||||
swipeEl.querySelectorAll('.category-pill').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
btn.addEventListener('click', () => {
|
||||
swipeEl.querySelectorAll('.category-pill').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
activeCategoryId = btn.dataset.id;
|
||||
@@ -409,6 +448,43 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Slider Controls (Pfeile + Mouse Drag)
|
||||
function initSliderControls() {
|
||||
const slider = document.getElementById('category-swipe');
|
||||
const btnLeft = document.getElementById('slide-left');
|
||||
const btnRight = document.getElementById('slide-right');
|
||||
|
||||
btnLeft.addEventListener('click', () => {
|
||||
slider.scrollBy({ left: -160, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
btnRight.addEventListener('click', () => {
|
||||
slider.scrollBy({ left: 160, behavior: 'smooth' });
|
||||
});
|
||||
|
||||
// Mouse Drag Unterstützung am Desktop
|
||||
let isDown = false;
|
||||
let startX;
|
||||
let scrollLeft;
|
||||
|
||||
slider.addEventListener('mousedown', (e) => {
|
||||
isDown = true;
|
||||
startX = e.pageX - slider.offsetLeft;
|
||||
scrollLeft = slider.scrollLeft;
|
||||
});
|
||||
|
||||
slider.addEventListener('mouseleave', () => { isDown = false; });
|
||||
slider.addEventListener('mouseup', () => { isDown = false; });
|
||||
|
||||
slider.addEventListener('mousemove', (e) => {
|
||||
if (!isDown) return;
|
||||
e.preventDefault();
|
||||
const x = e.pageX - slider.offsetLeft;
|
||||
const walk = (x - startX) * 1.5;
|
||||
slider.scrollLeft = scrollLeft - walk;
|
||||
});
|
||||
}
|
||||
|
||||
function renderMenu() {
|
||||
const container = document.getElementById('menu-container');
|
||||
const query = searchQuery.trim().toLowerCase();
|
||||
|
||||
Reference in New Issue
Block a user