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,608 @@
1
+ import {
2
+ type DateParts,
3
+ type DateSource,
4
+ type DayParts,
5
+ type MonthParts,
6
+ addDays,
7
+ addMonths,
8
+ daysInWeek,
9
+ getDayIndex,
10
+ weeksInMonth,
11
+ } from './date/helpers';
12
+ import { pad, pick } from './helpers';
13
+ import Locale from './locale';
14
+
15
+ export interface CalendarDay extends DayParts {
16
+ id: string;
17
+ position: number;
18
+ label: string;
19
+ ariaLabel: string;
20
+ weekdayPosition: number;
21
+ weekdayPositionFromEnd: number;
22
+ weekPosition: number;
23
+ isoWeeknumber: number;
24
+ startDate: Date;
25
+ noonDate: Date;
26
+ endDate: Date;
27
+ isToday: boolean;
28
+ isFirstDay: boolean;
29
+ isLastDay: boolean;
30
+ isDisabled: boolean;
31
+ isFocusable: boolean;
32
+ isFocused: boolean;
33
+ inMonth: boolean;
34
+ inPrevMonth: boolean;
35
+ inNextMonth: boolean;
36
+ onTop: boolean;
37
+ onBottom: boolean;
38
+ onLeft: boolean;
39
+ onRight: boolean;
40
+ classes: Array<string | object>;
41
+ locale: Locale;
42
+ }
43
+
44
+ export interface CalendarWeek {
45
+ id: string;
46
+ week: number;
47
+ weekPosition: number;
48
+ weeknumber: number;
49
+ isoWeeknumber: number;
50
+ weeknumberDisplay?: number;
51
+ days: CalendarDay[];
52
+ title: string;
53
+ }
54
+
55
+ export interface CalendarWeekday {
56
+ weekday: number;
57
+ label: string;
58
+ }
59
+
60
+ export type PageView = 'daily' | 'weekly' | 'monthly';
61
+
62
+ export type TitlePosition = 'center' | 'left' | 'right';
63
+
64
+ export interface Page {
65
+ id: string;
66
+ day?: number;
67
+ week?: number;
68
+ month: number;
69
+ year: number;
70
+ view: PageView;
71
+ trimWeeks: boolean;
72
+ position: number;
73
+ row: number;
74
+ rowFromEnd: number;
75
+ column: number;
76
+ columnFromEnd: number;
77
+ showWeeknumbers: boolean;
78
+ showIsoWeeknumbers: boolean;
79
+ weeknumberPosition: string;
80
+ monthTitle: string;
81
+ weekTitle?: string;
82
+ dayTitle?: string;
83
+ title: string;
84
+ titlePosition: TitlePosition;
85
+ shortMonthLabel: string;
86
+ monthLabel: string;
87
+ shortYearLabel: string;
88
+ yearLabel: string;
89
+ monthComps: MonthParts;
90
+ prevMonthComps: MonthParts;
91
+ nextMonthComps: MonthParts;
92
+ days: CalendarDay[];
93
+ weeks: CalendarWeek[];
94
+ weekdays: CalendarWeekday[];
95
+ viewDays: CalendarDay[];
96
+ viewWeeks: CalendarWeek[];
97
+ }
98
+
99
+ export type PageAddress = Pick<Page, 'day' | 'week' | 'month' | 'year'>;
100
+
101
+ export type PageConfig = Pick<
102
+ Page,
103
+ | 'day'
104
+ | 'week'
105
+ | 'month'
106
+ | 'year'
107
+ | 'view'
108
+ | 'titlePosition'
109
+ | 'trimWeeks'
110
+ | 'position'
111
+ | 'row'
112
+ | 'rowFromEnd'
113
+ | 'column'
114
+ | 'columnFromEnd'
115
+ | 'showWeeknumbers'
116
+ | 'showIsoWeeknumbers'
117
+ | 'weeknumberPosition'
118
+ >;
119
+
120
+ export type CachedPage = Pick<
121
+ Page,
122
+ | 'id'
123
+ | 'month'
124
+ | 'year'
125
+ | 'monthTitle'
126
+ | 'shortMonthLabel'
127
+ | 'monthLabel'
128
+ | 'shortYearLabel'
129
+ | 'yearLabel'
130
+ | 'monthComps'
131
+ | 'prevMonthComps'
132
+ | 'nextMonthComps'
133
+ | 'days'
134
+ | 'weeks'
135
+ | 'weekdays'
136
+ >;
137
+
138
+ const viewAddressKeys: Record<PageView, (keyof DateParts)[]> = {
139
+ daily: ['year', 'month', 'day'],
140
+ weekly: ['year', 'month', 'week'],
141
+ monthly: ['year', 'month'],
142
+ };
143
+
144
+ function getDays(
145
+ {
146
+ monthComps,
147
+ prevMonthComps,
148
+ nextMonthComps,
149
+ }: Pick<Page, 'monthComps' | 'prevMonthComps' | 'nextMonthComps'>,
150
+ locale: Locale,
151
+ ): CalendarDay[] {
152
+ const days: CalendarDay[] = [];
153
+ const {
154
+ firstDayOfWeek,
155
+ firstWeekday,
156
+ isoWeeknumbers,
157
+ weeknumbers,
158
+ numDays,
159
+ numWeeks,
160
+ } = monthComps;
161
+ const prevMonthDaysToShow =
162
+ firstWeekday +
163
+ (firstWeekday < firstDayOfWeek ? daysInWeek : 0) -
164
+ firstDayOfWeek;
165
+ let prevMonth = true;
166
+ let thisMonth = false;
167
+ let nextMonth = false;
168
+ let position = 0;
169
+ // Formatter for aria labels
170
+ const formatter = new Intl.DateTimeFormat(locale.id, {
171
+ weekday: 'long',
172
+ year: 'numeric',
173
+ month: 'short',
174
+ day: 'numeric',
175
+ });
176
+ // Init counters with previous month's data
177
+ let day = prevMonthComps.numDays - prevMonthDaysToShow + 1;
178
+ let dayFromEnd = prevMonthComps.numDays - day + 1;
179
+ let weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);
180
+ let weekdayOrdinalFromEnd = 1;
181
+ let week = prevMonthComps.numWeeks;
182
+ let weekFromEnd = 1;
183
+ let month = prevMonthComps.month;
184
+ let year = prevMonthComps.year;
185
+ // Store todays comps
186
+ const today = new Date();
187
+ const todayDay = today.getDate();
188
+ const todayMonth = today.getMonth() + 1;
189
+ const todayYear = today.getFullYear();
190
+ // Cycle through max weeks in month
191
+ for (let w = 1; w <= weeksInMonth; w++) {
192
+ // Cycle through days in week
193
+ for (
194
+ let i = 1, weekday = firstDayOfWeek;
195
+ i <= daysInWeek;
196
+ i++, weekday += weekday === daysInWeek ? 1 - daysInWeek : 1
197
+ ) {
198
+ // We need to know when to start counting actual month days
199
+ if (prevMonth && weekday === firstWeekday) {
200
+ // Reset counters for current month
201
+ day = 1;
202
+ dayFromEnd = monthComps.numDays;
203
+ weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);
204
+ weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);
205
+ week = 1;
206
+ weekFromEnd = numWeeks;
207
+ month = monthComps.month;
208
+ year = monthComps.year;
209
+ // ...and flag we're tracking actual month days
210
+ prevMonth = false;
211
+ thisMonth = true;
212
+ }
213
+ const startDate = locale.getDateFromParams(year, month, day, 0, 0, 0, 0);
214
+ const noonDate = locale.getDateFromParams(year, month, day, 12, 0, 0, 0);
215
+ const endDate = locale.getDateFromParams(
216
+ year,
217
+ month,
218
+ day,
219
+ 23,
220
+ 59,
221
+ 59,
222
+ 999,
223
+ );
224
+ const date = startDate;
225
+ const id = `${pad(year, 4)}-${pad(month, 2)}-${pad(day, 2)}`;
226
+ const weekdayPosition = i;
227
+ const weekdayPositionFromEnd = daysInWeek - i;
228
+ const weeknumber = weeknumbers[w - 1];
229
+ const isoWeeknumber = isoWeeknumbers[w - 1];
230
+ const isToday =
231
+ day === todayDay && month === todayMonth && year === todayYear;
232
+ const isFirstDay = thisMonth && day === 1;
233
+ const isLastDay = thisMonth && day === numDays;
234
+ const onTop = w === 1;
235
+ const onBottom = w === numWeeks;
236
+ const onLeft = i === 1;
237
+ const onRight = i === daysInWeek;
238
+ const dayIndex = getDayIndex(year, month, day);
239
+ days.push({
240
+ locale,
241
+ id,
242
+ position: ++position,
243
+ label: day.toString(),
244
+ ariaLabel: formatter.format(new Date(year, month - 1, day)),
245
+ day,
246
+ dayFromEnd,
247
+ weekday,
248
+ weekdayPosition,
249
+ weekdayPositionFromEnd,
250
+ weekdayOrdinal,
251
+ weekdayOrdinalFromEnd,
252
+ week,
253
+ weekFromEnd,
254
+ weekPosition: w,
255
+ weeknumber,
256
+ isoWeeknumber,
257
+ month,
258
+ year,
259
+ date,
260
+ startDate,
261
+ endDate,
262
+ noonDate,
263
+ dayIndex,
264
+ isToday,
265
+ isFirstDay,
266
+ isLastDay,
267
+ isDisabled: !thisMonth,
268
+ isFocusable: !thisMonth,
269
+ isFocused: false,
270
+ inMonth: thisMonth,
271
+ inPrevMonth: prevMonth,
272
+ inNextMonth: nextMonth,
273
+ onTop,
274
+ onBottom,
275
+ onLeft,
276
+ onRight,
277
+ classes: [
278
+ `id-${id}`,
279
+ `day-${day}`,
280
+ `day-from-end-${dayFromEnd}`,
281
+ `weekday-${weekday}`,
282
+ `weekday-position-${weekdayPosition}`,
283
+ `weekday-ordinal-${weekdayOrdinal}`,
284
+ `weekday-ordinal-from-end-${weekdayOrdinalFromEnd}`,
285
+ `week-${week}`,
286
+ `week-from-end-${weekFromEnd}`,
287
+ {
288
+ 'is-today': isToday,
289
+ 'is-first-day': isFirstDay,
290
+ 'is-last-day': isLastDay,
291
+ 'in-month': thisMonth,
292
+ 'in-prev-month': prevMonth,
293
+ 'in-next-month': nextMonth,
294
+ 'on-top': onTop,
295
+ 'on-bottom': onBottom,
296
+ 'on-left': onLeft,
297
+ 'on-right': onRight,
298
+ },
299
+ ],
300
+ });
301
+ // See if we've hit the last day of the month
302
+ if (thisMonth && isLastDay) {
303
+ thisMonth = false;
304
+ nextMonth = true;
305
+ // Reset counters to next month's data
306
+ day = 1;
307
+ dayFromEnd = numDays;
308
+ weekdayOrdinal = 1;
309
+ weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);
310
+ week = 1;
311
+ weekFromEnd = nextMonthComps.numWeeks;
312
+ month = nextMonthComps.month;
313
+ year = nextMonthComps.year;
314
+ // Still in the middle of the month (hasn't ended yet)
315
+ } else {
316
+ day++;
317
+ dayFromEnd--;
318
+ weekdayOrdinal = Math.floor((day - 1) / daysInWeek + 1);
319
+ weekdayOrdinalFromEnd = Math.floor((numDays - day) / daysInWeek + 1);
320
+ }
321
+ }
322
+ // Append week days
323
+ week++;
324
+ weekFromEnd--;
325
+ }
326
+ return days;
327
+ }
328
+
329
+ function getWeeks(
330
+ days: CalendarDay[],
331
+ showWeeknumbers: boolean,
332
+ showIsoWeeknumbers: boolean,
333
+ locale: Locale,
334
+ ): CalendarWeek[] {
335
+ const result = days.reduce(
336
+ (result: CalendarWeek[], day: CalendarDay, i) => {
337
+ const weekIndex = Math.floor(i / 7);
338
+ let week = result[weekIndex];
339
+ if (!week) {
340
+ week = {
341
+ id: `week-${weekIndex + 1}`,
342
+ title: '',
343
+ week: day.week,
344
+ weekPosition: day.weekPosition,
345
+ weeknumber: day.weeknumber,
346
+ isoWeeknumber: day.isoWeeknumber,
347
+ weeknumberDisplay: showWeeknumbers
348
+ ? day.weeknumber
349
+ : showIsoWeeknumbers
350
+ ? day.isoWeeknumber
351
+ : undefined,
352
+ days: [],
353
+ };
354
+ result[weekIndex] = week;
355
+ }
356
+ week.days.push(day);
357
+ return result;
358
+ },
359
+ Array(days.length / daysInWeek),
360
+ );
361
+ result.forEach(week => {
362
+ const fromDay = week.days[0];
363
+ const toDay = week.days[week.days.length - 1];
364
+ if (fromDay.month === toDay.month) {
365
+ week.title = `${locale.formatDate(fromDay.date, 'MMMM YYYY')}`;
366
+ } else if (fromDay.year === toDay.year) {
367
+ week.title = `${locale.formatDate(
368
+ fromDay.date,
369
+ 'MMM',
370
+ )} - ${locale.formatDate(toDay.date, 'MMM YYYY')}`;
371
+ } else {
372
+ week.title = `${locale.formatDate(
373
+ fromDay.date,
374
+ 'MMM YYYY',
375
+ )} - ${locale.formatDate(toDay.date, 'MMM YYYY')}`;
376
+ }
377
+ });
378
+ return result;
379
+ }
380
+
381
+ function getWeekdays(week: CalendarWeek, locale: Locale): CalendarWeekday[] {
382
+ return week.days.map(day => ({
383
+ label: locale.formatDate(day.date, locale.masks.weekdays),
384
+ weekday: day.weekday,
385
+ }));
386
+ }
387
+
388
+ export function getPageId(month: number, year: number) {
389
+ return `${year}.${pad(month, 2)}`;
390
+ }
391
+
392
+ export function getPageAddressForDate(
393
+ date: DateSource,
394
+ view: PageView,
395
+ locale: Locale,
396
+ ) {
397
+ return pick(
398
+ locale.getDateParts(locale.toDate(date)),
399
+ viewAddressKeys[view],
400
+ ) as PageAddress;
401
+ }
402
+
403
+ export function addPages(
404
+ { day, week, month, year }: PageAddress,
405
+ count: number,
406
+ view: PageView,
407
+ locale: Locale,
408
+ ): PageAddress {
409
+ if (view === 'daily' && day) {
410
+ const date = new Date(year, month - 1, day);
411
+ const newDate = addDays(date, count);
412
+ return {
413
+ day: newDate.getDate(),
414
+ month: newDate.getMonth() + 1,
415
+ year: newDate.getFullYear(),
416
+ };
417
+ } else if (view === 'weekly' && week) {
418
+ const comps = locale.getMonthParts(month, year);
419
+ const date = comps.firstDayOfMonth;
420
+ const newDate = addDays(date, (week - 1 + count) * 7);
421
+ const parts = locale.getDateParts(newDate);
422
+ return {
423
+ week: parts.week,
424
+ month: parts.month,
425
+ year: parts.year,
426
+ };
427
+ } else {
428
+ const date = new Date(year, month - 1, 1);
429
+ const newDate = addMonths(date, count);
430
+ return {
431
+ month: newDate.getMonth() + 1,
432
+ year: newDate.getFullYear(),
433
+ };
434
+ }
435
+ }
436
+
437
+ export function pageIsValid(page: PageAddress | null | undefined) {
438
+ return page != null && page.month != null && page.year != null;
439
+ }
440
+
441
+ export function pageIsBeforePage(
442
+ page: PageAddress | null | undefined,
443
+ comparePage: PageAddress | null | undefined,
444
+ ) {
445
+ if (!pageIsValid(page) || !pageIsValid(comparePage)) return false;
446
+ page = page as PageAddress;
447
+ comparePage = comparePage as PageAddress;
448
+ if (page.year !== comparePage.year) return page.year < comparePage.year;
449
+ if (page.month && comparePage.month && page.month !== comparePage.month)
450
+ return page.month < comparePage.month;
451
+ if (page.week && comparePage.week && page.week !== comparePage.week) {
452
+ return page.week < comparePage.week;
453
+ }
454
+ if (page.day && comparePage.day && page.day !== comparePage.day) {
455
+ return page.day < comparePage.day;
456
+ }
457
+ return false;
458
+ }
459
+
460
+ export function pageIsAfterPage(
461
+ page: PageAddress | null | undefined,
462
+ comparePage: PageAddress | null | undefined,
463
+ ) {
464
+ if (!pageIsValid(page) || !pageIsValid(comparePage)) return false;
465
+ page = page as PageAddress;
466
+ comparePage = comparePage as PageAddress;
467
+ if (page.year !== comparePage.year) {
468
+ return page.year > comparePage.year;
469
+ }
470
+ if (page.month && comparePage.month && page.month !== comparePage.month) {
471
+ return page.month > comparePage.month;
472
+ }
473
+ if (page.week && comparePage.week && page.week !== comparePage.week) {
474
+ return page.week > comparePage.week;
475
+ }
476
+ if (page.day && comparePage.day && page.day !== comparePage.day) {
477
+ return page.day > comparePage.day;
478
+ }
479
+ return false;
480
+ }
481
+
482
+ export function pageIsBetweenPages(
483
+ page: PageAddress | null | undefined,
484
+ fromPage: PageAddress | null | undefined,
485
+ toPage: PageAddress | null | undefined,
486
+ ) {
487
+ return (
488
+ (page || false) &&
489
+ !pageIsBeforePage(page, fromPage) &&
490
+ !pageIsAfterPage(page, toPage)
491
+ );
492
+ }
493
+
494
+ export function pageIsEqualToPage(
495
+ aPage: PageAddress | null | undefined,
496
+ bPage: PageAddress | null | undefined,
497
+ ) {
498
+ if (!aPage && bPage) return false;
499
+ if (aPage && !bPage) return false;
500
+ if (!aPage && !bPage) return true;
501
+ aPage = aPage as PageAddress;
502
+ bPage = bPage as PageAddress;
503
+ return (
504
+ aPage.year === bPage.year &&
505
+ aPage.month === bPage.month &&
506
+ aPage.week === bPage.week &&
507
+ aPage.day === bPage.day
508
+ );
509
+ }
510
+
511
+ export function pageRangeToArray(
512
+ from: PageAddress,
513
+ to: PageAddress,
514
+ view: PageView,
515
+ locale: Locale,
516
+ ) {
517
+ if (!pageIsValid(from) || !pageIsValid(to)) return [];
518
+ const result = [];
519
+ while (!pageIsAfterPage(from, to)) {
520
+ result.push(from);
521
+ from = addPages(from, 1, view, locale);
522
+ }
523
+ return result;
524
+ }
525
+
526
+ export function getPageKey(config: PageConfig) {
527
+ const { day, week, month, year } = config;
528
+ let id = `${year}-${pad(month, 2)}`;
529
+ if (week) id = `${id}-w${week}`;
530
+ if (day) id = `${id}-${pad(day, 2)}`;
531
+ return id;
532
+ }
533
+
534
+ export function getCachedPage(config: PageConfig, locale: Locale): CachedPage {
535
+ const { month, year, showWeeknumbers, showIsoWeeknumbers } = config;
536
+ const date = new Date(year, month - 1, 15);
537
+ const monthComps = locale.getMonthParts(month, year);
538
+ const prevMonthComps = locale.getPrevMonthParts(month, year);
539
+ const nextMonthComps = locale.getNextMonthParts(month, year);
540
+ const days = getDays({ monthComps, prevMonthComps, nextMonthComps }, locale);
541
+ const weeks = getWeeks(days, showWeeknumbers, showIsoWeeknumbers, locale);
542
+ const weekdays = getWeekdays(weeks[0], locale);
543
+ return {
544
+ id: getPageKey(config),
545
+ month,
546
+ year,
547
+ monthTitle: locale.formatDate(date, locale.masks.title),
548
+ shortMonthLabel: locale.formatDate(date, 'MMM'),
549
+ monthLabel: locale.formatDate(date, 'MMMM'),
550
+ shortYearLabel: year.toString().substring(2),
551
+ yearLabel: year.toString(),
552
+ monthComps,
553
+ prevMonthComps,
554
+ nextMonthComps,
555
+ days,
556
+ weeks,
557
+ weekdays,
558
+ };
559
+ }
560
+
561
+ export function getPage(config: PageConfig, cachedPage: CachedPage) {
562
+ const { day, week, view, trimWeeks } = config;
563
+ const page: Page = {
564
+ ...cachedPage,
565
+ ...config,
566
+ title: '',
567
+ viewDays: [],
568
+ viewWeeks: [],
569
+ };
570
+ switch (view) {
571
+ case 'daily': {
572
+ let dayObj = page.days.find(d => d.inMonth)!;
573
+ if (day) {
574
+ dayObj = page.days.find(d => d.day === day && d.inMonth) || dayObj;
575
+ } else if (week) {
576
+ dayObj = page.days.find(d => d.week === week && d.inMonth)!;
577
+ }
578
+ const weekObj = page.weeks[dayObj.week - 1];
579
+ page.viewWeeks = [weekObj];
580
+ page.viewDays = [dayObj];
581
+ page.week = dayObj.week;
582
+ page.weekTitle = weekObj.title;
583
+ page.day = dayObj.day;
584
+ page.dayTitle = dayObj.ariaLabel;
585
+ page.title = page.dayTitle;
586
+ break;
587
+ }
588
+ case 'weekly': {
589
+ page.week = week || 1;
590
+ const weekObj = page.weeks[page.week - 1];
591
+ page.viewWeeks = [weekObj];
592
+ page.viewDays = weekObj.days;
593
+ page.weekTitle = weekObj.title;
594
+ page.title = page.weekTitle;
595
+ break;
596
+ }
597
+ default: {
598
+ page.title = page.monthTitle;
599
+ page.viewWeeks = page.weeks.slice(
600
+ 0,
601
+ trimWeeks ? page.monthComps.numWeeks : undefined,
602
+ );
603
+ page.viewDays = page.days;
604
+ break;
605
+ }
606
+ }
607
+ return page;
608
+ }
@@ -0,0 +1,24 @@
1
+ import type { App as Application, Component } from 'vue';
2
+ import type { Defaults } from '../defaults';
3
+ import { get } from '../helpers';
4
+
5
+ export const registerComponent = (
6
+ instance: Application,
7
+ component: Component,
8
+ defaults: Defaults = {},
9
+ ) => {
10
+ if (component) {
11
+ const prefix = get(defaults, 'componentPrefix', '');
12
+ instance.component(`${prefix}${component.name}`, component);
13
+ }
14
+ };
15
+
16
+ export const registerComponentProgrammatic = (
17
+ instance: Application,
18
+ property: string,
19
+ component: Component,
20
+ ) => {
21
+ if (!instance.config.globalProperties.$test)
22
+ instance.config.globalProperties.$test = {};
23
+ instance.config.globalProperties.$test[property] = component;
24
+ };