@mantine-vue/schedule 3.5.0 → 3.7.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 (29) hide show
  1. package/cjs/index.cjs +925 -185
  2. package/cjs/index.cjs.map +1 -1
  3. package/esm/index.mjs +925 -186
  4. package/esm/index.mjs.map +1 -1
  5. package/lib/component-props.d.ts +11 -1
  6. package/lib/components/DayView/DayView.vue.d.ts +2 -0
  7. package/lib/components/MonthView/MonthView.types.d.ts +9 -1
  8. package/lib/components/MonthView/MonthView.vue.d.ts +2 -0
  9. package/lib/components/MonthView/get-month-view-events/reserve-row.d.ts +7 -0
  10. package/lib/components/ResourcesDayView/ResourcesDayView.types.d.ts +10 -1
  11. package/lib/components/ResourcesDayView/ResourcesDayView.vue.d.ts +2 -0
  12. package/lib/components/ResourcesMonthView/ResourcesMonthView.types.d.ts +10 -1
  13. package/lib/components/ResourcesMonthView/ResourcesMonthView.vue.d.ts +2 -0
  14. package/lib/components/ResourcesSchedule/ResourcesSchedule.types.d.ts +10 -1
  15. package/lib/components/ResourcesSchedule/ResourcesSchedule.vue.d.ts +2 -0
  16. package/lib/components/ResourcesWeekView/ResourcesWeekView.types.d.ts +10 -1
  17. package/lib/components/ResourcesWeekView/ResourcesWeekView.vue.d.ts +2 -0
  18. package/lib/components/Schedule/Schedule.types.d.ts +11 -1
  19. package/lib/components/Schedule/Schedule.vue.d.ts +2 -0
  20. package/lib/components/WeekView/WeekView.vue.d.ts +2 -0
  21. package/lib/hooks/use-event-resize.d.ts +6 -1
  22. package/lib/hooks/use-horizontal-event-resize.d.ts +6 -0
  23. package/lib/hooks/validate-event-resize.d.ts +26 -0
  24. package/lib/types.d.ts +38 -0
  25. package/lib/utils/index.d.ts +2 -0
  26. package/lib/utils/is-event-placement-allowed/is-event-placement-allowed.d.ts +13 -0
  27. package/package.json +4 -4
  28. package/styles.css +494 -441
  29. package/styles.layer.css +494 -441
@@ -2,7 +2,7 @@ import type { CSSProperties, HTMLAttributes, VNodeChild } from 'vue';
2
2
  import type { EmitsToProps } from '@mantine-vue/core';
3
3
  import type { ViewSelectEmits, ViewSelectProps } from './components/ScheduleHeader/ViewSelect/ViewSelect.types';
4
4
  import type { ScheduleLabelsOverride } from './labels';
5
- import type { AnyDateValue, DateLabelFormat, DateStringValue, DateTimeStringValue, ScheduleEventData, ScheduleMode, ScheduleViewLevel } from './types';
5
+ import type { AnyDateValue, DateLabelFormat, DateStringValue, DateTimeStringValue, PreventEventOverlap, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, ScheduleEventData, ScheduleEventPlacementRejectedData, ScheduleMode, ScheduleViewLevel } from './types';
6
6
  import type { BusinessHoursValue } from './utils';
7
7
  /**
8
8
  * Native attributes accepted by the header controls and the other button-like elements
@@ -177,6 +177,12 @@ export interface TimeViewOwnProps extends BaseViewOwnProps {
177
177
  * @default () => true
178
178
  */
179
179
  canDragEvent?: (event: ScheduleEventData) => boolean;
180
+ /** Returns false to reject a candidate internal event drop. */
181
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
182
+ /** Returns false to reject a candidate external drop. */
183
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
184
+ /** Rejects drops that overlap other events. */
185
+ preventEventOverlap?: PreventEventOverlap;
180
186
  /**
181
187
  * If set, dragging across time slots selects a range.
182
188
  * @default false
@@ -200,6 +206,8 @@ export interface TimeViewOwnProps extends BaseViewOwnProps {
200
206
  * @default () => true
201
207
  */
202
208
  canResizeEvent?: (event: ScheduleEventData) => boolean;
209
+ /** Returns false to reject a candidate resize. */
210
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
203
211
  }
204
212
  /**
205
213
  * Events emitted by every schedule view. Not a component of its own: `DayViewEmits`,
@@ -234,6 +242,8 @@ export interface TimeViewEmits extends BaseViewEmits {
234
242
  externalEventDrop: [dataTransfer: DataTransfer, dropDateTime: DateTimeStringValue];
235
243
  /** Emitted when an event is resized. */
236
244
  eventResize: [data: EventDropData];
245
+ /** Emitted when a drop or resize is rejected. */
246
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
237
247
  }
