layout shifts

This commit is contained in:
Vincent van der Wal
2026-08-01 13:37:04 +02:00
parent 792da49cac
commit fe961a27ae
24 changed files with 427 additions and 210 deletions
@@ -1,7 +1,12 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import { type ChartPanel, storedChartLayout } from '$lib/stores/settings';
import {
type ChartPanel,
type ChartRangePref,
storedChartLayout,
storedChartRange
} from '$lib/stores/settings';
import { formatZoned, getRelativeDayLabel, isSameDayInZone } from '$lib/utils/date';
@@ -86,11 +91,47 @@
liveCharts[0].setRange(start, start + days * SECONDS_PER_DAY);
}
function resetZoom(): void {
/** Drop any zoom and show the whole forecast. */
function showFullRange(): void {
liveCharts[0]?.resetRange();
onResetZoom?.();
}
/** Back to the range the meteograms are configured to open on. */
function resetZoom(): void {
applyDefaultRange();
onResetZoom?.();
}
// ─── Default range ──────────────────────────────────────────────────────────
/** Days the preference resolves to, or null for the full range. */
function rangeDaysFor(pref: ChartRangePref): number | null {
if (pref === 'today') return 1;
if (pref === '3d') return 3;
if (pref === '5d') return 5;
if (pref === 'all') return null;
// auto: a week of hourly data is unreadable on a phone-width plot
const phone = typeof window !== 'undefined' && window.matchMedia('(max-width: 767px)').matches;
return phone ? 3 : null;
}
function applyDefaultRange(): void {
const days = rangeDaysFor($storedChartRange);
if (days == null) liveCharts[0]?.resetRange();
else setRangeDays(new Date(), days);
}
// Applied once the charts exist, and again whenever the preference changes -
// but never after that, so it can't fight a zoom the user just set by hand.
let appliedPref: ChartRangePref | null = null;
$effect(() => {
const pref = $storedChartRange;
if (liveCharts.length === 0 || timestampsSec.length === 0 || appliedPref === pref) return;
appliedPref = pref;
applyDefaultRange();
});
const now = new Date();
// "Selected day" is redundant while today is the selected day, so hide it then
let rangePresets = $derived.by(() => {
@@ -100,7 +141,7 @@
...(isToday ? [] : [{ label: 'Selected day', apply: () => setRangeDays(selectedDay, 1) }]),
{ label: '3 days', apply: () => setRangeDays(new Date(), 3) },
{ label: '5 days', apply: () => setRangeDays(new Date(), 5) },
{ label: 'All', apply: () => resetZoom() }
{ label: 'All', apply: () => showFullRange() }
];
});