@chayns-components/date
Version:
A set of beautiful React components for developing your own applications with chayns.
313 lines (311 loc) • 13.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _core = require("@chayns-components/core");
var _chaynsApi = require("chayns-api");
var _react = _interopRequireWildcard(require("react"));
var _calendar = require("../../types/calendar");
var _calendar2 = require("../../utils/calendar");
var _date = require("../../utils/date");
var _Calendar = require("./Calendar.styles");
var _MonthWrapper = _interopRequireDefault(require("./month-wrapper/MonthWrapper"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const DEFAULT_MAX_DATE = (0, _date.addYears)(new Date(), 1);
const DEFAULT_MIN_DATE = (0, _date.subYears)(new Date(), 1);
const Calendar = ({
locale = _chaynsApi.Language.German,
maxDate = DEFAULT_MAX_DATE,
minDate = DEFAULT_MIN_DATE,
highlightedDates,
onChange,
customThumbColors,
selectedDate,
selectedDates,
selectedDateInterval,
categories,
isDisabled,
type = _calendar.CalendarType.Single,
shouldShowHighlightsInMonthOverlay = true,
disabledDates = [],
showMonthYearPickers: showMonthYearPickersProp,
onShownDatesChange = () => {}
}) => {
const [currentDate, setCurrentDate] = (0, _react.useState)();
const [shouldRenderTwoMonths, setShouldRenderTwoMonths] = (0, _react.useState)(true);
const [internalSelectedDate, setInternalSelectedDate] = (0, _react.useState)(() => type === _calendar.CalendarType.Multiple ? [] : undefined);
const [direction, setDirection] = (0, _react.useState)();
const [width, setWidth] = (0, _react.useState)(0);
const showMonthYearPickers = (0, _react.useMemo)(() => {
const hasMultipleMonths = (0, _date.differenceInCalendarMonths)(maxDate, minDate) > 0;
const hasMultipleYears = (0, _calendar2.getYearsBetween)(minDate, maxDate).length > 1;
return !!(showMonthYearPickersProp && (hasMultipleMonths || hasMultipleYears));
}, [minDate, maxDate, showMonthYearPickersProp]);
const calendarRef = (0, _react.useRef)(null);
(0, _react.useEffect)(() => {
if (currentDate) {
const start = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
if (shouldRenderTwoMonths) {
const end = new Date(currentDate.getFullYear(), currentDate.getMonth() + 2, 0);
onShownDatesChange({
start,
end
});
} else {
const end = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0);
onShownDatesChange({
start,
end
});
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentDate, shouldRenderTwoMonths]);
(0, _react.useEffect)(() => {
const bounds = {
start: minDate,
end: maxDate
};
if (type === _calendar.CalendarType.Single) {
if (selectedDate) {
const isDisabledDate = disabledDates.some(disabledDate => (0, _date.isSameDay)(selectedDate, disabledDate));
const isDateInBounds = (0, _date.isWithinInterval)(selectedDate, bounds);
if (!isDisabledDate && isDateInBounds) {
setInternalSelectedDate(selectedDate);
} else {
console.warn('[@chayns-components/date] Warning: Failed to set selectedDate, because it is disabled or out of bounds.', '\nselectedDate:', selectedDate, ...(isDisabledDate ? ['\nselectedDate is disabled'] : []), ...(isDateInBounds ? [] : ['\nselectedDate is outside of bounds:', {
minDate,
maxDate
}]));
setInternalSelectedDate(() => undefined);
}
} else {
setInternalSelectedDate(() => undefined);
}
} else if (type === _calendar.CalendarType.Multiple) {
if (selectedDates) {
const disabledSelectedDates = [];
const datesOutsideOfBounds = [];
const filteredDates = selectedDates.filter(date => {
if (disabledDates.some(disabledDate => (0, _date.isSameDay)(date, disabledDate))) {
disabledSelectedDates.push(date);
return false;
}
if (!(0, _date.isWithinInterval)(date, bounds)) {
datesOutsideOfBounds.push(date);
return false;
}
return true;
});
if (disabledSelectedDates.length > 0 || datesOutsideOfBounds.length > 0) {
console.warn('[@chayns-components/date] Warning: Failed to set all selectedDates, because some are disabled or out of bounds.', ...(disabledSelectedDates.length > 0 ? ['\nselectedDates that are disabled:', disabledSelectedDates] : []), ...(datesOutsideOfBounds.length > 0 ? ['\nselectedDates that are outside of bounds:', datesOutsideOfBounds, 'bounds:', {
minDate,
maxDate
}] : []));
}
setInternalSelectedDate(filteredDates);
} else {
setInternalSelectedDate([]);
}
} else if (type === _calendar.CalendarType.Interval) {
if (selectedDateInterval) {
const intervalIncludesDisabledDate = selectedDateInterval.end && disabledDates.some(disabledDate => (0, _date.isWithinInterval)(disabledDate, {
start: selectedDateInterval.start,
end: selectedDateInterval.end
}));
const intervalIsInBounds = (0, _date.isWithinInterval)(selectedDateInterval.start, bounds) && (!selectedDateInterval.end || (0, _date.isWithinInterval)(selectedDateInterval.end, bounds));
if (!intervalIncludesDisabledDate && intervalIsInBounds) {
setInternalSelectedDate(selectedDateInterval);
} else {
console.warn('[@chayns-components/date] Warning: Failed to set selectedDateInterval, because it includes disabled dates or dates that are out of bounds.', '\nselectedDateInterval:', selectedDateInterval, ...(intervalIncludesDisabledDate ? ['\ndisabled dates:', disabledDates] : []), ...(intervalIsInBounds ? [] : ['\nbounds:', {
minDate,
maxDate
}]));
setInternalSelectedDate(() => undefined);
}
}
}
}, [type, selectedDate, selectedDates, selectedDateInterval, disabledDates, minDate, maxDate]);
(0, _react.useEffect)(() => {
if (calendarRef.current) {
const resizeObserver = new ResizeObserver(entries => {
if (entries && entries[0]) {
const observedWidth = entries[0].contentRect.width;
setWidth(observedWidth - 30);
if (observedWidth < 430) {
setShouldRenderTwoMonths(false);
} else {
setShouldRenderTwoMonths(true);
}
}
});
resizeObserver.observe(calendarRef.current);
return () => {
resizeObserver.disconnect();
};
}
return () => {};
}, []);
(0, _react.useEffect)(() => {
setCurrentDate(prevDate => (0, _calendar2.isDateInRange)({
minDate,
maxDate,
currentDate: prevDate || new Date()
}));
}, [maxDate, minDate]);
const handleLeftArrowClick = (0, _react.useCallback)(() => {
if (direction) return;
setDirection('left');
setCurrentDate(prevDate => {
if (!prevDate) {
return prevDate;
}
const newDate = (0, _calendar2.getNewDate)(-1, prevDate);
return (0, _calendar2.isDateInRange)({
minDate,
maxDate,
currentDate: newDate
});
});
}, [maxDate, minDate, direction]);
const handleRightArrowClick = (0, _react.useCallback)(() => {
if (direction) return;
setDirection('right');
setCurrentDate(prevDate => {
if (!prevDate) {
return prevDate;
}
const newDate = (0, _calendar2.getNewDate)(1, prevDate);
return (0, _calendar2.isDateInRange)({
minDate,
maxDate,
currentDate: newDate
});
});
}, [maxDate, minDate, direction]);
const handleSelect = (0, _react.useCallback)(date => {
setInternalSelectedDate(prevDate => {
let onChangePayload = null;
let newInternalSelectedDate;
if (type === _calendar.CalendarType.Single) {
onChangePayload = date;
newInternalSelectedDate = date;
} else if (type === _calendar.CalendarType.Multiple) {
const prevSelectedDates = prevDate;
// Selects or unselects date , depending on if it is already selected.
if (prevSelectedDates.some(d => (0, _date.isSameDay)(d, date))) {
newInternalSelectedDate = prevSelectedDates.filter(d => !(0, _date.isSameDay)(d, date));
} else {
newInternalSelectedDate = [...prevSelectedDates, date];
}
onChangePayload = newInternalSelectedDate;
} else if (type === _calendar.CalendarType.Interval) {
const prevSelectedDateInterval = prevDate;
const updateInterval = (start, end) => {
const newInterval = {
start,
end
};
onChangePayload = newInterval;
newInternalSelectedDate = newInterval;
};
// Sets first selection as interval start.
if (!prevSelectedDateInterval) {
updateInterval(date);
} else if (prevSelectedDateInterval.start && !prevSelectedDateInterval.end) {
// Sets second selection as interval start, if it is earlier than the previous interval start.
// Else sets it as interval end.
if (date < prevSelectedDateInterval.start) {
updateInterval(date);
} else {
updateInterval(prevSelectedDateInterval.start, date);
}
} else {
// Resets interval if a third date is selected.
updateInterval(date);
}
}
if (typeof onChange === 'function' && onChangePayload) {
onChange(onChangePayload);
}
return newInternalSelectedDate;
});
}, [type, onChange]);
const handleAnimationFinished = () => {
setDirection(() => undefined);
};
const ShouldShowLeftArrow = (0, _react.useMemo)(() => {
if (!currentDate) {
return false;
}
return !(0, _date.isSameMonth)(currentDate, minDate);
}, [currentDate, minDate]);
const ShouldShowRightArrow = (0, _react.useMemo)(() => {
if (!currentDate) {
return false;
}
return !(0, _date.isSameMonth)(currentDate, maxDate);
}, [currentDate, maxDate]);
return /*#__PURE__*/_react.default.createElement(_Calendar.StyledCalendar, {
ref: calendarRef,
$isDisabled: isDisabled
}, ShouldShowLeftArrow ? /*#__PURE__*/_react.default.createElement(_Calendar.StyledCalendarIconWrapper, {
onClick: handleLeftArrowClick
}, /*#__PURE__*/_react.default.createElement("div", {
// TODO Use styled-components instead of inline styles
style: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap',
height: 'fit-content'
}
}, showMonthYearPickers && /*#__PURE__*/_react.default.createElement(_Calendar.StyledPseudoMonthYearPicker, null, /*#__PURE__*/_react.default.createElement(_core.ComboBox, {
lists: [{
list: []
}],
placeholder: ""
})), /*#__PURE__*/_react.default.createElement(_core.Icon, {
icons: ['fa fa-angle-left']
}))) : /*#__PURE__*/_react.default.createElement(_Calendar.StyledCalendarIconWrapperPseudo, null), currentDate && /*#__PURE__*/_react.default.createElement(_MonthWrapper.default, {
shouldRenderTwo: shouldRenderTwoMonths,
currentDate: currentDate,
width: width,
locale: locale,
direction: direction,
customThumbColors: customThumbColors,
onSelect: handleSelect,
selectedDate: internalSelectedDate,
highlightedDates: highlightedDates,
categories: categories,
onAnimationFinished: handleAnimationFinished,
minDate: minDate,
maxDate: maxDate,
type: type,
disabledDates: disabledDates,
setCurrentDate: setCurrentDate,
shouldShowHighlightsInMonthOverlay: shouldShowHighlightsInMonthOverlay,
showMonthYearPickers: showMonthYearPickers
}), ShouldShowRightArrow ? /*#__PURE__*/_react.default.createElement(_Calendar.StyledCalendarIconWrapper, {
onClick: handleRightArrowClick
}, /*#__PURE__*/_react.default.createElement("div", {
// TODO Use styled-components instead of inline styles
style: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'nowrap',
height: 'fit-content'
}
}, showMonthYearPickers && /*#__PURE__*/_react.default.createElement(_Calendar.StyledPseudoMonthYearPicker, null, /*#__PURE__*/_react.default.createElement(_core.ComboBox, {
lists: [{
list: []
}],
placeholder: ""
})), /*#__PURE__*/_react.default.createElement(_core.Icon, {
icons: ['fa fa-angle-right']
}))) : /*#__PURE__*/_react.default.createElement(_Calendar.StyledCalendarIconWrapperPseudo, null));
};
Calendar.displayName = 'Calendar';
var _default = exports.default = Calendar;
//# sourceMappingURL=Calendar.js.map