Slide day header and prefetch adjacent days

This commit is contained in:
2026-05-21 12:51:10 +02:00
parent 1dd5339a46
commit 2047cae61c
4 changed files with 22 additions and 9 deletions
+9 -3
View File
@@ -468,14 +468,20 @@ body.page-dashboard .content {
height: 11rem; height: 11rem;
margin-top: 0.95rem; margin-top: 0.95rem;
touch-action: pan-y; touch-action: pan-y;
transform: translateX(var(--day-strip-offset, 0)); }
.dashboard-compare-strip.is-dragging {
cursor: grabbing;
}
.dashboard-day__hero[data-day-slider] {
transform: translateX(var(--day-slider-offset, 0));
transition: transform 180ms ease; transition: transform 180ms ease;
will-change: transform; will-change: transform;
} }
.dashboard-compare-strip.is-dragging { .dashboard-day__hero[data-day-slider].is-dragging {
transition: none; transition: none;
cursor: grabbing;
} }
.compare-day { .compare-day {
+8 -5
View File
@@ -1014,6 +1014,7 @@
const unitInput = document.querySelector("[data-event-unit]"); const unitInput = document.querySelector("[data-event-unit]");
const swipeContainer = document.querySelector("[data-day-swipe]"); const swipeContainer = document.querySelector("[data-day-swipe]");
const dayStrip = document.querySelector("[data-day-strip]"); const dayStrip = document.querySelector("[data-day-strip]");
const daySlider = document.querySelector("[data-day-slider]");
const periodRail = document.querySelector(".range-period-rail"); const periodRail = document.querySelector(".range-period-rail");
const walkMode = document.body.dataset.walkMode || "time"; const walkMode = document.body.dataset.walkMode || "time";
@@ -1447,7 +1448,7 @@
typeSelect.addEventListener("change", syncUnit); typeSelect.addEventListener("change", syncUnit);
} }
if (swipeContainer && dayStrip) { if (swipeContainer && dayStrip && daySlider) {
let pointerStartX = 0; let pointerStartX = 0;
let pointerStartY = 0; let pointerStartY = 0;
let dragging = false; let dragging = false;
@@ -1456,7 +1457,8 @@
const resetStrip = () => { const resetStrip = () => {
dayStrip.classList.remove("is-dragging"); dayStrip.classList.remove("is-dragging");
dayStrip.style.setProperty("--day-strip-offset", "0px"); daySlider.classList.remove("is-dragging");
daySlider.style.setProperty("--day-slider-offset", "0px");
}; };
const handleSwipe = (deltaX, deltaY) => { const handleSwipe = (deltaX, deltaY) => {
@@ -1467,11 +1469,11 @@
if (deltaX < 0 && swipeContainer.dataset.nextDate) { if (deltaX < 0 && swipeContainer.dataset.nextDate) {
didSwipe = true; didSwipe = true;
dayStrip.style.setProperty("--day-strip-offset", "-120%"); daySlider.style.setProperty("--day-slider-offset", "-120%");
window.location.href = dashboardDayPath(swipeContainer.dataset.nextDate); window.location.href = dashboardDayPath(swipeContainer.dataset.nextDate);
} else if (deltaX > 0 && swipeContainer.dataset.prevDate) { } else if (deltaX > 0 && swipeContainer.dataset.prevDate) {
didSwipe = true; didSwipe = true;
dayStrip.style.setProperty("--day-strip-offset", "120%"); daySlider.style.setProperty("--day-slider-offset", "120%");
window.location.href = dashboardDayPath(swipeContainer.dataset.prevDate); window.location.href = dashboardDayPath(swipeContainer.dataset.prevDate);
} else { } else {
resetStrip(); resetStrip();
@@ -1490,6 +1492,7 @@
pointerStartX = event.clientX; pointerStartX = event.clientX;
pointerStartY = event.clientY; pointerStartY = event.clientY;
dayStrip.classList.add("is-dragging"); dayStrip.classList.add("is-dragging");
daySlider.classList.add("is-dragging");
dayStrip.setPointerCapture?.(event.pointerId); dayStrip.setPointerCapture?.(event.pointerId);
}); });
@@ -1507,7 +1510,7 @@
return; return;
} }
dayStrip.style.setProperty("--day-strip-offset", `${Math.max(-120, Math.min(120, deltaX))}px`); daySlider.style.setProperty("--day-slider-offset", `${Math.max(-120, Math.min(120, deltaX))}px`);
}); });
dayStrip.addEventListener("pointerup", event => { dayStrip.addEventListener("pointerup", event => {
+4
View File
@@ -36,6 +36,10 @@ $jsVersion = is_file(base_path('assets/js/app.js')) ? (string) filemtime(base_pa
<link rel="shortcut icon" href="/favicon.ico?v=20260412"> <link rel="shortcut icon" href="/favicon.ico?v=20260412">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/branding/apple-touch-icon.png?v=20260412"> <link rel="apple-touch-icon" sizes="180x180" href="/assets/branding/apple-touch-icon.png?v=20260412">
<link rel="manifest" href="/manifest.webmanifest"> <link rel="manifest" href="/manifest.webmanifest">
<?php if (($page ?? '') === 'dashboard' && ($dashboardView ?? '') === 'day'): ?>
<link rel="prefetch" href="/?view=day&amp;date=<?= e(rawurlencode((string) ($dashboardPrevDate ?? shift_date(today(), -1)))) ?>">
<link rel="prefetch" href="/?view=day&amp;date=<?= e(rawurlencode((string) ($dashboardNextDate ?? shift_date(today(), 1)))) ?>">
<?php endif; ?>
<link rel="stylesheet" href="/assets/css/app.css?v=<?= e($cssVersion) ?>"> <link rel="stylesheet" href="/assets/css/app.css?v=<?= e($cssVersion) ?>">
<script defer src="/assets/js/app.js?v=<?= e($jsVersion) ?>"></script> <script defer src="/assets/js/app.js?v=<?= e($jsVersion) ?>"></script>
</head> </head>
+1 -1
View File
@@ -55,7 +55,7 @@ $formatBalanceValue = static function (?array $entry) use ($settings): string {
<?php if ($dashboardView === 'day'): ?> <?php if ($dashboardView === 'day'): ?>
<div class="dashboard-day" data-day-swipe data-prev-date="<?= e($dashboardPrevDate) ?>" data-next-date="<?= e($dashboardNextDate) ?>"> <div class="dashboard-day" data-day-swipe data-prev-date="<?= e($dashboardPrevDate) ?>" data-next-date="<?= e($dashboardNextDate) ?>">
<div class="dashboard-day__hero"> <div class="dashboard-day__hero" data-day-slider>
<p class="dashboard-day__eyebrow"><?= e((string) $dayWeekday) ?></p> <p class="dashboard-day__eyebrow"><?= e((string) $dayWeekday) ?></p>
<h1><?= e(format_display_date((string) $dayEntry['date'], false)) ?></h1> <h1><?= e(format_display_date((string) $dayEntry['date'], false)) ?></h1>