Scroll the week to view the second row visible (showing also the previous week) rather than centered, for better UX.

This commit is contained in:
Leo Vasanko
2025-09-25 08:35:46 -06:00
parent 159bbf816d
commit 86a1a4d772
2 changed files with 11 additions and 15 deletions

View File

@@ -197,13 +197,13 @@ const {
getWeekIndex,
getFirstDayForVirtualWeek,
handleHeaderYearChange,
scrollToWeekCentered,
scrollToWeek,
} = vwm
function showDay(input) {
const dateStr = input instanceof Date ? toLocalString(input, DEFAULT_TZ) : String(input)
const weekIndex = getWeekIndex(fromLocalString(dateStr, DEFAULT_TZ))
scrollToWeekCentered(weekIndex, 'nav', true)
scrollToWeek(weekIndex, 'nav', true)
const diff = Math.abs(weekIndex - centerVisibleWeek.value)
const delay = Math.min(800, diff * 40)
setTimeout(() => {
@@ -228,10 +228,6 @@ const centerVisibleDateStr = computed(() => {
}
})
// createWeek logic moved to virtualWeeks plugin
// goToToday now provided by manager
function clearSelection() {
selection.value = { startDate: null, dayCount: 0 }
}

View File

@@ -287,20 +287,20 @@ export function createVirtualWeekManager({
function goToToday() {
const todayDate = new Date(calendarStore.now)
const targetWeekIndex = getWeekIndex(todayDate)
scrollToWeekCentered(targetWeekIndex, 'go-to-today', true)
scrollToWeek(targetWeekIndex, 'go-to-today', true)
}
function scrollToWeekCentered(weekIndex, reason = 'center-scroll', smooth = true) {
function scrollToWeek(weekIndex, reason = 'scroll', smooth = true) {
if (weekIndex == null || !isFinite(weekIndex)) return
const maxScroll = Math.max(0, contentHeight.value - viewportHeight.value)
const baseTop = (weekIndex - minVirtualWeek.value) * rowHeight.value
// Center: subtract half viewport minus half row height
let newScrollTop = baseTop - (viewportHeight.value / 2 - rowHeight.value / 2)
newScrollTop = Math.max(0, Math.min(newScrollTop, maxScroll))
// Scroll so that the top of the viewport aligns with the top of the previous week,
// making the target week the second visible week row
const newScrollTop = (weekIndex - 1 - minVirtualWeek.value) * rowHeight.value
const clampedScrollTop = Math.max(0, Math.min(newScrollTop, maxScroll))
if (smooth && viewport.value && typeof viewport.value.scrollTo === 'function') {
viewport.value.scrollTo({ top: newScrollTop, behavior: 'smooth' })
viewport.value.scrollTo({ top: clampedScrollTop, behavior: 'smooth' })
} else if (setScrollTopFn) {
setScrollTopFn(newScrollTop, reason)
setScrollTopFn(clampedScrollTop, reason)
scheduleWindowUpdate(reason)
}
}
@@ -322,7 +322,7 @@ export function createVirtualWeekManager({
getWeekIndex,
getFirstDayForVirtualWeek,
goToToday,
scrollToWeekCentered,
scrollToWeek,
handleHeaderYearChange,
attachScroll,
}