238
248
  /** Scoped slots that mirror the `renderEvent` and `renderEventBody` props. */
239
249
  export interface EventSlots {
@@ -31,6 +31,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<DayVie
31
31
  slotDragEnd: (rangeStart: string, rangeEnd: string) => any;
32
32
  externalEventDrop: (dataTransfer: DataTransfer, dropDateTime: string) => any;
33
33
  eventResize: (data: import("../..").EventDropData) => any;
34
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
34
35
  }, string, import("vue").PublicProps, Readonly<DayViewOwnProps> & Readonly<{
35
36
  onDateChange?: ((date: string) => any) | undefined;
36
37
  onEventDragStart?: ((event: ScheduleEventData) => any) | undefined;
@@ -43,6 +44,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<DayVie
43
44
  onSlotDragEnd?: ((rangeStart: string, rangeEnd: string) => any) | undefined;
44
45
  onExternalEventDrop?: ((dataTransfer: DataTransfer, dropDateTime: string) => any) | undefined;
45
46
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
47
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
46
48
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, import("../..").EventSlots>;
47
49
  type __VLS_WithSlots<T, S> = T & {
48
50
  new (): {
@@ -1,7 +1,7 @@
1
1
  import type { BoxProps, Factory, ScrollAreaProps } from '@mantine-vue/core';
2
2
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
3
3
  import type { BaseViewEmits, BaseViewOwnProps, EventDropData, EventSlots, ForwardedProps, NativeButtonProps } from '../../component-props';
4
- import type { DateLabelFormat, DateStringValue, DateTimeStringValue, DayOfWeek, ScheduleEventData } from '../../types';
4
+ import type { DateLabelFormat, DateStringValue, DateTimeStringValue, DayOfWeek, ScheduleEventData, ScheduleEventPlacementRejectedData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, PreventEventOverlap } from '../../types';
5
5
  import type { MoreEventsEmits, MoreEventsProps, MoreEventsStylesNames } from '../MoreEvents/MoreEvents.types';
6
6
  import type { ScheduleEventStylesNames } from '../ScheduleEvent/ScheduleEvent.types';
7
7
  import type { CombinedScheduleHeaderStylesNames } from '../ScheduleHeader/ScheduleHeader.types';
@@ -78,6 +78,12 @@ export interface MonthViewOwnProps extends BaseViewOwnProps, StylesApiProps<Mont
78
78
  * @default () => true
79
79
  */
80
80
  canDragEvent?: (event: ScheduleEventData) => boolean;
81
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
82
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
83
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
84
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
85
+ /** If set, drops that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging to compute live feedback, it must be pure and cheap. @default false */
86
+ preventEventOverlap?: PreventEventOverlap;
81
87
  /**
82
88
  * If set, items dragged in from outside the schedule can be dropped on a day, which emits
83
89
  * `externalEventDrop`. Enabling event drag and drop turns this on as well.
@@ -113,6 +119,8 @@ export interface MonthViewEmits extends BaseViewEmits {
113
119
  externalEventDrop: [dataTransfer: DataTransfer, date: DateStringValue];
114
120
  /** Emitted when a day range is selected by dragging. */
115
121
  slotDragEnd: [rangeStart: DateTimeStringValue, rangeEnd: DateTimeStringValue];
122
+ /** Emitted when a drop is rejected. */
123
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
116
124
  }
117
125
  export type MonthViewFactory = Factory<{
118
126
  props: Omit<MonthViewProps, 'rootRef'>;
@@ -36,6 +36,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<MonthV
36
36
  eventDrop: (data: import("../..").EventDropData) => any;
37
37
  slotDragEnd: (rangeStart: string, rangeEnd: string) => any;
38
38
  externalEventDrop: (dataTransfer: DataTransfer, date: string) => any;
39
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
39
40
  weekNumberClick: (date: string, nativeEvent: MouseEvent) => any;
40
41
  }, string, import("vue").PublicProps, Readonly<MonthViewOwnProps> & Readonly<{
41
42
  onDateChange?: ((date: string) => any) | undefined;
@@ -47,6 +48,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<MonthV
47
48
  onEventDrop?: ((data: import("../..").EventDropData) => any) | undefined;
48
49
  onSlotDragEnd?: ((rangeStart: string, rangeEnd: string) => any) | undefined;
49
50
  onExternalEventDrop?: ((dataTransfer: DataTransfer, date: string) => any) | undefined;
51
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
50
52
  onWeekNumberClick?: ((date: string, nativeEvent: MouseEvent) => any) | undefined;
51
53
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, import("../..").EventSlots>;
52
54
  type __VLS_WithSlots<T, S> = T & {
@@ -0,0 +1,7 @@
1
+ interface ReserveRowInput {
2
+ nextRowByDay: number[];
3
+ startDayIndex: number;
4
+ daysSpanned: number;
5
+ }
6
+ export declare function reserveRow({ nextRowByDay, startDayIndex, daysSpanned }: ReserveRowInput): number;
7
+ export {};
@@ -3,7 +3,7 @@ import type { BoxProps, Factory, ScrollAreaProps } from '@mantine-vue/core';
3
3
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
4
4
  import type { EventDropData, EventSlots, ForwardedProps, NativeButtonProps, RenderEvent, RenderEventBody } from '../../component-props';
5
5
  import type { ScheduleLabelsOverride } from '../../labels';
6
- import type { AnyDateValue, DateLabelFormat, DateStringValue, DateTimeStringValue, ScheduleEventData, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
6
+ import type { AnyDateValue, DateLabelFormat, DateStringValue, DateTimeStringValue, ScheduleEventData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, ScheduleEventPlacementRejectedData, PreventEventOverlap, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
7
7
  import type { BusinessHoursValue } from '../../utils';
8
8
  import type { MoreEventsEmits, MoreEventsProps, MoreEventsStylesNames } from '../MoreEvents/MoreEvents.types';
9
9
  import type { ScheduleEventStylesNames } from '../ScheduleEvent/ScheduleEvent.types';
@@ -266,6 +266,14 @@ export interface ResourcesDayViewOwnProps extends StylesApiProps<ResourcesDayVie
266
266
  * @default () => true
267
267
  */
268
268
  canResizeEvent?: (event: ScheduleEventData) => boolean;
269
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
270
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
271
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
272
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
273
+ /** Called on every pointer move while an event is resized to compute live feedback and again before the resize is committed, return `false` to reject the new size. Must be pure and cheap. */
274
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
275
+ /** If set, drops and resizes that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging and resizing to compute live feedback, it must be pure and cheap. @default false */
276
+ preventEventOverlap?: PreventEventOverlap;
269
277
  /**
270
278
  * Maximum number of instances generated per recurring series.
271
279
  * @default 2000
@@ -302,6 +310,7 @@ export interface ResourcesDayViewEmits {
302
310
  externalEventDrop: [data: ResourceExternalDropData];
303
311
  /** Emitted when an event is resized. */
304
312
  eventResize: [data: EventDropData];
313
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
305
314
  }
306
315
  export type ResourcesDayViewFactory = Factory<{
307
316
  props: Omit<ResourcesDayViewProps, 'rootRef'>;
@@ -34,6 +34,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
34
34
  slotDragEnd: (data: import("./ResourcesDayView.types").ResourceSlotDragEndData) => any;
35
35
  externalEventDrop: (data: import("./ResourcesDayView.types").ResourceExternalDropData) => any;
36
36
  eventResize: (data: import("../..").EventDropData) => any;
37
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
37
38
  }, string, import("vue").PublicProps, Readonly<ResourcesDayViewOwnProps> & Readonly<{
38
39
  onDateChange?: ((date: string) => any) | undefined;
39
40
  onEventDragStart?: ((event: ScheduleEventData) => any) | undefined;
@@ -45,6 +46,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
45
46
  onSlotDragEnd?: ((data: import("./ResourcesDayView.types").ResourceSlotDragEndData) => any) | undefined;
46
47
  onExternalEventDrop?: ((data: import("./ResourcesDayView.types").ResourceExternalDropData) => any) | undefined;
47
48
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
49
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
48
50
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ResourcesDayViewSlots>;
49
51
  type __VLS_WithSlots<T, S> = T & {
50
52
  new (): {
@@ -3,7 +3,7 @@ import type { BoxProps, Factory, ScrollAreaProps } from '@mantine-vue/core';
3
3
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
4
4
  import type { EventSlots, EventDropData, ForwardedProps, NativeButtonProps, RenderEvent, RenderEventBody } from '../../component-props';
5
5
  import type { ScheduleLabelsOverride } from '../../labels';
6
- import type { DateLabelFormat, DateStringValue, DayOfWeek, ScheduleEventData, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
6
+ import type { DateLabelFormat, DateStringValue, DayOfWeek, ScheduleEventData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, ScheduleEventPlacementRejectedData, PreventEventOverlap, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
7
7
  import type { MoreEventsEmits, MoreEventsProps, MoreEventsStylesNames } from '../MoreEvents/MoreEvents.types';
8
8
  import type { ScheduleEventStylesNames } from '../ScheduleEvent/ScheduleEvent.types';
9
9
  import type { CombinedScheduleHeaderStylesNames } from '../ScheduleHeader/ScheduleHeader.types';
@@ -170,6 +170,14 @@ export interface ResourcesMonthViewOwnProps extends StylesApiProps<ResourcesMont
170
170
  withEventResize?: boolean;
171
171
  /** Returns whether the given event may be resized. @default () => true */
172
172
  canResizeEvent?: (event: ScheduleEventData) => boolean;
173
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
174
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
175
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
176
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
177
+ /** Called on every pointer move while an event is resized to compute live feedback and again before the resize is committed, return `false` to reject the new size. Must be pure and cheap. */
178
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
179
+ /** If set, drops and resizes that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging and resizing to compute live feedback, it must be pure and cheap. @default false */
180
+ preventEventOverlap?: PreventEventOverlap;
173
181
  /**
174
182
  * If set, items dragged in from outside the schedule can be dropped on a day cell, which emits
175
183
  * `externalEventDrop`. Enabling event drag and drop turns this on as well.
@@ -227,6 +235,7 @@ export interface ResourcesMonthViewEmits {
227
235
  externalEventDrop: [data: ResourceExternalDropData];
228
236
  /** Emitted when an event resize gesture completes. */
229
237
  eventResize: [data: EventDropData];
238
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
230
239
  }
231
240
  export type ResourcesMonthViewFactory = Factory<{
232
241
  props: Omit<ResourcesMonthViewProps, 'rootRef'>;
@@ -36,6 +36,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
36
36
  slotDragEnd: (data: import("../ResourcesDayView").ResourceSlotDragEndData) => any;
37
37
  externalEventDrop: (data: import("../ResourcesDayView").ResourceExternalDropData) => any;
38
38
  eventResize: (data: import("../..").EventDropData) => any;
39
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
39
40
  }, string, import("vue").PublicProps, Readonly<ResourcesMonthViewOwnProps> & Readonly<{
40
41
  onDateChange?: ((date: string) => any) | undefined;
41
42
  onDayClick?: ((data: import("./ResourcesMonthView.types").ResourcesMonthViewDayClickData) => any) | undefined;
@@ -47,6 +48,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
47
48
  onSlotDragEnd?: ((data: import("../ResourcesDayView").ResourceSlotDragEndData) => any) | undefined;
48
49
  onExternalEventDrop?: ((data: import("../ResourcesDayView").ResourceExternalDropData) => any) | undefined;
49
50
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
51
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
50
52
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ResourcesMonthViewSlots>;
51
53
  type __VLS_WithSlots<T, S> = T & {
52
54
  new (): {
@@ -3,7 +3,7 @@ import type { BoxProps, Factory } from '@mantine-vue/core';
3
3
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
4
4
  import type { EventDropData, EventSlots, RenderEventBody } from '../../component-props';
5
5
  import type { ScheduleLabelsOverride } from '../../labels';
6
- import type { DateStringValue, ScheduleEventData, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup } from '../../types';
6
+ import type { DateStringValue, ScheduleEventData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, ScheduleEventPlacementRejectedData, PreventEventOverlap, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup } from '../../types';
7
7
  import type { ResourceExternalDropData, ResourceSlotDragEndData, ResourceTimeSlotClickData, ResourceViewDropData, ResourcesDayViewProps, ResourcesDayViewStylesNames } from '../ResourcesDayView/ResourcesDayView.types';
8
8
  import type { ResourcesMonthViewDayClickData, ResourcesMonthViewProps, ResourcesMonthViewStylesNames } from '../ResourcesMonthView/ResourcesMonthView.types';
9
9
  import type { ResourcesWeekViewProps, ResourcesWeekViewStylesNames } from '../ResourcesWeekView/ResourcesWeekView.types';
@@ -106,6 +106,14 @@ export interface ResourcesScheduleOwnProps extends StylesApiProps<ResourcesSched
106
106
  * @default () => true
107
107
  */
108
108
  canResizeEvent?: (event: ScheduleEventData) => boolean;
109
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
110
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
111
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
112
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
113
+ /** Called on every pointer move while an event is resized to compute live feedback and again before the resize is committed, return `false` to reject the new size. Must be pure and cheap. */
114
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
115
+ /** If set, drops and resizes that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging and resizing to compute live feedback, it must be pure and cheap. @default false */
116
+ preventEventOverlap?: PreventEventOverlap;
109
117
  /** If set, background events can be focused and clicked in day and week views. */
110
118
  withInteractiveBackgroundEvents?: boolean;
111
119
  /**
@@ -149,6 +157,7 @@ export interface ResourcesScheduleEmits {
149
157
  externalEventDrop: [data: ResourceExternalDropData];
150
158
  /** Emitted when an event is resized. */
151
159
  eventResize: [data: EventDropData];
160
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
152
161
  }
153
162
  export type ResourcesScheduleFactory = Factory<{
154
163
  props: Omit<ResourcesScheduleProps, 'rootRef'>;
@@ -21,6 +21,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
21
21
  slotDragEnd: (data: import("../ResourcesDayView").ResourceSlotDragEndData) => any;
22
22
  externalEventDrop: (data: import("../ResourcesDayView").ResourceExternalDropData) => any;
23
23
  eventResize: (data: import("../..").EventDropData) => any;
24
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
24
25
  "update:view": (view: ResourcesScheduleViewLevel) => any;
25
26
  }, string, import("vue").PublicProps, Readonly<ResourcesScheduleOwnProps> & Readonly<{
26
27
  "onUpdate:date"?: ((date: string) => any) | undefined;
@@ -35,6 +36,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
35
36
  onSlotDragEnd?: ((data: import("../ResourcesDayView").ResourceSlotDragEndData) => any) | undefined;
36
37
  onExternalEventDrop?: ((data: import("../ResourcesDayView").ResourceExternalDropData) => any) | undefined;
37
38
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
39
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
38
40
  "onUpdate:view"?: ((view: ResourcesScheduleViewLevel) => any) | undefined;
39
41
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ResourcesScheduleSlots>;
40
42
  type __VLS_WithSlots<T, S> = T & {
@@ -3,7 +3,7 @@ import type { BoxProps, Factory, ScrollAreaProps } from '@mantine-vue/core';
3
3
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
4
4
  import type { EventDropData, EventSlots, ForwardedProps, NativeButtonProps, RenderEvent, RenderEventBody } from '../../component-props';
5
5
  import type { ScheduleLabelsOverride } from '../../labels';
6
- import type { AnyDateValue, DateLabelFormat, DateStringValue, DayOfWeek, ScheduleEventData, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
6
+ import type { AnyDateValue, DateLabelFormat, DateStringValue, DayOfWeek, ScheduleEventData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, ScheduleEventPlacementRejectedData, PreventEventOverlap, ScheduleMode, ScheduleResourceData, ScheduleResourceGroup, ScheduleViewLevel } from '../../types';
7
7
  import type { BusinessHoursValue } from '../../utils';
8
8
  import type { MoreEventsEmits, MoreEventsProps, MoreEventsStylesNames } from '../MoreEvents/MoreEvents.types';
9
9
  import type { ScheduleEventStylesNames } from '../ScheduleEvent/ScheduleEvent.types';
@@ -247,6 +247,14 @@ export interface ResourcesWeekViewOwnProps extends StylesApiProps<ResourcesWeekV
247
247
  * @default () => true
248
248
  */
249
249
  canResizeEvent?: (event: ScheduleEventData) => boolean;
250
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
251
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
252
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
253
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
254
+ /** Called on every pointer move while an event is resized to compute live feedback and again before the resize is committed, return `false` to reject the new size. Must be pure and cheap. */
255
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
256
+ /** If set, drops and resizes that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging and resizing to compute live feedback, it must be pure and cheap. @default false */
257
+ preventEventOverlap?: PreventEventOverlap;
250
258
  /**
251
259
  * Maximum number of instances generated per recurring series.
252
260
  * @default 2000
@@ -308,6 +316,7 @@ export interface ResourcesWeekViewEmits {
308
316
  externalEventDrop: [data: ResourceExternalDropData];
309
317
  /** Emitted when an event is resized. */
310
318
  eventResize: [data: EventDropData];
319
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
311
320
  }
312
321
  export type ResourcesWeekViewFactory = Factory<{
313
322
  props: Omit<ResourcesWeekViewProps, 'rootRef'>;
@@ -39,6 +39,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
39
39
  slotDragEnd: (data: import("../ResourcesDayView").ResourceSlotDragEndData) => any;
40
40
  externalEventDrop: (data: import("../ResourcesDayView").ResourceExternalDropData) => any;
41
41
  eventResize: (data: import("../..").EventDropData) => any;
42
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
42
43
  }, string, import("vue").PublicProps, Readonly<ResourcesWeekViewOwnProps> & Readonly<{
43
44
  onDateChange?: ((date: string) => any) | undefined;
44
45
  onEventDragStart?: ((event: ScheduleEventData) => any) | undefined;
@@ -50,6 +51,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Resour
50
51
  onSlotDragEnd?: ((data: import("../ResourcesDayView").ResourceSlotDragEndData) => any) | undefined;
51
52
  onExternalEventDrop?: ((data: import("../ResourcesDayView").ResourceExternalDropData) => any) | undefined;
52
53
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
54
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
53
55
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ResourcesWeekViewSlots>;
54
56
  type __VLS_WithSlots<T, S> = T & {
55
57
  new (): {
@@ -3,7 +3,7 @@ import type { BoxProps, Factory } from '@mantine-vue/core';
3
3
  import type { StylesApiProps } from '@mantine-vue/core/styles-api';
4
4
  import type { EventDropData, EventSlots, ForwardedProps, RenderEventBody, TimeSlotClickData } from '../../component-props';
5
5
  import type { ScheduleLabelsOverride } from '../../labels';
6
- import type { DateStringValue, DateTimeStringValue, ScheduleEventData, ScheduleMode, ScheduleViewLevel } from '../../types';
6
+ import type { DateStringValue, DateTimeStringValue, ScheduleEventData, ScheduleEventPlacementRejectedData, ScheduleCanDropEventData, ScheduleCanDropExternalEventData, ScheduleCanResizeEventToData, PreventEventOverlap, ScheduleMode, ScheduleViewLevel } from '../../types';
7
7
  import type { DayViewEmits, DayViewProps, DayViewStylesNames } from '../DayView/DayView.types';
8
8
  import type { MobileMonthViewHeaderPayload, MobileMonthViewEmits, MobileMonthViewProps, MobileMonthViewStylesNames } from '../MobileMonthView/MobileMonthView.types';
9
9
  import type { MonthViewEmits, MonthViewProps, MonthViewStylesNames } from '../MonthView/MonthView.types';
@@ -88,6 +88,14 @@ export interface ScheduleOwnProps extends StylesApiProps<ScheduleFactory> {
88
88
  * @default () => true
89
89
  */
90
90
  canResizeEvent?: (event: ScheduleEventData) => boolean;
91
+ /** Called while an event is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. */
92
+ canDropEvent?: (data: ScheduleCanDropEventData) => boolean;
93
+ /** Called while an external item is dragged over a target to compute live feedback and again before the drop is committed, return `false` to reject the drop. Must be pure and cheap. Only `dataTransfer.types` can be read while the drag is in progress. */
94
+ canDropExternalEvent?: (data: ScheduleCanDropExternalEventData) => boolean;
95
+ /** Called on every pointer move while an event is resized to compute live feedback and again before the resize is committed, return `false` to reject the new size. Must be pure and cheap. */
96
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
97
+ /** If set, drops and resizes that would make the event overlap another event are rejected. Pass a function to decide per pair of events: return `true` to forbid the overlap. The function runs while dragging and resizing to compute live feedback, it must be pure and cheap. @default false */
98
+ preventEventOverlap?: PreventEventOverlap;
91
99
  /** If set, background events can be focused and clicked. Combined with event resize, timed background events in day and week views can also be resized. */
92
100
  withInteractiveBackgroundEvents?: boolean;
93
101
  /**
@@ -144,6 +152,8 @@ export interface ScheduleEmits {
144
152
  externalEventDrop: [dataTransfer: DataTransfer, dateTime: DateTimeStringValue];
145
153
  /** Emitted when an event is resized. */
146
154
  eventResize: [data: EventDropData];
155
+ /** Emitted when a drop or resize is rejected. */
156
+ eventPlacementRejected: [data: ScheduleEventPlacementRejectedData];
147
157
  }
148
158
  export type ScheduleFactory = Factory<{
149
159
  props: Omit<ScheduleProps, 'rootRef'>;
@@ -24,6 +24,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Schedu
24
24
  slotDragEnd: (rangeStart: string, rangeEnd: string) => any;
25
25
  externalEventDrop: (dataTransfer: DataTransfer, dateTime: string) => any;
26
26
  eventResize: (data: import("../..").EventDropData) => any;
27
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
27
28
  monthClick: (month: string) => any;
28
29
  "update:view": (view: ScheduleViewLevel) => any;
29
30
  }, string, import("vue").PublicProps, Readonly<ScheduleOwnProps> & Readonly<{
@@ -40,6 +41,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<Schedu
40
41
  onSlotDragEnd?: ((rangeStart: string, rangeEnd: string) => any) | undefined;
41
42
  onExternalEventDrop?: ((dataTransfer: DataTransfer, dateTime: string) => any) | undefined;
42
43
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
44
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
43
45
  onMonthClick?: ((month: string) => any) | undefined;
44
46
  "onUpdate:view"?: ((view: ScheduleViewLevel) => any) | undefined;
45
47
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, ScheduleSlots>;
@@ -40,6 +40,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<WeekVi
40
40
  slotDragEnd: (rangeStart: string, rangeEnd: string) => any;
41
41
  externalEventDrop: (dataTransfer: DataTransfer, dropDateTime: string) => any;
42
42
  eventResize: (data: import("../..").EventDropData) => any;
43
+ eventPlacementRejected: (data: import("../..").ScheduleEventPlacementRejectedData) => any;
43
44
  }, string, import("vue").PublicProps, Readonly<WeekViewOwnProps> & Readonly<{
44
45
  onDateChange?: ((date: string) => any) | undefined;
45
46
  onEventDragStart?: ((event: ScheduleEventData) => any) | undefined;
@@ -52,6 +53,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<WeekVi
52
53
  onSlotDragEnd?: ((rangeStart: string, rangeEnd: string) => any) | undefined;
53
54
  onExternalEventDrop?: ((dataTransfer: DataTransfer, dropDateTime: string) => any) | undefined;
54
55
  onEventResize?: ((data: import("../..").EventDropData) => any) | undefined;
56
+ onEventPlacementRejected?: ((data: import("../..").ScheduleEventPlacementRejectedData) => any) | undefined;
55
57
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, WeekViewSlots>;
56
58
  type __VLS_WithSlots<T, S> = T & {
57
59
  new (): {
@@ -1,5 +1,5 @@
1
1
  import type { EventDropData } from '../component-props';
2
- import type { ScheduleEventData, ScheduleMode } from '../types';
2
+ import type { PreventEventOverlap, ScheduleCanResizeEventToData, ScheduleEventData, ScheduleEventPlacementRejectedData, ScheduleMode } from '../types';
3
3
  type ResizeEdge = 'top' | 'bottom';
4
4
  interface HandleResizeStartInput {
5
5
  event: ScheduleEventData;
@@ -20,6 +20,10 @@ export interface UseEventResizeInput {
20
20
  onEventResize: (data: EventDropData) => void;
21
21
  canResizeEvent: () => ((event: ScheduleEventData) => boolean) | undefined;
22
22
  withBackgroundEvents?: () => boolean;
23
+ events?: () => ScheduleEventData[];
24
+ preventEventOverlap?: () => PreventEventOverlap | undefined;
25
+ canResizeEventTo?: () => ((data: ScheduleCanResizeEventToData) => boolean) | undefined;
26
+ onEventPlacementRejected?: (data: ScheduleEventPlacementRejectedData) => void;
23
27
  }
24
28
  export declare function useEventResize(input: UseEventResizeInput): {
25
29
  handleResizeStart: ({ event, edge, container, originalTop, originalHeight, eventDate, pointerEvent, }: HandleResizeStartInput) => void;
@@ -31,5 +35,6 @@ export declare function useEventResize(input: UseEventResizeInput): {
31
35
  } | null;
32
36
  isResizableEvent: (event: ScheduleEventData) => boolean;
33
37
  wasResizing: () => boolean;
38
+ resizeValid: import("vue").ComputedRef<boolean>;
34
39
  };
35
40
  export {};
@@ -1,5 +1,6 @@
1
1
  import type { EventDropData } from '../component-props';
2
2
  import type { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';
3
+ import type { PreventEventOverlap, ScheduleCanResizeEventToData, ScheduleEventPlacementRejectedData } from '../types';
3
4
  type ResizeEdge = 'start' | 'end';
4
5
  interface ResizeState {
5
6
  event: ScheduleEventData;
@@ -25,8 +26,13 @@ export declare function useHorizontalEventResize(input: {
25
26
  onEventResize: (data: EventDropData) => void;
26
27
  canResizeEvent: () => ((event: ScheduleEventData) => boolean) | undefined;
27
28
  withBackgroundEvents?: () => boolean;
29
+ events?: () => ScheduleEventData[];
30
+ preventEventOverlap?: () => PreventEventOverlap | undefined;
31
+ canResizeEventTo?: () => ((data: ScheduleCanResizeEventToData) => boolean) | undefined;
32
+ onEventPlacementRejected?: (data: ScheduleEventPlacementRejectedData) => void;
28
33
  }): {
29
34
  state: import("vue").ShallowRef<ResizeState | null, ResizeState | null>;
35
+ resizeValid: import("vue").Ref<boolean, boolean>;
30
36
  readonly resizingEdge: ResizeEdge | null;
31
37
  handleResizeStart: (params: {
32
38
  event: ScheduleEventData;
@@ -0,0 +1,26 @@
1
+ import type { DateTimeStringValue, PreventEventOverlap, ScheduleCanResizeEventToData, ScheduleEventData, ScheduleEventPlacementRejectedData } from '../types';
2
+ export interface EventResizeValidationOptions {
3
+ events?: ScheduleEventData[];
4
+ preventEventOverlap?: PreventEventOverlap;
5
+ canResizeEventTo?: (data: ScheduleCanResizeEventToData) => boolean;
6
+ onEventPlacementRejected?: (data: ScheduleEventPlacementRejectedData) => void;
7
+ }
8
+ export declare function validateEventResize({ event, start, end, edge, events, preventEventOverlap, canResizeEventTo, resourceId, }: EventResizeValidationOptions & {
9
+ event: ScheduleEventData;
10
+ start: DateTimeStringValue;
11
+ end: DateTimeStringValue;
12
+ edge: 'start' | 'end';
13
+ resourceId?: string | number;
14
+ }): {
15
+ valid: boolean;
16
+ conflicts: ScheduleEventData[];
17
+ reason: "overlap";
18
+ } | {
19
+ valid: boolean;
20
+ conflicts: never[];
21
+ reason: "rejected";
22
+ } | {
23
+ valid: boolean;
24
+ conflicts: never[];
25
+ reason: null;
26
+ };
package/lib/types.d.ts CHANGED
@@ -155,4 +155,42 @@ export interface DropTarget {
155
155
  /** Target slot index (for DayView/WeekView) */
156
156
  slotIndex?: number;
157
157
  }
158
+ export type PreventEventOverlap = boolean | ((stillEvent: ScheduleEventData, movingEvent: ScheduleEventData) => boolean);
159
+ export interface ScheduleCanDropEventData {
160
+ event: ScheduleEventData;
161
+ start: DateTimeStringValue;
162
+ end: DateTimeStringValue;
163
+ resourceId?: string | number;
164
+ }
165
+ export interface ScheduleCanDropExternalEventData {
166
+ dataTransfer: DataTransfer;
167
+ start: DateTimeStringValue;
168
+ resourceId?: string | number;
169
+ }
170
+ export interface ScheduleCanResizeEventToData {
171
+ event: ScheduleEventData;
172
+ start: DateTimeStringValue;
173
+ end: DateTimeStringValue;
174
+ edge: 'start' | 'end';
175
+ }
176
+ interface ScheduleEventPlacementRejectedBase {
177
+ start: DateTimeStringValue;
178
+ end: DateTimeStringValue;
179
+ conflicts: ScheduleEventData[];
180
+ reason: 'overlap' | 'rejected';
181
+ resourceId?: string | number;
182
+ }
183
+ export type ScheduleEventPlacementRejectedData = (ScheduleEventPlacementRejectedBase & {
184
+ action: 'drop';
185
+ event: ScheduleEventData;
186
+ }) | (ScheduleEventPlacementRejectedBase & {
187
+ action: 'resize';
188
+ event: ScheduleEventData;
189
+ edge: 'start' | 'end';
190
+ }) | (Omit<ScheduleEventPlacementRejectedBase, 'end'> & {
191
+ action: 'external-drop';
192
+ dataTransfer: DataTransfer;
193
+ reason: 'rejected';
194
+ conflicts: [];
195
+ });
158
196
  export {};
@@ -22,6 +22,8 @@ export { isAllDayEvent } from './is-all-day-event/is-all-day-event';
22
22
  export { validateEvent } from './validate-event/validate-event';
23
23
  export { sortEvents } from './sort-events/sort-events';
24
24
  export { isEventsOverlap } from './is-events-overlap/is-events-overlap';
25
+ export { isEventPlacementAllowed } from './is-event-placement-allowed/is-event-placement-allowed';
26
+ export type { IsEventPlacementAllowedInput } from './is-event-placement-allowed/is-event-placement-allowed';
25
27
  export { getVisibleEvents } from './get-visible-events/get-visible-events';
26
28
  export { isMultidayEvent } from './is-multiday-event/is-multiday-event';
27
29
  export { isEventInTimeRange } from './is-event-in-time-range/is-event-in-time-range';
@@ -0,0 +1,13 @@
1
+ import type { DateTimeStringValue, PreventEventOverlap, ScheduleEventData } from '../../types';
2
+ export interface IsEventPlacementAllowedInput {
3
+ event: ScheduleEventData;
4
+ start: DateTimeStringValue;
5
+ end: DateTimeStringValue;
6
+ events: ScheduleEventData[];
7
+ preventEventOverlap?: PreventEventOverlap;
8
+ resourceId?: string | number;
9
+ }
10
+ export declare function isEventPlacementAllowed({ event, start, end, events, preventEventOverlap, resourceId, }: IsEventPlacementAllowedInput): {
11
+ allowed: boolean;
12
+ conflicts: ScheduleEventData[];
13
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantine-vue/schedule",
3
- "version": "3.5.0",
3
+ "version": "3.7.0",
4
4
  "description": "Vue schedule and calendar components equivalent to @mantine/schedule",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -44,9 +44,9 @@
44
44
  "vue": "^3.5.0"
45
45
  },
46
46
  "peerDependencies": {
47
- "@mantine-vue/core": "3.5.0",
48
- "@mantine-vue/dates": "3.5.0",
49
- "@mantine-vue/hooks": "3.5.0",
47
+ "@mantine-vue/core": "3.7.0",
48
+ "@mantine-vue/dates": "3.7.0",
49
+ "@mantine-vue/hooks": "3.7.0",
50
50
  "dayjs": ">=1.0.0",
51
51
  "vue": "^3.5.0"
52
52
  }