@mantine-vue/schedule 3.4.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/cjs/index.cjs +1146 -262
  2. package/cjs/index.cjs.map +1 -1
  3. package/esm/index.mjs +1145 -263
  4. package/esm/index.mjs.map +1 -1
  5. package/lib/component-props.d.ts +13 -2
  6. package/lib/components/DayView/DayView.types.d.ts +7 -3
  7. package/lib/components/DayView/DayView.vue.d.ts +2 -0
  8. package/lib/components/DayView/get-day-view-events/get-day-positioned-events.d.ts +4 -2
  9. package/lib/components/DayView/get-day-view-events/get-day-view-events.d.ts +3 -2
  10. package/lib/components/MonthView/MonthView.types.d.ts +9 -1
  11. package/lib/components/MonthView/MonthView.vue.d.ts +2 -0
  12. package/lib/components/MonthView/get-month-view-events/reserve-row.d.ts +7 -0
  13. package/lib/components/ResourcesDayView/ResourcesDayView.types.d.ts +10 -1
  14. package/lib/components/ResourcesDayView/ResourcesDayView.vue.d.ts +2 -0
  15. package/lib/components/ResourcesDayView/index.d.ts +0 -1
  16. package/lib/components/ResourcesMonthView/ResourcesMonthView.types.d.ts +10 -1
  17. package/lib/components/ResourcesMonthView/ResourcesMonthView.vue.d.ts +2 -0
  18. package/lib/components/ResourcesSchedule/ResourcesSchedule.types.d.ts +10 -1
  19. package/lib/components/ResourcesSchedule/ResourcesSchedule.vue.d.ts +2 -0
  20. package/lib/components/ResourcesWeekView/ResourcesWeekView.types.d.ts +10 -1
  21. package/lib/components/ResourcesWeekView/ResourcesWeekView.vue.d.ts +2 -0
  22. package/lib/components/Schedule/Schedule.types.d.ts +12 -2
  23. package/lib/components/Schedule/Schedule.vue.d.ts +2 -0
  24. package/lib/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.types.d.ts +12 -0
  25. package/lib/components/ScheduleBackgroundEvent/ScheduleBackgroundEvent.vue.d.ts +2 -0
  26. package/lib/components/WeekView/WeekView.types.d.ts +7 -3
  27. package/lib/components/WeekView/WeekView.vue.d.ts +2 -0
  28. package/lib/components/WeekView/get-week-view-events/get-week-positioned-events.d.ts +4 -2
  29. package/lib/hooks/use-event-resize.d.ts +10 -2
  30. package/lib/hooks/use-horizontal-event-resize.d.ts +9 -1
  31. package/lib/hooks/validate-event-resize.d.ts +26 -0
  32. package/lib/types.d.ts +40 -0
  33. package/lib/utils/apply-cascade-layout/apply-cascade-layout.d.ts +5 -0
  34. package/lib/utils/get-overlap-clusters/get-overlap-clusters.d.ts +2 -0
  35. package/lib/utils/index.d.ts +4 -0
  36. package/lib/utils/is-event-placement-allowed/is-event-placement-allowed.d.ts +13 -0
  37. package/package.json +4 -4
  38. package/styles.css +711 -379
  39. package/styles.layer.css +711 -379
  40. package/lib/components/ResourcesDayView/get-overlap-clusters/get-overlap-clusters.d.ts +0 -2
package/esm/index.mjs CHANGED
@@ -358,6 +358,45 @@ function isEventsOverlap(event1, event2) {
358
358
  return first.startTimestamp < second.endTimestamp && second.startTimestamp < first.endTimestamp;
359
359
  }
360
360
  //#endregion
361
+ //#region src/utils/is-event-placement-allowed/is-event-placement-allowed.ts
362
+ function isSameEvent(event, other) {
363
+ if (event.id === other.id) return true;
364
+ const eventSeriesId = event.recurringEventId ?? event.recurringInstance?.recurringEventId;
365
+ const otherSeriesId = other.recurringEventId ?? other.recurringInstance?.recurringEventId;
366
+ const eventOccurrenceId = event.recurrenceId ?? event.recurringInstance?.recurrenceId;
367
+ const otherOccurrenceId = other.recurrenceId ?? other.recurringInstance?.recurrenceId;
368
+ return eventSeriesId !== void 0 && eventSeriesId === otherSeriesId && eventOccurrenceId !== void 0 && eventOccurrenceId === otherOccurrenceId;
369
+ }
370
+ var isMidnight = (value) => value.hour() === 0 && value.minute() === 0 && value.second() === 0;
371
+ function spansWholeDays(event) {
372
+ const start = dayjs(event.start);
373
+ const end = dayjs(event.end);
374
+ return isMidnight(start) && (isMidnight(end) || end.hour() === 23 && end.minute() === 59 && end.second() === 59);
375
+ }
376
+ function isEventPlacementAllowed({ event, start, end, events, preventEventOverlap, resourceId }) {
377
+ if (!preventEventOverlap) return {
378
+ allowed: true,
379
+ conflicts: []
380
+ };
381
+ const candidate = {
382
+ ...event,
383
+ start,
384
+ end,
385
+ ...resourceId !== void 0 ? { resourceId } : {}
386
+ };
387
+ const allDay = spansWholeDays(candidate);
388
+ const conflicts = events.filter((other) => {
389
+ if (other.display === "background" || isSameEvent(event, other)) return false;
390
+ if (resourceId !== void 0 && other.resourceId !== resourceId) return false;
391
+ if (spansWholeDays(other) !== allDay || !isEventsOverlap(other, candidate)) return false;
392
+ return typeof preventEventOverlap === "function" ? preventEventOverlap(other, candidate) : true;
393
+ });
394
+ return {
395
+ allowed: conflicts.length === 0,
396
+ conflicts
397
+ };
398
+ }
399
+ //#endregion
361
400
  //#region src/utils/get-visible-events/get-visible-events.ts
