Skip to content

Commit 2e82a99

Browse files
committed
add an top resizer to modify the start of events
1 parent dfbdcd0 commit 2e82a99

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

src/vue-cal/components/event.vue

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
:draggable="isDraggable ? 'true' : undefined"
88
@dragstart="isDraggable && dnd.eventDragStart($event, event)"
99
@dragend="isDraggable && dnd.eventDragEnd($event, event)")
10+
.vuecal__event-resizer.vuecal__event-resizer--top(v-if="isResizable" @dragstart.prevent.stop)
1011
.vuecal__event-details
1112
slot(v-if="$slots['event.all-day']" name="event.all-day" :event="event")
1213
slot(v-else-if="$slots[`event.${view.id}`]" :name="`event.${view.id}`" :event="event")
@@ -17,7 +18,7 @@
1718
span.vuecal__event-start {{ event._[`startTimeFormatted${config.twelveHour ? 12 : 24}`] }}
1819
span.vuecal__event-end(v-if="!view.isMonth")  - {{ event._[`endTimeFormatted${config.twelveHour ? 12 : 24}`] }}
1920
.vuecal__event-content(v-if="!inAllDayBar" v-html="event.content")
20-
.vuecal__event-resizer(v-if="isResizable" @dragstart.prevent.stop)
21+
.vuecal__event-resizer.vuecal__event-resizer--bottom(v-if="isResizable" @dragstart.prevent.stop)
2122
transition(name="vuecal-delete-btn")
2223
.vuecal__event-delete(v-if="event._.deleting" @click.stop="event.delete(3)") Delete
2324
</template>
@@ -40,7 +41,8 @@ const event = reactive(props.event)
4041
const touch = reactive({
4142
dragging: false,
4243
resizing: false,
43-
fromResizer: false, // If the drag originates from the resizer element.
44+
fromBottomResizer: false, // If the drag originates from the resizer element.
45+
fromTopResizer: false, // If the drag originates from the top resizer element.
4446
holding: false, // When the event is clicked and hold for a certain amount of time.
4547
holdTimer: null, // event click and hold detection.
4648
startX: 0, // The X coords at the start of the drag.
@@ -176,7 +178,9 @@ const eventListeners = computed(() => {
176178
const onMousedown = e => {
177179
const domEvent = e.touches?.[0] || e // Handle click or touch event.
178180
// If the event target is the resizer, set the resizing flag.
179-
touch.fromResizer = domEvent.target.matches('.vuecal__event-resizer, .vuecal__event-resizer *')
181+
touch.fromBottomResizer = domEvent.target.matches('.vuecal__event-resizer--bottom, .vuecal__event-resizer--bottom *')
182+
// Check if it's the top resizer
183+
touch.fromTopResizer = domEvent.target.matches('.vuecal__event-resizer--top, .vuecal__event-resizer--top *')
180184
181185
const rect = eventEl.value.getBoundingClientRect()
182186
touch.startX = (e.touches?.[0] || e).clientX - rect.left // Handle click or touch event coords.
@@ -202,7 +206,7 @@ const onDocMousemove = async e => {
202206
const domEvent = e.touches?.[0] || e // Handle click or touch event.
203207
204208
// Only the first touchmove to set the dragging flag.
205-
if (touch.fromResizer && !touch.resizing) {
209+
if ((touch.fromBottomResizer || touch.fromTopResizer) && !touch.resizing) {
206210
touch.resizing = true
207211
touch.resizingOriginalEvent = { ...event, _: { ...event._ } }
208212
globalTouchState.isResizingEvent = true // Add a CSS class on wrapper while resizing.
@@ -222,7 +226,7 @@ const onDocMousemove = async e => {
222226
touch.movePercentageY = touch.moveY * 100 / height
223227
}
224228
225-
if (touch.fromResizer) {
229+
if (touch.fromBottomResizer || touch.fromTopResizer) {
226230
const { newStart, newEnd } = computeStartEnd(event)
227231
228232
// If there's an @event-resize external listener, call it and ask for resizing approval.
@@ -284,7 +288,8 @@ const onDocMouseup = async e => {
284288
285289
document.removeEventListener(e.type === 'touchend' ? 'touchmove' : 'mousemove', onDocMousemove)
286290
touch.resizing = false
287-
touch.fromResizer = false
291+
touch.fromBottomResizer = false
292+
touch.fromTopResizer = false
288293
touch.dragging = false
289294
290295
touch.startX = 0
@@ -318,12 +323,16 @@ const computeStartEnd = event => {
318323
}
319324
320325
let newStart = event.start
321-
let newEnd = new Date(startMidnight.getTime() + minutes * 60000)
326+
let newEnd = event.end
327+
const newValue = new Date(startMidnight.getTime() + minutes * 60000)
322328
323-
// While resizing and event end is before event start.
324-
if (newEnd < touch.resizeStartDate) {
325-
newStart = newEnd
326-
newEnd = touch.resizeStartDate
329+
if (touch.fromTopResizer && newValue < event.end) {
330+
// When resizing from the top, modify the start time
331+
newStart = newValue
332+
}
333+
if(touch.fromBottomResizer && newValue > event.start) {
334+
// When resizing from the bottom, modify the end time
335+
newEnd = newValue
327336
}
328337
329338
return { newStart, newEnd }
@@ -364,13 +373,24 @@ onBeforeUnmount(() => {
364373
&--resizing {z-index: 100;}
365374
&-resizer {
366375
position: absolute;
367-
inset: auto 0 0;
376+
left: 0;
377+
right: 0;
368378
height: 8px;
369379
background-color: #fff;
370380
opacity: 0.1;
371381
transition: 0.25s;
372382
cursor: ns-resize;
373383
384+
&--top {
385+
top: 0;
386+
bottom: auto;
387+
}
388+
389+
&--bottom {
390+
top: auto;
391+
bottom: 0;
392+
}
393+
374394
&:hover {opacity: 0.25;}
375395
}
376396
}

src/vue-cal/default-theme.scss

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@
367367
&-details {
368368
flex-grow: 1;
369369
overflow: hidden;
370-
padding: 2px;
370+
padding: 7px 2px;
371371
font-size: 12px;
372372
}
373373
&-time {
@@ -380,7 +380,12 @@
380380

381381
&-resizer {
382382
// Over border (so there's no risk of triggering the event drag instead).
383-
inset: auto -1px -1px;
383+
&--top {
384+
inset: -1px -1px auto;
385+
}
386+
&--bottom {
387+
inset: auto -1px -1px;
388+
}
384389
border-bottom-left-radius: inherit;
385390
border-bottom-right-radius: inherit;
386391
}

0 commit comments

Comments
 (0)