UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

350 lines (346 loc) 17.1 kB
'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