362
401
  function getVisibleEvents({ maxEvents, totalEvents }) {
363
402
  if (totalEvents <= maxEvents) return {
@@ -394,8 +433,9 @@ function isEventInTimeRange({ event, startTime, endTime }) {
394
433
  const timeWindowEndMinutes = endHour * 60 + endMinute;
395
434
  const eventStart = dayjs(event.start);
396
435
  const eventEnd = dayjs(event.end);
436
+ const endsAtNextDayStart = eventEnd.isSame(eventStart.startOf("day").add(1, "day"), "second");
397
437
  const eventStartMinutes = eventStart.hour() * 60 + eventStart.minute();
398
- return !(eventEnd.hour() * 60 + eventEnd.minute() <= timeWindowStartMinutes || eventStartMinutes >= timeWindowEndMinutes);
438
+ return !((endsAtNextDayStart ? 1440 : eventEnd.hour() * 60 + eventEnd.minute()) <= timeWindowStartMinutes || eventStartMinutes >= timeWindowEndMinutes);
399
439
  }
400
440
  //#endregion
401
441
  //#region src/utils/is-within-week/is-within-week.ts
@@ -662,6 +702,43 @@ function expandRecurringEvents({ events, rangeStart, rangeEnd, expansionLimit =
662
702
  return output;
663
703
  }
664
704
  //#endregion
705
+ //#region src/utils/get-overlap-clusters/get-overlap-clusters.ts
706
+ function getOverlapClusters(events) {
707
+ const clusters = [];
708
+ const assigned = /* @__PURE__ */ new Set();
709
+ for (let i = 0; i < events.length; i++) {
710
+ if (assigned.has(i)) continue;
711
+ const cluster = [events[i]];
712
+ assigned.add(i);
713
+ let j = 0;
714
+ while (j < cluster.length) {
715
+ for (let k = 0; k < events.length; k++) if (!assigned.has(k) && isEventsOverlap(cluster[j], events[k])) {
716
+ cluster.push(events[k]);
717
+ assigned.add(k);
718
+ }
719
+ j += 1;
720
+ }
721
+ clusters.push(cluster);
722
+ }
723
+ return clusters;
724
+ }
725
+ //#endregion
726
+ //#region src/utils/apply-cascade-layout/apply-cascade-layout.ts
727
+ var BASE_STEP = 20;
728
+ var MIN_TOP_WIDTH = 60;
729
+ function applyCascadeLayout(events) {
730
+ const timedEvents = events.filter((event) => !event.position.allDay);
731
+ for (const cluster of getOverlapClusters(timedEvents)) {
732
+ const columns = Math.max(...cluster.map((event) => event.position.column)) + 1;
733
+ const step = columns > 1 ? Math.min(BASE_STEP, (100 - MIN_TOP_WIDTH) / (columns - 1)) : 0;
734
+ for (const event of cluster) {
735
+ event.position.overlaps = columns;
736
+ event.position.offset = event.position.column * step;
737
+ event.position.width = 100 - event.position.offset;
738
+ }
739
+ }
740
+ }
741
+ //#endregion
665
742
  //#region src/utils/get-ordered-resources/get-ordered-resources.ts
666
743
  function getOrderedResources(resources, groups) {
667
744
  if (!groups?.length) return {
@@ -892,9 +969,42 @@ function moveEventToAllDay(event, date) {
892
969
  };
893
970
  }
894
971
  //#endregion
972
+ //#region src/hooks/validate-event-resize.ts
973
+ function validateEventResize({ event, start, end, edge, events = [], preventEventOverlap, canResizeEventTo, resourceId }) {
974
+ const { allowed, conflicts } = isEventPlacementAllowed({
975
+ event,
976
+ start,
977
+ end,
978
+ events,
979
+ preventEventOverlap,
980
+ resourceId
981
+ });
982
+ if (!allowed) return {
983
+ valid: false,
984
+ conflicts,
985
+ reason: "overlap"
986
+ };
987
+ if (canResizeEventTo?.({
988
+ event,
989
+ start,
990
+ end,
991
+ edge
992
+ }) === false) return {
993
+ valid: false,
994
+ conflicts: [],
995
+ reason: "rejected"
996
+ };
997
+ return {
998
+ valid: true,
999
+ conflicts: [],
1000
+ reason: null
1001
+ };
1002
+ }
1003
+ //#endregion
895
1004
  //#region src/hooks/use-event-resize.ts
896
1005
  function useEventResize(input) {
897
1006
  const resizeState = shallowRef(null);
1007
+ const resizeValid = shallowRef(true);
898
1008
  let justResized = false;
899
1009
  let savedUserSelect = null;
900
1010
  const clampAndSnap = (minutes, state) => {
@@ -936,6 +1046,18 @@ function useEventResize(input) {
936
1046
  currentTop,
937
1047
  currentHeight
938
1048
  };
1049
+ const next = resizeState.value;
1050
+ const start = next.edge === "top" ? percentToDateTime(next.currentTop, next.eventDate, next) : next.originalStart;
1051
+ const end = next.edge === "bottom" ? percentToDateTime(next.currentTop + next.currentHeight, next.eventDate, next) : next.originalEnd;
1052
+ resizeValid.value = validateEventResize({
1053
+ event: next.event,
1054
+ start,
1055
+ end,
1056
+ edge: next.edge === "top" ? "start" : "end",
1057
+ events: input.events?.() ?? [],
1058
+ preventEventOverlap: input.preventEventOverlap?.(),
1059
+ canResizeEventTo: input.canResizeEventTo?.()
1060
+ }).valid;
939
1061
  });
940
1062
  const trackPointer = (event) => handlePointerMove(event.clientY);
941
1063
  const removeDocumentListeners = () => {
@@ -953,14 +1075,34 @@ function useEventResize(input) {
953
1075
  if (state && (state.currentTop !== state.originalTop || state.currentHeight !== state.originalHeight)) {
954
1076
  const newStart = state.edge === "top" ? percentToDateTime(state.currentTop, state.eventDate, state) : state.originalStart;
955
1077
  const newEnd = state.edge === "bottom" ? percentToDateTime(state.currentTop + state.currentHeight, state.eventDate, state) : state.originalEnd;
956
- input.onEventResize({
1078
+ const edge = state.edge === "top" ? "start" : "end";
1079
+ const validation = validateEventResize({
1080
+ event: state.event,
1081
+ start: newStart,
1082
+ end: newEnd,
1083
+ edge,
1084
+ events: input.events?.() ?? [],
1085
+ preventEventOverlap: input.preventEventOverlap?.(),
1086
+ canResizeEventTo: input.canResizeEventTo?.()
1087
+ });
1088
+ if (validation.valid) input.onEventResize({
957
1089
  eventId: state.eventId,
958
1090
  newStart,
959
1091
  newEnd,
960
1092
  event: state.event
961
1093
  });
1094
+ else input.onEventPlacementRejected?.({
1095
+ action: "resize",
1096
+ event: state.event,
1097
+ start: newStart,
1098
+ end: newEnd,
1099
+ edge,
1100
+ conflicts: validation.conflicts,
1101
+ reason: validation.reason
1102
+ });
962
1103
  }
963
1104
  resizeState.value = null;
1105
+ resizeValid.value = true;
964
1106
  removeDocumentListeners();
965
1107
  justResized = true;
966
1108
  requestAnimationFrame(() => {
@@ -996,25 +1138,29 @@ function useEventResize(input) {
996
1138
  intervalMinutes,
997
1139
  minHeightPercent: intervalMinutes / totalMinutes * 100
998
1140
  };
1141
+ resizeValid.value = true;
999
1142
  savedUserSelect = document.body.style.userSelect;
1000
1143
  document.body.style.userSelect = "none";
1001
1144
  document.addEventListener("pointermove", trackPointer);
1002
1145
  document.addEventListener("pointerup", handlePointerUp);
1003
1146
  };
1004
- const getResizePosition = (eventId) => {
1147
+ const getResizePosition = (eventId, eventDate) => {
1005
1148
  const state = resizeState.value;
1006
- return state?.eventId === eventId ? {
1149
+ return state?.eventId === eventId && (eventDate === void 0 || state.eventDate === eventDate) ? {
1007
1150
  top: state.currentTop,
1008
1151
  height: state.currentHeight
1009
1152
  } : null;
1010
1153
  };
1011
- const isResizableEvent = (event) => input.enabled() && input.mode() !== "static" && event.display !== "background" && (input.canResizeEvent()?.(event) ?? true);
1154
+ const isResizableEvent = (event) => input.enabled() && input.mode() !== "static" && (event.display !== "background" || input.withBackgroundEvents?.() === true) && (input.canResizeEvent()?.(event) ?? true);
1012
1155
  onBeforeUnmount(removeDocumentListeners);
1013
1156
  return {
1014
1157
  handleResizeStart,
1158
+ isResizing: computed(() => resizeState.value !== null),
1159
+ resizingEventId: computed(() => resizeState.value?.eventId ?? null),
1015
1160
  getResizePosition,
1016
1161
  isResizableEvent,
1017
- wasResizing: () => justResized
1162
+ wasResizing: () => justResized,
1163
+ resizeValid: computed(() => resizeValid.value)
1018
1164
  };
1019
1165
  }
1020
1166
  var CurrentTimeIndicator_module_default = {
@@ -1234,9 +1380,9 @@ function provideScheduleDragState(input = {}) {
1234
1380
  };
1235
1381
  }
1236
1382
  var ScheduleEvent_module_default = {
1237
- event: "_event_19lsr_1",
1238
- eventInner: "_eventInner_19lsr_14",
1239
- eventResizeHandle: "_eventResizeHandle_19lsr_186"
1383
+ event: "_event_iymqv_1",
1384
+ eventInner: "_eventInner_iymqv_14",
1385
+ eventResizeHandle: "_eventResizeHandle_iymqv_215"
1240
1386
  };
1241
1387
  //#endregion
1242
1388
  //#region src/components/ScheduleEvent/ScheduleEvent.vue?vue&type=script&setup=true&lang.ts
@@ -1616,9 +1762,20 @@ var ScheduleBackgroundEvent_default = /* @__PURE__ */ defineComponent({
1616
1762
  renderEventBody: {
1617
1763
  type: Function,
1618
1764
  default: void 0
1619
- }
1765
+ },
1766
+ withResize: {
1767
+ type: Boolean,
1768
+ default: false
1769
+ },
1770
+ resizeAxis: { default: "vertical" },
1771
+ resizeHandleProps: {},
1772
+ isResizing: {
1773
+ type: Boolean,
1774
+ default: false
1775
+ },
1776
+ activeResizeEdge: { default: void 0 }
1620
1777
  },
1621
- emits: ["eventClick"],
1778
+ emits: ["eventClick", "resizeStart"],
1622
1779
  setup(__props, { emit: __emit }) {
1623
1780
  const props = __props;
1624
1781
  const emit = __emit;
@@ -1657,7 +1814,11 @@ var ScheduleBackgroundEvent_default = /* @__PURE__ */ defineComponent({
1657
1814
  return {
1658
1815
  ...attrs,
1659
1816
  style,
1660
- mod: [attrs.mod, { interactive: props.interactive }],
1817
+ mod: [attrs.mod, {
1818
+ interactive: props.interactive,
1819
+ resizable: props.withResize,
1820
+ resizing: props.isResizing
1821
+ }],
1661
1822
  ...props.interactive ? {
1662
1823
  "data-event-id": props.event.id,
1663
1824
  title: props.event.title,
@@ -1667,7 +1828,17 @@ var ScheduleBackgroundEvent_default = /* @__PURE__ */ defineComponent({
1667
1828
  } : {}
1668
1829
  };
1669
1830
  });
1670
- const content = () => slots.default?.({ event: props.event }) ?? props.renderEventBody?.(props.event) ?? props.event.title;
1831
+ const content = () => {
1832
+ const body = slots.default?.({ event: props.event }) ?? props.renderEventBody?.(props.event) ?? props.event.title;
1833
+ const edges = props.resizeAxis === "horizontal" ? ["start", "end"] : ["top", "bottom"];
1834
+ return props.withResize ? [...edges.map((edge) => h(Box, {
1835
+ ...props.resizeHandleProps,
1836
+ key: edge,
1837
+ mod: { edge },
1838
+ "data-active": props.isResizing && props.activeResizeEdge === edge ? true : void 0,
1839
+ onPointerdown: (event) => emit("resizeStart", edge, event)
1840
+ })), body] : body;
1841
+ };
1671
1842
  const render = () => {
1672
1843
  const component = props.interactive ? UnstyledButton : Box;
1673
1844
  if (props.renderEvent) return props.renderEvent(props.event, {
@@ -2701,7 +2872,7 @@ function columnHasConflict$1({ columns, columnIndex, event, allDay, date }) {
2701
2872
  return hasTimeConflict;
2702
2873
  });
2703
2874
  }
2704
- function getDayPositionedEvents({ events, startTime, endTime, intervalMinutes, date }) {
2875
+ function getDayPositionedEvents({ events, startTime, endTime, intervalMinutes, date, eventOverlapMode = "columns" }) {
2705
2876
  const columns = [];
2706
2877
  const positioned = [];
2707
2878
  const sorted = sortEvents(events);
@@ -2741,14 +2912,18 @@ function getDayPositionedEvents({ events, startTime, endTime, intervalMinutes, d
2741
2912
  }
2742
2913
  });
2743
2914
  }
2915
+ for (const positionedEvent of positioned) if (positionedEvent.position.allDay) {
2916
+ positionedEvent.position.overlaps = 1;
2917
+ positionedEvent.position.width = 100;
2918
+ positionedEvent.position.offset = 0;
2919
+ }
2920
+ if (eventOverlapMode === "cascade") {
2921
+ applyCascadeLayout(positioned);
2922
+ return positioned;
2923
+ }
2744
2924
  for (const positionedEvent of positioned) {
2745
2925
  const { allDay, column } = positionedEvent.position;
2746
- if (allDay) {
2747
- positionedEvent.position.overlaps = 1;
2748
- positionedEvent.position.width = 100;
2749
- positionedEvent.position.offset = 0;
2750
- continue;
2751
- }
2926
+ if (allDay) continue;
2752
2927
  const directlyOverlapping = [];
2753
2928
  for (const otherEvent of positioned) {
2754
2929
  if (otherEvent === positionedEvent || otherEvent.position.allDay) continue;
@@ -2774,7 +2949,7 @@ function getDayPositionedEvents({ events, startTime, endTime, intervalMinutes, d
2774
2949
  }
2775
2950
  //#endregion
2776
2951
  //#region src/components/DayView/get-day-view-events/get-day-view-events.ts
2777
- function getDayViewEvents({ events, date, startTime, endTime, intervalMinutes }) {
2952
+ function getDayViewEvents({ events, date, startTime, endTime, intervalMinutes, eventOverlapMode }) {
2778
2953
  if (events === void 0) return {
2779
2954
  allDayEvents: [],
2780
2955
  regularEvents: [],
@@ -2809,7 +2984,8 @@ function getDayViewEvents({ events, date, startTime, endTime, intervalMinutes })
2809
2984
  startTime,
2810
2985
  endTime,
2811
2986
  intervalMinutes,
2812
- date
2987
+ date,
2988
+ eventOverlapMode
2813
2989
  });
2814
2990
  const allDayEvents = [];
2815
2991
  const regularEvents = [];
@@ -2872,17 +3048,19 @@ function getDayViewEvents({ events, date, startTime, endTime, intervalMinutes })
2872
3048
  };
2873
3049
  }
2874
3050
  var DayView_module_default = {
2875
- dayView: "_dayView_1nebu_1",
2876
- dayViewScrollArea: "_dayViewScrollArea_1nebu_22",
2877
- dayViewInner: "_dayViewInner_1nebu_32",
2878
- dayViewTimeSlots: "_dayViewTimeSlots_1nebu_36",
2879
- dayViewSlot: "_dayViewSlot_1nebu_39",
2880
- dayViewSlotLabels: "_dayViewSlotLabels_1nebu_44",
2881
- dayViewSlotLabel: "_dayViewSlotLabel_1nebu_44",
2882
- dayViewSlots: "_dayViewSlots_1nebu_74",
2883
- dayViewBackgroundEvent: "_dayViewBackgroundEvent_1nebu_178",
2884
- dayViewAllDay: "_dayViewAllDay_1nebu_201",
2885
- dayViewAllDayEvents: "_dayViewAllDayEvents_1nebu_206"
3051
+ dayView: "_dayView_18224_1",
3052
+ dayViewDragPreview: "_dayViewDragPreview_18224_13",
3053
+ dayViewScrollArea: "_dayViewScrollArea_18224_31",
3054
+ dayViewInner: "_dayViewInner_18224_41",
3055
+ dayViewTimeSlots: "_dayViewTimeSlots_18224_45",
3056
+ dayViewSlot: "_dayViewSlot_18224_48",
3057
+ dayViewSlotLabels: "_dayViewSlotLabels_18224_53",
3058
+ dayViewSlotLabel: "_dayViewSlotLabel_18224_53",
3059
+ dayViewSlots: "_dayViewSlots_18224_83",
3060
+ dayViewBackgroundEvent: "_dayViewBackgroundEvent_18224_196",
3061
+ dayViewBackgroundEventResizeHandle: "_dayViewBackgroundEventResizeHandle_18224_225",
3062
+ dayViewAllDay: "_dayViewAllDay_18224_272",
3063
+ dayViewAllDayEvents: "_dayViewAllDayEvents_18224_277"
2886
3064
  };
2887
3065
  //#endregion
2888
3066
  //#region src/components/DayView/DayView.vue?vue&type=script&setup=true&lang.ts
@@ -2913,6 +3091,8 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
2913
3091
  inheritAttrs: false,
2914
3092
  __name: "DayView",
2915
3093
  props: {
3094
+ eventOverlapMode: { default: "columns" },
3095
+ eventOverlapRaiseDelay: { default: 600 },
2916
3096
  intervalMinutes: { default: void 0 },
2917
3097
  headerFormat: {
2918
3098
  type: [String, Function],
@@ -2954,6 +3134,9 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
2954
3134
  type: Function,
2955
3135
  default: void 0
2956
3136
  },
3137
+ canDropEvent: {},
3138
+ canDropExternalEvent: {},
3139
+ preventEventOverlap: { type: [Boolean, Function] },
2957
3140
  withDragSlotSelect: { type: Boolean },
2958
3141
  withExternalEventDrop: { type: Boolean },
2959
3142
  startScrollTime: { default: void 0 },
@@ -2962,6 +3145,7 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
2962
3145
  type: Function,
2963
3146
  default: void 0
2964
3147
  },
3148
+ canResizeEventTo: {},
2965
3149
  date: {},
2966
3150
  events: { default: void 0 },
2967
3151
  locale: { default: void 0 },
@@ -3003,6 +3187,7 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3003
3187
  "slotDragEnd",
3004
3188
  "externalEventDrop",
3005
3189
  "eventResize",
3190
+ "eventPlacementRejected",
3006
3191
  "dateChange",
3007
3192
  "viewChange",
3008
3193
  "eventClick"
@@ -3043,6 +3228,7 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3043
3228
  const eventRenderers = computed(() => resolveEventRenderers(props, slots));
3044
3229
  const timeSlotsContainer = ref(null);
3045
3230
  const slotDropTarget = useSlotDropTarget();
3231
+ const dropDataTransfer = shallowRef(null);
3046
3232
  const date = computed(() => toDateString(props.date));
3047
3233
  const datePart = computed(() => dayjs(date.value).format("YYYY-MM-DD"));
3048
3234
  const now = computed(() => dayjs(props.getCurrentTime?.() ?? dayjs()));
@@ -3054,7 +3240,8 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3054
3240
  date: date.value,
3055
3241
  startTime: props.startTime,
3056
3242
  endTime: props.endTime,
3057
- intervalMinutes: props.intervalMinutes
3243
+ intervalMinutes: props.intervalMinutes,
3244
+ eventOverlapMode: props.eventOverlapMode
3058
3245
  }));
3059
3246
  const intervals = computed(() => getDayTimeIntervals({
3060
3247
  startTime: props.startTime,
@@ -3077,7 +3264,12 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3077
3264
  intervalMinutes: () => props.intervalMinutes,
3078
3265
  resizeIntervalMinutes: () => props.eventResizeInterval,
3079
3266
  onEventResize: (data) => emit("eventResize", data),
3080
- canResizeEvent: () => props.canResizeEvent
3267
+ canResizeEvent: () => props.canResizeEvent,
3268
+ events: () => expandedEvents.value,
3269
+ preventEventOverlap: () => props.preventEventOverlap,
3270
+ canResizeEventTo: () => props.canResizeEventTo,
3271
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data),
3272
+ withBackgroundEvents: () => Boolean(props.withInteractiveBackgroundEvents)
3081
3273
  });
3082
3274
  const slotDragSelect = useSlotDragSelect({
3083
3275
  enabled: () => withSlotSelect.value,
@@ -3099,9 +3291,35 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3099
3291
  isSlotDragging: () => slotDragSelect.isDragging(),
3100
3292
  onDragEnd: () => {
3101
3293
  slotDropTarget.reset();
3294
+ dropDataTransfer.value = null;
3102
3295
  emit("eventDragEnd");
3103
3296
  }
3104
3297
  });
3298
+ const dropValid = computed(() => {
3299
+ const target = slotDropTarget.dropTarget.value;
3300
+ const interval = target && intervals.value[target.slotIndex];
3301
+ if (!target || !interval) return true;
3302
+ const start = `${target.date} ${interval.startTime}`;
3303
+ const event = dragState.draggedEvent.value;
3304
+ if (event) {
3305
+ const next = moveEventTo(event, start);
3306
+ return isEventPlacementAllowed({
3307
+ event,
3308
+ start: next.newStart,
3309
+ end: next.newEnd,
3310
+ events: expandedEvents.value,
3311
+ preventEventOverlap: props.preventEventOverlap
3312
+ }).allowed && props.canDropEvent?.({
3313
+ event,
3314
+ start: next.newStart,
3315
+ end: next.newEnd
3316
+ }) !== false;
3317
+ }
3318
+ return dropDataTransfer.value ? props.canDropExternalEvent?.({
3319
+ dataTransfer: dropDataTransfer.value,
3320
+ start
3321
+ }) !== false : true;
3322
+ });
3105
3323
  onMounted(async () => {
3106
3324
  if (!props.startScrollTime) return;
3107
3325
  await nextTick();
@@ -3119,14 +3337,79 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3119
3337
  const emitDrop = (nativeEvent, target) => {
3120
3338
  nativeEvent.preventDefault();
3121
3339
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
3122
- if (event) emit("eventDrop", moveEventTo(event, target));
3123
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", nativeEvent.dataTransfer, target);
3340
+ if (event) {
3341
+ const next = moveEventTo(event, target);
3342
+ const validation = isEventPlacementAllowed({
3343
+ event,
3344
+ start: next.newStart,
3345
+ end: next.newEnd,
3346
+ events: expandedEvents.value,
3347
+ preventEventOverlap: props.preventEventOverlap
3348
+ });
3349
+ if (validation.allowed && props.canDropEvent?.({
3350
+ event,
3351
+ start: next.newStart,
3352
+ end: next.newEnd
3353
+ }) !== false) emit("eventDrop", next);
3354
+ else emit("eventPlacementRejected", {
3355
+ action: "drop",
3356
+ event,
3357
+ start: next.newStart,
3358
+ end: next.newEnd,
3359
+ conflicts: validation.conflicts,
3360
+ reason: validation.allowed ? "rejected" : "overlap"
3361
+ });
3362
+ } else if (nativeEvent.dataTransfer) if (props.canDropExternalEvent?.({
3363
+ dataTransfer: nativeEvent.dataTransfer,
3364
+ start: target
3365
+ }) !== false) emit("externalEventDrop", nativeEvent.dataTransfer, target);
3366
+ else emit("eventPlacementRejected", {
3367
+ action: "external-drop",
3368
+ dataTransfer: nativeEvent.dataTransfer,
3369
+ start: target,
3370
+ conflicts: [],
3371
+ reason: "rejected"
3372
+ });
3124
3373
  };
3125
3374
  const emitAllDayDrop = (nativeEvent) => {
3126
3375
  nativeEvent.preventDefault();
3127
3376
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
3128
- if (event) emit("eventDrop", moveEventToAllDay(event, datePart.value));
3129
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", nativeEvent.dataTransfer, `${datePart.value} 00:00:00`);
3377
+ if (event) {
3378
+ const next = moveEventToAllDay(event, datePart.value);
3379
+ const validation = isEventPlacementAllowed({
3380
+ event,
3381
+ start: next.newStart,
3382
+ end: next.newEnd,
3383
+ events: expandedEvents.value,
3384
+ preventEventOverlap: props.preventEventOverlap
3385
+ });
3386
+ if (validation.allowed && props.canDropEvent?.({
3387
+ event,
3388
+ start: next.newStart,
3389
+ end: next.newEnd
3390
+ }) !== false) emit("eventDrop", next);
3391
+ else emit("eventPlacementRejected", {
3392
+ action: "drop",
3393
+ event,
3394
+ start: next.newStart,
3395
+ end: next.newEnd,
3396
+ conflicts: validation.conflicts,
3397
+ reason: validation.allowed ? "rejected" : "overlap"
3398
+ });
3399
+ } else if (nativeEvent.dataTransfer) {
3400
+ const target = `${datePart.value} 00:00:00`;
3401
+ if (props.canDropExternalEvent?.({
3402
+ dataTransfer: nativeEvent.dataTransfer,
3403
+ start: target
3404
+ }) !== false) emit("externalEventDrop", nativeEvent.dataTransfer, target);
3405
+ else emit("eventPlacementRejected", {
3406
+ action: "external-drop",
3407
+ dataTransfer: nativeEvent.dataTransfer,
3408
+ start: target,
3409
+ conflicts: [],
3410
+ reason: "rejected"
3411
+ });
3412
+ }
3130
3413
  };
3131
3414
  const clickAllDaySlot = (nativeEvent) => emit("allDaySlotClick", date.value, nativeEvent);
3132
3415
  const clickTimeSlot = (slotIndex, nativeEvent) => {
@@ -3147,10 +3430,14 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3147
3430
  startTime: props.startTime,
3148
3431
  endTime: props.endTime
3149
3432
  });
3150
- const handleGridDragOver = (nativeEvent) => slotDropTarget.dragOver(nativeEvent, dropInput());
3433
+ const handleGridDragOver = (nativeEvent) => {
3434
+ dropDataTransfer.value = nativeEvent.dataTransfer;
3435
+ slotDropTarget.dragOver(nativeEvent, dropInput());
3436
+ };
3151
3437
  const handleGridDragLeave = (nativeEvent) => slotDropTarget.dragLeave(nativeEvent, timeSlotsContainer.value);
3152
3438
  const handleGridDrop = (nativeEvent) => {
3153
3439
  const target = slotDropTarget.drop(nativeEvent, dropInput());
3440
+ dropDataTransfer.value = null;
3154
3441
  if (target) emitDrop(nativeEvent, target.target);
3155
3442
  };
3156
3443
  const handleSlotKeydown = (nativeEvent, index) => {
@@ -3168,11 +3455,16 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3168
3455
  "business-hours": false,
3169
3456
  "non-business-hours": false
3170
3457
  }));
3171
- const backgroundEventStyle = (position) => ({
3172
- top: `${position.top}%`,
3173
- bottom: `${100 - position.top - position.height}%`,
3174
- minHeight: "1px"
3175
- });
3458
+ const backgroundEventStyle = (event) => {
3459
+ const resizePosition = eventResize.getResizePosition(event.id);
3460
+ const top = resizePosition?.top ?? event.position.top;
3461
+ const height = resizePosition?.height ?? event.position.height;
3462
+ return {
3463
+ top: `${top}%`,
3464
+ bottom: `${100 - top - height}%`,
3465
+ minHeight: "1px"
3466
+ };
3467
+ };
3176
3468
  const regularEventStyle = (event) => {
3177
3469
  const resizePosition = eventResize.getResizePosition(event.id);
3178
3470
  const top = resizePosition?.top ?? event.position.top;
@@ -3183,7 +3475,9 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3183
3475
  bottom: `${100 - top - height}%`,
3184
3476
  minHeight: "1px",
3185
3477
  width: `${event.position.width}%`,
3186
- insetInlineStart: `${event.position.offset}%`
3478
+ insetInlineStart: `${event.position.offset}%`,
3479
+ "--event-z-index": event.position.column + 3,
3480
+ "--event-z-index-raised": event.position.overlaps + 3
3187
3481
  };
3188
3482
  };
3189
3483
  const startEventResize = (event, edge, pointerEvent) => {
@@ -3206,10 +3500,14 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3206
3500
  return openBlock(), createBlock(unref(Box), mergeProps({
3207
3501
  ...unref(attrs),
3208
3502
  ...unref(getStyles)("dayView")
3209
- }, { mod: [{
3210
- static: isStatic.value,
3211
- "slot-dragging": unref(slotDragSelect).isDragging()
3212
- }, unref(attrs).mod] }), {
3503
+ }, {
3504
+ mod: [{
3505
+ static: isStatic.value,
3506
+ "slot-dragging": unref(slotDragSelect).isDragging()
3507
+ }, unref(attrs).mod],
3508
+ "data-event-interaction": unref(eventResize).isResizing.value || void 0,
3509
+ style: { "--event-raise-delay": `${unref(props).eventOverlapRaiseDelay}ms` }
3510
+ }), {
3213
3511
  default: withCtx(() => [unref(props).withHeader ? (openBlock(), createBlock(unref(ScheduleHeaderBase), mergeProps({
3214
3512
  key: 0,
3215
3513
  view: "day",
@@ -3341,12 +3639,20 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3341
3639
  ...eventRenderers.value,
3342
3640
  ...unref(staticStyles)("dayViewBackgroundEvent")
3343
3641
  }, {
3344
- style: backgroundEventStyle(event.position),
3345
- onEventClick: clickEvent
3642
+ style: backgroundEventStyle(event),
3643
+ "with-resize": unref(eventResize).isResizableEvent(event),
3644
+ "is-resizing": unref(eventResize).getResizePosition(event.id) !== null,
3645
+ "resize-handle-props": unref(staticStyles)("dayViewBackgroundEventResizeHandle"),
3646
+ onEventClick: clickResizableEvent,
3647
+ onResizeStart: (edge, pointerEvent) => startEventResize(event, edge, pointerEvent)
3346
3648
  }), null, 16, [
3347
3649
  "event",
3348
3650
  "interactive",
3349
- "style"
3651
+ "style",
3652
+ "with-resize",
3653
+ "is-resizing",
3654
+ "resize-handle-props",
3655
+ "onResizeStart"
3350
3656
  ]);
3351
3657
  }), 128)),
3352
3658
  (openBlock(true), createElementBlock(Fragment, null, renderList(dayEvents.value.regularEvents, (event) => {
@@ -3355,6 +3661,10 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3355
3661
  event,
3356
3662
  "auto-size": "",
3357
3663
  mode: unref(props).mode,
3664
+ mod: {
3665
+ cascade: unref(props).eventOverlapMode === "cascade",
3666
+ invalid: unref(eventResize).getResizePosition(event.id) !== null && !unref(eventResize).resizeValid.value
3667
+ },
3358
3668
  style: regularEventStyle(event),
3359
3669
  draggable: !isStatic.value && unref(props).withEventsDragAndDrop === true && (unref(props).canDragEvent?.(event) ?? true),
3360
3670
  "with-resize": unref(eventResize).isResizableEvent(event),
@@ -3370,6 +3680,7 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3370
3680
  }), null, 16, [
3371
3681
  "event",
3372
3682
  "mode",
3683
+ "mod",
3373
3684
  "style",
3374
3685
  "draggable",
3375
3686
  "with-resize",
@@ -3413,6 +3724,7 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3413
3724
  "hour-start": slot.isHourStart,
3414
3725
  static: isStatic.value,
3415
3726
  "drop-target": unref(slotDropTarget).isTarget(datePart.value, index),
3727
+ invalid: unref(slotDropTarget).isTarget(datePart.value, index) && !dropValid.value,
3416
3728
  "drag-selected": unref(slotDragSelect).isSlotSelected(index, datePart.value),
3417
3729
  "business-hours": businessHoursMods.value[index]["business-hours"],
3418
3730
  "non-business-hours": businessHoursMods.value[index]["non-business-hours"]
@@ -3442,7 +3754,11 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3442
3754
  _: 1
3443
3755
  }, 16, ["viewport-props"])]),
3444
3756
  _: 1
3445
- }, 16, ["mod"]);
3757
+ }, 16, [
3758
+ "mod",
3759
+ "data-event-interaction",
3760
+ "style"
3761
+ ]);
3446
3762
  };
3447
3763
  }
3448
3764
  }), {
@@ -3451,10 +3767,16 @@ var DayView = factory(/* @__PURE__ */ defineComponent({
3451
3767
  });
3452
3768
  //#endregion
3453
3769
  //#region src/components/MobileMonthView/get-mobile-month-view-events.ts
3770
+ function getEventEndDay(event) {
3771
+ const startDay = dayjs(event.start).startOf("day");
3772
+ const end = dayjs(event.end);
3773
+ const endDay = end.hour() === 0 && end.minute() === 0 && end.second() === 0 ? end.startOf("day").subtract(1, "day") : end.startOf("day");
3774
+ return endDay.isBefore(startDay) ? startDay : endDay;
3775
+ }
3454
3776
  function groupEventByDate$1(event, groupedEvents) {
3455
3777
  if (isMultidayEvent(event)) {
3456
3778
  const startDate = dayjs(event.start).startOf("day");
3457
- const endDate = dayjs(event.end).startOf("day");
3779
+ const endDate = getEventEndDay(event);
3458
3780
  for (let date = startDate; date.isBefore(endDate) || date.isSame(endDate); date = date.add(1, "day")) {
3459
3781
  const dateKey = date.format("YYYY-MM-DD");
3460
3782
  if (!groupedEvents[dateKey]) groupedEvents[dateKey] = [];
@@ -3470,9 +3792,11 @@ function getMobileMonthViewEvents({ date, events }) {
3470
3792
  const groupedEvents = {};
3471
3793
  if (events === void 0) return groupedEvents;
3472
3794
  const ids = /* @__PURE__ */ new Set();
3795
+ const monthStart = dayjs(date).startOf("month");
3796
+ const monthEnd = dayjs(date).endOf("month");
3473
3797
  for (const event of events) {
3474
3798
  if (event.display === "background") continue;
3475
- if (dayjs(event.start).isSame(dayjs(date), "month")) {
3799
+ if (!getEventEndDay(event).isBefore(monthStart, "day") && !dayjs(event.start).isAfter(monthEnd, "day")) {
3476
3800
  groupEventByDate$1(validateEvent(event), groupedEvents);
3477
3801
  if (!ids.has(event.id)) ids.add(event.id);
3478
3802
  else throw new Error(`[@mantine/schedule] MobileMonthView: Duplicated event ids found: ${event.id}`);
@@ -3856,17 +4180,6 @@ function calculateEventPositionInWeek({ eventStart, eventEnd, weekStart, weekEnd
3856
4180
  };
3857
4181
  }
3858
4182
  //#endregion
3859
- //#region src/components/MonthView/get-month-view-events/find-available-row.ts
3860
- function findAvailableRow({ existingEvents, startDayIndex, daysSpanned, weekStart }) {
3861
- let row = 0;
3862
- for (const existing of existingEvents) {
3863
- const existingStart = dayjs(existing.start).startOf("day");
3864
- const existingDayIndex = (existingStart.isBefore(weekStart) || existingStart.isSame(weekStart, "day") ? weekStart : existingStart).diff(weekStart, "day");
3865
- if (existingDayIndex + (existing.position?.width || 0) / 100 * 7 > startDayIndex && existingDayIndex < startDayIndex + daysSpanned) row = Math.max(row, (existing.position?.row || 0) + 1);
3866
- }
3867
- return row;
3868
- }
3869
- //#endregion
3870
4183
  //#region src/components/MonthView/get-month-view-events/get-weeks-in-range.ts
3871
4184
  function getWeeksInRange({ rangeStart, rangeEnd, firstDayOfWeek }) {
3872
4185
  const weeks = [];
@@ -3891,6 +4204,14 @@ function getWeeksInRange({ rangeStart, rangeEnd, firstDayOfWeek }) {
3891
4204
  };
3892
4205
  }
3893
4206
  //#endregion
4207
+ //#region src/components/MonthView/get-month-view-events/reserve-row.ts
4208
+ function reserveRow({ nextRowByDay, startDayIndex, daysSpanned }) {
4209
+ const endDayIndex = startDayIndex + daysSpanned;
4210
+ const row = Math.max(...nextRowByDay.slice(startDayIndex, endDayIndex));
4211
+ nextRowByDay.fill(row + 1, startDayIndex, endDayIndex);
4212
+ return row;
4213
+ }
4214
+ //#endregion
3894
4215
  //#region src/components/MonthView/get-month-view-events/get-month-positioned-events.ts
3895
4216
  function getMonthPositionedEvents({ date, events, firstDayOfWeek = 1, range }) {
3896
4217
  const groupedByWeek = {};
@@ -3901,6 +4222,11 @@ function getMonthPositionedEvents({ date, events, firstDayOfWeek = 1, range }) {
3901
4222
  rangeEnd: range ? dayjs(range.end) : dayjs(date).startOf("month").endOf("month"),
3902
4223
  firstDayOfWeek
3903
4224
  });
4225
+ const weekStates = weeks.map((week) => ({
4226
+ weekStart: dayjs(week[0]).startOf("day"),
4227
+ weekEnd: dayjs(week[6]).endOf("day"),
4228
+ nextRowByDay: Array.from({ length: 7 }).fill(0)
4229
+ }));
3904
4230
  for (let i = 0; i < weeks.length; i++) {
3905
4231
  groupedByWeek[i.toString()] = [];
3906
4232
  backgroundByWeek[i.toString()] = [];
@@ -3911,9 +4237,7 @@ function getMonthPositionedEvents({ date, events, firstDayOfWeek = 1, range }) {
3911
4237
  const eventEnd = rawEnd.hour() === 0 && rawEnd.minute() === 0 && rawEnd.second() === 0 ? rawEnd.startOf("day").subtract(1, "day") : rawEnd.startOf("day");
3912
4238
  const isMultiday = eventEnd.isAfter(eventStart);
3913
4239
  for (let weekIdx = 0; weekIdx < weeks.length; weekIdx++) {
3914
- const week = weeks[weekIdx];
3915
- const weekStart = dayjs(week[0]).startOf("day");
3916
- const weekEnd = dayjs(week[6]).endOf("day");
4240
+ const { weekStart, weekEnd, nextRowByDay } = weekStates[weekIdx];
3917
4241
  if ((eventStart.isBefore(weekEnd) || eventStart.isSame(weekEnd, "day")) && (eventEnd.isAfter(weekStart) || eventEnd.isSame(weekStart, "day"))) {
3918
4242
  const { startDayIndex, daysSpanned, startOffset, width, hanging } = calculateEventPositionInWeek({
3919
4243
  eventStart,
@@ -3935,11 +4259,10 @@ function getMonthPositionedEvents({ date, events, firstDayOfWeek = 1, range }) {
3935
4259
  });
3936
4260
  continue;
3937
4261
  }
3938
- const row = findAvailableRow({
3939
- existingEvents: groupedByWeek[weekIdx.toString()],
4262
+ const row = reserveRow({
4263
+ nextRowByDay,
3940
4264
  startDayIndex,
3941
- daysSpanned,
3942
- weekStart
4265
+ daysSpanned
3943
4266
  });
3944
4267
  const positionedEvent = {
3945
4268
  ...event,
@@ -4115,16 +4438,16 @@ function getRenderableMonthEventSegments({ events, groupedByDay, maxEventsPerDay
4115
4438
  });
4116
4439
  }
4117
4440
  var MonthView_module_default = {
4118
- monthView: "_monthView_hbhp2_1",
4119
- monthViewWeekdays: "_monthViewWeekdays_hbhp2_21",
4120
- monthViewWeek: "_monthViewWeek_hbhp2_21",
4121
- monthViewWeekNumber: "_monthViewWeekNumber_hbhp2_31",
4122
- monthViewWeekday: "_monthViewWeekday_hbhp2_21",
4123
- monthViewWeekdaysCorner: "_monthViewWeekdaysCorner_hbhp2_107",
4124
- monthViewDay: "_monthViewDay_hbhp2_114",
4125
- monthViewDayLabel: "_monthViewDayLabel_hbhp2_255",
4126
- monthViewBackgroundEvent: "_monthViewBackgroundEvent_hbhp2_271",
4127
- monthViewEvents: "_monthViewEvents_hbhp2_296"
4441
+ monthView: "_monthView_98v2r_1",
4442
+ monthViewWeekdays: "_monthViewWeekdays_98v2r_21",
4443
+ monthViewWeek: "_monthViewWeek_98v2r_21",
4444
+ monthViewWeekNumber: "_monthViewWeekNumber_98v2r_31",
4445
+ monthViewWeekday: "_monthViewWeekday_98v2r_21",
4446
+ monthViewWeekdaysCorner: "_monthViewWeekdaysCorner_98v2r_107",
4447
+ monthViewDay: "_monthViewDay_98v2r_114",
4448
+ monthViewDayLabel: "_monthViewDayLabel_98v2r_264",
4449
+ monthViewBackgroundEvent: "_monthViewBackgroundEvent_98v2r_280",
4450
+ monthViewEvents: "_monthViewEvents_98v2r_305"
4128
4451
  };
4129
4452
  //#endregion
4130
4453
  //#region src/components/MonthView/MonthView.vue?vue&type=script&setup=true&lang.ts
@@ -4133,6 +4456,7 @@ var _hoisted_1$5 = [
4133
4456
  "data-weekend",
4134
4457
  "data-static",
4135
4458
  "data-drop-target",
4459
+ "data-invalid",
4136
4460
  "data-drag-selected",
4137
4461
  "data-drag-slot-index",
4138
4462
  "data-drag-slot-group",
@@ -4207,6 +4531,9 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4207
4531
  type: Function,
4208
4532
  default: void 0
4209
4533
  },
4534
+ canDropEvent: {},
4535
+ canDropExternalEvent: {},
4536
+ preventEventOverlap: { type: [Boolean, Function] },
4210
4537
  withExternalEventDrop: { type: Boolean },
4211
4538
  withDragSlotSelect: { type: Boolean },
4212
4539
  monthYearSelectProps: { default: void 0 },
@@ -4252,6 +4579,7 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4252
4579
  "eventDragEnd",
4253
4580
  "externalEventDrop",
4254
4581
  "slotDragEnd",
4582
+ "eventPlacementRejected",
4255
4583
  "dateChange",
4256
4584
  "viewChange",
4257
4585
  "eventClick"
@@ -4292,6 +4620,7 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4292
4620
  const eventRenderers = computed(() => resolveEventRenderers(props, slots));
4293
4621
  const monthGrid = ref(null);
4294
4622
  const dropTarget = shallowRef(null);
4623
+ const dropValid = ref(true);
4295
4624
  const isStatic = computed(() => props.mode === "static");
4296
4625
  const month = computed(() => dayjs(props.date).startOf("month"));
4297
4626
  const maxEventsPerDay = computed(() => clampMaxEvents(props.maxEventsPerDay));
@@ -4382,7 +4711,29 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4382
4711
  const handleDragOver = (nativeEvent, date) => {
4383
4712
  nativeEvent.preventDefault();
4384
4713
  if (nativeEvent.dataTransfer) nativeEvent.dataTransfer.dropEffect = nativeEvent.dataTransfer.types.includes("application/json") ? "move" : "copy";
4385
- highlightDay(toDateString(date));
4714
+ const target = toDateString(date);
4715
+ const dragged = dragState.draggedEvent.value;
4716
+ if (dragged) {
4717
+ const next = moveEventTo(dragged, target);
4718
+ dropValid.value = isEventPlacementAllowed({
4719
+ event: dragged,
4720
+ start: next.newStart,
4721
+ end: next.newEnd,
4722
+ events: expandedEvents.value,
4723
+ preventEventOverlap: props.preventEventOverlap
4724
+ }).allowed && props.canDropEvent?.({
4725
+ event: dragged,
4726
+ start: next.newStart,
4727
+ end: next.newEnd
4728
+ }) !== false;
4729
+ } else if (nativeEvent.dataTransfer) {
4730
+ const start = `${target} 00:00:00`;
4731
+ dropValid.value = props.canDropExternalEvent?.({
4732
+ dataTransfer: nativeEvent.dataTransfer,
4733
+ start
4734
+ }) !== false;
4735
+ }
4736
+ highlightDay(target);
4386
4737
  };
4387
4738
  const handleDragLeave = (nativeEvent) => {
4388
4739
  if (!(nativeEvent.relatedTarget instanceof Node) || !monthGrid.value?.contains(nativeEvent.relatedTarget)) {
@@ -4394,14 +4745,48 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4394
4745
  nativeEvent.preventDefault();
4395
4746
  highlightDay.cancel();
4396
4747
  setDropTarget(null);
4748
+ dropValid.value = true;
4397
4749
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
4398
4750
  if (event) {
4399
4751
  const { start } = calculateMonthDropDate({
4400
4752
  draggedEvent: event,
4401
4753
  targetDay: toDateString(date)
4402
4754
  });
4403
- emit("eventDrop", moveEventTo(event, start));
4404
- } else if (nativeEvent.dataTransfer) emit("externalEventDrop", nativeEvent.dataTransfer, toDateString(date));
4755
+ const next = moveEventTo(event, start);
4756
+ const validation = isEventPlacementAllowed({
4757
+ event,
4758
+ start: next.newStart,
4759
+ end: next.newEnd,
4760
+ events: expandedEvents.value,
4761
+ preventEventOverlap: props.preventEventOverlap
4762
+ });
4763
+ if (validation.allowed && props.canDropEvent?.({
4764
+ event,
4765
+ start: next.newStart,
4766
+ end: next.newEnd
4767
+ }) !== false) emit("eventDrop", next);
4768
+ else emit("eventPlacementRejected", {
4769
+ action: "drop",
4770
+ event,
4771
+ start: next.newStart,
4772
+ end: next.newEnd,
4773
+ conflicts: validation.conflicts,
4774
+ reason: validation.allowed ? "rejected" : "overlap"
4775
+ });
4776
+ } else if (nativeEvent.dataTransfer) {
4777
+ const start = `${toDateString(date)} 00:00:00`;
4778
+ if (props.canDropExternalEvent?.({
4779
+ dataTransfer: nativeEvent.dataTransfer,
4780
+ start
4781
+ }) !== false) emit("externalEventDrop", nativeEvent.dataTransfer, toDateString(date));
4782
+ else emit("eventPlacementRejected", {
4783
+ action: "external-drop",
4784
+ dataTransfer: nativeEvent.dataTransfer,
4785
+ start,
4786
+ conflicts: [],
4787
+ reason: "rejected"
4788
+ });
4789
+ }
4405
4790
  };
4406
4791
  const segmentStyle = (position) => ({
4407
4792
  position: "absolute",
@@ -4475,6 +4860,7 @@ var MonthView = factory(/* @__PURE__ */ defineComponent({
4475
4860
  "data-weekend": unref(props).weekendDays.includes(unref(dayjs)(date).day()) || void 0,
4476
4861
  "data-static": isStatic.value || void 0,
4477
4862
  "data-drop-target": dropTarget.value === unref(toDateString)(date) || void 0,
4863
+ "data-invalid": dropTarget.value === unref(toDateString)(date) && !dropValid.value || void 0,
4478
4864
  "data-drag-selected": unref(slotDragSelect).isSlotSelected(weekIndex * 7 + dayIndex, "month") || void 0,
4479
4865
  "data-drag-slot-index": withSlotSelect.value ? weekIndex * 7 + dayIndex : void 0,
4480
4866
  "data-drag-slot-group": withSlotSelect.value ? MONTH_SLOT_GROUP : void 0,
@@ -4726,7 +5112,7 @@ function getHangingStatus({ eventStartDate, actualEndDate, weekDays }) {
4726
5112
  }
4727
5113
  //#endregion
4728
5114
  //#region src/components/WeekView/get-week-view-events/get-week-positioned-events.ts
4729
- function getWeekPositionedEvents({ date, events, startTime, endTime, intervalMinutes, firstDayOfWeek = 1, weekendDays = [0, 6], withWeekendDays = true }) {
5115
+ function getWeekPositionedEvents({ date, events, startTime, endTime, intervalMinutes, firstDayOfWeek = 1, weekendDays = [0, 6], withWeekendDays = true, eventOverlapMode = "columns" }) {
4730
5116
  const weekDays = getWeekDays({
4731
5117
  week: date,
4732
5118
  firstDayOfWeek,
@@ -4885,7 +5271,8 @@ function getWeekPositionedEvents({ date, events, startTime, endTime, intervalMin
4885
5271
  });
4886
5272
  }
4887
5273
  }
4888
- for (const day of weekDays) calculateRegularEventOverlaps(grouped.regularEvents[day]);
5274
+ for (const day of weekDays) if (eventOverlapMode === "cascade") applyCascadeLayout(grouped.regularEvents[day]);
5275
+ else calculateRegularEventOverlaps(grouped.regularEvents[day]);
4889
5276
  if (grouped.allDayEvents.length > 0) {
4890
5277
  const eventRows = assignEventRows(grouped.allDayEvents);
4891
5278
  const assignedRows = /* @__PURE__ */ new Set();
@@ -4920,27 +5307,29 @@ function getWeekViewEvents(input) {
4920
5307
  });
4921
5308
  }
4922
5309
  var WeekView_module_default = {
4923
- weekView: "_weekView_1f3zt_1",
4924
- weekViewRoot: "_weekViewRoot_1f3zt_22",
4925
- weekViewInner: "_weekViewInner_1f3zt_30",
4926
- weekViewScrollArea: "_weekViewScrollArea_1f3zt_36",
4927
- weekViewHeader: "_weekViewHeader_1f3zt_42",
4928
- weekViewCorner: "_weekViewCorner_1f3zt_57",
4929
- weekViewSlotLabels: "_weekViewSlotLabels_1f3zt_68",
4930
- weekViewSlotLabel: "_weekViewSlotLabel_1f3zt_68",
4931
- weekViewDay: "_weekViewDay_1f3zt_95",
4932
- weekViewDayLabel: "_weekViewDayLabel_1f3zt_100",
4933
- weekViewDayNumber: "_weekViewDayNumber_1f3zt_138",
4934
- weekViewDayWeekday: "_weekViewDayWeekday_1f3zt_154",
4935
- weekViewBackgroundEvent: "_weekViewBackgroundEvent_1f3zt_160",
4936
- weekViewDaySlots: "_weekViewDaySlots_1f3zt_183",
4937
- weekViewDaySlot: "_weekViewDaySlot_1f3zt_183",
4938
- weekViewWeekLabel: "_weekViewWeekLabel_1f3zt_281",
4939
- weekViewWeekNumber: "_weekViewWeekNumber_1f3zt_287",
4940
- weekViewAllDaySlots: "_weekViewAllDaySlots_1f3zt_293",
4941
- weekViewAllDaySlotsLabel: "_weekViewAllDaySlotsLabel_1f3zt_298",
4942
- weekViewAllDaySlotsEvents: "_weekViewAllDaySlotsEvents_1f3zt_305",
4943
- weekViewAllDaySlotsList: "_weekViewAllDaySlotsList_1f3zt_312"
5310
+ weekView: "_weekView_1ttnb_1",
5311
+ weekViewRoot: "_weekViewRoot_1ttnb_22",
5312
+ weekViewDragPreview: "_weekViewDragPreview_1ttnb_33",
5313
+ weekViewInner: "_weekViewInner_1ttnb_39",
5314
+ weekViewScrollArea: "_weekViewScrollArea_1ttnb_45",
5315
+ weekViewHeader: "_weekViewHeader_1ttnb_51",
5316
+ weekViewCorner: "_weekViewCorner_1ttnb_66",
5317
+ weekViewSlotLabels: "_weekViewSlotLabels_1ttnb_77",
5318
+ weekViewSlotLabel: "_weekViewSlotLabel_1ttnb_77",
5319
+ weekViewDay: "_weekViewDay_1ttnb_104",
5320
+ weekViewDayLabel: "_weekViewDayLabel_1ttnb_109",
5321
+ weekViewDayNumber: "_weekViewDayNumber_1ttnb_147",
5322
+ weekViewDayWeekday: "_weekViewDayWeekday_1ttnb_163",
5323
+ weekViewBackgroundEvent: "_weekViewBackgroundEvent_1ttnb_169",
5324
+ weekViewBackgroundEventResizeHandle: "_weekViewBackgroundEventResizeHandle_1ttnb_198",
5325
+ weekViewDaySlots: "_weekViewDaySlots_1ttnb_246",
5326
+ weekViewDaySlot: "_weekViewDaySlot_1ttnb_246",
5327
+ weekViewWeekLabel: "_weekViewWeekLabel_1ttnb_353",
5328
+ weekViewWeekNumber: "_weekViewWeekNumber_1ttnb_359",
5329
+ weekViewAllDaySlots: "_weekViewAllDaySlots_1ttnb_365",
5330
+ weekViewAllDaySlotsLabel: "_weekViewAllDaySlotsLabel_1ttnb_370",
5331
+ weekViewAllDaySlotsEvents: "_weekViewAllDaySlotsEvents_1ttnb_377",
5332
+ weekViewAllDaySlotsList: "_weekViewAllDaySlotsList_1ttnb_384"
4944
5333
  };
4945
5334
  //#endregion
4946
5335
  //#region src/components/WeekView/WeekView.vue?vue&type=script&setup=true&lang.ts
@@ -4983,6 +5372,8 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
4983
5372
  inheritAttrs: false,
4984
5373
  __name: "WeekView",
4985
5374
  props: {
5375
+ eventOverlapMode: { default: "columns" },
5376
+ eventOverlapRaiseDelay: { default: 600 },
4986
5377
  intervalMinutes: { default: void 0 },
4987
5378
  withCurrentTimeIndicator: {
4988
5379
  type: Boolean,
@@ -5054,6 +5445,9 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5054
5445
  type: Function,
5055
5446
  default: void 0
5056
5447
  },
5448
+ canDropEvent: {},
5449
+ canDropExternalEvent: {},
5450
+ preventEventOverlap: { type: [Boolean, Function] },
5057
5451
  withDragSlotSelect: { type: Boolean },
5058
5452
  withExternalEventDrop: { type: Boolean },
5059
5453
  startScrollTime: { default: void 0 },
@@ -5062,6 +5456,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5062
5456
  type: Function,
5063
5457
  default: void 0
5064
5458
  },
5459
+ canResizeEventTo: {},
5065
5460
  date: {},
5066
5461
  events: { default: void 0 },
5067
5462
  locale: { default: void 0 },
@@ -5103,6 +5498,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5103
5498
  "slotDragEnd",
5104
5499
  "externalEventDrop",
5105
5500
  "eventResize",
5501
+ "eventPlacementRejected",
5106
5502
  "dateChange",
5107
5503
  "viewChange",
5108
5504
  "eventClick"
@@ -5147,6 +5543,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5147
5543
  };
5148
5544
  const daySlotsContainers = /* @__PURE__ */ new Map();
5149
5545
  const slotDropTarget = useSlotDropTarget();
5546
+ const dropDataTransfer = shallowRef(null);
5150
5547
  const isStatic = computed(() => props.mode === "static");
5151
5548
  /** The plural names are the deprecated aliases; the canonical prop wins when both are set. */
5152
5549
  const withWeekNumber = computed(() => props.withWeekNumbers ?? props.withWeekNumber);
@@ -5171,7 +5568,8 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5171
5568
  intervalMinutes: props.intervalMinutes,
5172
5569
  firstDayOfWeek: props.firstDayOfWeek,
5173
5570
  weekendDays: props.weekendDays,
5174
- withWeekendDays: props.withWeekendDays
5571
+ withWeekendDays: props.withWeekendDays,
5572
+ eventOverlapMode: props.eventOverlapMode
5175
5573
  }));
5176
5574
  const intervals = computed(() => getDayTimeIntervals({
5177
5575
  startTime: props.startTime,
@@ -5188,7 +5586,8 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5188
5586
  }));
5189
5587
  const rootVars = computed(() => ({
5190
5588
  "--number-of-days": String(days.value.length),
5191
- "--indicator-offset-index": currentWeekdayIndex.value === -1 ? void 0 : String(currentWeekdayIndex.value + 1)
5589
+ "--indicator-offset-index": currentWeekdayIndex.value === -1 ? void 0 : String(currentWeekdayIndex.value + 1),
5590
+ "--event-raise-delay": `${props.eventOverlapRaiseDelay}ms`
5192
5591
  }));
5193
5592
  /**
5194
5593
  * Everything the template needs per day column.
@@ -5235,7 +5634,12 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5235
5634
  intervalMinutes: () => props.intervalMinutes,
5236
5635
  resizeIntervalMinutes: () => props.eventResizeInterval,
5237
5636
  onEventResize: (data) => emit("eventResize", data),
5238
- canResizeEvent: () => props.canResizeEvent
5637
+ canResizeEvent: () => props.canResizeEvent,
5638
+ events: () => expandedEvents.value,
5639
+ preventEventOverlap: () => props.preventEventOverlap,
5640
+ canResizeEventTo: () => props.canResizeEventTo,
5641
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data),
5642
+ withBackgroundEvents: () => Boolean(props.withInteractiveBackgroundEvents)
5239
5643
  });
5240
5644
  const slotDragSelect = useSlotDragSelect({
5241
5645
  enabled: () => withSlotSelect.value,
@@ -5266,9 +5670,35 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5266
5670
  isSlotDragging: () => slotDragSelect.isDragging(),
5267
5671
  onDragEnd: () => {
5268
5672
  slotDropTarget.reset();
5673
+ dropDataTransfer.value = null;
5269
5674
  emit("eventDragEnd");
5270
5675
  }
5271
5676
  });
5677
+ const dropValid = computed(() => {
5678
+ const target = slotDropTarget.dropTarget.value;
5679
+ const interval = target && intervals.value[target.slotIndex];
5680
+ if (!target || !interval) return true;
5681
+ const start = `${target.date} ${interval.startTime}`;
5682
+ const event = dragState.draggedEvent.value;
5683
+ if (event) {
5684
+ const next = moveEventTo(event, start);
5685
+ return isEventPlacementAllowed({
5686
+ event,
5687
+ start: next.newStart,
5688
+ end: next.newEnd,
5689
+ events: expandedEvents.value,
5690
+ preventEventOverlap: props.preventEventOverlap
5691
+ }).allowed && props.canDropEvent?.({
5692
+ event,
5693
+ start: next.newStart,
5694
+ end: next.newEnd
5695
+ }) !== false;
5696
+ }
5697
+ return dropDataTransfer.value ? props.canDropExternalEvent?.({
5698
+ dataTransfer: dropDataTransfer.value,
5699
+ start
5700
+ }) !== false : true;
5701
+ });
5272
5702
  const clickEvent = (event, nativeEvent) => emit("eventClick", event, nativeEvent);
5273
5703
  const dragStart = (event) => {
5274
5704
  dragState.startEventDrag(event);
@@ -5322,15 +5752,80 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5322
5752
  const emitDrop = (nativeEvent, target) => {
5323
5753
  nativeEvent.preventDefault();
5324
5754
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
5325
- if (event) emit("eventDrop", moveEventTo(event, target));
5326
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", nativeEvent.dataTransfer, target);
5755
+ if (event) {
5756
+ const next = moveEventTo(event, target);
5757
+ const validation = isEventPlacementAllowed({
5758
+ event,
5759
+ start: next.newStart,
5760
+ end: next.newEnd,
5761
+ events: expandedEvents.value,
5762
+ preventEventOverlap: props.preventEventOverlap
5763
+ });
5764
+ if (validation.allowed && props.canDropEvent?.({
5765
+ event,
5766
+ start: next.newStart,
5767
+ end: next.newEnd
5768
+ }) !== false) emit("eventDrop", next);
5769
+ else emit("eventPlacementRejected", {
5770
+ action: "drop",
5771
+ event,
5772
+ start: next.newStart,
5773
+ end: next.newEnd,
5774
+ conflicts: validation.conflicts,
5775
+ reason: validation.allowed ? "rejected" : "overlap"
5776
+ });
5777
+ } else if (nativeEvent.dataTransfer) if (props.canDropExternalEvent?.({
5778
+ dataTransfer: nativeEvent.dataTransfer,
5779
+ start: target
5780
+ }) !== false) emit("externalEventDrop", nativeEvent.dataTransfer, target);
5781
+ else emit("eventPlacementRejected", {
5782
+ action: "external-drop",
5783
+ dataTransfer: nativeEvent.dataTransfer,
5784
+ start: target,
5785
+ conflicts: [],
5786
+ reason: "rejected"
5787
+ });
5327
5788
  };
5328
5789
  const emitAllDayDrop = (nativeEvent, date) => {
5329
5790
  nativeEvent.preventDefault();
5330
5791
  const dayKey = dayjs(date).format("YYYY-MM-DD");
5331
5792
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
5332
- if (event) emit("eventDrop", moveEventToAllDay(event, dayKey));
5333
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", nativeEvent.dataTransfer, `${dayKey} 00:00:00`);
5793
+ if (event) {
5794
+ const next = moveEventToAllDay(event, dayKey);
5795
+ const validation = isEventPlacementAllowed({
5796
+ event,
5797
+ start: next.newStart,
5798
+ end: next.newEnd,
5799
+ events: expandedEvents.value,
5800
+ preventEventOverlap: props.preventEventOverlap
5801
+ });
5802
+ if (validation.allowed && props.canDropEvent?.({
5803
+ event,
5804
+ start: next.newStart,
5805
+ end: next.newEnd
5806
+ }) !== false) emit("eventDrop", next);
5807
+ else emit("eventPlacementRejected", {
5808
+ action: "drop",
5809
+ event,
5810
+ start: next.newStart,
5811
+ end: next.newEnd,
5812
+ conflicts: validation.conflicts,
5813
+ reason: validation.allowed ? "rejected" : "overlap"
5814
+ });
5815
+ } else if (nativeEvent.dataTransfer) {
5816
+ const target = `${dayKey} 00:00:00`;
5817
+ if (props.canDropExternalEvent?.({
5818
+ dataTransfer: nativeEvent.dataTransfer,
5819
+ start: target
5820
+ }) !== false) emit("externalEventDrop", nativeEvent.dataTransfer, target);
5821
+ else emit("eventPlacementRejected", {
5822
+ action: "external-drop",
5823
+ dataTransfer: nativeEvent.dataTransfer,
5824
+ start: target,
5825
+ conflicts: [],
5826
+ reason: "rejected"
5827
+ });
5828
+ }
5334
5829
  };
5335
5830
  const dropInput = (date) => ({
5336
5831
  container: daySlotsContainers.get(date),
@@ -5341,10 +5836,14 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5341
5836
  startTime: props.startTime,
5342
5837
  endTime: props.endTime
5343
5838
  });
5344
- const handleDayDragOver = (nativeEvent, date) => slotDropTarget.dragOver(nativeEvent, dropInput(date));
5839
+ const handleDayDragOver = (nativeEvent, date) => {
5840
+ dropDataTransfer.value = nativeEvent.dataTransfer;
5841
+ slotDropTarget.dragOver(nativeEvent, dropInput(date));
5842
+ };
5345
5843
  const handleDayDragLeave = (nativeEvent, date) => slotDropTarget.dragLeave(nativeEvent, daySlotsContainers.get(date));
5346
5844
  const handleDayDrop = (nativeEvent, date) => {
5347
5845
  const target = slotDropTarget.drop(nativeEvent, dropInput(date));
5846
+ dropDataTransfer.value = null;
5348
5847
  if (target) emitDrop(nativeEvent, target.target);
5349
5848
  };
5350
5849
  const allDayEventStyle = (position) => ({
@@ -5353,12 +5852,17 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5353
5852
  width: `${position.width}%`,
5354
5853
  top: `${position.row * 22}px`
5355
5854
  });
5356
- const backgroundEventStyle = (position) => ({
5357
- top: `${position.top}%`,
5358
- bottom: `${100 - position.top - position.height}%`,
5359
- minHeight: "1px",
5360
- width: "100%"
5361
- });
5855
+ const backgroundEventStyle = (event, date) => {
5856
+ const resizePosition = eventResize.getResizePosition(event.id, dayjs(date).format("YYYY-MM-DD"));
5857
+ const top = resizePosition?.top ?? event.position.top;
5858
+ const height = resizePosition?.height ?? event.position.height;
5859
+ return {
5860
+ top: `${top}%`,
5861
+ bottom: `${100 - top - height}%`,
5862
+ minHeight: "1px",
5863
+ width: "100%"
5864
+ };
5865
+ };
5362
5866
  const regularEventStyle = (event) => {
5363
5867
  const resizePosition = eventResize.getResizePosition(event.id);
5364
5868
  const top = resizePosition?.top ?? event.position.top;
@@ -5369,7 +5873,9 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5369
5873
  bottom: `${100 - top - height}%`,
5370
5874
  minHeight: "1px",
5371
5875
  width: `${event.position.width}%`,
5372
- insetInlineStart: `${event.position.offset}%`
5876
+ insetInlineStart: `${event.position.offset}%`,
5877
+ "--event-z-index": event.position.column + 3,
5878
+ "--event-z-index-raised": event.position.overlaps + 3
5373
5879
  };
5374
5880
  };
5375
5881
  const startEventResize = (event, date, edge, pointerEvent) => {
@@ -5419,7 +5925,10 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5419
5925
  "next-control-props",
5420
5926
  "today-control-props",
5421
5927
  "view-select-props"
5422
- ])) : createCommentVNode("", true), createVNode(unref(Box), mergeProps({ "root-ref": setWeekRoot }, unref(getStyles)("weekViewRoot", { style: rootVars.value }), { mod: { "with-weekends": unref(props).withWeekendDays } }), {
5928
+ ])) : createCommentVNode("", true), createVNode(unref(Box), mergeProps({ "root-ref": setWeekRoot }, unref(getStyles)("weekViewRoot", { style: rootVars.value }), {
5929
+ mod: { "with-weekends": unref(props).withWeekendDays },
5930
+ "data-event-interaction": unref(eventResize).isResizing.value || void 0
5931
+ }), {
5423
5932
  default: withCtx(() => [createVNode(unref(ScrollArea).Autosize, mergeProps({ "scrollbar-size": 4 }, {
5424
5933
  ...unref(props).scrollAreaProps,
5425
5934
  ...unref(getStyles)("weekViewScrollArea")
@@ -5545,6 +6054,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5545
6054
  "data-drag-slot-index": withSlotSelect.value ? slotIndex : void 0,
5546
6055
  "data-drag-slot-group": withSlotSelect.value ? column.key : void 0,
5547
6056
  "data-drop-target": unref(slotDropTarget).isTarget(column.key, slotIndex) || void 0,
6057
+ "data-invalid": unref(slotDropTarget).isTarget(column.key, slotIndex) && !dropValid.value ? true : void 0,
5548
6058
  "data-drag-selected": unref(slotDragSelect).isSlotSelected(slotIndex, column.key) || void 0,
5549
6059
  "data-business-hours": businessHoursMods.value[dayIndex][slotIndex]["business-hours"] || void 0,
5550
6060
  "data-non-business-hours": businessHoursMods.value[dayIndex][slotIndex]["non-business-hours"] || void 0,
@@ -5561,6 +6071,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5561
6071
  "data-drag-slot-index",
5562
6072
  "data-drag-slot-group",
5563
6073
  "data-drop-target",
6074
+ "data-invalid",
5564
6075
  "data-drag-selected",
5565
6076
  "data-business-hours",
5566
6077
  "data-non-business-hours",
@@ -5581,12 +6092,20 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5581
6092
  ...eventRenderers.value,
5582
6093
  ...unref(staticStyles)("weekViewBackgroundEvent")
5583
6094
  }, {
5584
- style: backgroundEventStyle(event.position),
5585
- onEventClick: clickEvent
6095
+ style: backgroundEventStyle(event, column.date),
6096
+ "with-resize": unref(eventResize).isResizableEvent(event) && !event.position.allDay,
6097
+ "is-resizing": unref(eventResize).getResizePosition(event.id, column.date) !== null,
6098
+ "resize-handle-props": unref(staticStyles)("weekViewBackgroundEventResizeHandle"),
6099
+ onEventClick: clickResizableEvent,
6100
+ onResizeStart: (edge, pointerEvent) => startEventResize(event, column.date, edge, pointerEvent)
5586
6101
  }), null, 16, [
5587
6102
  "event",
5588
6103
  "interactive",
5589
- "style"
6104
+ "style",
6105
+ "with-resize",
6106
+ "is-resizing",
6107
+ "resize-handle-props",
6108
+ "onResizeStart"
5590
6109
  ]);
5591
6110
  }), 128)),
5592
6111
  (openBlock(true), createElementBlock(Fragment, null, renderList(grouped.value.regularEvents[column.date] || [], (event) => {
@@ -5595,6 +6114,10 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5595
6114
  event,
5596
6115
  "auto-size": "",
5597
6116
  mode: unref(props).mode,
6117
+ mod: {
6118
+ cascade: unref(props).eventOverlapMode === "cascade",
6119
+ invalid: unref(eventResize).getResizePosition(event.id) !== null && !unref(eventResize).resizeValid.value
6120
+ },
5598
6121
  style: regularEventStyle(event),
5599
6122
  draggable: isDraggableEvent(event),
5600
6123
  "with-resize": unref(eventResize).isResizableEvent(event),
@@ -5610,6 +6133,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5610
6133
  }), null, 16, [
5611
6134
  "event",
5612
6135
  "mode",
6136
+ "mod",
5613
6137
  "style",
5614
6138
  "draggable",
5615
6139
  "with-resize",
@@ -5627,7 +6151,7 @@ var WeekView = factory(/* @__PURE__ */ defineComponent({
5627
6151
  _: 1
5628
6152
  }, 16, ["viewport-props"])]),
5629
6153
  _: 1
5630
- }, 16, ["mod"])]),
6154
+ }, 16, ["mod", "data-event-interaction"])]),
5631
6155
  _: 1
5632
6156
  }, 16, ["mod"]);
5633
6157
  };
@@ -6052,6 +6576,22 @@ var Schedule = factory(/* @__PURE__ */ defineComponent({
6052
6576
  type: Function,
6053
6577
  default: void 0
6054
6578
  },
6579
+ canDropEvent: {
6580
+ type: Function,
6581
+ default: void 0
6582
+ },
6583
+ canDropExternalEvent: {
6584
+ type: Function,
6585
+ default: void 0
6586
+ },
6587
+ canResizeEventTo: {
6588
+ type: Function,
6589
+ default: void 0
6590
+ },
6591
+ preventEventOverlap: {
6592
+ type: [Boolean, Function],
6593
+ default: void 0
6594
+ },
6055
6595
  withInteractiveBackgroundEvents: {
6056
6596
  type: Boolean,
6057
6597
  default: void 0
@@ -6083,7 +6623,8 @@ var Schedule = factory(/* @__PURE__ */ defineComponent({
6083
6623
  "monthClick",
6084
6624
  "slotDragEnd",
6085
6625
  "externalEventDrop",
6086
- "eventResize"
6626
+ "eventResize",
6627
+ "eventPlacementRejected"
6087
6628
  ],
6088
6629
  setup(__props, { emit: __emit }) {
6089
6630
  const rawProps = __props;
@@ -6142,6 +6683,10 @@ var Schedule = factory(/* @__PURE__ */ defineComponent({
6142
6683
  withExternalEventDrop: props.withExternalEventDrop,
6143
6684
  withEventResize: props.withEventResize,
6144
6685
  canResizeEvent: props.canResizeEvent,
6686
+ canDropEvent: props.canDropEvent,
6687
+ canDropExternalEvent: props.canDropExternalEvent,
6688
+ canResizeEventTo: props.canResizeEventTo,
6689
+ preventEventOverlap: props.preventEventOverlap,
6145
6690
  withInteractiveBackgroundEvents: props.mode === "static" ? false : props.withInteractiveBackgroundEvents,
6146
6691
  recurrenceExpansionLimit: props.recurrenceExpansionLimit,
6147
6692
  ...eventRenderers.value,
@@ -6165,7 +6710,8 @@ var Schedule = factory(/* @__PURE__ */ defineComponent({
6165
6710
  onMonthClick: (month) => emit("monthClick", month),
6166
6711
  onSlotDragEnd: (rangeStart, rangeEnd) => emit("slotDragEnd", rangeStart, rangeEnd),
6167
6712
  onExternalEventDrop: (dataTransfer, dateTime) => emit("externalEventDrop", dataTransfer, dateTime),
6168
- onEventResize: (data) => emit("eventResize", data)
6713
+ onEventResize: (data) => emit("eventResize", data),
6714
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data)
6169
6715
  };
6170
6716
  const views = {
6171
6717
  day: DayView,
@@ -6235,6 +6781,7 @@ var Schedule = factory(/* @__PURE__ */ defineComponent({
6235
6781
  //#region src/hooks/use-horizontal-event-resize.ts
6236
6782
  function useHorizontalEventResize(input) {
6237
6783
  const state = shallowRef(null);
6784
+ const resizeValid = ref(true);
6238
6785
  let justResized = false;
6239
6786
  let savedUserSelect = "";
6240
6787
  const metrics = () => {
@@ -6279,6 +6826,18 @@ function useHorizontalEventResize(input) {
6279
6826
  current.currentWidth = right - current.currentLeft;
6280
6827
  }
6281
6828
  state.value = { ...current };
6829
+ const start = current.edge === "start" ? toDateTime(current.currentLeft, current.eventDate) : current.originalStart;
6830
+ const end = current.edge === "end" ? toDateTime(current.currentLeft + current.currentWidth, current.eventDate) : current.originalEnd;
6831
+ resizeValid.value = validateEventResize({
6832
+ event: current.event,
6833
+ start,
6834
+ end,
6835
+ edge: current.edge,
6836
+ events: input.events?.() ?? [],
6837
+ preventEventOverlap: input.preventEventOverlap?.(),
6838
+ canResizeEventTo: input.canResizeEventTo?.(),
6839
+ resourceId: current.event.resourceId
6840
+ }).valid;
6282
6841
  });
6283
6842
  const trackPointer = (event) => move(event.clientX);
6284
6843
  const cleanup = () => {
@@ -6290,13 +6849,37 @@ function useHorizontalEventResize(input) {
6290
6849
  const finish = () => {
6291
6850
  move.cancel();
6292
6851
  const current = state.value;
6293
- if (current && (current.currentLeft !== current.originalLeft || current.currentWidth !== current.originalWidth)) input.onEventResize({
6294
- eventId: current.event.id,
6295
- newStart: current.edge === "start" ? toDateTime(current.currentLeft, current.eventDate) : current.originalStart,
6296
- newEnd: current.edge === "end" ? toDateTime(current.currentLeft + current.currentWidth, current.eventDate) : current.originalEnd,
6297
- event: current.event
6298
- });
6852
+ if (current && (current.currentLeft !== current.originalLeft || current.currentWidth !== current.originalWidth)) {
6853
+ const start = current.edge === "start" ? toDateTime(current.currentLeft, current.eventDate) : current.originalStart;
6854
+ const end = current.edge === "end" ? toDateTime(current.currentLeft + current.currentWidth, current.eventDate) : current.originalEnd;
6855
+ const validation = validateEventResize({
6856
+ event: current.event,
6857
+ start,
6858
+ end,
6859
+ edge: current.edge,
6860
+ events: input.events?.() ?? [],
6861
+ preventEventOverlap: input.preventEventOverlap?.(),
6862
+ canResizeEventTo: input.canResizeEventTo?.(),
6863
+ resourceId: current.event.resourceId
6864
+ });
6865
+ if (validation.valid) input.onEventResize({
6866
+ eventId: current.event.id,
6867
+ newStart: start,
6868
+ newEnd: end,
6869
+ event: current.event
6870
+ });
6871
+ else input.onEventPlacementRejected?.({
6872
+ action: "resize",
6873
+ event: current.event,
6874
+ start,
6875
+ end,
6876
+ edge: current.edge,
6877
+ conflicts: validation.conflicts,
6878
+ reason: validation.reason
6879
+ });
6880
+ }
6299
6881
  state.value = null;
6882
+ resizeValid.value = true;
6300
6883
  cleanup();
6301
6884
  justResized = true;
6302
6885
  requestAnimationFrame(() => justResized = false);
@@ -6314,6 +6897,7 @@ function useHorizontalEventResize(input) {
6314
6897
  dayIndex: params.dayIndex ?? 0,
6315
6898
  dayCount: params.dayCount ?? 1
6316
6899
  };
6900
+ resizeValid.value = true;
6317
6901
  savedUserSelect = document.body.style.userSelect;
6318
6902
  document.body.style.userSelect = "none";
6319
6903
  document.addEventListener("pointermove", trackPointer);
@@ -6322,35 +6906,20 @@ function useHorizontalEventResize(input) {
6322
6906
  onBeforeUnmount(cleanup);
6323
6907
  return {
6324
6908
  state,
6909
+ resizeValid,
6910
+ get resizingEdge() {
6911
+ return state.value?.edge ?? null;
6912
+ },
6325
6913
  handleResizeStart,
6326
- getResizePosition: (id) => state.value?.event.id === id ? {
6914
+ getResizePosition: (id, eventDate) => state.value?.event.id === id && (eventDate === void 0 || state.value.eventDate === eventDate) ? {
6327
6915
  left: state.value.currentLeft,
6328
6916
  width: state.value.currentWidth
6329
6917
  } : null,
6330
- isResizableEvent: (event) => input.enabled() && input.mode() !== "static" && event.display !== "background" && (input.canResizeEvent()?.(event) ?? true),
6918
+ isResizableEvent: (event) => input.enabled() && input.mode() !== "static" && (event.display !== "background" || input.withBackgroundEvents?.() === true) && (input.canResizeEvent()?.(event) ?? true),
6331
6919
  wasResizing: () => justResized
6332
6920
  };
6333
6921
  }
6334
6922
  //#endregion
6335
- //#region src/components/ResourcesDayView/get-overlap-clusters/get-overlap-clusters.ts
6336
- function getOverlapClusters(events) {
6337
- const sorted = [...events].sort((a, b) => a.position.top - b.position.top);
6338
- const clusters = [];
6339
- let current = [];
6340
- let end = -1;
6341
- sorted.forEach((event) => {
6342
- if (current.length && event.position.top >= end) {
6343
- clusters.push(current);
6344
- current = [];
6345
- end = -1;
6346
- }
6347
- current.push(event);
6348
- end = Math.max(end, event.position.top + event.position.height);
6349
- });
6350
- if (current.length) clusters.push(current);
6351
- return clusters;
6352
- }
6353
- //#endregion
6354
6923
  //#region src/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.ts
6355
6924
  function getResourcesDayViewEvents({ events, resources, date, startTime, endTime, intervalMinutes }) {
6356
6925
  const result = {
@@ -6448,27 +7017,27 @@ function getResourcesDayViewEvents({ events, resources, date, startTime, endTime
6448
7017
  return result;
6449
7018
  }
6450
7019
  var ResourcesDayView_module_default = {
6451
- resourcesDayView: "_resourcesDayView_wmj51_1",
6452
- resourcesDayViewRoot: "_resourcesDayViewRoot_wmj51_22",
6453
- resourcesDayViewScrollArea: "_resourcesDayViewScrollArea_wmj51_30",
6454
- resourcesDayViewInner: "_resourcesDayViewInner_wmj51_39",
6455
- resourcesDayViewTimeLabelsRow: "_resourcesDayViewTimeLabelsRow_wmj51_44",
6456
- resourcesDayViewCorner: "_resourcesDayViewCorner_wmj51_57",
6457
- resourcesDayViewTimeLabel: "_resourcesDayViewTimeLabel_wmj51_44",
6458
- resourcesDayViewRow: "_resourcesDayViewRow_wmj51_96",
6459
- resourcesDayViewResourceLabel: "_resourcesDayViewResourceLabel_wmj51_100",
6460
- resourcesDayViewGroupColumn: "_resourcesDayViewGroupColumn_wmj51_124",
6461
- resourcesDayViewGroupColumnEmpty: "_resourcesDayViewGroupColumnEmpty_wmj51_125",
6462
- resourcesDayViewRowSlots: "_resourcesDayViewRowSlots_wmj51_153",
6463
- resourcesDayViewRowSlot: "_resourcesDayViewRowSlot_wmj51_153",
6464
- resourcesDayViewCurrentTimeIndicator: "_resourcesDayViewCurrentTimeIndicator_wmj51_231",
6465
- resourcesDayViewCurrentTimeIndicatorLine: "_resourcesDayViewCurrentTimeIndicatorLine_wmj51_243",
6466
- resourcesDayViewCurrentTimeIndicatorThumb: "_resourcesDayViewCurrentTimeIndicatorThumb_wmj51_249",
6467
- resourcesDayViewCurrentTimeIndicatorTimeBubble: "_resourcesDayViewCurrentTimeIndicatorTimeBubble_wmj51_259",
6468
- resourcesDayViewBackgroundEvent: "_resourcesDayViewBackgroundEvent_wmj51_278",
6469
- resourcesDayViewAllDayEvent: "_resourcesDayViewAllDayEvent_wmj51_300",
6470
- resourcesDayViewEventWrapper: "_resourcesDayViewEventWrapper_wmj51_306",
6471
- resourcesDayViewResizeHandle: "_resourcesDayViewResizeHandle_wmj51_310"
7020
+ resourcesDayView: "_resourcesDayView_1ak2d_1",
7021
+ resourcesDayViewRoot: "_resourcesDayViewRoot_1ak2d_22",
7022
+ resourcesDayViewScrollArea: "_resourcesDayViewScrollArea_1ak2d_30",
7023
+ resourcesDayViewInner: "_resourcesDayViewInner_1ak2d_39",
7024
+ resourcesDayViewTimeLabelsRow: "_resourcesDayViewTimeLabelsRow_1ak2d_44",
7025
+ resourcesDayViewCorner: "_resourcesDayViewCorner_1ak2d_57",
7026
+ resourcesDayViewTimeLabel: "_resourcesDayViewTimeLabel_1ak2d_44",
7027
+ resourcesDayViewRow: "_resourcesDayViewRow_1ak2d_96",
7028
+ resourcesDayViewResourceLabel: "_resourcesDayViewResourceLabel_1ak2d_100",
7029
+ resourcesDayViewGroupColumn: "_resourcesDayViewGroupColumn_1ak2d_124",
7030
+ resourcesDayViewGroupColumnEmpty: "_resourcesDayViewGroupColumnEmpty_1ak2d_125",
7031
+ resourcesDayViewRowSlots: "_resourcesDayViewRowSlots_1ak2d_153",
7032
+ resourcesDayViewRowSlot: "_resourcesDayViewRowSlot_1ak2d_153",
7033
+ resourcesDayViewCurrentTimeIndicator: "_resourcesDayViewCurrentTimeIndicator_1ak2d_240",
7034
+ resourcesDayViewCurrentTimeIndicatorLine: "_resourcesDayViewCurrentTimeIndicatorLine_1ak2d_252",
7035
+ resourcesDayViewCurrentTimeIndicatorThumb: "_resourcesDayViewCurrentTimeIndicatorThumb_1ak2d_258",
7036
+ resourcesDayViewCurrentTimeIndicatorTimeBubble: "_resourcesDayViewCurrentTimeIndicatorTimeBubble_1ak2d_268",
7037
+ resourcesDayViewBackgroundEvent: "_resourcesDayViewBackgroundEvent_1ak2d_287",
7038
+ resourcesDayViewAllDayEvent: "_resourcesDayViewAllDayEvent_1ak2d_315",
7039
+ resourcesDayViewEventWrapper: "_resourcesDayViewEventWrapper_1ak2d_321",
7040
+ resourcesDayViewResizeHandle: "_resourcesDayViewResizeHandle_1ak2d_325"
6472
7041
  };
6473
7042
  //#endregion
6474
7043
  //#region src/components/ResourcesDayView/ResourcesDayView.vue?vue&type=script&setup=true&lang.ts
@@ -6593,6 +7162,10 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6593
7162
  type: Function,
6594
7163
  default: void 0
6595
7164
  },
7165
+ canDropEvent: {},
7166
+ canDropExternalEvent: {},
7167
+ canResizeEventTo: {},
7168
+ preventEventOverlap: { type: [Boolean, Function] },
6596
7169
  recurrenceExpansionLimit: { default: void 0 },
6597
7170
  maxEventsPerTimeSlot: { default: void 0 },
6598
7171
  moreEventsProps: { default: void 0 },
@@ -6611,7 +7184,8 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6611
7184
  "timeSlotClick",
6612
7185
  "slotDragEnd",
6613
7186
  "externalEventDrop",
6614
- "eventResize"
7187
+ "eventResize",
7188
+ "eventPlacementRejected"
6615
7189
  ],
6616
7190
  setup(__props, { emit: __emit }) {
6617
7191
  const rawProps = __props;
@@ -6655,6 +7229,7 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6655
7229
  rootElement.value = node instanceof HTMLElement ? node : null;
6656
7230
  };
6657
7231
  const dropTarget = shallowRef(null);
7232
+ const dropValid = ref(true);
6658
7233
  const scrolled = ref(false);
6659
7234
  const scrolledX = ref(false);
6660
7235
  const isStatic = computed(() => props.mode === "static");
@@ -6730,7 +7305,12 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6730
7305
  intervalMinutes: () => props.intervalMinutes,
6731
7306
  resizeIntervalMinutes: () => props.eventResizeInterval,
6732
7307
  onEventResize: (data) => emit("eventResize", data),
6733
- canResizeEvent: () => props.canResizeEvent
7308
+ canResizeEvent: () => props.canResizeEvent,
7309
+ events: () => expandedEvents.value,
7310
+ preventEventOverlap: () => props.preventEventOverlap,
7311
+ canResizeEventTo: () => props.canResizeEventTo,
7312
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data),
7313
+ withBackgroundEvents: () => Boolean(props.withInteractiveBackgroundEvents)
6734
7314
  });
6735
7315
  onMounted(async () => {
6736
7316
  if (!props.startScrollTime) return;
@@ -6763,15 +7343,51 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6763
7343
  if (!intervals.value[slotIndex]) return;
6764
7344
  const target = getSnappedDropTarget(nativeEvent, slotIndex);
6765
7345
  const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
6766
- if (event) emit("eventDrop", {
6767
- ...moveEventTo(event, target),
7346
+ if (event) {
7347
+ const next = moveEventTo(event, target);
7348
+ const validation = isEventPlacementAllowed({
7349
+ event,
7350
+ start: next.newStart,
7351
+ end: next.newEnd,
7352
+ events: expandedEvents.value,
7353
+ preventEventOverlap: props.preventEventOverlap,
7354
+ resourceId
7355
+ });
7356
+ if (validation.allowed && props.canDropEvent?.({
7357
+ event,
7358
+ start: next.newStart,
7359
+ end: next.newEnd,
7360
+ resourceId
7361
+ }) !== false) emit("eventDrop", {
7362
+ ...next,
7363
+ resourceId
7364
+ });
7365
+ else emit("eventPlacementRejected", {
7366
+ action: "drop",
7367
+ event,
7368
+ start: next.newStart,
7369
+ end: next.newEnd,
7370
+ resourceId,
7371
+ conflicts: validation.conflicts,
7372
+ reason: validation.allowed ? "rejected" : "overlap"
7373
+ });
7374
+ } else if (nativeEvent.dataTransfer) if (props.canDropExternalEvent?.({
7375
+ dataTransfer: nativeEvent.dataTransfer,
7376
+ start: target,
6768
7377
  resourceId
6769
- });
6770
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", {
7378
+ }) !== false) emit("externalEventDrop", {
6771
7379
  dataTransfer: nativeEvent.dataTransfer,
6772
7380
  dropDateTime: target,
6773
7381
  resourceId
6774
7382
  });
7383
+ else emit("eventPlacementRejected", {
7384
+ action: "external-drop",
7385
+ dataTransfer: nativeEvent.dataTransfer,
7386
+ start: target,
7387
+ resourceId,
7388
+ conflicts: [],
7389
+ reason: "rejected"
7390
+ });
6775
7391
  };
6776
7392
  const getSnappedDropTarget = (nativeEvent, slotIndex) => {
6777
7393
  const interval = intervals.value[slotIndex];
@@ -6802,6 +7418,28 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6802
7418
  */
6803
7419
  const resolveDropTarget = rafThrottle((nativeEvent, resourceId, resourceIndex) => {
6804
7420
  const slotIndex = getSlotIndexAtPoint(nativeEvent, resourceIndex);
7421
+ const target = slotIndex < 0 ? null : getSnappedDropTarget(nativeEvent, slotIndex);
7422
+ const event = dragState.draggedEvent.value;
7423
+ if (target && event) {
7424
+ const next = moveEventTo(event, target);
7425
+ dropValid.value = isEventPlacementAllowed({
7426
+ event,
7427
+ start: next.newStart,
7428
+ end: next.newEnd,
7429
+ events: expandedEvents.value,
7430
+ preventEventOverlap: props.preventEventOverlap,
7431
+ resourceId
7432
+ }).allowed && props.canDropEvent?.({
7433
+ event,
7434
+ start: next.newStart,
7435
+ end: next.newEnd,
7436
+ resourceId
7437
+ }) !== false;
7438
+ } else if (target && nativeEvent.dataTransfer) dropValid.value = props.canDropExternalEvent?.({
7439
+ dataTransfer: nativeEvent.dataTransfer,
7440
+ start: target,
7441
+ resourceId
7442
+ }) !== false;
6805
7443
  setDropTarget(slotIndex < 0 ? null : {
6806
7444
  resourceId,
6807
7445
  slotIndex
@@ -6829,6 +7467,9 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6829
7467
  const groupInfo = (resourceIndex) => hasGroups.value ? ordered.value.resourceGroupMap[resourceIndex] : void 0;
6830
7468
  const backgroundEvents = (resourceId) => [...positioned.value.backgroundTimedEvents[resourceId] || [], ...positioned.value.backgroundAllDayEvents[resourceId] || []];
6831
7469
  const backgroundEventStyle = (event) => {
7470
+ const resizePosition = resize.getResizePosition(event.id);
7471
+ const left = resizePosition?.left ?? event.position.top;
7472
+ const width = resizePosition?.width ?? event.position.height;
6832
7473
  const colors = theme.value.variantColorResolver({
6833
7474
  color: event.color || theme.value.primaryColor,
6834
7475
  theme: theme.value,
@@ -6836,8 +7477,8 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
6836
7477
  autoContrast: true
6837
7478
  });
6838
7479
  return {
6839
- left: `${event.position.top}%`,
6840
- right: `${100 - event.position.top - event.position.height}%`,
7480
+ left: `${left}%`,
7481
+ right: `${100 - left - width}%`,
6841
7482
  minWidth: "1px",
6842
7483
  top: 0,
6843
7484
  height: "100%",
@@ -7055,11 +7696,22 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
7055
7696
  ...unref(getStyles)("resourcesDayViewBackgroundEvent")
7056
7697
  }, {
7057
7698
  style: backgroundEventStyle(event),
7058
- onEventClick: clickEvent
7699
+ "with-resize": unref(resize).isResizableEvent(event) && !event.position.allDay,
7700
+ "resize-axis": "horizontal",
7701
+ "is-resizing": unref(resize).getResizePosition(event.id) !== null,
7702
+ "active-resize-edge": unref(resize).resizingEdge,
7703
+ "resize-handle-props": unref(staticStyles)("resourcesDayViewResizeHandle"),
7704
+ onEventClick: clickEvent,
7705
+ onResizeStart: (edge, pointerEvent) => startResize(event, resourceIndex, edge, pointerEvent)
7059
7706
  }), null, 16, [
7060
7707
  "event",
7061
7708
  "interactive",
7062
- "style"
7709
+ "style",
7710
+ "with-resize",
7711
+ "is-resizing",
7712
+ "active-resize-edge",
7713
+ "resize-handle-props",
7714
+ "onResizeStart"
7063
7715
  ])]);
7064
7716
  }), 128)),
7065
7717
  (openBlock(true), createElementBlock(Fragment, null, renderList(allDayEvents(resource.id), (event, index) => {
@@ -7101,7 +7753,8 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
7101
7753
  style: {
7102
7754
  width: "100%",
7103
7755
  height: "100%"
7104
- }
7756
+ },
7757
+ mod: { invalid: unref(resize).getResizePosition(event.id) !== null && !unref(resize).resizeValid.value }
7105
7758
  }, { ref_for: true }, {
7106
7759
  ...eventRenderers.value,
7107
7760
  ...stylesApi.value
@@ -7114,6 +7767,7 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
7114
7767
  "radius",
7115
7768
  "mode",
7116
7769
  "draggable",
7770
+ "mod",
7117
7771
  "onClick"
7118
7772
  ]), unref(resize).isResizableEvent(event) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, renderList(["start", "end"], (edge) => {
7119
7773
  return createElementVNode("div", mergeProps({ key: edge }, { ref_for: true }, unref(staticStyles)("resourcesDayViewResizeHandle"), {
@@ -7159,6 +7813,7 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
7159
7813
  "data-business-hours": businessHoursMods.value[slotIndex]["business-hours"] || void 0,
7160
7814
  "data-non-business-hours": businessHoursMods.value[slotIndex]["non-business-hours"] || void 0,
7161
7815
  "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.slotIndex === slotIndex || void 0,
7816
+ "data-invalid": dropTarget.value?.resourceId === resource.id && dropTarget.value.slotIndex === slotIndex && !dropValid.value || void 0,
7162
7817
  "data-drag-selected": unref(slotSelect).isSlotSelected(slotIndex, String(resource.id)) || void 0,
7163
7818
  "data-static": isStatic.value || void 0,
7164
7819
  "data-drag-slot-index": unref(props).withDragSlotSelect ? slotIndex : void 0,
@@ -7189,6 +7844,7 @@ var ResourcesDayView = factory(/* @__PURE__ */ defineComponent({
7189
7844
  "data-business-hours",
7190
7845
  "data-non-business-hours",
7191
7846
  "data-drop-target",
7847
+ "data-invalid",
7192
7848
  "data-drag-selected",
7193
7849
  "data-static",
7194
7850
  "data-drag-slot-index",
@@ -7308,31 +7964,31 @@ function getResourcesWeekViewEvents({ events, resources, weekdays, startTime, en
7308
7964
  };
7309
7965
  }
7310
7966
  var ResourcesWeekView_module_default = {
7311
- resourcesWeekView: "_resourcesWeekView_1komm_1",
7312
- resourcesWeekViewRoot: "_resourcesWeekViewRoot_1komm_19",
7313
- resourcesWeekViewScrollArea: "_resourcesWeekViewScrollArea_1komm_26",
7314
- resourcesWeekViewInner: "_resourcesWeekViewInner_1komm_34",
7315
- resourcesWeekViewHeaderRows: "_resourcesWeekViewHeaderRows_1komm_39",
7316
- resourcesWeekViewCorner: "_resourcesWeekViewCorner_1komm_48",
7317
- resourcesWeekViewHeaderContent: "_resourcesWeekViewHeaderContent_1komm_63",
7318
- resourcesWeekViewDayLabelsRow: "_resourcesWeekViewDayLabelsRow_1komm_67",
7319
- resourcesWeekViewDayLabel: "_resourcesWeekViewDayLabel_1komm_67",
7320
- resourcesWeekViewTimeLabelsRow: "_resourcesWeekViewTimeLabelsRow_1komm_94",
7321
- resourcesWeekViewTimeLabel: "_resourcesWeekViewTimeLabel_1komm_94",
7322
- resourcesWeekViewRow: "_resourcesWeekViewRow_1komm_121",
7323
- resourcesWeekViewResourceLabel: "_resourcesWeekViewResourceLabel_1komm_125",
7324
- resourcesWeekViewGroupColumn: "_resourcesWeekViewGroupColumn_1komm_149",
7325
- resourcesWeekViewGroupColumnEmpty: "_resourcesWeekViewGroupColumnEmpty_1komm_150",
7326
- resourcesWeekViewRowSlots: "_resourcesWeekViewRowSlots_1komm_178",
7327
- resourcesWeekViewRowSlot: "_resourcesWeekViewRowSlot_1komm_178",
7328
- resourcesWeekViewBackgroundEvent: "_resourcesWeekViewBackgroundEvent_1komm_250",
7329
- resourcesWeekViewAllDayEvent: "_resourcesWeekViewAllDayEvent_1komm_272",
7330
- resourcesWeekViewEventWrapper: "_resourcesWeekViewEventWrapper_1komm_277",
7331
- resourcesWeekViewResizeHandle: "_resourcesWeekViewResizeHandle_1komm_281",
7332
- resourcesWeekViewCurrentTimeIndicator: "_resourcesWeekViewCurrentTimeIndicator_1komm_322",
7333
- resourcesWeekViewCurrentTimeIndicatorLine: "_resourcesWeekViewCurrentTimeIndicatorLine_1komm_334",
7334
- resourcesWeekViewCurrentTimeIndicatorThumb: "_resourcesWeekViewCurrentTimeIndicatorThumb_1komm_340",
7335
- resourcesWeekViewCurrentTimeIndicatorTimeBubble: "_resourcesWeekViewCurrentTimeIndicatorTimeBubble_1komm_350"
7967
+ resourcesWeekView: "_resourcesWeekView_1g2tz_1",
7968
+ resourcesWeekViewRoot: "_resourcesWeekViewRoot_1g2tz_19",
7969
+ resourcesWeekViewScrollArea: "_resourcesWeekViewScrollArea_1g2tz_26",
7970
+ resourcesWeekViewInner: "_resourcesWeekViewInner_1g2tz_34",
7971
+ resourcesWeekViewHeaderRows: "_resourcesWeekViewHeaderRows_1g2tz_39",
7972
+ resourcesWeekViewCorner: "_resourcesWeekViewCorner_1g2tz_48",
7973
+ resourcesWeekViewHeaderContent: "_resourcesWeekViewHeaderContent_1g2tz_63",
7974
+ resourcesWeekViewDayLabelsRow: "_resourcesWeekViewDayLabelsRow_1g2tz_67",
7975
+ resourcesWeekViewDayLabel: "_resourcesWeekViewDayLabel_1g2tz_67",
7976
+ resourcesWeekViewTimeLabelsRow: "_resourcesWeekViewTimeLabelsRow_1g2tz_94",
7977
+ resourcesWeekViewTimeLabel: "_resourcesWeekViewTimeLabel_1g2tz_94",
7978
+ resourcesWeekViewRow: "_resourcesWeekViewRow_1g2tz_121",
7979
+ resourcesWeekViewResourceLabel: "_resourcesWeekViewResourceLabel_1g2tz_125",
7980
+ resourcesWeekViewGroupColumn: "_resourcesWeekViewGroupColumn_1g2tz_149",
7981
+ resourcesWeekViewGroupColumnEmpty: "_resourcesWeekViewGroupColumnEmpty_1g2tz_150",
7982
+ resourcesWeekViewRowSlots: "_resourcesWeekViewRowSlots_1g2tz_178",
7983
+ resourcesWeekViewRowSlot: "_resourcesWeekViewRowSlot_1g2tz_178",
7984
+ resourcesWeekViewBackgroundEvent: "_resourcesWeekViewBackgroundEvent_1g2tz_259",
7985
+ resourcesWeekViewAllDayEvent: "_resourcesWeekViewAllDayEvent_1g2tz_287",
7986
+ resourcesWeekViewEventWrapper: "_resourcesWeekViewEventWrapper_1g2tz_292",
7987
+ resourcesWeekViewResizeHandle: "_resourcesWeekViewResizeHandle_1g2tz_296",
7988
+ resourcesWeekViewCurrentTimeIndicator: "_resourcesWeekViewCurrentTimeIndicator_1g2tz_373",
7989
+ resourcesWeekViewCurrentTimeIndicatorLine: "_resourcesWeekViewCurrentTimeIndicatorLine_1g2tz_385",
7990
+ resourcesWeekViewCurrentTimeIndicatorThumb: "_resourcesWeekViewCurrentTimeIndicatorThumb_1g2tz_391",
7991
+ resourcesWeekViewCurrentTimeIndicatorTimeBubble: "_resourcesWeekViewCurrentTimeIndicatorTimeBubble_1g2tz_401"
7336
7992
  };
7337
7993
  //#endregion
7338
7994
  //#region src/components/ResourcesWeekView/ResourcesWeekView.vue?vue&type=script&setup=true&lang.ts
@@ -7466,6 +8122,10 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7466
8122
  type: Function,
7467
8123
  default: void 0
7468
8124
  },
8125
+ canDropEvent: {},
8126
+ canDropExternalEvent: {},
8127
+ canResizeEventTo: {},
8128
+ preventEventOverlap: { type: [Boolean, Function] },
7469
8129
  recurrenceExpansionLimit: { default: void 0 },
7470
8130
  maxEventsPerTimeSlot: { default: void 0 },
7471
8131
  moreEventsProps: { default: void 0 },
@@ -7498,7 +8158,8 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7498
8158
  "timeSlotClick",
7499
8159
  "slotDragEnd",
7500
8160
  "externalEventDrop",
7501
- "eventResize"
8161
+ "eventResize",
8162
+ "eventPlacementRejected"
7502
8163
  ],
7503
8164
  setup(__props, { emit: __emit }) {
7504
8165
  const rawProps = __props;
@@ -7542,6 +8203,7 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7542
8203
  rootElement.value = node instanceof HTMLElement ? node : null;
7543
8204
  };
7544
8205
  const dropTarget = shallowRef(null);
8206
+ const dropValid = ref(true);
7545
8207
  const scrolledX = ref(false);
7546
8208
  const isStatic = computed(() => props.mode === "static");
7547
8209
  const intervals = computed(() => getDayTimeIntervals({
@@ -7629,7 +8291,12 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7629
8291
  intervalMinutes: () => props.intervalMinutes,
7630
8292
  resizeIntervalMinutes: () => props.eventResizeInterval,
7631
8293
  onEventResize: (data) => emit("eventResize", data),
7632
- canResizeEvent: () => props.canResizeEvent
8294
+ canResizeEvent: () => props.canResizeEvent,
8295
+ events: () => props.events ?? [],
8296
+ preventEventOverlap: () => props.preventEventOverlap,
8297
+ canResizeEventTo: () => props.canResizeEventTo,
8298
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data),
8299
+ withBackgroundEvents: () => Boolean(props.withInteractiveBackgroundEvents)
7633
8300
  });
7634
8301
  onMounted(async () => {
7635
8302
  if (!props.startScrollDateTime) return;
@@ -7671,15 +8338,51 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7671
8338
  if (!day || !interval) return;
7672
8339
  const target = getSnappedDropTarget(nativeEvent, day, flatIndex, interval.startTime);
7673
8340
  const event = getDropEvent(props.events, nativeEvent.dataTransfer);
7674
- if (event) emit("eventDrop", {
7675
- ...moveEventTo(event, target),
8341
+ if (event) {
8342
+ const next = moveEventTo(event, target);
8343
+ const validation = isEventPlacementAllowed({
8344
+ event,
8345
+ start: next.newStart,
8346
+ end: next.newEnd,
8347
+ events: props.events ?? [],
8348
+ preventEventOverlap: props.preventEventOverlap,
8349
+ resourceId
8350
+ });
8351
+ if (validation.allowed && props.canDropEvent?.({
8352
+ event,
8353
+ start: next.newStart,
8354
+ end: next.newEnd,
8355
+ resourceId
8356
+ }) !== false) emit("eventDrop", {
8357
+ ...next,
8358
+ resourceId
8359
+ });
8360
+ else emit("eventPlacementRejected", {
8361
+ action: "drop",
8362
+ event,
8363
+ start: next.newStart,
8364
+ end: next.newEnd,
8365
+ resourceId,
8366
+ conflicts: validation.conflicts,
8367
+ reason: validation.allowed ? "rejected" : "overlap"
8368
+ });
8369
+ } else if (nativeEvent.dataTransfer) if (props.canDropExternalEvent?.({
8370
+ dataTransfer: nativeEvent.dataTransfer,
8371
+ start: target,
7676
8372
  resourceId
7677
- });
7678
- else if (nativeEvent.dataTransfer) emit("externalEventDrop", {
8373
+ }) !== false) emit("externalEventDrop", {
7679
8374
  dataTransfer: nativeEvent.dataTransfer,
7680
8375
  dropDateTime: target,
7681
8376
  resourceId
7682
8377
  });
8378
+ else emit("eventPlacementRejected", {
8379
+ action: "external-drop",
8380
+ dataTransfer: nativeEvent.dataTransfer,
8381
+ start: target,
8382
+ resourceId,
8383
+ conflicts: [],
8384
+ reason: "rejected"
8385
+ });
7683
8386
  };
7684
8387
  const getSnappedDropTarget = (nativeEvent, day, flatIndex, slotStartTime) => {
7685
8388
  if (props.eventDragInterval == null) return `${day} ${slotStartTime}`;
@@ -7710,6 +8413,31 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7710
8413
  */
7711
8414
  const resolveDropTarget = rafThrottle((nativeEvent, resourceId, resourceIndex) => {
7712
8415
  const flatIndex = getFlatIndexAtPoint(nativeEvent, resourceIndex);
8416
+ const count = slotsPerDay.value;
8417
+ const day = weekdays.value[Math.floor(flatIndex / count)];
8418
+ const interval = intervals.value[flatIndex % count];
8419
+ const target = flatIndex >= 0 && day && interval ? getSnappedDropTarget(nativeEvent, day, flatIndex, interval.startTime) : null;
8420
+ const event = dragState.draggedEvent.value;
8421
+ if (target && event) {
8422
+ const next = moveEventTo(event, target);
8423
+ dropValid.value = isEventPlacementAllowed({
8424
+ event,
8425
+ start: next.newStart,
8426
+ end: next.newEnd,
8427
+ events: props.events ?? [],
8428
+ preventEventOverlap: props.preventEventOverlap,
8429
+ resourceId
8430
+ }).allowed && props.canDropEvent?.({
8431
+ event,
8432
+ start: next.newStart,
8433
+ end: next.newEnd,
8434
+ resourceId
8435
+ }) !== false;
8436
+ } else if (target && nativeEvent.dataTransfer) dropValid.value = props.canDropExternalEvent?.({
8437
+ dataTransfer: nativeEvent.dataTransfer,
8438
+ start: target,
8439
+ resourceId
8440
+ }) !== false;
7713
8441
  setDropTarget(flatIndex < 0 ? null : {
7714
8442
  resourceId,
7715
8443
  flatIndex
@@ -7745,7 +8473,10 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7745
8473
  dayIndex
7746
8474
  }));
7747
8475
  });
7748
- const backgroundEventStyle = (event, dayIndex) => {
8476
+ const backgroundEventStyle = (event, day, dayIndex) => {
8477
+ const resizePosition = resize.getResizePosition(event.id, day);
8478
+ const left = resizePosition?.left ?? event.position.top;
8479
+ const width = resizePosition?.width ?? event.position.height;
7749
8480
  const colors = theme.value.variantColorResolver({
7750
8481
  color: event.color || theme.value.primaryColor,
7751
8482
  theme: theme.value,
@@ -7753,8 +8484,8 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
7753
8484
  autoContrast: true
7754
8485
  });
7755
8486
  return {
7756
- left: `${dayOffset(dayIndex) + event.position.top / 100 * dayWidth.value}%`,
7757
- right: `${100 - dayOffset(dayIndex) - (event.position.top + event.position.height) / 100 * dayWidth.value}%`,
8487
+ left: `${dayOffset(dayIndex) + left / 100 * dayWidth.value}%`,
8488
+ right: `${100 - dayOffset(dayIndex) - (left + width) / 100 * dayWidth.value}%`,
7758
8489
  minWidth: "1px",
7759
8490
  top: 0,
7760
8491
  height: "100%",
@@ -8006,12 +8737,23 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
8006
8737
  ...eventRenderers.value,
8007
8738
  ...unref(getStyles)("resourcesWeekViewBackgroundEvent")
8008
8739
  }, {
8009
- style: backgroundEventStyle(entry.event, entry.dayIndex),
8010
- onEventClick: clickEvent
8740
+ style: backgroundEventStyle(entry.event, entry.day, entry.dayIndex),
8741
+ "with-resize": unref(resize).isResizableEvent(entry.event) && !entry.event.position.allDay,
8742
+ "resize-axis": "horizontal",
8743
+ "is-resizing": unref(resize).getResizePosition(entry.event.id, entry.day) !== null,
8744
+ "active-resize-edge": unref(resize).resizingEdge,
8745
+ "resize-handle-props": unref(staticStyles)("resourcesWeekViewResizeHandle"),
8746
+ onEventClick: clickEvent,
8747
+ onResizeStart: (edge, pointerEvent) => startResize(entry.event, entry.day, entry.dayIndex, resourceIndex, edge, pointerEvent)
8011
8748
  }), null, 16, [
8012
8749
  "event",
8013
8750
  "interactive",
8014
- "style"
8751
+ "style",
8752
+ "with-resize",
8753
+ "is-resizing",
8754
+ "active-resize-edge",
8755
+ "resize-handle-props",
8756
+ "onResizeStart"
8015
8757
  ])]);
8016
8758
  }), 128)),
8017
8759
  (openBlock(true), createElementBlock(Fragment, null, renderList(allDayBars(resource.id), (bar) => {
@@ -8057,7 +8799,8 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
8057
8799
  style: {
8058
8800
  width: "100%",
8059
8801
  height: "100%"
8060
- }
8802
+ },
8803
+ mod: { invalid: unref(resize).getResizePosition(entry.event.id) !== null && !unref(resize).resizeValid.value }
8061
8804
  }, { ref_for: true }, {
8062
8805
  ...eventRenderers.value,
8063
8806
  ...stylesApi.value
@@ -8070,6 +8813,7 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
8070
8813
  "radius",
8071
8814
  "mode",
8072
8815
  "draggable",
8816
+ "mod",
8073
8817
  "onClick"
8074
8818
  ]), unref(resize).isResizableEvent(entry.event) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, renderList(["start", "end"], (edge) => {
8075
8819
  return createElementVNode("div", mergeProps({ key: edge }, { ref_for: true }, unref(staticStyles)("resourcesWeekViewResizeHandle"), {
@@ -8117,6 +8861,7 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
8117
8861
  "data-business-hours": businessHoursMods.value[dayIndex][slotIndex]["business-hours"] || void 0,
8118
8862
  "data-non-business-hours": businessHoursMods.value[dayIndex][slotIndex]["non-business-hours"] || void 0,
8119
8863
  "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.flatIndex === dayIndex * slotsPerDay.value + slotIndex || void 0,
8864
+ "data-invalid": dropTarget.value?.resourceId === resource.id && dropTarget.value.flatIndex === dayIndex * slotsPerDay.value + slotIndex && !dropValid.value || void 0,
8120
8865
  "data-drag-selected": unref(slotSelect).isSlotSelected(dayIndex * slotsPerDay.value + slotIndex, String(resource.id)) || void 0,
8121
8866
  "data-static": isStatic.value || void 0,
8122
8867
  "data-drag-slot-index": unref(props).withDragSlotSelect ? dayIndex * slotsPerDay.value + slotIndex : void 0,
@@ -8148,6 +8893,7 @@ var ResourcesWeekView = factory(/* @__PURE__ */ defineComponent({
8148
8893
  "data-business-hours",
8149
8894
  "data-non-business-hours",
8150
8895
  "data-drop-target",
8896
+ "data-invalid",
8151
8897
  "data-drag-selected",
8152
8898
  "data-static",
8153
8899
  "data-drag-slot-index",
@@ -8277,23 +9023,23 @@ function getResourcesMonthViewLayout({ days, events, resourceId, maxRows }) {
8277
9023
  };
8278
9024
  }
8279
9025
  var ResourcesMonthView_module_default = {
8280
- resourcesMonthView: "_resourcesMonthView_uqbdi_1",
8281
- resourcesMonthViewRoot: "_resourcesMonthViewRoot_uqbdi_17",
8282
- resourcesMonthViewScrollArea: "_resourcesMonthViewScrollArea_uqbdi_24",
8283
- resourcesMonthViewInner: "_resourcesMonthViewInner_uqbdi_33",
8284
- resourcesMonthViewDayLabelsRow: "_resourcesMonthViewDayLabelsRow_uqbdi_37",
8285
- resourcesMonthViewCorner: "_resourcesMonthViewCorner_uqbdi_46",
8286
- resourcesMonthViewDayLabel: "_resourcesMonthViewDayLabel_uqbdi_37",
8287
- resourcesMonthViewDayLabelWeekday: "_resourcesMonthViewDayLabelWeekday_uqbdi_85",
8288
- resourcesMonthViewDayLabelNumber: "_resourcesMonthViewDayLabelNumber_uqbdi_92",
8289
- resourcesMonthViewRow: "_resourcesMonthViewRow_uqbdi_97",
8290
- resourcesMonthViewResourceLabel: "_resourcesMonthViewResourceLabel_uqbdi_101",
8291
- resourcesMonthViewGroupColumn: "_resourcesMonthViewGroupColumn_uqbdi_120",
8292
- resourcesMonthViewGroupColumnEmpty: "_resourcesMonthViewGroupColumnEmpty_uqbdi_121",
8293
- resourcesMonthViewRowSlots: "_resourcesMonthViewRowSlots_uqbdi_149",
8294
- resourcesMonthViewCell: "_resourcesMonthViewCell_uqbdi_154",
8295
- resourcesMonthViewEventWrapper: "_resourcesMonthViewEventWrapper_uqbdi_230",
8296
- resourcesMonthViewResizeHandle: "_resourcesMonthViewResizeHandle_uqbdi_231"
9026
+ resourcesMonthView: "_resourcesMonthView_1rka1_1",
9027
+ resourcesMonthViewRoot: "_resourcesMonthViewRoot_1rka1_17",
9028
+ resourcesMonthViewScrollArea: "_resourcesMonthViewScrollArea_1rka1_24",
9029
+ resourcesMonthViewInner: "_resourcesMonthViewInner_1rka1_33",
9030
+ resourcesMonthViewDayLabelsRow: "_resourcesMonthViewDayLabelsRow_1rka1_37",
9031
+ resourcesMonthViewCorner: "_resourcesMonthViewCorner_1rka1_46",
9032
+ resourcesMonthViewDayLabel: "_resourcesMonthViewDayLabel_1rka1_37",
9033
+ resourcesMonthViewDayLabelWeekday: "_resourcesMonthViewDayLabelWeekday_1rka1_85",
9034
+ resourcesMonthViewDayLabelNumber: "_resourcesMonthViewDayLabelNumber_1rka1_92",
9035
+ resourcesMonthViewRow: "_resourcesMonthViewRow_1rka1_97",
9036
+ resourcesMonthViewResourceLabel: "_resourcesMonthViewResourceLabel_1rka1_101",
9037
+ resourcesMonthViewGroupColumn: "_resourcesMonthViewGroupColumn_1rka1_120",
9038
+ resourcesMonthViewGroupColumnEmpty: "_resourcesMonthViewGroupColumnEmpty_1rka1_121",
9039
+ resourcesMonthViewRowSlots: "_resourcesMonthViewRowSlots_1rka1_149",
9040
+ resourcesMonthViewCell: "_resourcesMonthViewCell_1rka1_154",
9041
+ resourcesMonthViewEventWrapper: "_resourcesMonthViewEventWrapper_1rka1_239",
9042
+ resourcesMonthViewResizeHandle: "_resourcesMonthViewResizeHandle_1rka1_240"
8297
9043
  };
8298
9044
  //#endregion
8299
9045
  //#region src/components/ResourcesMonthView/ResourcesMonthView.vue?vue&type=script&setup=true&lang.ts
@@ -8402,6 +9148,10 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8402
9148
  type: Function,
8403
9149
  default: void 0
8404
9150
  },
9151
+ canDropEvent: {},
9152
+ canDropExternalEvent: {},
9153
+ canResizeEventTo: {},
9154
+ preventEventOverlap: { type: [Boolean, Function] },
8405
9155
  withExternalEventDrop: { type: Boolean },
8406
9156
  withDragSlotSelect: { type: Boolean },
8407
9157
  labels: { default: void 0 },
@@ -8425,7 +9175,8 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8425
9175
  "eventDragEnd",
8426
9176
  "slotDragEnd",
8427
9177
  "externalEventDrop",
8428
- "eventResize"
9178
+ "eventResize",
9179
+ "eventPlacementRejected"
8429
9180
  ],
8430
9181
  setup(__props, { emit: __emit }) {
8431
9182
  const rawProps = __props;
@@ -8469,6 +9220,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8469
9220
  rootElement.value = node instanceof HTMLElement ? node : null;
8470
9221
  };
8471
9222
  const dropTarget = shallowRef(null);
9223
+ const dropValid = ref(true);
8472
9224
  const isStatic = computed(() => props.mode === "static");
8473
9225
  const month = computed(() => dayjs(props.date).startOf("month"));
8474
9226
  const monthString = computed(() => month.value.format("YYYY-MM-DD"));
@@ -8484,6 +9236,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8484
9236
  expansionLimit: props.recurrenceExpansionLimit
8485
9237
  }));
8486
9238
  const resizeState = shallowRef(null);
9239
+ const resizeValid = ref(true);
8487
9240
  let justResized = false;
8488
9241
  const effectiveEvents = computed(() => {
8489
9242
  const state = resizeState.value;
@@ -8556,18 +9309,57 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8556
9309
  draggedEvent: dragged,
8557
9310
  targetDay: day
8558
9311
  });
8559
- emit("eventDrop", {
9312
+ const start = dayjs(next.start).format("YYYY-MM-DD HH:mm:ss");
9313
+ const end = dayjs(next.end).format("YYYY-MM-DD HH:mm:ss");
9314
+ const validation = isEventPlacementAllowed({
9315
+ event: dragged,
9316
+ start,
9317
+ end,
9318
+ events: expandedEvents.value,
9319
+ preventEventOverlap: props.preventEventOverlap,
9320
+ resourceId
9321
+ });
9322
+ if (validation.allowed && props.canDropEvent?.({
9323
+ event: dragged,
9324
+ start,
9325
+ end,
9326
+ resourceId
9327
+ }) !== false) emit("eventDrop", {
8560
9328
  eventId: dragged.id,
8561
- newStart: dayjs(next.start).format("YYYY-MM-DD HH:mm:ss"),
8562
- newEnd: dayjs(next.end).format("YYYY-MM-DD HH:mm:ss"),
9329
+ newStart: start,
9330
+ newEnd: end,
8563
9331
  event: dragged,
8564
9332
  resourceId
8565
9333
  });
8566
- } else if (nativeEvent.dataTransfer) emit("externalEventDrop", {
8567
- dataTransfer: nativeEvent.dataTransfer,
8568
- dropDateTime: `${day} 00:00:00`,
8569
- resourceId
8570
- });
9334
+ else emit("eventPlacementRejected", {
9335
+ action: "drop",
9336
+ event: dragged,
9337
+ start,
9338
+ end,
9339
+ resourceId,
9340
+ conflicts: validation.conflicts,
9341
+ reason: validation.allowed ? "rejected" : "overlap"
9342
+ });
9343
+ } else if (nativeEvent.dataTransfer) {
9344
+ const start = `${day} 00:00:00`;
9345
+ if (props.canDropExternalEvent?.({
9346
+ dataTransfer: nativeEvent.dataTransfer,
9347
+ start,
9348
+ resourceId
9349
+ }) !== false) emit("externalEventDrop", {
9350
+ dataTransfer: nativeEvent.dataTransfer,
9351
+ dropDateTime: start,
9352
+ resourceId
9353
+ });
9354
+ else emit("eventPlacementRejected", {
9355
+ action: "external-drop",
9356
+ dataTransfer: nativeEvent.dataTransfer,
9357
+ start,
9358
+ resourceId,
9359
+ conflicts: [],
9360
+ reason: "rejected"
9361
+ });
9362
+ }
8571
9363
  };
8572
9364
  const setDropTarget = (next) => {
8573
9365
  const current = dropTarget.value;
@@ -8582,6 +9374,36 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8582
9374
  */
8583
9375
  const resolveDropTarget = rafThrottle((nativeEvent, resourceId, resourceIndex) => {
8584
9376
  const dayIndex = indexAtPoint(nativeEvent, resourceIndex);
9377
+ const day = days.value[dayIndex];
9378
+ const dragged = dragState.draggedEvent.value;
9379
+ if (day && dragged) {
9380
+ const next = calculateMonthDropDate({
9381
+ draggedEvent: dragged,
9382
+ targetDay: day
9383
+ });
9384
+ const start = dayjs(next.start).format("YYYY-MM-DD HH:mm:ss");
9385
+ const end = dayjs(next.end).format("YYYY-MM-DD HH:mm:ss");
9386
+ dropValid.value = isEventPlacementAllowed({
9387
+ event: dragged,
9388
+ start,
9389
+ end,
9390
+ events: expandedEvents.value,
9391
+ preventEventOverlap: props.preventEventOverlap,
9392
+ resourceId
9393
+ }).allowed && props.canDropEvent?.({
9394
+ event: dragged,
9395
+ start,
9396
+ end,
9397
+ resourceId
9398
+ }) !== false;
9399
+ } else if (day && nativeEvent.dataTransfer) {
9400
+ const start = `${day} 00:00:00`;
9401
+ dropValid.value = props.canDropExternalEvent?.({
9402
+ dataTransfer: nativeEvent.dataTransfer,
9403
+ start,
9404
+ resourceId
9405
+ }) !== false;
9406
+ }
8585
9407
  setDropTarget(dayIndex < 0 ? null : {
8586
9408
  resourceId,
8587
9409
  dayIndex
@@ -8704,6 +9526,16 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8704
9526
  ...calculateResizeDates(state.event, state.edge, days.value[dayIndex]),
8705
9527
  dayIndex
8706
9528
  };
9529
+ resizeValid.value = validateEventResize({
9530
+ event: state.event,
9531
+ start: resizeState.value.start,
9532
+ end: resizeState.value.end,
9533
+ edge: state.edge,
9534
+ events: expandedEvents.value,
9535
+ preventEventOverlap: props.preventEventOverlap,
9536
+ canResizeEventTo: props.canResizeEventTo,
9537
+ resourceId: state.event.resourceId
9538
+ }).valid;
8707
9539
  };
8708
9540
  const stopResizeListeners = () => {
8709
9541
  document.removeEventListener("pointermove", handleResizeMove);
@@ -8714,12 +9546,33 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8714
9546
  const state = resizeState.value;
8715
9547
  stopResizeListeners();
8716
9548
  resizeState.value = null;
8717
- if (emitChange && state && (state.start !== state.originalStart || state.end !== state.originalEnd)) emit("eventResize", {
8718
- eventId: state.event.id,
8719
- newStart: state.start,
8720
- newEnd: state.end,
8721
- event: state.event
8722
- });
9549
+ if (emitChange && state && (state.start !== state.originalStart || state.end !== state.originalEnd)) {
9550
+ const validation = validateEventResize({
9551
+ event: state.event,
9552
+ start: state.start,
9553
+ end: state.end,
9554
+ edge: state.edge,
9555
+ events: expandedEvents.value,
9556
+ preventEventOverlap: props.preventEventOverlap,
9557
+ canResizeEventTo: props.canResizeEventTo,
9558
+ resourceId: state.event.resourceId
9559
+ });
9560
+ if (validation.valid) emit("eventResize", {
9561
+ eventId: state.event.id,
9562
+ newStart: state.start,
9563
+ newEnd: state.end,
9564
+ event: state.event
9565
+ });
9566
+ else emit("eventPlacementRejected", {
9567
+ action: "resize",
9568
+ event: state.event,
9569
+ start: state.start,
9570
+ end: state.end,
9571
+ edge: state.edge,
9572
+ conflicts: validation.conflicts,
9573
+ reason: validation.reason
9574
+ });
9575
+ }
8723
9576
  justResized = true;
8724
9577
  requestAnimationFrame(() => justResized = false);
8725
9578
  };
@@ -8745,6 +9598,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8745
9598
  end,
8746
9599
  dayIndex: -1
8747
9600
  };
9601
+ resizeValid.value = true;
8748
9602
  document.addEventListener("pointermove", handleResizeMove);
8749
9603
  document.addEventListener("pointerup", handleResizeEnd);
8750
9604
  document.addEventListener("pointercancel", handleResizeCancel);
@@ -8873,6 +9727,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8873
9727
  mode: unref(props).mode,
8874
9728
  draggable: isDraggableEvent(entry.event),
8875
9729
  "is-resizing": isResizingEvent(entry.event),
9730
+ mod: { invalid: isResizingEvent(entry.event) && !resizeValid.value },
8876
9731
  style: {
8877
9732
  "width": "100%",
8878
9733
  "height": "100%"
@@ -8890,6 +9745,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8890
9745
  "mode",
8891
9746
  "draggable",
8892
9747
  "is-resizing",
9748
+ "mod",
8893
9749
  "onClick"
8894
9750
  ]),
8895
9751
  isResizableEvent(entry.event) ? (openBlock(), createElementBlock("div", mergeProps({
@@ -8927,6 +9783,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8927
9783
  mode: unref(props).mode,
8928
9784
  draggable: isDraggableEvent(segment.event),
8929
9785
  "is-resizing": isResizingEvent(segment.event),
9786
+ mod: { invalid: isResizingEvent(segment.event) && !resizeValid.value },
8930
9787
  style: {
8931
9788
  "width": "100%",
8932
9789
  "height": "100%"
@@ -8945,6 +9802,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
8945
9802
  "mode",
8946
9803
  "draggable",
8947
9804
  "is-resizing",
9805
+ "mod",
8948
9806
  "onClick"
8949
9807
  ]),
8950
9808
  isResizableEvent(segment.event) && segment.hanging !== "start" && segment.hanging !== "both" ? (openBlock(), createElementBlock("div", mergeProps({
@@ -9000,6 +9858,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
9000
9858
  }, { ref_for: true }, unref(staticStyles)("resourcesMonthViewCell"), {
9001
9859
  "data-weekend": unref(props).weekendDays.includes(unref(dayjs)(day).day()) || void 0,
9002
9860
  "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.dayIndex === dayIndex || void 0,
9861
+ "data-invalid": dropTarget.value?.resourceId === resource.id && dropTarget.value.dayIndex === dayIndex && !dropValid.value || void 0,
9003
9862
  "data-drag-selected": unref(slotSelect).isSlotSelected(dayIndex, String(resource.id)) || void 0,
9004
9863
  "data-static": isStatic.value || void 0,
9005
9864
  "data-drag-slot-index": unref(props).withDragSlotSelect ? dayIndex : void 0,
@@ -9027,6 +9886,7 @@ var ResourcesMonthView = factory(/* @__PURE__ */ defineComponent({
9027
9886
  }, 1040, [
9028
9887
  "data-weekend",
9029
9888
  "data-drop-target",
9889
+ "data-invalid",
9030
9890
  "data-drag-selected",
9031
9891
  "data-static",
9032
9892
  "data-drag-slot-index",
@@ -9098,6 +9958,22 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9098
9958
  type: Function,
9099
9959
  default: void 0
9100
9960
  },
9961
+ canDropEvent: {
9962
+ type: Function,
9963
+ default: void 0
9964
+ },
9965
+ canDropExternalEvent: {
9966
+ type: Function,
9967
+ default: void 0
9968
+ },
9969
+ canResizeEventTo: {
9970
+ type: Function,
9971
+ default: void 0
9972
+ },
9973
+ preventEventOverlap: {
9974
+ type: [Boolean, Function],
9975
+ default: void 0
9976
+ },
9101
9977
  withInteractiveBackgroundEvents: {
9102
9978
  type: Boolean,
9103
9979
  default: void 0
@@ -9124,7 +10000,8 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9124
10000
  "dayClick",
9125
10001
  "slotDragEnd",
9126
10002
  "externalEventDrop",
9127
- "eventResize"
10003
+ "eventResize",
10004
+ "eventPlacementRejected"
9128
10005
  ],
9129
10006
  setup(__props, { emit: __emit }) {
9130
10007
  const rawProps = __props;
@@ -9186,6 +10063,9 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9186
10063
  renderResourceLabel: props.renderResourceLabel,
9187
10064
  withEventsDragAndDrop: isStatic.value ? false : props.withEventsDragAndDrop,
9188
10065
  canDragEvent: props.canDragEvent,
10066
+ canDropEvent: props.canDropEvent,
10067
+ canDropExternalEvent: props.canDropExternalEvent,
10068
+ preventEventOverlap: props.preventEventOverlap,
9189
10069
  withDragSlotSelect: props.withDragSlotSelect,
9190
10070
  recurrenceExpansionLimit: props.recurrenceExpansionLimit,
9191
10071
  withInteractiveBackgroundEvents: isStatic.value ? false : props.withInteractiveBackgroundEvents,
@@ -9197,6 +10077,7 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9197
10077
  onEventClick: (event, nativeEvent) => emit("eventClick", event, nativeEvent),
9198
10078
  onSlotDragEnd: (data) => emit("slotDragEnd", data),
9199
10079
  onExternalEventDrop: (data) => emit("externalEventDrop", data),
10080
+ onEventPlacementRejected: (data) => emit("eventPlacementRejected", data),
9200
10081
  ...eventRenderers.value,
9201
10082
  ...stylesApi.value
9202
10083
  }));
@@ -9204,6 +10085,7 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9204
10085
  onTimeSlotClick: (data) => emit("timeSlotClick", data),
9205
10086
  withEventResize: isStatic.value ? false : props.withEventResize,
9206
10087
  canResizeEvent: props.canResizeEvent,
10088
+ canResizeEventTo: props.canResizeEventTo,
9207
10089
  onEventResize: (data) => emit("eventResize", data)
9208
10090
  }));
9209
10091
  const activeView = computed(() => {
@@ -9263,6 +10145,6 @@ var ResourcesSchedule = factory(/* @__PURE__ */ defineComponent({
9263
10145
  }
9264
10146
  }), { classes: ResourcesSchedule_module_default });
9265
10147
  //#endregion
9266
- export { CurrentTimeIndicator, DEFAULT_SCHEDULE_LABELS, DayView, DragContext, HeaderControl, MobileMonthView, MonthView, MonthYearSelect, MoreEvents, ResourcesDayView, ResourcesMonthView, ResourcesSchedule, ResourcesWeekView, Schedule, ScheduleBackgroundEvent_default as ScheduleBackgroundEvent, ScheduleEvent, ScheduleHeader, ScheduleHeaderBase, ScheduleHeaderNext, ScheduleHeaderPrevious, ScheduleHeaderToday, ViewSelect, WeekView, YearView, calculateDropTime, calculateMonthDropDate, clampIntervalMinutes, compareMonthEvents, createHeaderNavigation, expandRecurringEvents, formatDate, getBusinessHoursMod, getCurrentTimePosition, getDayPosition, getDayPositionedEvents, getDayTimeIntervals, getDayViewEvents, getEndOfWeek, getGroupToResourceIdMap, getLabel, getMonthDays, getMonthPositionedEvents, getMonthRange, getMonthViewEvents, getMonthsByQuarter, getMonthsList, getOrderedResources, getOverlapClusters, getRenderableMonthEventSegments, getResourcesDayViewEvents, getResourcesMonthViewLayout, getResourcesWeekViewEvents, getStartOfWeek, getVisibleEvents, getWeekDays, getWeekLabel, getWeekNumber, getWeekPositionedEvents, getWeekViewEvents, getWeekdaysNames, getYearsList, handleResourcesGridKeyDown, isAfterMinDate, isAllDayEvent, isBeforeMaxDate, isEventInTimeRange, isEventsOverlap, isInTimeRange, isMultiDayEvent, isMultidayEvent, isSameMonth, isWithinWeek, nextWeek, parseTimeString, previousWeek, provideDragContext, provideScheduleDragState, sortEvents, toDateString, toTimeString, useDragContext, useScheduleHeaderLabels, validateEvent };
10148
+ export { CurrentTimeIndicator, DEFAULT_SCHEDULE_LABELS, DayView, DragContext, HeaderControl, MobileMonthView, MonthView, MonthYearSelect, MoreEvents, ResourcesDayView, ResourcesMonthView, ResourcesSchedule, ResourcesWeekView, Schedule, ScheduleBackgroundEvent_default as ScheduleBackgroundEvent, ScheduleEvent, ScheduleHeader, ScheduleHeaderBase, ScheduleHeaderNext, ScheduleHeaderPrevious, ScheduleHeaderToday, ViewSelect, WeekView, YearView, applyCascadeLayout, calculateDropTime, calculateMonthDropDate, clampIntervalMinutes, compareMonthEvents, createHeaderNavigation, expandRecurringEvents, formatDate, getBusinessHoursMod, getCurrentTimePosition, getDayPosition, getDayPositionedEvents, getDayTimeIntervals, getDayViewEvents, getEndOfWeek, getGroupToResourceIdMap, getLabel, getMonthDays, getMonthPositionedEvents, getMonthRange, getMonthViewEvents, getMonthsByQuarter, getMonthsList, getOrderedResources, getOverlapClusters, getRenderableMonthEventSegments, getResourcesDayViewEvents, getResourcesMonthViewLayout, getResourcesWeekViewEvents, getStartOfWeek, getVisibleEvents, getWeekDays, getWeekLabel, getWeekNumber, getWeekPositionedEvents, getWeekViewEvents, getWeekdaysNames, getYearsList, handleResourcesGridKeyDown, isAfterMinDate, isAllDayEvent, isBeforeMaxDate, isEventInTimeRange, isEventPlacementAllowed, isEventsOverlap, isInTimeRange, isMultiDayEvent, isMultidayEvent, isSameMonth, isWithinWeek, nextWeek, parseTimeString, previousWeek, provideDragContext, provideScheduleDragState, sortEvents, toDateString, toTimeString, useDragContext, useScheduleHeaderLabels, validateEvent };
9267
10149
 
9268
10150
  //# sourceMappingURL=index.mjs.map