fix(time-tracking) : keep calendar header sticky below page header
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
<template>
|
||||
<div ref="calendarEl" class="relative overflow-auto rounded-lg border border-neutral-200 bg-white" style="max-height: calc(100vh - 280px);">
|
||||
<div ref="calendarEl" class="relative rounded-lg border border-neutral-200 bg-white">
|
||||
<!-- Day headers -->
|
||||
<div class="sticky top-0 z-20 flex border-b border-neutral-200 bg-white">
|
||||
<div
|
||||
class="sticky z-20 flex border-b border-neutral-200 bg-white"
|
||||
:style="{ top: `${stickyOffset}px` }"
|
||||
>
|
||||
<div class="w-16 shrink-0 border-r border-neutral-200" />
|
||||
<div
|
||||
v-for="day in days"
|
||||
@@ -131,6 +134,7 @@ const props = defineProps<{
|
||||
entries: TimeEntry[]
|
||||
startDate: Date
|
||||
viewMode: 'week' | 'day'
|
||||
stickyOffset?: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -148,15 +152,28 @@ const dayLabels = ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
|
||||
const calendarEl = ref<HTMLElement | null>(null)
|
||||
const gridBodyEl = ref<HTMLElement | null>(null)
|
||||
const dayColumnEls = ref<HTMLElement[]>([])
|
||||
const stickyOffset = computed(() => props.stickyOffset ?? 0)
|
||||
|
||||
function getScrollParent(): HTMLElement | null {
|
||||
let el = calendarEl.value?.parentElement
|
||||
while (el) {
|
||||
if (el.scrollHeight > el.clientHeight && getComputedStyle(el).overflowY !== 'visible') return el
|
||||
el = el.parentElement
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Scroll to current hour on mount
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (!calendarEl.value) return
|
||||
const scrollParent = getScrollParent()
|
||||
if (!scrollParent) return
|
||||
const now = new Date()
|
||||
const currentMinutes = now.getHours() * 60 + now.getMinutes()
|
||||
const scrollTarget = (currentMinutes / 60) * hourHeight - calendarEl.value.clientHeight / 3
|
||||
calendarEl.value.scrollTop = Math.max(0, scrollTarget)
|
||||
const calendarTop = calendarEl.value.offsetTop
|
||||
const scrollTarget = calendarTop + (currentMinutes / 60) * hourHeight - scrollParent.clientHeight / 3
|
||||
scrollParent.scrollTop = Math.max(0, scrollTarget)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -470,12 +487,13 @@ function onDragMove(event: MouseEvent) {
|
||||
}
|
||||
|
||||
function autoScrollLoop() {
|
||||
if (!autoScrollActive || !lastMouseEvent || !calendarEl.value || !dragState.value) {
|
||||
const scrollParent = getScrollParent()
|
||||
if (!autoScrollActive || !lastMouseEvent || !scrollParent || !dragState.value) {
|
||||
autoScrollActive = false
|
||||
return
|
||||
}
|
||||
|
||||
const rect = calendarEl.value.getBoundingClientRect()
|
||||
const rect = scrollParent.getBoundingClientRect()
|
||||
const edgeSize = 60
|
||||
const maxSpeed = 10
|
||||
|
||||
@@ -484,10 +502,10 @@ function autoScrollLoop() {
|
||||
|
||||
let scrolled = false
|
||||
if (distFromTop < edgeSize && distFromTop > 0) {
|
||||
calendarEl.value.scrollTop -= maxSpeed * (1 - distFromTop / edgeSize)
|
||||
scrollParent.scrollTop -= maxSpeed * (1 - distFromTop / edgeSize)
|
||||
scrolled = true
|
||||
} else if (distFromBottom < edgeSize && distFromBottom > 0) {
|
||||
calendarEl.value.scrollTop += maxSpeed * (1 - distFromBottom / edgeSize)
|
||||
scrollParent.scrollTop += maxSpeed * (1 - distFromBottom / edgeSize)
|
||||
scrolled = true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user