@coreui/react-pro
Version:
UI Components Library for React.js
350 lines (346 loc) • 17.1 kB
JavaScript
'use strict';
var React = require('react');
var PropTypes = require('prop-types');
var index = require('../../_virtual/index.js');
var CCalendarNavigation = require('./CCalendarNavigation.js');
var utils = require('./utils.js');
require('../../node_modules/tslib/tslib.es6.js');
require('@popperjs/core');
var useForkedRef = require('../../hooks/useForkedRef.js');
var CCalendarPanel = require('./CCalendarPanel.js');
const CCalendar = React.forwardRef(({ ariaNavNextMonthLabel = 'Next month', ariaNavNextYearLabel = 'Next year', ariaNavPrevMonthLabel = 'Previous month', ariaNavPrevYearLabel = 'Previous year', startDate, endDate, calendarDate = startDate || endDate || null, calendars = 1, className, dayFormat = 'numeric', disabledDates, firstDayOfWeek = 1, locale = 'default', maxDate, minDate, navigation = true, navNextIcon, navNextDoubleIcon, navPrevIcon, navPrevDoubleIcon, navYearFirst, range, selectAdjacementDays = false, selectEndDate, selectionType = 'day', showAdjacementDays = true, showWeekNumber = false, weekdayFormat = 2, weekNumbersLabel, onCalendarDateChange, onDateHover, onEndDateChange, onStartDateChange, onSelectEndChange, onViewChanged, }, ref) => {
const calendarRef = React.useRef(null);
const forkedRef = useForkedRef.useForkedRef(ref, calendarRef);
const [_calendarDate, setCalendarDate] = React.useState(null);
React.useEffect(() => {
const viewMap = {
day: 'days',
week: 'days',
month: 'months',
year: 'years',
};
handleViewChange(viewMap[selectionType] || 'days');
}, [selectionType]);
React.useEffect(() => {
if (calendarDate === null) {
setCalendarDate(new Date());
return;
}
if (calendarDate) {
const date = utils.convertToDateObject(calendarDate, selectionType);
if (!utils.isSameDateAs(_calendarDate, date)) {
setCalendarDate(date);
}
}
}, [calendarDate]);
const [_startDate, setStartDate] = React.useState(startDate ? utils.convertToDateObject(startDate, selectionType) : null);
const [_endDate, setEndDate] = React.useState(endDate ? utils.convertToDateObject(endDate, selectionType) : null);
React.useEffect(() => {
const date = startDate ? utils.convertToDateObject(startDate, selectionType) : null;
if ((date === null || date === void 0 ? void 0 : date.getTime()) !== (_startDate === null || _startDate === void 0 ? void 0 : _startDate.getTime())) {
setStartDate(date);
}
}, [startDate]);
React.useEffect(() => {
const date = endDate ? utils.convertToDateObject(endDate, selectionType) : null;
if ((date === null || date === void 0 ? void 0 : date.getTime()) !== (_endDate === null || _endDate === void 0 ? void 0 : _endDate.getTime())) {
setEndDate(date);
}
}, [endDate]);
const [_hoverDate, setHoverDate] = React.useState(null);
const [_maxDate, setMaxDate] = React.useState(maxDate ? utils.convertToDateObject(maxDate, selectionType) : null);
React.useEffect(() => {
setMaxDate(maxDate ? utils.convertToDateObject(maxDate, selectionType) : null);
}, [maxDate]);
const [_minDate, setMinDate] = React.useState(minDate ? utils.convertToDateObject(minDate, selectionType) : null);
React.useEffect(() => {
setMinDate(minDate ? utils.convertToDateObject(minDate, selectionType) : null);
}, [minDate]);
const [_selectEndDate, setSelectEndDate] = React.useState(selectEndDate);
React.useEffect(() => {
setSelectEndDate(selectEndDate);
}, [selectEndDate]);
const [view, setView] = React.useState('days');
const [focusOn, setFocusOn] = React.useState();
React.useEffect(() => {
var _a;
if (typeof focusOn === 'number') {
const list = utils.getSelectableDates(calendarRef.current);
(_a = list[focusOn]) === null || _a === void 0 ? void 0 : _a.focus();
setFocusOn(undefined);
}
}, [view]);
const setCalendarPage = (years, months = 0, setMonth) => {
if (_calendarDate === null) {
return;
}
const year = _calendarDate.getFullYear();
const month = _calendarDate.getMonth();
const d = new Date(year, month, 1);
if (years) {
d.setFullYear(d.getFullYear() + years);
}
if (months) {
d.setMonth(d.getMonth() + months);
}
setCalendarDate(d);
onCalendarDateChange === null || onCalendarDateChange === void 0 ? void 0 : onCalendarDateChange(d);
};
const handleStartDateChange = (date) => {
date = date ? utils.convertToDateObject(date, selectionType) : null;
if (date) {
date = utils.setTimeFromDate(date, _startDate);
}
setStartDate(date);
onStartDateChange === null || onStartDateChange === void 0 ? void 0 : onStartDateChange(utils.getDateBySelectionType(date, selectionType));
};
const handleEndDateChange = (date) => {
date = date ? utils.convertToDateObject(date, selectionType) : null;
if (date) {
date = utils.setTimeFromDate(date, _endDate);
}
setEndDate(date);
onEndDateChange === null || onEndDateChange === void 0 ? void 0 : onEndDateChange(utils.getDateBySelectionType(date, selectionType));
};
const handleSelectEndDateChange = (value) => {
setSelectEndDate(value);
onSelectEndChange === null || onSelectEndChange === void 0 ? void 0 : onSelectEndChange(value);
};
const handleViewChange = (value) => {
setView(value);
onViewChanged === null || onViewChanged === void 0 ? void 0 : onViewChanged(value);
};
const handleCalendarClick = (date, index) => {
const _date = new Date(date);
if (view === 'days') {
setCalendarDate(index ? new Date(_date.setMonth(_date.getMonth() - index)) : _date);
}
if (view === 'months' && selectionType !== 'month') {
setCalendarDate(index ? new Date(_date.setMonth(_date.getMonth() - index)) : _date);
handleViewChange('days');
return;
}
if (view === 'years' && selectionType !== 'year') {
setCalendarDate(index ? new Date(_date.setFullYear(_date.getFullYear() - index)) : _date);
handleViewChange('months');
return;
}
// Allow to change the calendarDate but not startDate or endDate
if (utils.isDateDisabled(date, _minDate, _maxDate, disabledDates)) {
return;
}
if (range) {
if (_selectEndDate) {
handleSelectEndDateChange(false);
if (_startDate && _startDate > date) {
handleStartDateChange(null);
handleEndDateChange(null);
return;
}
if (utils.isDisableDateInRange(_startDate, date, disabledDates)) {
handleStartDateChange(null);
handleEndDateChange(null);
return;
}
handleEndDateChange(date);
return;
}
if (_endDate && _endDate < date) {
handleStartDateChange(null);
handleEndDateChange(null);
return;
}
if (utils.isDisableDateInRange(date, _endDate, disabledDates)) {
handleStartDateChange(null);
handleEndDateChange(null);
return;
}
handleSelectEndDateChange(true);
handleStartDateChange(date);
return;
}
handleStartDateChange(date);
};
const handleCalendarKeyDown = (event, date, index) => {
if (event.code === 'Space' || event.key === 'Enter') {
event.preventDefault();
if ((view === 'months' && selectionType !== 'month') ||
(view === 'years' && selectionType !== 'year')) {
setFocusOn(0);
}
handleCalendarClick(date, index);
}
if (event.key === 'ArrowRight' ||
event.key === 'ArrowLeft' ||
event.key === 'ArrowUp' ||
event.key === 'ArrowDown') {
event.preventDefault();
if (_maxDate &&
date >= _maxDate &&
(event.key === 'ArrowRight' || event.key === 'ArrowDown')) {
return;
}
if (_minDate &&
date <= _minDate &&
(event.key === 'ArrowLeft' || event.key === 'ArrowUp')) {
return;
}
let element = event.target;
if (selectionType === 'week' && element.tabIndex === -1) {
element = element.closest('tr[tabindex="0"]');
}
const list = utils.getSelectableDates(calendarRef.current);
const index = list.indexOf(element);
const first = index === 0;
const last = index === list.length - 1;
const toBoundary = {
start: index,
end: list.length - (index + 1),
};
const gap = {
ArrowRight: 1,
ArrowLeft: -1,
ArrowUp: selectionType === 'week' && view === 'days' ? -1 : view === 'days' ? -7 : -3,
ArrowDown: selectionType === 'week' && view === 'days' ? 1 : view === 'days' ? 7 : 3,
};
if ((event.key === 'ArrowRight' && last) ||
(event.key === 'ArrowDown' && toBoundary['end'] < gap['ArrowDown']) ||
(event.key === 'ArrowLeft' && first) ||
(event.key === 'ArrowUp' && toBoundary['start'] < Math.abs(gap['ArrowUp']))) {
if (view === 'days') {
setCalendarPage(0, event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1);
}
if (view === 'months') {
setCalendarPage(event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1);
}
if (view === 'years') {
setCalendarPage(event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 10 : -10);
}
setTimeout(() => {
var _a, _b;
const _list = utils.getSelectableDates((_a = element.parentNode) === null || _a === void 0 ? void 0 : _a.parentNode);
if (_list.length > 0 && event.key === 'ArrowRight') {
_list[0].focus();
}
if (_list.length > 0 && event.key === 'ArrowLeft') {
(_b = _list.at(-1)) === null || _b === void 0 ? void 0 : _b.focus();
}
if (_list.length > 0 && event.key === 'ArrowDown') {
_list[gap['ArrowDown'] - (list.length - index)].focus();
}
if (_list.length > 0 && event.key === 'ArrowUp') {
_list[_list.length - (Math.abs(gap['ArrowUp']) + 1 - (index + 1))].focus();
}
}, 1);
return;
}
if (list[index + gap[event.key]].tabIndex === 0) {
list[index + gap[event.key]].focus();
return;
}
for (let i = index; i < list.length; event.key === 'ArrowRight' || event.key === 'ArrowDown' ? i++ : i--) {
if (list[i + gap[event.key]].tabIndex === 0) {
list[i + gap[event.key]].focus();
break;
}
}
}
};
const handleCalendarMouseEnter = (date) => {
if (utils.isDateDisabled(date, _minDate, _maxDate, disabledDates)) {
return;
}
date = utils.setTimeFromDate(date, selectEndDate ? _endDate : _startDate);
setHoverDate(date);
if (date) {
onDateHover === null || onDateHover === void 0 ? void 0 : onDateHover(utils.getDateBySelectionType(date, selectionType));
}
};
const handleCalendarMouseLeave = () => {
setHoverDate(null);
onDateHover === null || onDateHover === void 0 ? void 0 : onDateHover(null);
};
const handleNavigationOnClick = (direction, double = false) => {
if (direction === 'prev') {
if (double) {
setCalendarPage(view === 'years' ? -10 : -1);
return;
}
if (view !== 'days') {
setCalendarPage(-1);
return;
}
setCalendarPage(0, -1);
return;
}
if (direction === 'next') {
if (double) {
setCalendarPage(view === 'years' ? 10 : 1);
return;
}
if (view !== 'days') {
setCalendarPage(1);
return;
}
setCalendarPage(0, 1);
return;
}
};
return (React.createElement("div", { className: index.default('calendars', {
[`select-${selectionType}`]: selectionType && view === 'days',
'show-week-numbers': showWeekNumber,
}, className), ref: forkedRef }, _calendarDate &&
Array.from({ length: calendars }, (_, index$1) => {
const calendarDate = utils.getCalendarDate(_calendarDate, index$1, view);
return (React.createElement("div", { className: index.default('calendar', view), key: index$1 },
React.createElement(CCalendarNavigation.CCalendarNavigation, { ariaNavNextMonthLabel: ariaNavNextMonthLabel, ariaNavNextYearLabel: ariaNavNextYearLabel, ariaNavPrevMonthLabel: ariaNavPrevMonthLabel, ariaNavPrevYearLabel: ariaNavPrevYearLabel, calendarDate: calendarDate, locale: locale, navigation: navigation, navNextDoubleIcon: navNextDoubleIcon, navNextIcon: navNextIcon, navPrevDoubleIcon: navPrevDoubleIcon, navPrevIcon: navPrevIcon, navYearFirst: navYearFirst, onMonthClick: () => handleViewChange('months'), onNavigationClick: handleNavigationOnClick, onYearClick: () => handleViewChange('years'), view: view }),
React.createElement(CCalendarPanel.CCalendarPanel, { calendarDate: calendarDate, dayFormat: dayFormat, disabledDates: disabledDates, endDate: _endDate, firstDayOfWeek: firstDayOfWeek, hoverDate: _hoverDate, locale: locale, maxDate: _maxDate, minDate: _minDate, onCalendarClick: (date) => handleCalendarClick(date, index$1), onCalendarKeyDown: (event, date) => handleCalendarKeyDown(event, date, index$1), onCalendarMouseEnter: handleCalendarMouseEnter, onCalendarMouseLeave: handleCalendarMouseLeave, order: index$1, selectAdjacementDays: selectAdjacementDays, selectEndDate: _selectEndDate, selectionType: selectionType, showAdjacementDays: showAdjacementDays, showWeekNumber: showWeekNumber, startDate: _startDate, view: view, weekdayFormat: weekdayFormat, weekNumbersLabel: weekNumbersLabel })));
})));
});
CCalendar.propTypes = {
ariaNavNextMonthLabel: PropTypes.string,
ariaNavNextYearLabel: PropTypes.string,
ariaNavPrevMonthLabel: PropTypes.string,
ariaNavPrevYearLabel: PropTypes.string,
className: PropTypes.string,
calendarDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
calendars: PropTypes.number,
dayFormat: PropTypes.oneOfType([
PropTypes.func,
PropTypes.oneOf(['2-digit', 'numeric']),
]),
disabledDates: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.array, PropTypes.func]),
endDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
firstDayOfWeek: PropTypes.number,
locale: PropTypes.string,
maxDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
minDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
navigation: PropTypes.bool,
navNextIcon: PropTypes.node,
navNextDoubleIcon: PropTypes.node,
navPrevIcon: PropTypes.node,
navPrevDoubleIcon: PropTypes.node,
navYearFirst: PropTypes.bool,
range: PropTypes.bool,
selectAdjacementDays: PropTypes.bool,
selectEndDate: PropTypes.bool,
selectionType: PropTypes.oneOf(['day', 'week', 'month', 'year']),
showAdjacementDays: PropTypes.bool,
showWeekNumber: PropTypes.bool,
startDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.string]),
weekdayFormat: PropTypes.oneOfType([
PropTypes.func,
PropTypes.number,
PropTypes.oneOf(['long', 'narrow', 'short']),
]),
weekNumbersLabel: PropTypes.string,
onDateHover: PropTypes.func,
onCalendarDateChange: PropTypes.func,
onEndDateChange: PropTypes.func,
onSelectEndChange: PropTypes.func,
onStartDateChange: PropTypes.func,
onViewChanged: PropTypes.func,
};
CCalendar.displayName = 'CCalendar';
exports.CCalendar = CCalendar;
//# sourceMappingURL=CCalendar.js.map