calendar/src/components/CalendarWeek.vue
Leo Vasanko 5a0d6804bc Mouse/touch event handling improvement
- prefer passive handlers
- fix event moving on touch
- faster selection updates
2025-08-27 08:39:26 -06:00

95 lines
2.1 KiB
Vue

<script setup>
import CalendarDay from './CalendarDay.vue'
import EventOverlay from './EventOverlay.vue'
const props = defineProps({ week: Object, dragging: { type: Boolean, default: false } })
const emit = defineEmits([
'day-mousedown',
'day-mouseenter',
'day-mouseup',
'day-touchstart',
'event-click',
])
const handleDayMouseDown = (dateStr) => {
emit('day-mousedown', dateStr)
}
const handleDayMouseEnter = (dateStr) => {
emit('day-mouseenter', dateStr)
}
const handleDayMouseUp = (dateStr) => {
emit('day-mouseup', dateStr)
}
const handleDayTouchStart = (dateStr) => {
emit('day-touchstart', dateStr)
}
// touchmove & touchend handled globally in CalendarView
const handleEventClick = (payload) => {
emit('event-click', payload)
}
// Only apply upside-down rotation (bottomup) for Latin script month labels
function shouldRotateMonth(label) {
if (!label) return false
try {
return /\p{Script=Latin}/u.test(label)
} catch (e) {
return /[A-Za-z\u00C0-\u024F\u1E00-\u1EFF]/u.test(label)
}
}
</script>
<template>
<div class="week-row" :style="{ top: `${props.week.top}px` }">
<div class="week-label">W{{ props.week.weekNumber }}</div>
<div class="days-grid">
<CalendarDay
v-for="day in props.week.days"
:key="day.date"
:day="day"
:dragging="props.dragging"
@mousedown="handleDayMouseDown(day.date)"
@mouseenter="handleDayMouseEnter(day.date)"
@mouseup="handleDayMouseUp(day.date)"
@touchstart.passive="handleDayTouchStart(day.date)"
/>
<EventOverlay :week="props.week" @event-click="handleEventClick" />
</div>
</div>
</template>
<style scoped>
.week-row {
display: grid;
grid-template-columns: var(--week-w) repeat(7, 1fr);
position: absolute;
height: var(--row-h);
width: 100%;
}
.week-label {
display: grid;
place-items: center;
width: 100%;
color: var(--muted);
font-size: 1.2em;
font-weight: 500;
user-select: none;
height: var(--row-h);
}
.days-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
position: relative;
height: 100%;
width: 100%;
}
</style>