UNPKG

@coreui/react-pro

Version:

UI Components Library for React.js

292 lines (288 loc) 21.1 kB
'use strict'; var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js'); var React = require('react'); var index = require('../../_virtual/index.js'); var PropTypes = require('prop-types'); var lib = require('../../_virtual/lib.js'); var CButton = require('../button/CButton.js'); var CCalendar = require('../calendar/CCalendar.js'); var utils = require('../calendar/utils.js'); var CFormControlWrapper = require('../form/CFormControlWrapper.js'); var CPicker = require('../picker/CPicker.js'); var CTimePicker = require('../time-picker/CTimePicker.js'); var useDebouncedCallback = require('../../hooks/useDebouncedCallback.js'); require('@popperjs/core'); var utils$1 = require('./utils.js'); var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; const CDateRangePicker = React.forwardRef((_a, ref) => { var { ariaNavNextMonthLabel, ariaNavNextYearLabel, ariaNavPrevMonthLabel, ariaNavPrevYearLabel, calendars = 2, cancelButton = 'Cancel', cancelButtonColor = 'primary', cancelButtonSize = 'sm', cancelButtonVariant = 'ghost', className, cleaner = true, closeOnSelect = true, confirmButton = 'OK', confirmButtonColor = 'primary', confirmButtonSize = 'sm', confirmButtonVariant, dayFormat, disabled, disabledDates, endDate, feedback, feedbackInvalid, feedbackValid, firstDayOfWeek, footer, id, indicator = true, inputDateFormat, inputDateParse, inputOnChangeDelay = 750, inputReadOnly, invalid, label, locale = 'default', maxDate, minDate, name, navigation, navYearFirst, onEndDateChange, onHide, onStartDateChange, onShow, placeholder = ['Start date', 'End date'], portal = true, previewDateOnHover = true, range = true, ranges, rangesButtonsColor = 'secondary', rangesButtonsSize, rangesButtonsVariant = 'ghost', required, separator = true, selectAdjacementDays, selectionType = 'day', showAdjacementDays, showWeekNumber, size, startDate, text, timepicker, toggler, todayButton = 'Today', todayButtonColor = 'primary', todayButtonSize = 'sm', todayButtonVariant, tooltipFeedback, valid, visible, weekdayFormat, weekNumbersLabel, calendarDate = startDate || endDate || null } = _a, rest = tslib_es6.__rest(_a, ["ariaNavNextMonthLabel", "ariaNavNextYearLabel", "ariaNavPrevMonthLabel", "ariaNavPrevYearLabel", "calendars", "cancelButton", "cancelButtonColor", "cancelButtonSize", "cancelButtonVariant", "className", "cleaner", "closeOnSelect", "confirmButton", "confirmButtonColor", "confirmButtonSize", "confirmButtonVariant", "dayFormat", "disabled", "disabledDates", "endDate", "feedback", "feedbackInvalid", "feedbackValid", "firstDayOfWeek", "footer", "id", "indicator", "inputDateFormat", "inputDateParse", "inputOnChangeDelay", "inputReadOnly", "invalid", "label", "locale", "maxDate", "minDate", "name", "navigation", "navYearFirst", "onEndDateChange", "onHide", "onStartDateChange", "onShow", "placeholder", "portal", "previewDateOnHover", "range", "ranges", "rangesButtonsColor", "rangesButtonsSize", "rangesButtonsVariant", "required", "separator", "selectAdjacementDays", "selectionType", "showAdjacementDays", "showWeekNumber", "size", "startDate", "text", "timepicker", "toggler", "todayButton", "todayButtonColor", "todayButtonSize", "todayButtonVariant", "tooltipFeedback", "valid", "visible", "weekdayFormat", "weekNumbersLabel", "calendarDate"]); const inputEndRef = React.useRef(null); const inputStartRef = React.useRef(null); const formRef = React.useRef(null); const [_calendarDate, setCalendarDate] = React.useState(calendarDate); const [_endDate, setEndDate] = React.useState(endDate !== null && endDate !== void 0 ? endDate : null); const [_maxDate, setMaxDate] = React.useState(maxDate !== null && maxDate !== void 0 ? maxDate : null); const [_minDate, setMinDate] = React.useState(minDate !== null && minDate !== void 0 ? minDate : null); const [_startDate, setStartDate] = React.useState(startDate !== null && startDate !== void 0 ? startDate : null); const [_visible, setVisible] = React.useState(visible); const [initialStartDate, setInitialStartDate] = React.useState(startDate !== null && startDate !== void 0 ? startDate : null); const [initialEndDate, setInitialEndDate] = React.useState(endDate !== null && endDate !== void 0 ? endDate : null); const [inputStartHoverValue, setInputStartHoverValue] = React.useState(null); const [inputEndHoverValue, setInputEndHoverValue] = React.useState(null); const [isValid, setIsValid] = React.useState(valid !== null && valid !== void 0 ? valid : (invalid === true ? false : undefined)); const [selectEndDate, setSelectEndDate] = React.useState(false); React.useEffect(() => { setIsValid(valid !== null && valid !== void 0 ? valid : (invalid === true ? false : undefined)); }, [valid, invalid]); React.useEffect(() => { if (startDate) { setStartDate(startDate); setInputValue(inputStartRef.current, startDate); } }, [startDate]); React.useEffect(() => { if (endDate) { setEndDate(endDate); setInputValue(inputEndRef.current, endDate); } }, [endDate]); React.useEffect(() => { if (maxDate) { setMaxDate(maxDate); } }, [maxDate]); React.useEffect(() => { if (minDate) { setMinDate(minDate); } }, [minDate]); React.useEffect(() => { if (inputStartRef.current && inputStartRef.current.form) { formRef.current = inputStartRef.current.form; } }, [inputStartRef]); React.useEffect(() => { if (formRef.current) { formRef.current.addEventListener('submit', (event) => { setTimeout(() => handleFormValidation(event.target)); }); handleFormValidation(formRef.current); } }, [formRef, _startDate, _endDate]); const formatDate = (date) => { if (inputDateFormat) { const convertedDate = date instanceof Date ? new Date(date) : utils.convertToDateObject(date, selectionType); if (!convertedDate || (convertedDate instanceof Date && Number.isNaN(convertedDate.getTime()))) { return ''; } return inputDateFormat(convertedDate); } if (selectionType !== 'day') { return date; } const _date = new Date(date); if (Number.isNaN(_date.getTime())) { return ''; } return timepicker ? _date.toLocaleString(locale) : _date.toLocaleDateString(locale); }; const setInputValue = (el, date) => { if (!el) { return; } if (date) { el.value = formatDate(date); return; } el.value = ''; }; const handleDateHover = (date) => { if (!previewDateOnHover) { return; } if (selectEndDate) { setInputEndHoverValue(date); } else { setInputStartHoverValue(date); } }; const handleClear = (event) => { event.stopPropagation(); setStartDate(null); setEndDate(null); setInputValue(inputStartRef.current, null); setInputValue(inputEndRef.current, null); onStartDateChange === null || onStartDateChange === void 0 ? void 0 : onStartDateChange(null); onEndDateChange === null || onEndDateChange === void 0 ? void 0 : onEndDateChange(null); }; const handleEndDateChange = (date) => { setEndDate(date); setInputValue(inputEndRef.current, date); setInputEndHoverValue(null); onEndDateChange === null || onEndDateChange === void 0 ? void 0 : onEndDateChange(date); if (timepicker || footer) { return; } if (closeOnSelect && _startDate !== null) { setVisible(false); } }; const handleFormValidation = (form) => { if (!form.classList.contains('was-validated')) { return; } if ((range && _startDate && _endDate) || (!range && _startDate)) { return setIsValid(true); } setIsValid(false); }; const handleStartDateChange = (date) => { setStartDate(date); setInputValue(inputStartRef.current, date); setInputStartHoverValue(null); onStartDateChange === null || onStartDateChange === void 0 ? void 0 : onStartDateChange(date); if (timepicker || footer) { return; } if (closeOnSelect && !range) { setVisible(false); } }; const handleOnChange = useDebouncedCallback.useDebouncedCallback((value, input) => { let date = null; if (inputDateParse) { date = inputDateParse(value); } else if (selectionType === 'day') { date = utils.getLocalDateFromString(value, locale, timepicker); } else { date = utils.convertToDateObject(value, selectionType); } if (date instanceof Date && utils.isDateDisabled(date, _minDate ? utils.convertToDateObject(_minDate, selectionType) : null, _maxDate ? utils.convertToDateObject(_maxDate, selectionType) : null, disabledDates)) { return; // Don't update if date is disabled } const isStartInput = input === 'start'; const inputRef = isStartInput ? inputStartRef : inputEndRef; const setDate = isStartInput ? setStartDate : setEndDate; const onChange = isStartInput ? onStartDateChange : onEndDateChange; const validDate = date !== null && date !== void 0 ? date : null; let formatedDate = validDate; // Update calendar date for valid dates if (validDate instanceof Date && validDate.getTime()) { if (selectionType !== 'day') { formatedDate = utils.getDateBySelectionType(validDate, selectionType); } setCalendarDate(formatedDate); setInputValue(inputRef.current, formatedDate); } // Update state and input setDate(formatedDate); onChange === null || onChange === void 0 ? void 0 : onChange(formatedDate); }, inputOnChangeDelay); const renderInput = (type) => { const isStart = type === 'start'; const hoverValue = isStart ? inputStartHoverValue : inputEndHoverValue; const inputRef = isStart ? inputStartRef : inputEndRef; const placeholderText = isStart ? Array.isArray(placeholder) ? placeholder[0] : placeholder : placeholder[1]; const inputElement = (React.createElement("input", Object.assign({ autoComplete: "off", className: index.default('date-picker-input', { hover: hoverValue, }), disabled: disabled }, (id && { id: utils$1.getInputIdOrName(id, range, type) }), (name && { name: utils$1.getInputIdOrName(name, range, type) }), (id && !Array.isArray(id) && !name && { name: isStart ? (range ? `${id}-start-date` : `${id}-date`) : `${id}-end-date`, }), { placeholder: placeholderText, readOnly: inputReadOnly, required: required, onChange: (event) => { handleOnChange(event.target.value, type); }, onClick: () => setSelectEndDate(!isStart), ref: inputRef }))); if (previewDateOnHover && !disabled) { return (React.createElement("div", { className: "date-picker-input-wrapper" }, inputElement, hoverValue && (React.createElement("input", { className: "date-picker-input date-picker-input-preview", readOnly: true, value: formatDate(hoverValue) })))); } return inputElement; }; const InputGroup = () => (React.createElement("div", { className: "date-picker-input-group" }, renderInput('start'), range && separator !== false && React.createElement("div", { className: "date-picker-separator" }), range && renderInput('end'), indicator && (typeof indicator === 'boolean' ? (React.createElement("div", Object.assign({ className: "date-picker-indicator" }, (!disabled && { onClick: () => setVisible(!_visible), onKeyDown: (event) => { if (event.key === 'Enter') { setVisible(!_visible); } }, tabIndex: 0, })))) : (indicator)), cleaner && (_startDate || _endDate) && (typeof cleaner === 'boolean' ? (React.createElement("div", { className: "date-picker-cleaner", onClick: (event) => handleClear(event) })) : (React.isValidElement(cleaner) && React.cloneElement(cleaner, { onClick: (event) => handleClear(event), }))))); return (React.createElement(CFormControlWrapper.CFormControlWrapper, Object.assign({ describedby: rest['aria-describedby'], feedback: feedback, feedbackInvalid: feedbackInvalid, feedbackValid: feedbackValid }, (id && !Array.isArray(id) && { id: id }), { invalid: isValid === false ? true : false, label: label, text: text, tooltipFeedback: tooltipFeedback, valid: isValid }), React.createElement(CPicker.CPicker, Object.assign({ className: index.default('date-picker', { [`date-picker-${size}`]: size, disabled: disabled, 'is-invalid': isValid === false ? true : false, 'is-valid': isValid, }, className), disabled: disabled, dropdownClassNames: "date-picker-dropdown", footer: footer || timepicker, footerContent: React.createElement("div", { className: "date-picker-footer" }, todayButton && (React.createElement(CButton.CButton, { className: "me-auto", color: todayButtonColor, size: todayButtonSize, variant: todayButtonVariant, onClick: () => { const date = new Date(); handleStartDateChange(date); if (range) handleEndDateChange(date); setCalendarDate(date); } }, todayButton)), cancelButton && (React.createElement(CButton.CButton, { color: cancelButtonColor, size: cancelButtonSize, variant: cancelButtonVariant, onClick: () => { handleStartDateChange(initialStartDate); if (range) handleEndDateChange(initialEndDate); setVisible(false); } }, cancelButton)), confirmButton && (React.createElement(CButton.CButton, { color: confirmButtonColor, size: confirmButtonSize, variant: confirmButtonVariant, onClick: () => { setVisible(false); } }, confirmButton))), toggler: toggler !== null && toggler !== void 0 ? toggler : InputGroup(), portal: portal, onHide: () => { setVisible(false); onHide === null || onHide === void 0 ? void 0 : onHide(); }, onShow: () => { setInitialStartDate(_startDate); setInitialEndDate(_endDate); setVisible(true); onShow === null || onShow === void 0 ? void 0 : onShow(); }, visible: _visible }, rest, { ref: ref }), React.createElement("div", { className: "date-picker-body" }, ranges && (React.createElement("div", { className: "date-picker-ranges" }, Object.keys(ranges).map((key, index) => (React.createElement(CButton.CButton, { color: rangesButtonsColor, key: index, onClick: () => { handleStartDateChange(ranges[key][0]); handleEndDateChange(ranges[key][1]); }, size: rangesButtonsSize, variant: rangesButtonsVariant }, key))))), React.createElement(CCalendar.CCalendar, { ariaNavNextMonthLabel: ariaNavNextMonthLabel, ariaNavNextYearLabel: ariaNavNextYearLabel, ariaNavPrevMonthLabel: ariaNavPrevMonthLabel, ariaNavPrevYearLabel: ariaNavPrevYearLabel, calendarDate: _calendarDate, calendars: lib.libExports.isMobile ? 1 : calendars, className: "date-picker-calendars", dayFormat: dayFormat, disabledDates: disabledDates, endDate: _endDate, firstDayOfWeek: firstDayOfWeek, locale: locale, maxDate: _maxDate, minDate: _minDate, navigation: navigation, navYearFirst: navYearFirst, range: range, selectAdjacementDays: selectAdjacementDays, selectEndDate: selectEndDate, selectionType: selectionType, showAdjacementDays: showAdjacementDays, showWeekNumber: showWeekNumber, startDate: _startDate, weekdayFormat: weekdayFormat, weekNumbersLabel: weekNumbersLabel, onDateHover: (date) => handleDateHover(date), onCalendarDateChange: (date) => setCalendarDate(date), onStartDateChange: (date) => handleStartDateChange(date), onEndDateChange: (date) => handleEndDateChange(date), onSelectEndChange: (value) => setSelectEndDate(value) }), timepicker && (React.createElement("div", { className: "date-picker-timepickers" }, (lib.libExports.isMobile && range) || (range && calendars === 1) ? (React.createElement(React.Fragment, null, React.createElement(CTimePicker.CTimePicker, { container: "inline", disabled: _startDate === null ? true : false, locale: locale, onTimeChange: (_, __, date) => date && handleStartDateChange(date), time: _startDate && new Date(_startDate), variant: "select" }), React.createElement(CTimePicker.CTimePicker, { container: "inline", disabled: _endDate === null ? true : false, locale: locale, onTimeChange: (_, __, date) => date && handleEndDateChange(date), time: _endDate && new Date(_endDate), variant: "select" }))) : (Array.from({ length: calendars }).map((_, index) => (React.createElement(CTimePicker.CTimePicker, { container: "inline", disabled: index === 0 ? _startDate === null ? true : false : _endDate === null ? true : false, key: index, locale: locale, onTimeChange: (_, __, date) => index === 0 ? date && handleStartDateChange(date) : date && handleEndDateChange(date), time: index === 0 ? _startDate && new Date(_startDate) : _endDate && new Date(_endDate), variant: "select" })))))))))); }); CDateRangePicker.displayName = 'CDateRangePicker'; CDateRangePicker.propTypes = Object.assign(Object.assign(Object.assign(Object.assign({}, CCalendar.CCalendar.propTypes), CFormControlWrapper.CFormControlWrapper.propTypes), CPicker.CPicker.propTypes), { cancelButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), cancelButtonColor: (_a = CButton.CButton.propTypes) === null || _a === void 0 ? void 0 : _a.color, cancelButtonSize: (_b = CButton.CButton.propTypes) === null || _b === void 0 ? void 0 : _b.size, cancelButtonVariant: (_c = CButton.CButton.propTypes) === null || _c === void 0 ? void 0 : _c.variant, calendars: PropTypes.number, className: PropTypes.string, cleaner: PropTypes.bool, closeOnSelect: PropTypes.bool, confirmButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), confirmButtonColor: (_d = CButton.CButton.propTypes) === null || _d === void 0 ? void 0 : _d.color, confirmButtonSize: (_e = CButton.CButton.propTypes) === null || _e === void 0 ? void 0 : _e.size, confirmButtonVariant: (_f = CButton.CButton.propTypes) === null || _f === void 0 ? void 0 : _f.variant, id: PropTypes.oneOfType([PropTypes.string, PropTypes.any]), indicator: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), inputDateFormat: PropTypes.func, inputDateParse: PropTypes.func, inputOnChangeDelay: PropTypes.number, inputReadOnly: PropTypes.bool, name: PropTypes.oneOfType([PropTypes.string, PropTypes.any]), placeholder: PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string.isRequired), ]), previewDateOnHover: PropTypes.bool, range: PropTypes.bool, ranges: PropTypes.object, rangesButtonsColor: (_g = CButton.CButton.propTypes) === null || _g === void 0 ? void 0 : _g.color, rangesButtonsSize: (_h = CButton.CButton.propTypes) === null || _h === void 0 ? void 0 : _h.size, rangesButtonsVariant: (_j = CButton.CButton.propTypes) === null || _j === void 0 ? void 0 : _j.variant, required: PropTypes.bool, separator: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), size: PropTypes.oneOf(['sm', 'lg']), timepicker: PropTypes.bool, todayButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]), todayButtonColor: (_k = CButton.CButton.propTypes) === null || _k === void 0 ? void 0 : _k.color, todayButtonSize: (_l = CButton.CButton.propTypes) === null || _l === void 0 ? void 0 : _l.size, todayButtonVariant: (_m = CButton.CButton.propTypes) === null || _m === void 0 ? void 0 : _m.variant }); exports.CDateRangePicker = CDateRangePicker; //# sourceMappingURL=CDateRangePicker.js.map