@ipohjs/calendar
Version:
Minimal module to compute a calendar
145 lines • 6.37 kB
JavaScript
import { fromPartsToUtcDate } from './helpers/from-parts-to-utc-date.js';
import { getFormatter } from './helpers/get-formatter.js';
import { getWeekNumber } from './helpers/get-week-number.js';
import { normalizeWeekday } from './helpers/normalize-weekday.js';
import { toValidWeekday } from './helpers/to-valid-weekday.js';
export function calendar(maybeInit) {
const init = maybeInit || {};
const { calendarMode, date, dayFormat, disabledDates, disabledDays, firstDayOfWeek, fullDateFormat, locale, max, min, showWeekNumber, weekNumberTemplate, weekNumberType, } = init;
const calendarMode2 = calendarMode || 'grid';
const disabledDates2 = disabledDates || [];
const disabledDays2 = disabledDays || [];
const firstDayOfWeek2 = firstDayOfWeek || 0;
const locale2 = locale || 'en-US';
const showWeekNumber2 = showWeekNumber || false;
const weekNumberTemplate2 = weekNumberTemplate || 'Week %s';
const weekNumberType2 = weekNumberType || 'first-4-day-week';
const isCalendarFormatGrid = calendarMode2 === 'grid';
const validFirstDayOfWeek = toValidWeekday(firstDayOfWeek2);
const validShowWeekNumber = isCalendarFormatGrid ? showWeekNumber2 : false;
const validDisabledDays = disabledDays2.map((n) => toValidWeekday(n));
const validDisabledDates = disabledDates2.map((d) => +d);
const disabledDaysSet = new Set(validDisabledDays);
const disabledDaysSetWithOffset = new Set(disabledDays2.map((n) => normalizeWeekday(n, validFirstDayOfWeek, validShowWeekNumber)));
const disabledDatesSet = new Set(validDisabledDates);
const disabledDatesList = Array.from(disabledDatesSet);
const dateYear = date.getUTCFullYear();
const dateMonth = date.getUTCMonth();
const firstDateOfMonth = fromPartsToUtcDate(dateYear, dateMonth, 1);
const firstDateOfMonthStr = firstDateOfMonth.toJSON();
const simpleCalendarKey = `${firstDateOfMonthStr}:${locale2}`;
const additionalCol = isCalendarFormatGrid && validShowWeekNumber ? [7] : [];
const firstDayOfWeekOffset = normalizeWeekday(firstDateOfMonth.getUTCDay(), validFirstDayOfWeek, validShowWeekNumber);
const minTime = +(null == min ? new Date('2000-01-01') : min);
const maxTime = +(null == max ? new Date('2100-12-31') : max);
const rows = [];
const rowsList = [];
const totalDays = fromPartsToUtcDate(dateYear, 1 + dateMonth, 0).getUTCDate();
const dayFormat2 = getFormatter(dayFormat);
const fullDateFormat2 = getFormatter(fullDateFormat);
let calendarComplete = false;
let curDay = 1;
for (const rowIdx of [0, 1, 2, 3, 4, 5]) {
const cols = [0, 1, 2, 3, 4, 5, 6].concat(additionalCol);
const colLen = cols.length;
const columns = [];
const columnsOrRowsListToPush = isCalendarFormatGrid ? columns : rowsList;
for (const colIdx of cols) {
const idx = colIdx + rowIdx * colLen;
if (isCalendarFormatGrid &&
!calendarComplete &&
validShowWeekNumber &&
colIdx === 0) {
const weekNumberOffset = rowIdx < 1 ? validFirstDayOfWeek : 0;
const weekNumber = getWeekNumber(weekNumberType2, fromPartsToUtcDate(dateYear, dateMonth, curDay - weekNumberOffset));
const weekLabel = weekNumberTemplate2.replace('%s', String(weekNumber));
columns.push({
disabled: true,
fullDate: null,
key: `${simpleCalendarKey}:${weekLabel}`,
label: weekLabel,
value: `${weekNumber}`,
});
continue;
}
if (calendarComplete || idx < firstDayOfWeekOffset) {
columnsOrRowsListToPush.push({
disabled: true,
fullDate: null,
key: `${simpleCalendarKey}:empty-col-${idx}`,
label: '',
value: '',
});
continue;
}
const curDate = fromPartsToUtcDate(dateYear, dateMonth, curDay);
const curTime = +curDate;
const isDisabledDay = disabledDaysSetWithOffset.has(colIdx) ||
disabledDatesSet.has(curTime) ||
curTime < minTime ||
curTime > maxTime;
if (isDisabledDay)
disabledDatesSet.add(curTime);
columnsOrRowsListToPush.push({
disabled: isDisabledDay,
fullDate: curDate,
key: `${simpleCalendarKey}:${curDate.toJSON()}`,
label: fullDateFormat2(curDate),
value: dayFormat2(curDate),
});
curDay += 1;
if (curDay > totalDays)
calendarComplete = true;
}
if (isCalendarFormatGrid) {
rows.push({
columns,
key: `${simpleCalendarKey}:cal-row-${rowIdx}`,
});
}
}
const calendarKey = [
firstDateOfMonthStr,
validFirstDayOfWeek,
locale2,
null == max ? '' : max.toJSON(),
null == min ? '' : min.toJSON(),
Array.from(disabledDaysSet).join(','),
disabledDatesList.join(','),
weekNumberType2,
]
.filter(Boolean)
.join(':');
const baseResult = {
disabledDatesSet,
disabledDaysSet,
key: calendarKey,
};
const calendarResult = isCalendarFormatGrid
? ({
...baseResult,
datesGrid: rows,
toJSON() {
const { disabledDatesSet, disabledDaysSet, toJSON: _, ...rest } = this;
return {
...rest,
disabledDates: [...disabledDatesSet],
disabledDays: [...disabledDaysSet],
};
},
})
: ({
...baseResult,
datesList: rowsList,
toJSON() {
const { disabledDatesSet, disabledDaysSet, toJSON: _, ...rest } = this;
return {
...rest,
disabledDates: [...disabledDatesSet],
disabledDays: [...disabledDaysSet],
};
},
});
return calendarResult;
}
//# sourceMappingURL=calendar.js.map