1 | import { getWeekNumber } from './helpers/get-week-number';
|
2 | import { normalizeWeekday } from './helpers/normalize-weekday';
|
3 | import { toUTCDate } from './helpers/to-utc-date';
|
4 | import { toValidWeekday } from './helpers/to-valid-weekday';
|
5 | export function calendar(init) {
|
6 | const { date, dayFormat, disabledDates = [], disabledDays = [], firstDayOfWeek = 0, fullDateFormat, locale = 'en-US', max, min, showWeekNumber = false, weekNumberTemplate = 'Week %s', weekNumberType = 'first-4-day-week', } = init || {};
|
7 | const firstDayOfWeek2 = toValidWeekday(firstDayOfWeek);
|
8 | const dateYear = date.getUTCFullYear();
|
9 | const dateMonth = date.getUTCMonth();
|
10 | const firstDateOfMonth = toUTCDate(dateYear, dateMonth, 1);
|
11 | const disabledDaysSet = new Set(disabledDays.map(n => normalizeWeekday(n, firstDayOfWeek2, showWeekNumber)));
|
12 | const disabledDatesSet = new Set(disabledDates.map(n => +n));
|
13 | const calendarKey = [
|
14 | firstDateOfMonth.toJSON(),
|
15 | firstDayOfWeek2,
|
16 | locale,
|
17 | null == max ? '' : max.toJSON(),
|
18 | null == min ? '' : min.toJSON(),
|
19 | Array.from(disabledDaysSet).join(','),
|
20 | Array.from(disabledDatesSet).join(','),
|
21 | weekNumberType,
|
22 | ].filter(Boolean).join(':');
|
23 | const firstDayOfWeekOffset = normalizeWeekday(firstDateOfMonth.getUTCDay(), firstDayOfWeek2, showWeekNumber);
|
24 | const minTime = null == min ? +new Date('2000-01-01') : +min;
|
25 | const maxTime = null == max ? +new Date('2100-12-31') : +max;
|
26 | const colNum = showWeekNumber ? 8 : 7;
|
27 | const totalDays = toUTCDate(dateYear, 1 + dateMonth, 0).getUTCDate();
|
28 | const rows = [];
|
29 | let cols = [];
|
30 | let calendarComplete = false;
|
31 | let curDay = 1;
|
32 | for (const row of [0, 1, 2, 3, 4, 5]) {
|
33 | for (const col of ([0, 1, 2, 3, 4, 5, 6].concat(colNum === 7 ? [] : [7]))) {
|
34 | const idx = col + (row * colNum);
|
35 | if (!calendarComplete && showWeekNumber && col === 0) {
|
36 | const weekNumberOffset = row < 1 ? firstDayOfWeek2 : 0;
|
37 | const weekNumber = getWeekNumber(weekNumberType, toUTCDate(dateYear, dateMonth, curDay - weekNumberOffset));
|
38 | const weekLabel = weekNumberTemplate.replace('%s', String(weekNumber));
|
39 | cols.push({
|
40 | fullDate: null,
|
41 | label: weekLabel,
|
42 | value: `${weekNumber}`,
|
43 | key: `${calendarKey}:${weekLabel}`,
|
44 | disabled: true,
|
45 | });
|
46 | continue;
|
47 | }
|
48 | if (calendarComplete || idx < firstDayOfWeekOffset) {
|
49 | cols.push({
|
50 | fullDate: null,
|
51 | label: '',
|
52 | value: '',
|
53 | key: `${calendarKey}:${idx}`,
|
54 | disabled: true,
|
55 | });
|
56 | continue;
|
57 | }
|
58 | const curDate = toUTCDate(dateYear, dateMonth, curDay);
|
59 | const curTime = +curDate;
|
60 | const isDisabledDay = disabledDaysSet.has(col) ||
|
61 | disabledDatesSet.has(curTime) ||
|
62 | (curTime < minTime || curTime > maxTime);
|
63 | if (isDisabledDay)
|
64 | disabledDatesSet.add(curTime);
|
65 | cols.push({
|
66 | fullDate: curDate,
|
67 | label: fullDateFormat(curDate),
|
68 | value: dayFormat(curDate),
|
69 | key: `${calendarKey}:${curDate.toJSON()}`,
|
70 | disabled: isDisabledDay,
|
71 | });
|
72 | curDay += 1;
|
73 | if (curDay > totalDays)
|
74 | calendarComplete = true;
|
75 | }
|
76 | rows.push(cols);
|
77 | cols = [];
|
78 | }
|
79 | return {
|
80 | disabledDatesSet,
|
81 | calendar: rows,
|
82 | disabledDaysSet: new Set(disabledDays.map(n => toValidWeekday(n))),
|
83 | key: calendarKey,
|
84 | };
|
85 | }
|
86 |
|
\ | No newline at end of file |