106 lines
2.3 KiB
Vue
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>
|