calendar/src/components/CalendarWeek.vue
Leo Vasanko 018b9ecc55 vue (#1)
Port to Vue. Also implements plenty of new functionality.
2025-08-22 23:34:33 +01:00

106 lines
2.3 KiB
Vue

<script setup>
import CalendarDay from './CalendarDay.vue'
import EventOverlay from './EventOverlay.vue'
const props = defineProps({
week: Object
})
const emit = defineEmits(['day-mousedown', 'day-mouseenter', 'day-mouseup', 'day-touchstart', 'day-touchmove', 'day-touchend', '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)
}
const handleDayTouchMove = (dateStr) => {
emit('day-touchmove', dateStr)
}
const handleDayTouchEnd = (dateStr) => {
emit('day-touchend', dateStr)
}
const handleEventClick = (eventId) => {
emit('event-click', eventId)
}
</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"
@mousedown="handleDayMouseDown(day.date)"
@mouseenter="handleDayMouseEnter(day.date)"
@mouseup="handleDayMouseUp(day.date)"
@touchstart="handleDayTouchStart(day.date)"
@touchmove="handleDayTouchMove(day.date)"
@touchend="handleDayTouchEnd(day.date)"
@event-click="handleEventClick"
/>
<EventOverlay
:week="props.week"
@event-click="handleEventClick"
/>
</div>
</div>
</template>
<style scoped>
.week-row {
display: grid;
grid-template-columns: var(--label-w) repeat(7, 1fr) 3rem;
position: absolute;
height: var(--cell-h);
width: 100%;
}
.week-label {
display: grid;
place-items: center;
width: 100%;
color: var(--muted);
font-size: 1.2em;
font-weight: 500;
/* Prevent text selection */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
}
.days-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
position: relative;
height: 100%;
width: 100%;
}
/* Fixed heights for cells and labels (from cells.css) */
.week-row :deep(.cell),
.week-label {
height: var(--cell-h);
}
</style>