@demark-pro/react-booking-calendar
Version:
A responsive customizable React Booking calendar with overbooking protection
1,131 lines (1,109 loc) • 144 kB
JavaScript
/*!
@demark-pro/react-booking-calendar v4.0.5
undefined
Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('memoize-one'), require('react-window'), require('react-virtualized-auto-sizer')) :
typeof define === 'function' && define.amd ? define(['exports', 'react', 'memoize-one', 'react-window', 'react-virtualized-auto-sizer'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Calendar = {}, global.React, global.memoize, global.reactWindow, global.AutoSizer));
})(this, (function (exports, React, memoize, reactWindow, AutoSizer) { 'use strict';
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var React__default = /*#__PURE__*/_interopDefaultCompat(React);
var memoize__default = /*#__PURE__*/_interopDefaultCompat(memoize);
var AutoSizer__default = /*#__PURE__*/_interopDefaultCompat(AutoSizer);
var _assign = function __assign() {
_assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return _assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var toDate = function toDate(value) {
return new Date(value);
};
var getGregorianFormat = function getGregorianFormat(format) {
return _assign(_assign({}, format), {
calendar: "gregory"
});
};
function formatDate(date, format, options) {
var _date = toDate(date);
return _date.toLocaleDateString(options === null || options === void 0 ? void 0 : options.locale, getGregorianFormat(format));
}
function formatNumber(value, options) {
var locale = options === null || options === void 0 ? void 0 : options.locale;
return new Intl.NumberFormat(locale, {
useGrouping: false
}).format(value);
}
function formatDay(date, options) {
return formatNumber(toDate(date).getDate(), options);
}
function formatMonthYear(date, options) {
return formatDate(date, {
month: "long",
year: "numeric"
}, options);
}
function addDays(date, amount) {
var _date = toDate(date);
if (!amount) return _date;
_date.setDate(_date.getDate() + amount);
return _date;
}
function addMonths(date, amount) {
var _date = toDate(date);
if (!amount) return _date;
var dayOfMonth = _date.getDate();
var endOfDesiredMonth = _date;
endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
var daysInMonth = endOfDesiredMonth.getDate();
if (dayOfMonth >= daysInMonth) {
return endOfDesiredMonth;
} else {
_date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
return _date;
}
}
function startOfDay(date) {
var _date = toDate(date);
_date.setHours(0, 0, 0, 0);
return _date;
}
function endOfDay(date) {
var _date = toDate(date);
_date.setHours(23, 59, 59, 999);
return _date;
}
function isSameDay(dateLeft, dateRight) {
var dateLeftStartOfDay = startOfDay(dateLeft);
var dateRightStartOfDay = startOfDay(dateRight);
return +dateLeftStartOfDay === +dateRightStartOfDay;
}
function isSameMonth(dateLeft, dateRight) {
var _dateLeft = toDate(dateLeft);
var _dateRight = toDate(dateRight);
return _dateLeft.getFullYear() === _dateRight.getFullYear() && _dateLeft.getMonth() === _dateRight.getMonth();
}
function isSameYear(dateLeft, dateRight) {
var _dateLeft = toDate(dateLeft);
var _dateRight = toDate(dateRight);
return _dateLeft.getFullYear() === _dateRight.getFullYear();
}
function isWeekend(date) {
var day = toDate(date).getDay();
return day === 0 || day === 6;
}
function isBefore(date, dateToCompare) {
var _date = toDate(date);
var _dateToCompare = toDate(dateToCompare);
return +_date < +_dateToCompare;
}
function isAfter(date, dateToCompare) {
var _date = toDate(date);
var _dateToCompare = toDate(dateToCompare);
return _date.getTime() > _dateToCompare.getTime();
}
function isEqual(leftDate, rightDate) {
var _dateLeft = toDate(leftDate);
var _dateRight = toDate(rightDate);
return +_dateLeft === +_dateRight;
}
function startOfWeek(date, options) {
var _a;
var weekStartsOn = (_a = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _a !== void 0 ? _a : 0;
var _date = toDate(date);
var day = _date.getDay();
var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
_date.setDate(_date.getDate() - diff);
_date.setHours(0, 0, 0, 0);
return _date;
}
function endOfWeek(date, options) {
var _a;
var weekStartsOn = (_a = options === null || options === void 0 ? void 0 : options.weekStartsOn) !== null && _a !== void 0 ? _a : 0;
var _date = toDate(date);
var day = _date.getDay();
var diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn);
_date.setDate(_date.getDate() + diff);
_date.setHours(23, 59, 59, 999);
return _date;
}
function startOfMonth(date) {
var _date = toDate(date);
_date.setDate(1);
_date.setHours(0, 0, 0, 0);
return _date;
}
function endOfMonth(date) {
var _date = toDate(date);
var month = _date.getMonth();
_date.setFullYear(_date.getFullYear(), month + 1, 0);
_date.setHours(23, 59, 59, 999);
return _date;
}
var isBetween = function isBetween(date, from, to, inclusivity) {
if (inclusivity === void 0) {
inclusivity = "()";
}
var isBeforeSome = inclusivity[0] === "{",
isAfterSome = inclusivity[1] === "}",
isBeforeEqual = inclusivity[0] === "[",
isAfterEqual = inclusivity[1] === "]";
if (isBeforeSome || isAfterSome) {
return (isBeforeSome ? isSameDay(from, date) || isBefore(from, date) : isBefore(from, date)) && (isAfterSome ? isSameDay(to, date) || isAfter(to, date) : isAfter(to, date));
}
return (isBeforeEqual ? isEqual(from, date) || isBefore(from, date) : isBefore(from, date)) && (isAfterEqual ? isEqual(to, date) || isAfter(to, date) : isAfter(to, date));
};
var isBetweenInterval = function isBetweenInterval(startDate, endDate, from, to, inclusivity) {
if (inclusivity === void 0) {
inclusivity = "()";
}
return isBetween(startDate, from, to, inclusivity) || isBetween(endDate, from, to, inclusivity);
};
function cn() {
var classes = [];
for (var _i = 0; _i < arguments.length; _i++) {
classes[_i] = arguments[_i];
}
return classes.filter(function (className) {
return typeof className === "string" && className.length > 0;
}).join(" ");
}
function getAttributes(attributes) {
return Object.entries(attributes).reduce(function (a, _a) {
var _b;
var k = _a[0],
v = _a[1];
return !!v ? _assign(_assign({}, a), (_b = {}, _b[k] = true, _b)) : a;
}, {});
}
var getSelectedDates = function getSelectedDates(selected) {
return selected.map(function (s) {
return s ? new Date(s) : null;
}).concat(Array.from({
length: 2 - selected.length
}, function () {
return null;
}));
};
var preProtection = function preProtection(date, state, commonProps) {
var protection = commonProps.protection,
range = commonProps.range,
isStart = commonProps.isStart,
selected = commonProps.selected;
if (state.isDisabled || !!protection) return null;
var startDate = selected[0],
endDate = selected[1];
if (range) return startDate ? [startDate, date] : [date];
return isStart ? [date, endDate] : [startDate, date];
};
var createMonthDays = memoize__default.default(function (_a) {
var dateOfMonth = _a.dateOfMonth,
options = _a.options;
var days = [];
var monthStart = startOfMonth(dateOfMonth);
var monthEnd = endOfMonth(dateOfMonth);
var weekStart = startOfWeek(monthStart, options);
var weekEnd = endOfWeek(monthEnd, options);
var day = weekStart;
while (day <= weekEnd) {
var cloneDay = day;
days.push({
date: cloneDay,
monthStartDate: monthStart
});
day = addDays(cloneDay, 1);
}
return days;
});
var createScrollableDays = memoize__default.default(function (_a) {
var dateOfMonth = _a.dateOfMonth,
options = _a.options,
_b = _a.monthsCount,
monthsCount = _b === void 0 ? 6 : _b;
var days = [];
var _loop_1 = function _loop_1(i) {
var currentMonth = addMonths(dateOfMonth, +i);
var monthDays = createMonthDays({
dateOfMonth: currentMonth,
options: options
});
var rowFiller = Array.from({
length: 7
}).map(function () {
return {
date: currentMonth,
monthStartDate: currentMonth,
isMonthRow: true
};
});
days = __spreadArray(__spreadArray(__spreadArray([], days, true), rowFiller, true), monthDays, true);
};
for (var i in Array.from({
length: monthsCount
})) {
_loop_1(i);
}
return days;
});
var getDayState = function getDayState(_a) {
var day = _a.day,
_b = _a.selected,
selected = _b === void 0 ? [] : _b,
_c = _a.reserved,
reserved = _c === void 0 ? [] : _c,
_d = _a.disabled,
disabled = _d === void 0 ? false : _d;
var date = day.date,
monthStartDate = day.monthStartDate;
var today = new Date();
var dayStart = startOfDay(date);
var dayEnd = endOfDay(date);
var todayStart = startOfDay(today);
var state = {};
state.isSameYear = date.getFullYear() === today.getFullYear();
state.isSameMonth = isSameMonth(date, monthStartDate);
state.isStartMonth = isSameDay(date, startOfMonth(date));
state.isEndMonth = isSameDay(date, endOfMonth(date));
state.isToday = isSameDay(date, today);
state.isPast = dayStart.getTime() < todayStart.getTime();
state.isSelectedStart = selected[0] ? isSameDay(date, selected[0]) : false;
state.isSelectedEnd = selected[1] ? isSameDay(date, selected[1]) : false;
state.isSelected = !!(selected[0] && selected[1] && isBetween(date, selected[0], selected[1], "{}"));
state.isReserved = reserved.some(function (r) {
return isBetween(dayEnd, r.startDate, r.endDate, "{}") && isBetween(dayStart, r.startDate, r.endDate, "{}");
});
state.isAvailable = !state.isReserved;
state.isReservedStart = reserved.some(function (r) {
return isSameDay(r.startDate, date);
});
state.isReservedEnd = reserved.some(function (r) {
return isSameDay(r.endDate, date);
});
state.isDisabled = typeof disabled === "function" ? disabled(date, state) : disabled;
return state;
};
function getDayAttributes(state, options) {
if (!options || !options.useAttributes) return {};
var attributes = {};
if (state.isSelected || state.isSelectedStart || state.isSelectedEnd) attributes["data-selected"] = true;
if (state.isSelectedStart) attributes["data-selected-start"] = true;
if (state.isSelectedEnd) attributes["data-selected-end"] = true;
if (state.isReserved) attributes["data-reserved"] = true;
if (state.isReservedStart) attributes["data-reserved-start"] = true;
if (state.isReservedEnd) attributes["data-reserved-end"] = true;
if (state.isPast) attributes["data-past"] = true;
if (state.isToday) attributes["data-today"] = true;
return attributes;
}
function isNumeric(value) {
return typeof value === "number";
}
var CalendarContainer = function CalendarContainer(props) {
var getClassNames = props.getClassNames,
children = props.children,
innerProps = props.innerProps;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
isScrollable = _a.isScrollable,
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["isScrollable", "className"]);
var classNames = getClassNames("CalendarContainer", className);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: classNames
}, getAttributes({
"data-scrollable": !!isScrollable
}), restInner), children);
};
var MonthContainer = function MonthContainer(props) {
var children = props.children,
innerProps = props.innerProps,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("MonthContainer", className)
}, restInner), children);
};
var WeekContainer = function WeekContainer(props) {
var getClassNames = props.getClassNames,
children = props.children,
innerProps = props.innerProps;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("WeekContainer", className)
}, restInner), children);
};
var DaysContainer = function DaysContainer(props) {
var getClassNames = props.getClassNames,
children = props.children,
innerProps = props.innerProps;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
role: "listbox",
className: getClassNames("DaysContainer", className)
}, restInner), children);
};
var DayContainer = function DayContainer(props) {
var date = props.date,
state = props.state,
innerProps = props.innerProps,
children = props.children,
getClassNames = props.getClassNames,
options = props.options;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_onClick = _a.onClick,
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["onClick", "className"]);
var attributes = getAttributes({
"data-selected": !!state.isSelected || !!state.isSelectedStart || !!state.isSelectedEnd,
"data-reserved": !!state.isReserved,
"data-past": !!state.isPast,
"data-start-month": !!state.isStartMonth,
"data-end-month": !!state.isEndMonth
});
return /*#__PURE__*/React__default.default.createElement("div", _assign({
"aria-label": formatDate(date, {}, options),
role: "option",
tabIndex: -1,
className: getClassNames("DayContainer", className),
onClick: function onClick() {
return _onClick && _onClick(date, state);
}
}, attributes, restInner), children);
};
var MonthArrowBack = function MonthArrowBack(props) {
var innerProps = props.innerProps,
getClassNames = props.getClassNames,
month = props.month,
year = props.year,
options = props.options;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
ariaLabel = _a["aria-label"],
restInner = __rest(_a, ["className", "aria-label"]);
var label = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : typeof month === "number" && typeof year === "number" ? formatMonthYear(new Date(year, month - 1), options) : "Previous month";
return /*#__PURE__*/React__default.default.createElement("button", _assign({
type: "button",
className: getClassNames("MonthArrowBack", className),
"aria-label": label
}, restInner), /*#__PURE__*/React__default.default.createElement("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, /*#__PURE__*/React__default.default.createElement("path", {
d: "M14 17a1 1 0 0 1-.707-.293l-4-4a1 1 0 0 1 0-1.414l4-4a1 1 0 1 1 1.414 1.414L11.414 12l3.293 3.293A1 1 0 0 1 14 17z"
})));
};
var MonthArrowNext = function MonthArrowNext(props) {
var innerProps = props.innerProps,
getClassNames = props.getClassNames,
month = props.month,
year = props.year,
options = props.options;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
ariaLabel = _a["aria-label"],
restInner = __rest(_a, ["className", "aria-label"]);
var label = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : typeof month === "number" && typeof year === "number" ? formatMonthYear(new Date(year, month + 1), options) : "Next month";
return /*#__PURE__*/React__default.default.createElement("button", _assign({
type: "button",
"aria-label": label,
className: getClassNames("MonthArrowNext", className)
}, restInner), /*#__PURE__*/React__default.default.createElement("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, /*#__PURE__*/React__default.default.createElement("path", {
d: "M14 17a1 1 0 0 1-.707-.293l-4-4a1 1 0 0 1 0-1.414l4-4a1 1 0 1 1 1.414 1.414L11.414 12l3.293 3.293A1 1 0 0 1 14 17z"
})));
};
var MonthContent = function MonthContent(props) {
var year = props.year,
month = props.month,
options = props.options,
innerProps = props.innerProps,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {};
_a.isScrollable;
var _b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["isScrollable", "className"]);
var date = new Date(year, month);
var monthContent = formatDate(date, {
month: "long"
}, options);
var yearContent = formatNumber(year, options);
var attributes = getAttributes({
"data-some-month": isSameMonth(date, new Date()),
"data-some-year": isSameYear(date, new Date())
});
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("MonthContent", className)
}, attributes, restInner), /*#__PURE__*/React__default.default.createElement("span", null, monthContent), /*#__PURE__*/React__default.default.createElement("span", null, yearContent));
};
var WeekContent = function WeekContent(props) {
var day = props.day,
options = props.options,
innerProps = props.innerProps,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
var startDate = startOfWeek(new Date(), options);
var date = addDays(startDate, day);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("WeekContent", className)
}, getAttributes({
"data-weekend": isWeekend(date)
}), restInner), formatDate(date, {
weekday: "short"
}, options));
};
var DayContent = function DayContent(props) {
var children = props.children,
innerProps = props.innerProps,
state = props.state,
options = props.options,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("DayContent", className)
}, getDayAttributes(state, options), restInner), children);
};
var DaySelection = function DaySelection(props) {
var innerProps = props.innerProps,
state = props.state,
options = props.options,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
if (!isShow$1(state)) return null;
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("DaySelection", className)
}, getDayAttributes(state, options), restInner));
};
var isShow$1 = function isShow(state) {
return state.isSelected || state.isSelectedStart || state.isSelectedEnd;
};
var DayToday = function DayToday(props) {
var innerProps = props.innerProps,
state = props.state,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
if (!state.isToday) return null;
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("DayToday", className)
}, restInner));
};
var DayReservation = function DayReservation(props) {
var innerProps = props.innerProps,
state = props.state,
getClassNames = props.getClassNames;
var _a = innerProps !== null && innerProps !== void 0 ? innerProps : {},
_b = _a.className,
className = _b === void 0 ? "" : _b,
restInner = __rest(_a, ["className"]);
if (!isShow(state)) return null;
return /*#__PURE__*/React__default.default.createElement("div", _assign({
className: getClassNames("DayReservation", className)
}, restInner));
};
var isShow = function isShow(state) {
return state.isReserved || state.isReservedStart || state.isReservedEnd;
};
var componentClasses = {
CalendarContainer: "calendar-container",
MonthContainer: "month-container",
MonthContent: "month-content",
MonthArrowBack: "month-arrow-back",
MonthArrowNext: "month-arrow-next",
WeekContainer: "week-container",
WeekContent: "week-content",
DaysContainer: "days-container",
DayContainer: "day-container",
DayContent: "day-content",
DaySelection: "day-selection",
DayReservation: "day-reservation",
DayToday: "day-today"
};
var components = {
CalendarContainer: CalendarContainer,
MonthContainer: MonthContainer,
MonthContent: MonthContent,
MonthArrowBack: MonthArrowBack,
MonthArrowNext: MonthArrowNext,
WeekContainer: WeekContainer,
WeekContent: WeekContent,
DaysContainer: DaysContainer,
DayContainer: DayContainer,
DayContent: DayContent,
DaySelection: DaySelection,
DayReservation: DayReservation,
DayToday: DayToday
};
var defaultComponents = function defaultComponents(componentsByProps) {
if (componentsByProps === void 0) {
componentsByProps = {};
}
return _assign(_assign({}, components), componentsByProps);
};
var selectedInit = [null, null];
var isStartInit = true;
var initialDateInit = new Date();
var reservedInit = [];
var rangeInit = false;
var disabledInit = false;
new Date().getMonth();
new Date().getFullYear();
var getProtectedTime = function getProtectedTime(date, reserved) {
var initTime = {
// startDate: startOfDay(date),
// endDate: endOfDay(date),
startDate: date,
endDate: date
};
var reserveEnd = reserved.find(function (d) {
return isSameDay(d.endDate, date);
});
var reserveStart = reserved.find(function (d) {
return isSameDay(d.startDate, date);
});
if (reserveEnd) initTime.startDate = new Date(reserveEnd.endDate);
if (reserveStart) initTime.endDate = new Date(reserveStart.startDate);
return initTime;
};
function getProtectedInterval(date, state, commonProps) {
var selected = commonProps.selected,
reserved = commonProps.reserved,
range = commonProps.range;
var validate = validateBooking(date, state, commonProps);
if (validate) return validate;
var startDate = selected[0],
endDate = selected[1];
var isStart = range ? !startDate : commonProps.isStart;
var freeTime = getProtectedTime(date, reserved);
var newStart = isStart ? isSameDay(date, new Date()) ? new Date() : freeTime.startDate : startDate;
var newEnd = !isStart ? freeTime.endDate : endDate;
var interval = [newStart || null, newEnd || null];
return {
overbookType: null,
interval: interval
};
}
var validateBooking = function validateBooking(date, state, commonProps) {
var selected = commonProps.selected,
reserved = commonProps.reserved,
range = commonProps.range;
var startDate = selected[0],
endDate = selected[1];
var isStart = range ? !startDate : commonProps.isStart;
var interval = [getProtectedTime(date, reserved).startDate];
// if "PAST"
if (state.isPast) return {
overbookType: "PAST",
interval: null
};
// if reserved between
if (!state.isAvailable) return {
overbookType: "BOOKED",
interval: null
};
// if selected length 0 or 2 then set selected date
if (range && (!startDate && !endDate || startDate && endDate)) {
return {
overbookType: null,
interval: interval
};
}
if (isStart) {
// if selected start date after end date
if (endDate && isBefore(endDate, date)) {
return {
overbookType: "AFTER_END",
interval: range ? interval : null
};
}
} else {
// if selected end date before start date
if (startDate && isBefore(date, startDate)) {
return {
overbookType: "BEFORE_START",
interval: range ? interval : null
};
}
}
var isReservedBetween = startDate && reserved.find(function (r) {
return isBetweenInterval(r.startDate, r.endDate, startDate, startOfDay(date));
});
// if booked beetwen start date and current date
if (isReservedBetween) {
return {
overbookType: "BOOKED_BETWEEN",
interval: range || isStart ? interval : null
};
}
return null;
};
function Calendar(props) {
var _a = props.selected,
selected = _a === void 0 ? selectedInit : _a,
_b = props.isStart,
isStart = _b === void 0 ? isStartInit : _b,
_c = props.initialDate,
initialDate = _c === void 0 ? initialDateInit : _c,
_d = props.reserved,
reserved = _d === void 0 ? reservedInit : _d,
_e = props.range,
range = _e === void 0 ? rangeInit : _e,
_f = props.protection,
protection = _f === void 0 ? true : _f,
_g = props.disabled,
disabled = _g === void 0 ? disabledInit : _g,
month = props.month,
year = props.year,
_h = props.components,
components = _h === void 0 ? {} : _h,
_j = props.classNames,
classNames = _j === void 0 ? {} : _j,
_k = props.options,
options = _k === void 0 ? {} : _k,
onOverbook = props.onOverbook,
onChange = props.onChange,
onMonthChange = props.onMonthChange,
onYearChange = props.onYearChange,
innerProps = __rest(props, ["selected", "isStart", "initialDate", "reserved", "range", "protection", "disabled", "month", "year", "components", "classNames", "options", "onOverbook", "onChange", "onMonthChange", "onYearChange"]);
var defaultDate = initialDate ? new Date(initialDate) : initialDateInit;
var initialMonth = isNumeric(month) ? month : defaultDate.getMonth();
var initialYear = isNumeric(year) ? year : defaultDate.getFullYear();
var _l = React.useState(initialMonth),
activeMonth = _l[0],
setActiveMonth = _l[1];
var _m = React.useState(initialYear),
activeYear = _m[0],
setActiveYear = _m[1];
var isMonthControlled = isNumeric(month);
var isYearControlled = isNumeric(year);
var isControled = isMonthControlled && isYearControlled;
React.useEffect(function () {
if (isMonthControlled) setActiveMonth(month);
}, [isMonthControlled, month]);
React.useEffect(function () {
if (isYearControlled) setActiveYear(year);
}, [isYearControlled, year]);
var currentMonth = isControled ? month : activeMonth;
var currentYear = isControled ? year : activeYear;
var _o = getSelectedDates(selected),
startDate = _o[0],
endDate = _o[1];
// ==============================
// getClassNames
// ==============================
var getClassNames = function getClassNames(name, classes) {
var defaultClass = "calendar__".concat(componentClasses[name]);
var propsClasses = classNames[name];
return cn(defaultClass, propsClasses, classes);
};
// ==============================
// commonProps
// ==============================
var commonProps = {
selected: [startDate, endDate],
reserved: reserved,
disabled: disabled,
protection: protection,
range: range,
isStart: isStart,
options: options,
getClassNames: getClassNames
};
// ==============================
// handleMonthChange
// ==============================
var handleChangeMonth = function handleChangeMonth(value) {
var _a = getMonthYear(value, currentYear),
newMonth = _a[0],
newYear = _a[1];
if (onMonthChange) onMonthChange(newMonth, newYear !== null && newYear !== void 0 ? newYear : currentYear);
if (newYear !== null && onYearChange) onYearChange(newYear);
if (isControled) return;
setActiveMonth(newMonth);
if (newYear !== null) setActiveYear(newYear);
};
// ==============================
// handleClickDay
// ==============================
var handleClickDay = function handleClickDay(date, state) {
var preSelected = preProtection(date, state, commonProps);
if (preSelected !== null) {
if (onChange) onChange(preSelected);
return;
}
var _a = getProtectedInterval(date, state, commonProps),
interval = _a.interval,
overbookType = _a.overbookType;
if (overbookType && !interval) {
if (onOverbook) onOverbook(date, overbookType);
return;
}
if (interval && onChange) onChange(interval);
return;
};
// ==============================
// Import components
// ==============================
var _p = defaultComponents(components),
CalendarContainer = _p.CalendarContainer,
MonthContainer = _p.MonthContainer,
MonthArrowBack = _p.MonthArrowBack,
MonthArrowNext = _p.MonthArrowNext,
MonthContent = _p.MonthContent,
WeekContainer = _p.WeekContainer,
WeekContent = _p.WeekContent,
DaysContainer = _p.DaysContainer,
DayContainer = _p.DayContainer,
DayContent = _p.DayContent,
DaySelection = _p.DaySelection,
DayReservation = _p.DayReservation,
DayToday = _p.DayToday;
var startMonth = new Date(currentYear, currentMonth);
var days = createMonthDays({
dateOfMonth: startMonth,
options: options
});
return /*#__PURE__*/React__default.default.createElement(CalendarContainer, _assign({}, commonProps, {
innerProps: _assign({}, innerProps)
}), /*#__PURE__*/React__default.default.createElement(MonthContainer, _assign({}, commonProps), /*#__PURE__*/React__default.default.createElement(MonthArrowBack, _assign({}, commonProps, {
month: currentMonth,
year: currentYear,
innerProps: {
onClick: function onClick() {
return handleChangeMonth(currentMonth - 1);
}
}
})), /*#__PURE__*/React__default.default.createElement(MonthContent, _assign({
month: currentMonth,
year: currentYear
}, commonProps)), /*#__PURE__*/React__default.default.createElement(MonthArrowNext, _assign({}, commonProps, {
month: currentMonth,
year: currentYear,
innerProps: {
onClick: function onClick() {
return handleChangeMonth(currentMonth + 1);
}
}
}))), /*#__PURE__*/React__default.default.createElement(WeekContainer, _assign({}, commonProps), Array.from({
length: 7
}).map(function (_, key) {
return /*#__PURE__*/React__default.default.createElement(WeekContent, _assign({
key: "calendar_week_container_".concat(key),
day: key
}, commonProps, {
innerProps: {}
}));
})), /*#__PURE__*/React__default.default.createElement(DaysContainer, _assign({}, commonProps), days.map(function (day, key) {
var dayProps = {
date: day.date,
state: getDayState({
day: day,
selected: selected,
reserved: reserved,
disabled: disabled
})
};
return /*#__PURE__*/React__default.default.createElement(DayContainer, _assign({
key: "calendar_day_container_".concat(key),
innerProps: {
onClick: handleClickDay
}
}, dayProps, commonProps), /*#__PURE__*/React__default.default.createElement(DayContent, _assign({}, dayProps, commonProps), formatDay(day.date, options)), /*#__PURE__*/React__default.default.createElement(DayToday, _assign({}, dayProps, commonProps)), /*#__PURE__*/React__default.default.createElement(DaySelection, _assign({}, dayProps, commonProps)), /*#__PURE__*/React__default.default.createElement(DayReservation, _assign({}, dayProps, commonProps)));
})));
}
var getMonthYear = function getMonthYear(newMonth, year) {
var month = newMonth;
var newYear = null;
if (newMonth > 11) {
month = 0;
newYear = year + 1;
}
if (newMonth < 0) {
month = 11;
newYear = year - 1;
}
return [month, newYear];
};
// ==============================
// Cell
// ==============================
var Cell = /*#__PURE__*/React.memo(function (_a) {
var columnIndex = _a.columnIndex,
rowIndex = _a.rowIndex,
style = _a.style,
data = _a.data;
var days = data.days,
components = data.components,
commonProps = data.commonProps,
onChange = data.onChange,
onOverbook = data.onOverbook;
var selected = commonProps.selected,
reserved = commonProps.reserved,
disabled = commonProps.disabled,
options = commonProps.options;
var MonthContainer = components.MonthContainer,
MonthContent = components.MonthContent,
DayContainer = components.DayContainer,
DayContent = components.DayContent,
DayToday = components.DayToday,
DaySelection = components.DaySelection,
DayReservation = components.DayReservation;
var dayIndex = rowIndex * 7 + columnIndex;
var day = days[dayIndex];
if (!day) return null;
var date = day.date;
var state = getDayState({
day: day,
selected: selected,
reserved: reserved,
disabled: disabled
});
var handleClickDay = function handleClickDay() {
var preSelected = preProtection(date, state, commonProps);
if (preSelected !== null) {
if (onChange) onChange(preSelected);
return;
}
var _a = getProtectedInterval(date, state, commonProps),
interval = _a.interval,
overbookType = _a.overbookType;
if (overbookType && !interval) {
if (onOverbook) onOverbook(date, overbookType);
return;
}
if (interval && onChange) onChange(interval);
};
if (day.isMonthRow) {
if (columnIndex !== 3) return null;
return /*#__PURE__*/React__default.default.createElement(MonthContainer, _assign({}, commonProps, {
innerProps: {
style: style
}
}), /*#__PURE__*/React__default.default.createElement(MonthContent, _assign({
month: day.date.getMonth(),
year: day.date.getFullYear()
}, commonProps, {
innerProps: {
isScrollable: true
}
})));
}
var dayProps = {
date: day.date,
state: state
};
return /*#__PURE__*/React__default.default.createElement(DayContainer, _assign({
innerProps: {
style: style,
onClick: handleClickDay
}
}, dayProps, commonProps), state.isSameMonth && /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, /*#__PURE__*/React__default.default.createElement(DayContent, _assign({}, dayProps, commonProps), formatDay(day.date, options)), /*#__PURE__*/React__default.default.createElement(DayToday, _assign({}, dayProps, {
state: state
}, commonProps)), /*#__PURE__*/React__default.default.createElement(DaySelection, _assign({}, dayProps, {
state: state
}, commonProps)), /*#__PURE__*/React__default.default.createElement(DayReservation, _assign({}, dayProps, {
state: state
}, commonProps))));
}, reactWindow.areEqual);
var Grid = function Grid(_a) {
var width = _a.width,
height = _a.height,
colHeight = _a.colHeight,
items = _a.items,
initialScroll = _a.initialScroll,
components = _a.components,
commonProps = _a.commonProps,
isStart = _a.isStart,
range = _a.range,
onOverbook = _a.onOverbook,
onScroll = _a.onScroll,
onChange = _a.onChange,
props = __rest(_a, ["width", "height", "colHeight", "items", "initialScroll", "components", "commonProps", "isStart", "range", "onOverbook", "onScroll", "onChange"]);
React.useEffect(function () {}, [items, initialScroll]);
return /*#__PURE__*/React__default.default.createElement(reactWindow.FixedSizeGrid, _assign({
height: height,
width: width,
columnCount: 7,
columnWidth: width / 7,
rowCount: items.length / 7,
rowHeight: colHeight,
overscanRowCount: 4,
initialScrollTop: getInitialScroll(colHeight, items, initialScroll),
itemData: {
days: items,
commonProps: commonProps,
components: components,
isStart: isStart,
range: range,
onOverbook: onOverbook,
onChange: onChange
},
onScroll: onScroll
}, props), Cell);
};
var ScrollableCalendar = function ScrollableCalendar(props) {
var _a = props.startMonth,
startMonth = _a === void 0 ? new Date() : _a,
_b = props.selected,
selected = _b === void 0 ? selectedInit : _b,
_c = props.reserved,
reserved = _c === void 0 ? reservedInit : _c,
_d = props.components,
components = _d === void 0 ? {} : _d,
_e = props.classNames,
classNames = _e === void 0 ? {} : _e,
_f = props.isStart,
isStart = _f === void 0 ? isStartInit : _f,
_g = props.range,
range = _g === void 0 ? rangeInit : _g,
_h = props.disabled,
disabled = _h === void 0 ? disabledInit : _h,
_j = props.protection,
protection = _j === void 0 ? false : _j,
initialScroll = props.initialScroll,
_k = props.monthsCount,
monthsCount = _k === void 0 ? 6 : _k,
_l = props.colHeight,
colHeight = _l === void 0 ? 55 : _l,
_m = props.options,
options = _m === void 0 ? {} : _m,
onOverbook = props.onOverbook,
onChange = props.onChange,
onScroll = props.onScroll,
innerProps = __rest(props, ["startMonth", "selected", "reserved", "components", "classNames", "isStart", "range", "disabled", "protection", "initialScroll", "monthsCount", "colHeight", "options", "onOverbook", "onChange", "onScroll"]);
var _o = getSelectedDates(selected),
startDate = _o[0],
endDate = _o[1];
// ==============================
// getClassNames
// ==============================
var getClassNames = function getClassNames(compName, classes) {
var defaultClass = "calendar__".concat(componentClasses[compName]);
var propsClasses = classNames[compName];
return cn(defaultClass, propsClasses, classes);
};
var commonProps = {
selected: [startDate, endDate],
reserved: reserved,
disabled: disabled,
protection: protection,
range: range,
isStart: isStart,
options: options,
getClassNames: getClassNames
};
var calendarComponents = defaultComponents(components);
var CalendarContainer = calendarComponents.CalendarContainer,
WeekContainer = calendarComponents.WeekContainer,
WeekContent = calendarComponents.WeekContent,
DaysContainer = calendarComponents.DaysContainer;
var items = createScrollableDays({
dateOfMonth: startMonth,
monthsCount: monthsCount,
options: options
});
return /*#__PURE__*/React__default.default.createElement(CalendarContainer, _assign({}, commonProps, {
innerProps: _assign(_assign({}, innerProps), {
isScrollable: true
})
}), /*#__PURE__*/React__default.default.createElement(WeekContainer, _assign({
innerProps: {}
}, commonProps), Array.from({
length: 7
}).map(function (_, key) {
return /*#__PURE__*/React__default.default.createElement(WeekContent, _assign({
key: "scrollable_calendar_week_container_".concat(key),
day: key
}, commonProps, {
innerProps: {}
}));
})), /*#__PURE__*/React__default.default.createElement(DaysContainer, _assign({}, commonProps), /*#__PURE__*/React__default.default.createElement(AutoSizer__default.default, null, function (_a) {
var height = _a.height,
width = _a.width;
return /*#__PURE__*/React__default.default.createElement(Grid, {
height: height,
width: width,
items: items,
colHeight: colHeight,
initialScroll: initialScroll,
components: calendarComponents,
commonProps: commonProps,
isStart: isStart,
range: range,
onScroll: onScroll,
onOverbook: onOverbook,
onChange: onChange
});
})));
};
var getInitialScroll = function getInitialScroll(colHeight, days, initialScroll) {
if (!days || days.length === 0 || !initialScroll) return;
var rows = 0;
for (var key in days) {
var day = days[key];
if (+key !== 0 && +key % 7 === 0) rows++;
if (isSameDay(day.date, initialScroll)) {
if (day.date.getDate() === 1) rows--;
break;
}
}
return rows * colHeight;
};
exports.Calendar = Calendar;
exports.ScrollableCalendar = ScrollableCalendar;
exports.getProtectedInterval = getProtectedInterval;
exports.getProtectedTime = getProtectedTime;
}));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QtYm9va2luZy1jYWxlbmRhci5qcyIsInNvdXJjZXMiOlsiLi4vbm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIi4uL3NyYy91dGlscy9kYXRlLnV0aWxzLnRzIiwiLi4vc3JjL2hlbHBlcnMudHMiLCIuLi9zcmMvY29tcG9uZW50cy9jb250YWluZXJzLnRzeCIsIi4uL3NyYy9jb21wb25lbnRzL01vbnRoQXJyb3dCYWNrLnRzeCIsIi4uL3NyYy9jb21wb25lbnRzL01vbnRoQXJyb3dOZXh0LnRzeCIsIi4uL3NyYy9jb21wb25lbnRzL01vbnRoQ29udGVudC50c3giLCIuLi9zcmMvY29tcG9uZW50cy9XZWVrQ29udGVudC50c3giLCIuLi9zcmMvY29tcG9uZW50cy9EYXlDb250ZW50LnRzeCIsIi4uL3NyYy9jb21wb25lbnRzL0RheVNlbGVjdGlvbi50c3giLCIuLi9zcmMvY29tcG9uZW50cy9EYXlUb2RheS50c3giLCIuLi9zcmMvY29tcG9uZW50cy9EYXlSZXNlcnZhdGlvbi50c3giLCIuLi9zcmMvY29tcG9uZW50cy9pbmRleC50cyIsIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMvZ2V0LXByb3RlY3RlZC10aW1lLnRzeCIsIi4uL3NyYy91dGlscy9nZXQtcHJvdGVjdGVkLWludGVydmFsLnRzIiwiLi4vc3JjL2NhbGVuZGFyLnRzeCIsIi4uL3NyYy9zY3JvbGxhYmxlLWNhbGVuZGFyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UsIFN1cHByZXNzZWRFcnJvciwgU3ltYm9sLCBJdGVyYXRvciAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvci