v-calendar-3 1.0.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 (147) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +142 -0
  3. package/dist/cjs/index.css +1133 -0
  4. package/dist/cjs/index.js +10699 -0
  5. package/dist/cjs/index.js.map +1 -0
  6. package/dist/cjs/package.json +1 -0
  7. package/dist/es/index.js +10678 -0
  8. package/dist/es/index.js.map +1 -0
  9. package/dist/es/style.css +1134 -0
  10. package/dist/iife/index.js +2 -0
  11. package/dist/iife/index.js.map +1 -0
  12. package/dist/mjs/index.mjs +10678 -0
  13. package/dist/mjs/index.mjs.map +1 -0
  14. package/dist/mjs/style.css +1134 -0
  15. package/dist/style.css +1134 -0
  16. package/dist/types/components/BaseIcon/BaseIcon.vue.d.ts +41 -0
  17. package/dist/types/components/BaseIcon/icons/IconChevronDown.vue.d.ts +3 -0
  18. package/dist/types/components/BaseIcon/icons/IconChevronLeft.vue.d.ts +3 -0
  19. package/dist/types/components/BaseIcon/icons/IconChevronRight.vue.d.ts +3 -0
  20. package/dist/types/components/BaseIcon/icons/IconClock.vue.d.ts +3 -0
  21. package/dist/types/components/BaseIcon/icons/index.d.ts +4 -0
  22. package/dist/types/components/BaseSelect/BaseSelect.vue.d.ts +26 -0
  23. package/dist/types/components/Calendar/Calendar.vue.d.ts +2526 -0
  24. package/dist/types/components/Calendar/CalendarDay.vue.d.ts +83 -0
  25. package/dist/types/components/Calendar/CalendarDayPopover.vue.d.ts +3 -0
  26. package/dist/types/components/Calendar/CalendarHeader.vue.d.ts +13 -0
  27. package/dist/types/components/Calendar/CalendarNav.vue.d.ts +4 -0
  28. package/dist/types/components/Calendar/CalendarNavPopover.vue.d.ts +3 -0
  29. package/dist/types/components/Calendar/CalendarPage.vue.d.ts +3 -0
  30. package/dist/types/components/Calendar/CalendarPageProvider.vue.d.ts +17 -0
  31. package/dist/types/components/Calendar/CalendarSlot.vue.d.ts +15 -0
  32. package/dist/types/components/Calendar/CalendarTitleSelect.vue.d.ts +15 -0
  33. package/dist/types/components/CalendarGrid/CalendarCell.vue.d.ts +9 -0
  34. package/dist/types/components/CalendarGrid/CalendarCellPopover.vue.d.ts +209 -0
  35. package/dist/types/components/CalendarGrid/CalendarDayCell.vue.d.ts +8 -0
  36. package/dist/types/components/CalendarGrid/CalendarEventDetails.vue.d.ts +15 -0
  37. package/dist/types/components/CalendarGrid/CalendarEventEdit.vue.d.ts +26 -0
  38. package/dist/types/components/CalendarGrid/CalendarGrid.vue.d.ts +134 -0
  39. package/dist/types/components/CalendarGrid/CalendarGridWeek.vue.d.ts +8 -0
  40. package/dist/types/components/CalendarGrid/CalendarViewSelect.vue.d.ts +3 -0
  41. package/dist/types/components/CalendarGrid/CalendarWeekCell.vue.d.ts +10 -0
  42. package/dist/types/components/CalendarGrid/Constraints.d.ts +16 -0
  43. package/dist/types/components/DatePicker/DatePicker.vue.d.ts +15251 -0
  44. package/dist/types/components/DatePicker/DatePickerBase.vue.d.ts +3 -0
  45. package/dist/types/components/DatePicker/DatePickerPopover.vue.d.ts +3 -0
  46. package/dist/types/components/DatePicker/TimePicker.vue.d.ts +10089 -0
  47. package/dist/types/components/Popover/Popover.vue.d.ts +72 -0
  48. package/dist/types/components/Popover/PopoverRow.vue.d.ts +17 -0
  49. package/dist/types/components/index.d.ts +4 -0
  50. package/dist/types/index.d.cts +40981 -0
  51. package/dist/types/index.d.mts +40981 -0
  52. package/dist/types/index.d.ts +40981 -0
  53. package/dist/types/use/base.d.ts +67 -0
  54. package/dist/types/use/calendar.d.ts +2422 -0
  55. package/dist/types/use/calendarGrid.d.ts +9370 -0
  56. package/dist/types/use/datePicker.d.ts +20210 -0
  57. package/dist/types/use/page.d.ts +20 -0
  58. package/dist/types/use/slots.d.ts +5 -0
  59. package/dist/types/use/timePicker.d.ts +10089 -0
  60. package/dist/types/utils/attribute.d.ts +49 -0
  61. package/dist/types/utils/cache.d.ts +10 -0
  62. package/dist/types/utils/calendar/event.d.ts +111 -0
  63. package/dist/types/utils/config/index.d.ts +5 -0
  64. package/dist/types/utils/date/helpers.d.ts +161 -0
  65. package/dist/types/utils/date/range.d.ts +74 -0
  66. package/dist/types/utils/date/repeat.d.ts +34 -0
  67. package/dist/types/utils/date/rules.d.ts +82 -0
  68. package/dist/types/utils/defaults/index.d.ts +30 -0
  69. package/dist/types/utils/defaults/locales.d.ts +9 -0
  70. package/dist/types/utils/glyph.d.ts +58 -0
  71. package/dist/types/utils/helpers.d.ts +49 -0
  72. package/dist/types/utils/locale.d.ts +48 -0
  73. package/dist/types/utils/page.d.ts +95 -0
  74. package/dist/types/utils/plugins/index.d.ts +4 -0
  75. package/dist/types/utils/popovers.d.ts +47 -0
  76. package/dist/types/utils/theme.d.ts +17 -0
  77. package/dist/types/utils/touch.d.ts +8 -0
  78. package/dist/types/utils/useDisplayMode.d.ts +12 -0
  79. package/dist/types/utils/watchers.d.ts +6 -0
  80. package/package.json +115 -0
  81. package/src/components/BaseIcon/BaseIcon.vue +29 -0
  82. package/src/components/BaseIcon/icons/IconChevronDown.vue +5 -0
  83. package/src/components/BaseIcon/icons/IconChevronLeft.vue +5 -0
  84. package/src/components/BaseIcon/icons/IconChevronRight.vue +5 -0
  85. package/src/components/BaseIcon/icons/IconClock.vue +11 -0
  86. package/src/components/BaseIcon/icons/index.ts +4 -0
  87. package/src/components/BaseSelect/BaseSelect.vue +136 -0
  88. package/src/components/Calendar/Calendar.vue +116 -0
  89. package/src/components/Calendar/CalendarDay.vue +422 -0
  90. package/src/components/Calendar/CalendarDayPopover.vue +44 -0
  91. package/src/components/Calendar/CalendarHeader.vue +203 -0
  92. package/src/components/Calendar/CalendarNav.vue +325 -0
  93. package/src/components/Calendar/CalendarNavPopover.vue +24 -0
  94. package/src/components/Calendar/CalendarPage.vue +140 -0
  95. package/src/components/Calendar/CalendarPageProvider.vue +15 -0
  96. package/src/components/Calendar/CalendarSlot.vue +36 -0
  97. package/src/components/Calendar/CalendarTitleSelect.vue +72 -0
  98. package/src/components/CalendarGrid/CalendarCell.vue +112 -0
  99. package/src/components/CalendarGrid/CalendarCellPopover.vue +93 -0
  100. package/src/components/CalendarGrid/CalendarDayCell.vue +57 -0
  101. package/src/components/CalendarGrid/CalendarEventDetails.vue +71 -0
  102. package/src/components/CalendarGrid/CalendarEventEdit.vue +195 -0
  103. package/src/components/CalendarGrid/CalendarGrid.vue +715 -0
  104. package/src/components/CalendarGrid/CalendarGridWeek.vue +60 -0
  105. package/src/components/CalendarGrid/CalendarViewSelect.vue +34 -0
  106. package/src/components/CalendarGrid/CalendarWeekCell.vue +52 -0
  107. package/src/components/CalendarGrid/Constraints.ts +40 -0
  108. package/src/components/DatePicker/DatePicker.vue +27 -0
  109. package/src/components/DatePicker/DatePickerBase.vue +53 -0
  110. package/src/components/DatePicker/DatePickerPopover.vue +37 -0
  111. package/src/components/DatePicker/TimePicker.vue +167 -0
  112. package/src/components/Popover/Popover.vue +572 -0
  113. package/src/components/Popover/PopoverRow.vue +94 -0
  114. package/src/components/index.ts +4 -0
  115. package/src/index.ts +24 -0
  116. package/src/styles/index.css +48 -0
  117. package/src/styles/theme.css +322 -0
  118. package/src/styles/transitions.css +77 -0
  119. package/src/use/base.ts +144 -0
  120. package/src/use/calendar.ts +796 -0
  121. package/src/use/calendarGrid.ts +954 -0
  122. package/src/use/datePicker.ts +909 -0
  123. package/src/use/page.ts +78 -0
  124. package/src/use/slots.ts +17 -0
  125. package/src/use/timePicker.ts +194 -0
  126. package/src/utils/attribute.ts +107 -0
  127. package/src/utils/cache.ts +30 -0
  128. package/src/utils/calendar/event.ts +335 -0
  129. package/src/utils/config/index.ts +11 -0
  130. package/src/utils/date/helpers.ts +1039 -0
  131. package/src/utils/date/range.ts +274 -0
  132. package/src/utils/date/repeat.ts +135 -0
  133. package/src/utils/date/rules.ts +290 -0
  134. package/src/utils/defaults/index.ts +77 -0
  135. package/src/utils/defaults/locales.ts +123 -0
  136. package/src/utils/defaults/masks.json +15 -0
  137. package/src/utils/defaults/touch.json +5 -0
  138. package/src/utils/glyph.ts +305 -0
  139. package/src/utils/helpers.ts +181 -0
  140. package/src/utils/locale.ts +275 -0
  141. package/src/utils/page.ts +608 -0
  142. package/src/utils/plugins/index.ts +24 -0
  143. package/src/utils/popovers.ts +216 -0
  144. package/src/utils/theme.ts +58 -0
  145. package/src/utils/touch.ts +72 -0
  146. package/src/utils/useDisplayMode.ts +198 -0
  147. package/src/utils/watchers.ts +26 -0
