nuxt-ui-elements-pro 0.1.5 → 0.1.6
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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +50 -15
- package/dist/runtime/components/EventCalendar.d.vue.ts +48 -42
- package/dist/runtime/components/EventCalendar.vue +116 -610
- package/dist/runtime/components/EventCalendar.vue.d.ts +48 -42
- package/dist/runtime/components/EventCalendarHeader.d.vue.ts +26 -0
- package/dist/runtime/components/EventCalendarHeader.vue +48 -0
- package/dist/runtime/components/EventCalendarHeader.vue.d.ts +26 -0
- package/dist/runtime/components/EventCalendarListView.d.vue.ts +25 -0
- package/dist/runtime/components/EventCalendarListView.vue +95 -0
- package/dist/runtime/components/EventCalendarListView.vue.d.ts +25 -0
- package/dist/runtime/components/EventCalendarMonthView.d.vue.ts +34 -0
- package/dist/runtime/components/EventCalendarMonthView.vue +336 -0
- package/dist/runtime/components/EventCalendarMonthView.vue.d.ts +34 -0
- package/dist/runtime/components/EventCalendarTimeGrid.d.vue.ts +31 -0
- package/dist/runtime/components/EventCalendarTimeGrid.vue +306 -0
- package/dist/runtime/components/EventCalendarTimeGrid.vue.d.ts +31 -0
- package/dist/runtime/composables/useEventCalendar.d.ts +52 -0
- package/dist/runtime/composables/useEventCalendar.js +362 -0
- package/dist/runtime/composables/useEventCalendarContext.d.ts +8 -0
- package/dist/runtime/composables/useEventCalendarContext.js +11 -0
- package/dist/runtime/composables/useEventCalendarDragDrop.d.ts +1 -1
- package/dist/runtime/composables/useEventCalendarDragDrop.js +11 -9
- package/dist/runtime/composables/useEventCalendarKeyboard.d.ts +20 -0
- package/dist/runtime/composables/useEventCalendarKeyboard.js +128 -0
- package/dist/runtime/composables/useEventCalendarResize.d.ts +31 -0
- package/dist/runtime/composables/useEventCalendarResize.js +87 -0
- package/dist/runtime/composables/useEventCalendarSelect.d.ts +21 -0
- package/dist/runtime/composables/useEventCalendarSelect.js +119 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/types/event-calendar.d.ts +169 -0
- package/dist/runtime/types/index.d.ts +4 -0
- package/dist/runtime/types/index.js +4 -0
- package/dist/runtime/utils/event-calendar.d.ts +22 -1
- package/dist/runtime/utils/event-calendar.js +199 -1
- package/dist/runtime/utils/recurrence.d.ts +30 -0
- package/dist/runtime/utils/recurrence.js +150 -0
- package/package.json +15 -6
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { toCalendarDate, toCalendarDateTime } from "@internationalized/date";
|
|
2
|
+
import { onUnmounted, ref } from "vue";
|
|
3
|
+
export function useEventCalendarResize(options) {
|
|
4
|
+
const { editable, normalizedEvents, gridConfig, slotHeight, onEventResize, onResizeStart, onResizeEnd } = options;
|
|
5
|
+
const resizingEventId = ref(null);
|
|
6
|
+
const resizePreviewHeightPx = ref(null);
|
|
7
|
+
let activeEvent = null;
|
|
8
|
+
let originalHeightPx = 0;
|
|
9
|
+
function onPointerMove(e) {
|
|
10
|
+
if (!activeEvent) return;
|
|
11
|
+
const config = gridConfig();
|
|
12
|
+
const deltaY = e.clientY - pointerStartY;
|
|
13
|
+
const rawHeight = originalHeightPx + deltaY;
|
|
14
|
+
const snappedHeight = Math.round(rawHeight / slotHeight) * slotHeight;
|
|
15
|
+
const minHeightPx = 15 / config.slotDuration * slotHeight;
|
|
16
|
+
const maxDurationMinutes = config.endHour * 60 - activeEvent.startMinutes;
|
|
17
|
+
const maxHeightPx = maxDurationMinutes / config.slotDuration * slotHeight;
|
|
18
|
+
resizePreviewHeightPx.value = Math.max(minHeightPx, Math.min(snappedHeight, maxHeightPx));
|
|
19
|
+
}
|
|
20
|
+
function onPointerUp(_e) {
|
|
21
|
+
document.removeEventListener("pointermove", onPointerMove);
|
|
22
|
+
document.removeEventListener("pointerup", onPointerUp);
|
|
23
|
+
if (activeEvent) {
|
|
24
|
+
const event2 = normalizedEvents.value.find((ev) => ev.id === activeEvent.id);
|
|
25
|
+
if (event2) {
|
|
26
|
+
onResizeEnd({ event: event2.original });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!activeEvent || resizePreviewHeightPx.value == null) {
|
|
30
|
+
cleanup();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (resizePreviewHeightPx.value === originalHeightPx) {
|
|
34
|
+
cleanup();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const config = gridConfig();
|
|
38
|
+
const newDurationMinutes = resizePreviewHeightPx.value / slotHeight * config.slotDuration;
|
|
39
|
+
const newEndMinutes = activeEvent.startMinutes + newDurationMinutes;
|
|
40
|
+
const newEndHour = Math.floor(newEndMinutes / 60);
|
|
41
|
+
const newEndMinute = Math.round(newEndMinutes % 60);
|
|
42
|
+
const startDate = toCalendarDate(activeEvent.start);
|
|
43
|
+
const newEnd = toCalendarDateTime(startDate).set({ hour: newEndHour, minute: newEndMinute });
|
|
44
|
+
const event = normalizedEvents.value.find((ev) => ev.id === activeEvent.id);
|
|
45
|
+
if (event) {
|
|
46
|
+
onEventResize({
|
|
47
|
+
event: event.original,
|
|
48
|
+
oldStart: event.start,
|
|
49
|
+
oldEnd: event.end,
|
|
50
|
+
newStart: event.start,
|
|
51
|
+
newEnd
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
cleanup();
|
|
55
|
+
}
|
|
56
|
+
let pointerStartY = 0;
|
|
57
|
+
function onResizePointerDown(event, e) {
|
|
58
|
+
if (!editable() || !event.resizable) return;
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
resizingEventId.value = event.id;
|
|
62
|
+
activeEvent = event;
|
|
63
|
+
originalHeightPx = event.heightPx;
|
|
64
|
+
resizePreviewHeightPx.value = event.heightPx;
|
|
65
|
+
pointerStartY = e.clientY;
|
|
66
|
+
const normalized = normalizedEvents.value.find((ev) => ev.id === event.id);
|
|
67
|
+
if (normalized) {
|
|
68
|
+
onResizeStart({ event: normalized.original });
|
|
69
|
+
}
|
|
70
|
+
document.addEventListener("pointermove", onPointerMove);
|
|
71
|
+
document.addEventListener("pointerup", onPointerUp);
|
|
72
|
+
}
|
|
73
|
+
function cleanup() {
|
|
74
|
+
resizingEventId.value = null;
|
|
75
|
+
resizePreviewHeightPx.value = null;
|
|
76
|
+
activeEvent = null;
|
|
77
|
+
}
|
|
78
|
+
onUnmounted(() => {
|
|
79
|
+
document.removeEventListener("pointermove", onPointerMove);
|
|
80
|
+
document.removeEventListener("pointerup", onPointerUp);
|
|
81
|
+
});
|
|
82
|
+
return {
|
|
83
|
+
resizingEventId,
|
|
84
|
+
resizePreviewHeightPx,
|
|
85
|
+
onResizePointerDown
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CalendarDate } from "@internationalized/date";
|
|
2
|
+
import type { CalendarView, SelectPayload } from "../types/event-calendar.js";
|
|
3
|
+
export interface UseEventCalendarSelectOptions {
|
|
4
|
+
selectable: () => boolean;
|
|
5
|
+
view: () => CalendarView;
|
|
6
|
+
slotDuration: () => number;
|
|
7
|
+
startHour: () => number;
|
|
8
|
+
endHour: () => number;
|
|
9
|
+
onSelect: (payload: SelectPayload) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function useEventCalendarSelect(options: UseEventCalendarSelectOptions): {
|
|
12
|
+
isSelecting: import("vue").Ref<boolean, boolean>;
|
|
13
|
+
preventNextClick: import("vue").Ref<boolean, boolean>;
|
|
14
|
+
isSlotInSelection: (date: CalendarDate, hour: number, minute: number) => boolean;
|
|
15
|
+
isDateInSelection: (date: CalendarDate) => boolean;
|
|
16
|
+
onSlotPointerDown: (date: CalendarDate, hour: number, minute: number, e: PointerEvent) => void;
|
|
17
|
+
onSlotPointerMove: (date: CalendarDate, hour: number, minute: number) => void;
|
|
18
|
+
onDayCellPointerDown: (date: CalendarDate, e: PointerEvent) => void;
|
|
19
|
+
onDayCellPointerMove: (date: CalendarDate) => void;
|
|
20
|
+
onSelectionPointerUp: () => void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { toCalendarDateTime } from "@internationalized/date";
|
|
2
|
+
import { ref, shallowRef } from "vue";
|
|
3
|
+
export function useEventCalendarSelect(options) {
|
|
4
|
+
const { selectable, slotDuration, onSelect } = options;
|
|
5
|
+
const isSelecting = ref(false);
|
|
6
|
+
const selectionAnchor = shallowRef(null);
|
|
7
|
+
const selectionEnd = shallowRef(null);
|
|
8
|
+
const preventNextClick = ref(false);
|
|
9
|
+
const didMove = ref(false);
|
|
10
|
+
function isEventTarget(e) {
|
|
11
|
+
const el = e.target;
|
|
12
|
+
if (!el) return false;
|
|
13
|
+
return !!el.closest("[data-slot='timeEvent'], [data-slot='eventChip']");
|
|
14
|
+
}
|
|
15
|
+
function toMinutes(point) {
|
|
16
|
+
return (point.hour ?? 0) * 60 + (point.minute ?? 0);
|
|
17
|
+
}
|
|
18
|
+
function clearState() {
|
|
19
|
+
isSelecting.value = false;
|
|
20
|
+
selectionAnchor.value = null;
|
|
21
|
+
selectionEnd.value = null;
|
|
22
|
+
didMove.value = false;
|
|
23
|
+
}
|
|
24
|
+
function onSlotPointerDown(date, hour, minute, e) {
|
|
25
|
+
if (!selectable() || e.button !== 0 || isEventTarget(e)) return;
|
|
26
|
+
selectionAnchor.value = { date, hour, minute };
|
|
27
|
+
selectionEnd.value = { date, hour, minute };
|
|
28
|
+
isSelecting.value = true;
|
|
29
|
+
didMove.value = false;
|
|
30
|
+
}
|
|
31
|
+
function onSlotPointerMove(date, hour, minute) {
|
|
32
|
+
if (!isSelecting.value || !selectionAnchor.value) return;
|
|
33
|
+
if (date.toString() !== selectionAnchor.value.date.toString()) return;
|
|
34
|
+
selectionEnd.value = { date, hour, minute };
|
|
35
|
+
didMove.value = true;
|
|
36
|
+
}
|
|
37
|
+
function onDayCellPointerDown(date, e) {
|
|
38
|
+
if (!selectable() || e.button !== 0 || isEventTarget(e)) return;
|
|
39
|
+
selectionAnchor.value = { date };
|
|
40
|
+
selectionEnd.value = { date };
|
|
41
|
+
isSelecting.value = true;
|
|
42
|
+
didMove.value = false;
|
|
43
|
+
}
|
|
44
|
+
function onDayCellPointerMove(date) {
|
|
45
|
+
if (!isSelecting.value || !selectionAnchor.value) return;
|
|
46
|
+
selectionEnd.value = { date };
|
|
47
|
+
didMove.value = true;
|
|
48
|
+
}
|
|
49
|
+
function onSelectionPointerUp() {
|
|
50
|
+
if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) {
|
|
51
|
+
clearState();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const anchor = selectionAnchor.value;
|
|
55
|
+
const end = selectionEnd.value;
|
|
56
|
+
const isTimeGrid = anchor.hour !== void 0;
|
|
57
|
+
if (isTimeGrid) {
|
|
58
|
+
const anchorMinutes = toMinutes(anchor);
|
|
59
|
+
const endMinutes = toMinutes(end);
|
|
60
|
+
const duration = slotDuration();
|
|
61
|
+
let startMinutes;
|
|
62
|
+
let finalEndMinutes;
|
|
63
|
+
if (anchorMinutes <= endMinutes) {
|
|
64
|
+
startMinutes = anchorMinutes;
|
|
65
|
+
finalEndMinutes = endMinutes + duration;
|
|
66
|
+
} else {
|
|
67
|
+
startMinutes = endMinutes;
|
|
68
|
+
finalEndMinutes = anchorMinutes + duration;
|
|
69
|
+
}
|
|
70
|
+
const startDt = toCalendarDateTime(anchor.date).set({
|
|
71
|
+
hour: Math.floor(startMinutes / 60),
|
|
72
|
+
minute: startMinutes % 60
|
|
73
|
+
});
|
|
74
|
+
const endDt = toCalendarDateTime(anchor.date).set({
|
|
75
|
+
hour: Math.floor(finalEndMinutes / 60),
|
|
76
|
+
minute: finalEndMinutes % 60
|
|
77
|
+
});
|
|
78
|
+
onSelect({ start: startDt, end: endDt, allDay: false });
|
|
79
|
+
} else {
|
|
80
|
+
const cmp = anchor.date.compare(end.date);
|
|
81
|
+
const startDate = cmp <= 0 ? anchor.date : end.date;
|
|
82
|
+
const endDate = cmp <= 0 ? end.date : anchor.date;
|
|
83
|
+
onSelect({ start: startDate, end: endDate, allDay: true });
|
|
84
|
+
}
|
|
85
|
+
if (didMove.value) {
|
|
86
|
+
preventNextClick.value = true;
|
|
87
|
+
}
|
|
88
|
+
clearState();
|
|
89
|
+
}
|
|
90
|
+
function isSlotInSelection(date, hour, minute) {
|
|
91
|
+
if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) return false;
|
|
92
|
+
if (selectionAnchor.value.hour === void 0) return false;
|
|
93
|
+
if (date.toString() !== selectionAnchor.value.date.toString()) return false;
|
|
94
|
+
const anchorMin = toMinutes(selectionAnchor.value);
|
|
95
|
+
const endMin = toMinutes(selectionEnd.value);
|
|
96
|
+
const slotMin = hour * 60 + minute;
|
|
97
|
+
const lo = Math.min(anchorMin, endMin);
|
|
98
|
+
const hi = Math.max(anchorMin, endMin);
|
|
99
|
+
return slotMin >= lo && slotMin <= hi;
|
|
100
|
+
}
|
|
101
|
+
function isDateInSelection(date) {
|
|
102
|
+
if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) return false;
|
|
103
|
+
if (selectionAnchor.value.hour !== void 0) return false;
|
|
104
|
+
const anchorCmp = date.compare(selectionAnchor.value.date);
|
|
105
|
+
const endCmp = date.compare(selectionEnd.value.date);
|
|
106
|
+
return anchorCmp >= 0 && endCmp <= 0 || anchorCmp <= 0 && endCmp >= 0;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
isSelecting,
|
|
110
|
+
preventNextClick,
|
|
111
|
+
isSlotInSelection,
|
|
112
|
+
isDateInSelection,
|
|
113
|
+
onSlotPointerDown,
|
|
114
|
+
onSlotPointerMove,
|
|
115
|
+
onDayCellPointerDown,
|
|
116
|
+
onDayCellPointerMove,
|
|
117
|
+
onSelectionPointerUp
|
|
118
|
+
};
|
|
119
|
+
}
|
package/dist/runtime/index.d.ts
CHANGED
package/dist/runtime/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { CalendarDate, CalendarDateTime, DateValue } from "@internationalized/date";
|
|
2
|
+
import type { ComputedRef, Ref, ShallowRef } from "vue";
|
|
3
|
+
/** All supported calendar view modes */
|
|
4
|
+
export type CalendarView = "month" | "week" | "day" | "list";
|
|
2
5
|
/**
|
|
3
6
|
* Represents an event on the calendar.
|
|
4
7
|
* Accepts flexible date inputs (Date, ISO string, or DateValue).
|
|
@@ -18,6 +21,16 @@ export interface CalendarEvent {
|
|
|
18
21
|
allDay?: boolean;
|
|
19
22
|
/** Whether this event can be dragged. Defaults to true */
|
|
20
23
|
draggable?: boolean;
|
|
24
|
+
/** Whether this event can be resized. Defaults to true */
|
|
25
|
+
resizable?: boolean;
|
|
26
|
+
/** RFC 5545 RRULE string, e.g. "FREQ=WEEKLY;BYDAY=MO,WE,FR". Requires the `rrule` package. */
|
|
27
|
+
rrule?: string;
|
|
28
|
+
/** Dates to exclude from the recurrence (RFC 5545 EXDATE) */
|
|
29
|
+
exdate?: (Date | string | DateValue)[];
|
|
30
|
+
/** Duration in minutes. Used to compute end for each occurrence. If absent, inferred from start/end. */
|
|
31
|
+
duration?: number;
|
|
32
|
+
/** ID of the parent recurring event. Present only on expanded occurrences (set internally). */
|
|
33
|
+
recurringEventId?: string | number;
|
|
21
34
|
}
|
|
22
35
|
/** Internal normalized event with parsed dates */
|
|
23
36
|
export interface NormalizedEvent {
|
|
@@ -28,7 +41,10 @@ export interface NormalizedEvent {
|
|
|
28
41
|
color: string;
|
|
29
42
|
allDay: boolean;
|
|
30
43
|
draggable: boolean;
|
|
44
|
+
resizable: boolean;
|
|
31
45
|
original: CalendarEvent;
|
|
46
|
+
/** ID of the parent recurring event. Present only on expanded occurrences. */
|
|
47
|
+
recurringEventId?: string | number;
|
|
32
48
|
}
|
|
33
49
|
/** A single day cell in the calendar grid */
|
|
34
50
|
export interface CalendarDay {
|
|
@@ -73,6 +89,9 @@ export interface DayViewOptions {
|
|
|
73
89
|
/** Minutes per time slot row @defaultValue 30 */
|
|
74
90
|
slotDuration?: 15 | 30 | 60;
|
|
75
91
|
}
|
|
92
|
+
/** List/agenda view configuration */
|
|
93
|
+
export interface ListViewOptions {
|
|
94
|
+
}
|
|
76
95
|
/** A timed event with computed pixel positions and overlap column info */
|
|
77
96
|
export interface PositionedEvent extends NormalizedEvent {
|
|
78
97
|
topPx: number;
|
|
@@ -89,4 +108,154 @@ export interface EventDropPayload {
|
|
|
89
108
|
oldEnd: CalendarDate | CalendarDateTime;
|
|
90
109
|
newStart: CalendarDate | CalendarDateTime;
|
|
91
110
|
newEnd: CalendarDate | CalendarDateTime;
|
|
111
|
+
/** Parent recurring event ID. Set when a recurring occurrence was dropped. */
|
|
112
|
+
recurringEventId?: string | number;
|
|
113
|
+
/** The specific occurrence date/time that was dragged. Set when a recurring occurrence was dropped. */
|
|
114
|
+
occurrenceDate?: CalendarDate | CalendarDateTime;
|
|
115
|
+
}
|
|
116
|
+
/** Payload emitted after a resize operation */
|
|
117
|
+
export interface EventResizePayload {
|
|
118
|
+
event: CalendarEvent;
|
|
119
|
+
oldStart: CalendarDate | CalendarDateTime;
|
|
120
|
+
oldEnd: CalendarDate | CalendarDateTime;
|
|
121
|
+
newStart: CalendarDate | CalendarDateTime;
|
|
122
|
+
newEnd: CalendarDate | CalendarDateTime;
|
|
123
|
+
}
|
|
124
|
+
/** Payload emitted after a click or drag selection */
|
|
125
|
+
export interface SelectPayload {
|
|
126
|
+
start: CalendarDate | CalendarDateTime;
|
|
127
|
+
end: CalendarDate | CalendarDateTime;
|
|
128
|
+
allDay: boolean;
|
|
129
|
+
}
|
|
130
|
+
/** A spanning event positioned within a week row of the month grid */
|
|
131
|
+
export interface MonthSpanningEvent {
|
|
132
|
+
event: NormalizedEvent;
|
|
133
|
+
/** 0-based column index where this bar starts within the week */
|
|
134
|
+
startCol: number;
|
|
135
|
+
/** Number of columns this bar spans */
|
|
136
|
+
span: number;
|
|
137
|
+
/** 0-based lane (row) index assigned by the greedy algorithm */
|
|
138
|
+
lane: number;
|
|
139
|
+
/** Whether this bar includes the event's true start date */
|
|
140
|
+
isStart: boolean;
|
|
141
|
+
/** Whether this bar includes the event's true end date */
|
|
142
|
+
isEnd: boolean;
|
|
143
|
+
}
|
|
144
|
+
/** A single-day event positioned within a week row of the month grid */
|
|
145
|
+
export interface MonthSingleDayEvent {
|
|
146
|
+
event: NormalizedEvent;
|
|
147
|
+
/** 0-based column index */
|
|
148
|
+
col: number;
|
|
149
|
+
/** 0-based row index among single-day events for this column */
|
|
150
|
+
row: number;
|
|
151
|
+
/** Pre-computed CSS grid row (accounts for per-column spanning offset) */
|
|
152
|
+
gridRow: number;
|
|
153
|
+
}
|
|
154
|
+
/** Per-day overflow info for "+N more" */
|
|
155
|
+
export interface MonthDayOverflow {
|
|
156
|
+
col: number;
|
|
157
|
+
hiddenCount: number;
|
|
158
|
+
hiddenEvents: NormalizedEvent[];
|
|
159
|
+
/** Grid row index for the "+N more" chip */
|
|
160
|
+
gridRow: number;
|
|
161
|
+
}
|
|
162
|
+
/** Complete layout data for one week row in the month view */
|
|
163
|
+
export interface MonthWeekLayout {
|
|
164
|
+
week: CalendarWeek;
|
|
165
|
+
spanning: MonthSpanningEvent[];
|
|
166
|
+
singleDay: MonthSingleDayEvent[];
|
|
167
|
+
overflow: MonthDayOverflow[];
|
|
168
|
+
/** Total event rows for grid-template-rows */
|
|
169
|
+
totalEventRows: number;
|
|
170
|
+
/** Number of spanning lanes used */
|
|
171
|
+
spanningLaneCount: number;
|
|
172
|
+
}
|
|
173
|
+
/** Layout for the all-day row in week/day time grid view */
|
|
174
|
+
export interface AllDayLayout {
|
|
175
|
+
/** Spanning event bars with lane assignments */
|
|
176
|
+
spanning: MonthSpanningEvent[];
|
|
177
|
+
/** Total number of lanes used */
|
|
178
|
+
laneCount: number;
|
|
179
|
+
}
|
|
180
|
+
/** A day column in the week/day time grid view */
|
|
181
|
+
export interface TimeGridDay extends CalendarDay {
|
|
182
|
+
dateKey: string;
|
|
183
|
+
allDayEvents: NormalizedEvent[];
|
|
184
|
+
timedEvents: PositionedEvent[];
|
|
185
|
+
}
|
|
186
|
+
/** The context provided by EventCalendar root to sub-components via provide/inject */
|
|
187
|
+
export interface EventCalendarContext {
|
|
188
|
+
displayDate: ComputedRef<CalendarDate>;
|
|
189
|
+
view: ComputedRef<CalendarView>;
|
|
190
|
+
locale: ComputedRef<string>;
|
|
191
|
+
weekStartsOn: ComputedRef<0 | 1 | 2 | 3 | 4 | 5 | 6>;
|
|
192
|
+
editable: ComputedRef<boolean>;
|
|
193
|
+
loading: ComputedRef<boolean>;
|
|
194
|
+
color: ComputedRef<string>;
|
|
195
|
+
monthConfig: ComputedRef<{
|
|
196
|
+
maxEvents: number;
|
|
197
|
+
fixedWeeks: boolean;
|
|
198
|
+
}>;
|
|
199
|
+
weekConfig: ComputedRef<{
|
|
200
|
+
startHour: number;
|
|
201
|
+
endHour: number;
|
|
202
|
+
slotDuration: number;
|
|
203
|
+
}>;
|
|
204
|
+
dayConfig: ComputedRef<{
|
|
205
|
+
startHour: number;
|
|
206
|
+
endHour: number;
|
|
207
|
+
slotDuration: number;
|
|
208
|
+
}>;
|
|
209
|
+
monthWeeks: ComputedRef<CalendarWeek[]>;
|
|
210
|
+
monthWeekLayouts: ComputedRef<MonthWeekLayout[]>;
|
|
211
|
+
weekdayLabels: ComputedRef<string[]>;
|
|
212
|
+
weekDays: ComputedRef<CalendarDay[]>;
|
|
213
|
+
dayViewDate: ComputedRef<CalendarDay>;
|
|
214
|
+
listDays: ComputedRef<CalendarDay[]>;
|
|
215
|
+
timeGridDays: ComputedRef<TimeGridDay[]>;
|
|
216
|
+
allDayLayout: ComputedRef<AllDayLayout>;
|
|
217
|
+
timeGridSlots: ComputedRef<TimeSlot[]>;
|
|
218
|
+
headerTitle: ComputedRef<string>;
|
|
219
|
+
formatTime: (d: CalendarDate | CalendarDateTime) => string;
|
|
220
|
+
formatTimeRange: (start: CalendarDate | CalendarDateTime, end: CalendarDate | CalendarDateTime) => string;
|
|
221
|
+
getEventStyle: (event: NormalizedEvent, bgOpacity?: number) => Record<string, string>;
|
|
222
|
+
isEventStart: (event: NormalizedEvent, date: CalendarDate) => boolean;
|
|
223
|
+
goToPrev: () => void;
|
|
224
|
+
goToNext: () => void;
|
|
225
|
+
goToToday: () => void;
|
|
226
|
+
setView: (v: CalendarView) => void;
|
|
227
|
+
handleDateClick: (day: CalendarDay) => void;
|
|
228
|
+
handleEventClick: (event: NormalizedEvent, e: Event) => void;
|
|
229
|
+
ui: ComputedRef<any>;
|
|
230
|
+
propUi: ComputedRef<any>;
|
|
231
|
+
draggedEventId: Ref<string | number | null>;
|
|
232
|
+
dropTargetKey: Ref<string | null>;
|
|
233
|
+
dragSnapSlot: Ref<string | null>;
|
|
234
|
+
onDragStart: (event: NormalizedEvent, e: DragEvent) => void;
|
|
235
|
+
onDragEnd: (e: DragEvent) => void;
|
|
236
|
+
onDragOver: (key: string, e: DragEvent) => void;
|
|
237
|
+
onDragLeave: () => void;
|
|
238
|
+
onTimeGridDragOver: (dateKey: string, e: DragEvent) => void;
|
|
239
|
+
onSlotDragOver: (slotKey: string, e: DragEvent) => void;
|
|
240
|
+
onDropMonthCell: (targetDate: CalendarDate, e: DragEvent) => void;
|
|
241
|
+
onDropTimeGrid: (targetDate: CalendarDate, e: DragEvent) => void;
|
|
242
|
+
resizingEventId: Ref<string | number | null>;
|
|
243
|
+
resizePreviewHeightPx: Ref<number | null>;
|
|
244
|
+
onResizePointerDown: (event: PositionedEvent, e: PointerEvent) => void;
|
|
245
|
+
focusedDate: ShallowRef<CalendarDate>;
|
|
246
|
+
isFocusedDate: (date: CalendarDate) => boolean;
|
|
247
|
+
onGridKeydown: (e: KeyboardEvent) => void;
|
|
248
|
+
formatDateAriaLabel: (date: CalendarDate) => string;
|
|
249
|
+
formatEventAriaLabel: (event: NormalizedEvent) => string;
|
|
250
|
+
selectable: ComputedRef<boolean>;
|
|
251
|
+
isSelecting: Ref<boolean>;
|
|
252
|
+
isSlotInSelection: (date: CalendarDate, hour: number, minute: number) => boolean;
|
|
253
|
+
isDateInSelection: (date: CalendarDate) => boolean;
|
|
254
|
+
onSlotPointerDown: (date: CalendarDate, hour: number, minute: number, e: PointerEvent) => void;
|
|
255
|
+
onSlotPointerMove: (date: CalendarDate, hour: number, minute: number) => void;
|
|
256
|
+
onDayCellPointerDown: (date: CalendarDate, e: PointerEvent) => void;
|
|
257
|
+
onDayCellPointerMove: (date: CalendarDate) => void;
|
|
258
|
+
onSelectionPointerUp: () => void;
|
|
259
|
+
preventNextClick: Ref<boolean>;
|
|
260
|
+
SLOT_HEIGHT: number;
|
|
92
261
|
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export * from "./event-calendar.js";
|
|
2
2
|
export * from "../components/EventCalendar.vue.js";
|
|
3
|
+
export * from "../components/EventCalendarHeader.vue.js";
|
|
4
|
+
export * from "../components/EventCalendarMonthView.vue.js";
|
|
5
|
+
export * from "../components/EventCalendarTimeGrid.vue.js";
|
|
6
|
+
export * from "../components/EventCalendarListView.vue.js";
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export * from "./event-calendar.js";
|
|
2
2
|
export * from "../components/EventCalendar.vue";
|
|
3
|
+
export * from "../components/EventCalendarHeader.vue";
|
|
4
|
+
export * from "../components/EventCalendarMonthView.vue";
|
|
5
|
+
export * from "../components/EventCalendarTimeGrid.vue";
|
|
6
|
+
export * from "../components/EventCalendarListView.vue";
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { CalendarDate, CalendarDateTime } from "@internationalized/date";
|
|
2
|
-
import type { NormalizedEvent, PositionedEvent } from "../types/event-calendar.js";
|
|
2
|
+
import type { NormalizedEvent, PositionedEvent, CalendarWeek, MonthWeekLayout, AllDayLayout, TimeGridDay } from "../types/event-calendar.js";
|
|
3
|
+
/**
|
|
4
|
+
* Compute the start of the week for any weekStartsOn value (0=Sunday … 6=Saturday).
|
|
5
|
+
* Uses getDayOfWeek with a fixed locale ('en-US') so Sunday is always 0.
|
|
6
|
+
*/
|
|
7
|
+
export declare function startOfWeekByDay(date: CalendarDate, weekStartsOn: number): CalendarDate;
|
|
8
|
+
/**
|
|
9
|
+
* Compute the end of the week for any weekStartsOn value.
|
|
10
|
+
*/
|
|
11
|
+
export declare function endOfWeekByDay(date: CalendarDate, weekStartsOn: number): CalendarDate;
|
|
3
12
|
/** Check whether a DateValue has hour/minute (CalendarDateTime vs CalendarDate) */
|
|
4
13
|
export declare function hasTimeComponent(d: CalendarDate | CalendarDateTime): boolean;
|
|
5
14
|
/**
|
|
@@ -14,3 +23,15 @@ export declare function layoutTimedEvents(events: NormalizedEvent[], config: {
|
|
|
14
23
|
endHour: number;
|
|
15
24
|
slotDuration: number;
|
|
16
25
|
}, slotHeight: number): PositionedEvent[];
|
|
26
|
+
/**
|
|
27
|
+
* Compute layout for one week row in the month view.
|
|
28
|
+
*
|
|
29
|
+
* Assigns spanning (all-day / multi-day) events to horizontal lanes,
|
|
30
|
+
* then positions single-day events below. Returns grid row info for rendering.
|
|
31
|
+
*/
|
|
32
|
+
export declare function layoutMonthWeekEvents(week: CalendarWeek, maxEvents: number): MonthWeekLayout;
|
|
33
|
+
/**
|
|
34
|
+
* Layout algorithm for the all-day row in week/day time grid views.
|
|
35
|
+
* Same greedy lane assignment as month view but without maxEvents cap or single-day partitioning.
|
|
36
|
+
*/
|
|
37
|
+
export declare function layoutAllDayEvents(days: TimeGridDay[]): AllDayLayout;
|