@@ -0,0 +1,335 @@
1
+ import { addDays } from 'date-fns';
2
+ import { type ComputedRef, computed, reactive, toRefs } from 'vue';
3
+ import type { DragOffset, ResizeOffset } from '../../use/calendarGrid';
4
+ import { MS_PER_MINUTE, roundDate } from '../date/helpers';
5
+ import { DateRange } from '../date/range';
6
+ import { clamp, omit } from '../helpers';
7
+ import Locale from '../locale';
8
+ import type { CalendarDay } from '../page';
9
+ import type { PopoverOptions } from '../popovers';
10
+
11
+ export interface ResizeOrigin {
12
+ start: Date;
13
+ end: Date;
14
+ isStart: boolean;
15
+ }
16
+
17
+ export interface DragOrigin {
18
+ day: CalendarDay;
19
+ start: Date;
20
+ end: Date;
21
+ minOffsetWeeks: number;
22
+ maxOffsetWeeks: number;
23
+ minOffsetWeekdays: number;
24
+ maxOffsetWeekdays: number;
25
+ minOffsetMs: number;
26
+ maxOffsetMs: number;
27
+ durationMs: number;
28
+ }
29
+
30
+ export interface EventConfig {
31
+ key: PropertyKey;
32
+ summary: string;
33
+ description: string;
34
+ start: Date;
35
+ end: Date;
36
+ range: DateRange;
37
+ allDay: boolean;
38
+ color: string;
39
+ selected: boolean;
40
+ }
41
+
42
+ export interface EventState {
43
+ key: any;
44
+ summary: string;
45
+ description: string;
46
+ range: DateRange;
47
+ allDay: boolean;
48
+ color: string;
49
+ fill: string;
50
+ selected: boolean;
51
+ draggable: boolean;
52
+ dragging: boolean;
53
+ resizable: boolean;
54
+ resizing: boolean;
55
+ editing: boolean;
56
+ order: number;
57
+ snapMinutes: number;
58
+ minDurationMinutes: number;
59
+ maxDurationMinutes: number;
60
+ popover: Partial<PopoverOptions> | null;
61
+ resizeOrigin: ResizeOrigin | null;
62
+ dragOrigin: DragOrigin | null;
63
+ }
64
+
65
+ export interface EventContext {
66
+ days: ComputedRef<CalendarDay[]>;
67
+ dayRows: ComputedRef<number>;
68
+ dayColumns: ComputedRef<number>;
69
+ isDaily: ComputedRef<boolean>;
70
+ isMonthly: ComputedRef<boolean>;
71
+ locale: ComputedRef<Locale>;
72
+ }
73
+
74
+ export type Event = ReturnType<typeof createEvent>;
75
+
76
+ export function createEvent(config: Partial<EventConfig>, ctx: EventContext) {
77
+ if (!config.key) throw new Error('Key required for events');
78
+
79
+ const range = rangeFromConfig(config);
80
+ if (!range) {
81
+ throw new Error('Start and end dates required for events');
82
+ }
83
+
84
+ const state: EventState = reactive({
85
+ key: config.key,
86
+ range,
87
+ allDay: false,
88
+ summary: 'New Event',
89
+ description: '',
90
+ color: 'indigo',
91
+ fill: 'light',
92
+ selected: false,
93
+ draggable: true,
94
+ dragging: false,
95
+ resizable: true,
96
+ resizing: false,
97
+ editing: false,
98
+ order: 0,
99
+ minDurationMinutes: 15,
100
+ maxDurationMinutes: 0,
101
+ snapMinutes: 15,
102
+ popover: null,
103
+ resizeOrigin: null,
104
+ dragOrigin: null,
105
+ ...omit(config, 'range', 'start', 'end'),
106
+ });
107
+
108
+ function rangeFromConfig({ range, start, end }: Partial<EventConfig>) {
109
+ if (range != null) return range;
110
+ if (!start || !end) {
111
+ throw new Error('Start and end dates required for events');
112
+ }
113
+ return ctx.locale.value.range({ start, end });
114
+ }
115
+
116
+ function formatDate(date: Date, mask: string) {
117
+ return locale.value.formatDate(date, mask);
118
+ }
119
+
120
+ function formatTime(date: Date) {
121
+ if (!date) return '';
122
+ return formatDate(date, 'h:mma');
123
+ }
124
+
125
+ const locale = computed(() => ctx.locale.value);
126
+
127
+ const refSelector = computed(() => `[data-cell-id="${state.key}"]`);
128
+ const minDurationMs = computed(
129
+ () => state.minDurationMinutes * MS_PER_MINUTE,
130
+ );
131
+ const maxDurationMs = computed(
132
+ () => state.maxDurationMinutes * MS_PER_MINUTE,
133
+ );
134
+ const snapMs = computed(() => state.snapMinutes * MS_PER_MINUTE);
135
+
136
+ const startDate = computed(() => state.range.start!.date);
137
+ const startDateTime = computed(() => startDate.value.getTime());
138
+ const startTimeLabel = computed(() => formatTime(startDate.value));
139
+
140
+ const endDate = computed(() => state.range.end!.date);
141
+ const endDateTime = computed(() => endDate.value.getTime());
142
+ const endTimeLabel = computed(() => formatTime(endDate.value));
143
+
144
+ const timeLabel = computed(() => {
145
+ return `${startTimeLabel.value} - ${endTimeLabel.value}`;
146
+ });
147
+
148
+ const durationMs = computed(
149
+ () => endDate.value.getTime() - startDate.value.getTime(),
150
+ );
151
+ const durationMinutes = computed(() => durationMs.value / MS_PER_MINUTE);
152
+
153
+ const isMultiDay = computed(() => state.range.isMultiDay);
154
+ const isWeekly = computed(() => state.allDay || isMultiDay.value);
155
+
156
+ const isSolid = computed(() => {
157
+ return state.allDay || !ctx.isMonthly.value;
158
+ });
159
+
160
+ const dragIsDirty = computed(() => {
161
+ const { dragging, dragOrigin } = state;
162
+ if (!dragging || !dragOrigin) return false;
163
+ return (
164
+ dragOrigin.start.getTime() !== startDateTime.value ||
165
+ dragOrigin.end.getTime() !== endDateTime.value
166
+ );
167
+ });
168
+
169
+ // #region Resizing
170
+
171
+ function startResize(day: CalendarDay, isStart: boolean) {
172
+ if (!state.resizable || state.resizing || state.dragging) return;
173
+ state.resizing = true;
174
+ state.resizeOrigin = {
175
+ start: state.range.start!.date,
176
+ end: state.range.end!.date,
177
+ isStart,
178
+ };
179
+ }
180
+
181
+ function updateResize(offset: ResizeOffset) {
182
+ if (!state.resizing || !state.resizeOrigin) return;
183
+ const { resizeOrigin } = state;
184
+ let { start, end } = resizeOrigin;
185
+ const weeksToAdd = offset.weeks;
186
+ const weekdaysToAdd = offset.weekdays;
187
+ const daysToAdd = weeksToAdd * ctx.dayColumns.value + weekdaysToAdd;
188
+ const msToAdd = offset.ms;
189
+ if (resizeOrigin.isStart) {
190
+ if (daysToAdd !== 0) {
191
+ start = addDays(resizeOrigin.start, daysToAdd);
192
+ }
193
+ if (msToAdd !== 0) {
194
+ start = new Date(resizeOrigin.start.getTime() + msToAdd);
195
+ }
196
+ } else {
197
+ if (daysToAdd !== 0) {
198
+ end = addDays(resizeOrigin.end, daysToAdd);
199
+ }
200
+ if (msToAdd !== 0) {
201
+ end = new Date(resizeOrigin.end.getTime() + msToAdd);
202
+ }
203
+ }
204
+ state.range = locale.value.range({ start, end });
205
+ resizeToConstraints();
206
+ }
207
+
208
+ function stopResize() {
209
+ state.resizing = false;
210
+ }
211
+
212
+ // #endregion Resizing
213
+
214
+ // #region Dragging
215
+
216
+ function startDrag(day: CalendarDay) {
217
+ if (!state.draggable || state.dragging || state.resizing) return;
218
+ state.dragging = true;
219
+ const start = state.range.start!.date;
220
+ const end = state.range.end!.date;
221
+ const durationMs = state.range.end!.dateTime - state.range.start!.dateTime;
222
+ const minOffsetWeeks = ctx.isMonthly.value ? -day.weekPosition + 1 : 0;
223
+ const maxOffsetWeeks = ctx.isMonthly.value
224
+ ? ctx.dayRows.value - day.weekPosition
225
+ : 0;
226
+ const minOffsetWeekdays = ctx.isDaily.value ? 0 : -day.weekdayPosition + 1;
227
+ const maxOffsetWeekdays = ctx.isDaily.value
228
+ ? 0
229
+ : ctx.dayColumns.value - day.weekdayPosition;
230
+ const minOffsetMs = day.startDate.getTime() - start.getTime();
231
+ const maxOffsetMs = day.endDate.getTime() - end.getTime();
232
+ state.dragOrigin = {
233
+ day,
234
+ start,
235
+ end,
236
+ durationMs,
237
+ minOffsetWeeks,
238
+ maxOffsetWeeks,
239
+ minOffsetWeekdays,
240
+ maxOffsetWeekdays,
241
+ minOffsetMs,
242
+ maxOffsetMs,
243
+ };
244
+ }
245
+
246
+ function updateDrag(offset: DragOffset) {
247
+ if (!state.dragging || !state.dragOrigin) return;
248
+ const {
249
+ durationMs,
250
+ minOffsetWeekdays,
251
+ maxOffsetWeekdays,
252
+ minOffsetWeeks,
253
+ maxOffsetWeeks,
254
+ minOffsetMs,
255
+ maxOffsetMs,
256
+ } = state.dragOrigin;
257
+ let { start } = state.dragOrigin;
258
+ const weeksToAdd = clamp(offset.weeks, minOffsetWeeks, maxOffsetWeeks);
259
+ const weekdaysToAdd = clamp(
260
+ offset.weekdays,
261
+ minOffsetWeekdays,
262
+ maxOffsetWeekdays,
263
+ );
264
+ const daysToAdd = weeksToAdd * ctx.dayColumns.value + weekdaysToAdd;
265
+ // Set the new date info
266
+ start = addDays(start, daysToAdd);
267
+ if (!ctx.isMonthly.value && !isWeekly.value) {
268
+ const msToAdd = clamp(offset.ms, minOffsetMs, maxOffsetMs);
269
+ start = roundDate(start.getTime() + msToAdd, snapMs.value);
270
+ }
271
+ const end = new Date(start.getTime() + durationMs);
272
+ state.range = locale.value.range({ start, end });
273
+ }
274
+
275
+ function stopDrag() {
276
+ if (!state.dragging || !state.dragOrigin) return false;
277
+ state.dragging = false;
278
+ state.dragOrigin = null;
279
+ }
280
+
281
+ // #endregion Dragging
282
+
283
+ function resizeToConstraints() {
284
+ if (state.allDay) return;
285
+ const { start, end } = state.range;
286
+ let startTime = start!.dateTime;
287
+ let endTime = end!.dateTime;
288
+ startTime = roundDate(startTime, snapMs.value).getTime();
289
+ endTime = roundDate(endTime, snapMs.value).getTime();
290
+ if (minDurationMs.value > 0 && endTime - startTime < minDurationMs.value) {
291
+ endTime = startTime + minDurationMs.value;
292
+ }
293
+ if (maxDurationMs.value > 0 && endTime - startTime > maxDurationMs.value) {
294
+ endTime = startTime + maxDurationMs.value;
295
+ }
296
+ state.range = locale.value.range({
297
+ start: new Date(startTime),
298
+ end: new Date(endTime),
299
+ });
300
+ }
301
+
302
+ function compareTo(b: Event) {
303
+ if (state.selected !== b.selected) return state.selected ? -1 : 1;
304
+ if (isWeekly.value && !b.isWeekly) return isWeekly.value ? -1 : -1;
305
+ return startDate.value.getTime() - b.startDate.getTime();
306
+ }
307
+
308
+ return reactive({
309
+ ...toRefs(state),
310
+ refSelector,
311
+ isMultiDay,
312
+ isWeekly,
313
+ durationMs,
314
+ durationMinutes,
315
+ startDate,
316
+ startDateTime,
317
+ startTimeLabel,
318
+ endDate,
319
+ endDateTime,
320
+ endTimeLabel,
321
+ timeLabel,
322
+ isSolid,
323
+ dragIsDirty,
324
+ formatDate,
325
+ formatTime,
326
+ resizeToConstraints,
327
+ startResize,
328
+ updateResize,
329
+ stopResize,
330
+ startDrag,
331
+ updateDrag,
332
+ stopDrag,
333
+ compareTo,
334
+ });
335
+ }
@@ -0,0 +1,11 @@
1
+ import type { App as Application } from 'vue';
2
+
3
+ const config = {};
4
+
5
+ export { config as default };
6
+
7
+ export let VueInstance: Application;
8
+
9
+ export const setVueInstance = (instance: Application) => {
10
+ VueInstance = instance;
11
+ };