reactstrap-date-picker
Version:
Reactstrap based, zero dependencies, date picker
1,330 lines (1,280 loc) • 46.7 kB
JavaScript
/**
* reactstrap-date-picker v2.0.0-beta.2
*
* https://reactstrap-date-picker.afialapis.com/
*
* Copyright (c) Donato Lorenzo <donato@afialapis.com>
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
'use strict';
var React = require('react');
var reactstrap = require('reactstrap');
var useCheckProps = function useCheckProps(value, defaultValue) {
if (value && defaultValue) {
return 'Conflicting DatePicker properties \'value\' and \'defaultValue\'';
}
return undefined;
};
var InputGroup = function InputGroup(_ref) {
var children = _ref.children,
customInputGroup = _ref.customInputGroup,
size = _ref.size,
inputId = _ref.inputId;
if (customInputGroup != undefined) {
return /*#__PURE__*/React.cloneElement(customInputGroup, {
children: children
});
}
return /*#__PURE__*/React.createElement(reactstrap.InputGroup, {
size: size,
id: inputId,
className: "rdp-input-group"
}, children);
};
var InputOverlay = function InputOverlay(_ref) {
var oid = _ref.oid,
overlayContainerRef = _ref.overlayContainerRef,
children = _ref.children;
return /*#__PURE__*/React.createElement("div", {
ref: overlayContainerRef,
id: oid,
className: "rdp-overlay"
}, children);
};
var InputHidden = function InputHidden(_ref) {
var inputId = _ref.inputId,
name = _ref.name,
value = _ref.value,
formattedValue = _ref.formattedValue,
hiddenInputRef = _ref.hiddenInputRef;
return /*#__PURE__*/React.createElement("input", {
ref: hiddenInputRef,
type: "hidden",
className: "rdp-hidden",
id: inputId,
name: name,
value: value || '',
"data-formattedvalue": formattedValue
});
};
var InputClearButton = function InputClearButton(_ref) {
var inputValue = _ref.inputValue,
disabled = _ref.disabled,
clearButtonElement = _ref.clearButtonElement,
_onClick = _ref.onClick;
return /*#__PURE__*/React.createElement("div", {
className: "rdp-addon input-group-append"
}, /*#__PURE__*/React.createElement(reactstrap.InputGroupText, {
onClick: function onClick() {
return disabled ? null : _onClick();
},
style: {
opacity: inputValue && !disabled ? 1 : 0.5,
cursor: inputValue && !disabled ? 'pointer' : 'not-allowed'
}
}, clearButtonElement));
};
function _extends() {
return _extends = Object.assign ? Object.assign.bind() : function (n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
}
return n;
}, _extends.apply(null, arguments);
}
var InputControlInput = function InputControlInput(_ref) {
var customControl = _ref.customControl,
controlId = _ref.controlId,
value = _ref.value,
required = _ref.required,
placeholder = _ref.placeholder,
inputRef = _ref.inputRef,
disabled = _ref.disabled,
className = _ref.className,
style = _ref.style,
autoFocus = _ref.autoFocus,
autoComplete = _ref.autoComplete,
valid = _ref.valid,
invalid = _ref.invalid,
onInvalid = _ref.onInvalid,
noValidate = _ref.noValidate,
onKeyDown = _ref.onKeyDown,
onFocus = _ref.onFocus,
onBlur = _ref.onBlur,
onChange = _ref.onChange;
var validityClassNames = (invalid === true ? 'is-invalid' : '') + " " + (valid === true ? 'is-valid' : '');
if (customControl != undefined) {
return /*#__PURE__*/React.cloneElement(customControl, {
id: controlId,
value: value || '',
required: required,
placeholder: placeholder,
ref: inputRef,
disabled: disabled,
className: "rdp-form-control " + (className || '') + " " + (customControl.props.className || '') + " " + validityClassNames,
style: _extends({}, customControl.props.style || {}, style || {}),
autoComplete: autoComplete,
onInvalid: onInvalid,
noValidate: noValidate,
onKeyDown: onKeyDown,
onFocus: onFocus,
onBlur: onBlur,
onChange: onChange,
valid: valid,
invalid: invalid
});
}
return /*#__PURE__*/React.createElement(reactstrap.Input, {
id: controlId,
name: controlId,
value: value || '',
required: required,
placeholder: placeholder,
innerRef: inputRef,
disabled: disabled,
type: "text",
className: "rdp-form-control " + (className || '') + " " + validityClassNames,
style: style,
autoFocus: autoFocus,
autoComplete: autoComplete,
onInvalid: onInvalid,
noValidate: noValidate,
onKeyDown: onKeyDown,
onFocus: onFocus,
onBlur: onBlur,
onChange: onChange,
valid: valid,
invalid: invalid
});
};
var setTimeToNoon = function setTimeToNoon(date) {
if (!date) {
return null;
}
date.setHours(12 - date.getTimezoneOffset() / 60);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
return date;
};
var getDateFromIsoString = function getDateFromIsoString(isoString) {
return isoString ? setTimeToNoon(new Date(isoString)) : null;
};
var getIsoStringFromDate = function getIsoStringFromDate(date) {
return date ? setTimeToNoon(date).toISOString() : null;
};
var _makeInputValueString = function _makeInputValueString(date, separator, dateFormat) {
var month = date.getMonth() + 1;
var day = date.getDate();
if (dateFormat.match(/MM.DD.YYYY/)) {
return (month > 9 ? month : "0" + month) + separator + (day > 9 ? day : "0" + day) + separator + date.getFullYear();
} else if (dateFormat.match(/DD.MM.YYYY/)) {
return (day > 9 ? day : "0" + day) + separator + (month > 9 ? month : "0" + month) + separator + date.getFullYear();
} else {
return date.getFullYear() + separator + (month > 9 ? month : "0" + month) + separator + (day > 9 ? day : "0" + day);
}
};
var useInputValues = function useInputValues(controlInputRef, value, defaultValue, minDate, maxDate, dateFormat, onClear, onChange) {
var _useState = React.useState(dateFormat.match(/[^A-Z]/)[0]),
separator = _useState[0],
setSeparator = _useState[1];
var _useState2 = React.useState(null),
innerValue = _useState2[0],
setInnerValue = _useState2[1];
var _useState3 = React.useState(null),
inputValue = _useState3[0],
setInputValue = _useState3[1];
var _useState4 = React.useState(null),
displayDate = _useState4[0],
setDisplayDate = _useState4[1];
var _useState5 = React.useState(null),
selectedDate = _useState5[0],
setSelectedDate = _useState5[1];
// handle props changes
React.useEffect(function () {
setSeparator(dateFormat.match(/[^A-Z]/)[0]);
}, [dateFormat]);
// handle input values
React.useEffect(function () {
var isoString = value || defaultValue;
var minDate = getDateFromIsoString(minDate);
var maxDate = getDateFromIsoString(maxDate);
var nSelectedDate = getDateFromIsoString(isoString);
var nInnerValue = getIsoStringFromDate(nSelectedDate);
var nInputValue = isoString ? _makeInputValueString(nSelectedDate, separator, dateFormat) : null;
var nDisplayDate;
if (nSelectedDate) {
//nDisplayDate = new Date(nSelectedDate)
nDisplayDate = nSelectedDate;
} else {
var today = getDateFromIsoString(new Date().toISOString());
if (minDate && Date.parse(minDate) >= Date.parse(today)) {
nDisplayDate = minDate;
} else if (maxDate && Date.parse(maxDate) <= Date.parse(today)) {
nDisplayDate = maxDate;
} else {
nDisplayDate = today;
}
}
setInnerValue(nInnerValue);
setInputValue(nInputValue);
setSelectedDate(nSelectedDate);
setDisplayDate(nDisplayDate);
}, [value, defaultValue, minDate, maxDate, separator, dateFormat]);
//
var handleClear = /*useCallback(*/function handleClear() {
if (onClear) {
onClear();
} else {
setInnerValue(null);
setInputValue(null);
setSelectedDate(null);
setDisplayDate(null);
if (onChange) {
onChange(null, null);
}
}
}; /*, [onClear, onChange])*/
var handleBadInput = /*useCallback(*/function handleBadInput(originalValue, tail) {
if (tail === void 0) {
tail = false;
}
var parts = originalValue.replace(new RegExp("[^0-9" + separator + "]"), '').split(separator);
if (dateFormat.match(/MM.DD.YYYY/) || dateFormat.match(/DD.MM.YYYY/)) {
if (parts[0] && parts[0].length > 2) {
parts[1] = parts[0].slice(2) + (parts[1] || '');
parts[0] = parts[0].slice(0, 2);
}
if (parts[1] && parts[1].length > 2) {
parts[2] = parts[1].slice(2) + (parts[2] || '');
parts[1] = parts[1].slice(0, 2);
}
if (parts[2]) {
parts[2] = parts[2].slice(0, 4);
if (tail) {
if (parts[2].length < 4) {
parts[2] = parts[2].padEnd(4, '0');
}
}
}
} else {
if (parts[0] && parts[0].length > 4) {
parts[1] = parts[0].slice(4) + (parts[1] || '');
parts[0] = parts[0].slice(0, 4);
}
if (parts[1] && parts[1].length > 2) {
parts[2] = parts[1].slice(2) + (parts[2] || '');
parts[1] = parts[1].slice(0, 2);
}
if (parts[2]) {
parts[2] = parts[2].slice(0, 2);
}
}
var nInputValue = parts.join(separator);
setInputValue(nInputValue);
}; /*, [dateFormat, separator])*/
var handleBadInputOnBlur = function handleBadInputOnBlur() {
var _controlInputRef$curr;
var originalValue = (controlInputRef == null || (_controlInputRef$curr = controlInputRef.current) == null ? void 0 : _controlInputRef$curr.value) || '';
if (originalValue) {
handleBadInput(originalValue, true);
}
};
var handleInputChange = /*useCallback(*/function handleInputChange() {
var _controlInputRef$curr2;
var originalValue = (controlInputRef == null || (_controlInputRef$curr2 = controlInputRef.current) == null ? void 0 : _controlInputRef$curr2.value) || '';
var nInputValue = originalValue.replace(/(-|\/\/)/g, separator).slice(0, 10);
if (!nInputValue) {
handleClear();
return;
}
var month, day, year;
if (dateFormat.match(/MM.DD.YYYY/)) {
if (!nInputValue.match(/[0-1][0-9].[0-3][0-9].[1-2][0-9][0-9][0-9]/)) {
return handleBadInput(originalValue);
}
month = nInputValue.slice(0, 2).replace(/[^0-9]/g, '');
day = nInputValue.slice(3, 5).replace(/[^0-9]/g, '');
year = nInputValue.slice(6, 10).replace(/[^0-9]/g, '');
} else if (dateFormat.match(/DD.MM.YYYY/)) {
if (!nInputValue.match(/[0-3][0-9].[0-1][0-9].[1-2][0-9][0-9][0-9]/)) {
return handleBadInput(originalValue);
}
day = nInputValue.slice(0, 2).replace(/[^0-9]/g, '');
month = nInputValue.slice(3, 5).replace(/[^0-9]/g, '');
year = nInputValue.slice(6, 10).replace(/[^0-9]/g, '');
} else {
if (!nInputValue.match(/[1-2][0-9][0-9][0-9].[0-1][0-9].[0-3][0-9]/)) {
return handleBadInput(originalValue);
}
year = nInputValue.slice(0, 4).replace(/[^0-9]/g, '');
month = nInputValue.slice(5, 7).replace(/[^0-9]/g, '');
day = nInputValue.slice(8, 10).replace(/[^0-9]/g, '');
}
var monthInteger = parseInt(month, 10);
var dayInteger = parseInt(day, 10);
var yearInteger = parseInt(year, 10);
if (monthInteger > 12 || dayInteger > 31) {
return handleBadInput(originalValue);
}
var beforeMinDate = minDate && Date.parse(originalValue) < Date.parse(minDate);
var afterMaxDate = maxDate && Date.parse(originalValue) > Date.parse(maxDate);
if (beforeMinDate || afterMaxDate) {
return handleBadInput(originalValue);
}
if (!isNaN(monthInteger) && !isNaN(dayInteger) && !isNaN(yearInteger) && monthInteger <= 12 && dayInteger <= 31 && yearInteger > 999) {
var nSelectedDate = getDateFromIsoString(new Date(yearInteger, monthInteger - 1, dayInteger, 12, 0, 0, 0).toISOString());
var nInnerValue = getIsoStringFromDate(nSelectedDate);
setSelectedDate(nSelectedDate);
setDisplayDate(nSelectedDate);
setInnerValue(nInnerValue);
if (onChange) {
onChange(nInnerValue, nInputValue);
}
}
setInputValue(nInputValue);
}; /*, [controlInputRef, separator, onChange, minDate, maxDate])*/
var handleChangeMonth = function handleChangeMonth(nDisplayDate) {
setDisplayDate(nDisplayDate);
};
var handleChangeDate = /*useCallback(*/function handleChangeDate(nSelectedDate) {
var nInnerValue = getIsoStringFromDate(nSelectedDate);
var nInputValue = _makeInputValueString(nSelectedDate, separator, dateFormat);
setInputValue(nInputValue);
setSelectedDate(nSelectedDate);
setDisplayDate(nSelectedDate);
setInnerValue(nInnerValue);
if (onChange) {
onChange(nInnerValue, nInputValue);
}
}; /*, [separator, dateFormat, onChange])*/
return [innerValue, inputValue, displayDate, selectedDate, handleClear, handleInputChange, handleChangeMonth, handleChangeDate, handleBadInputOnBlur];
};
var getInstanceCount = function getInstanceCount() {
if (typeof window === 'object') {
if (window._reactstrapDatePickerInstance == undefined) {
window._reactstrapDatePickerInstance = 0;
}
var next = window._reactstrapDatePickerInstance + 1;
window._reactstrapDatePickerInstance = next;
return next;
} else if (typeof process === 'object') {
if (process._reactstrapDatePickerInstance == undefined) {
process._reactstrapDatePickerInstance = 0;
}
var _next = process._reactstrapDatePickerInstance + 1;
process._reactstrapDatePickerInstance = _next;
return _next;
} else {
console.error("Reactstrap Date Picker cannot determine environment (it is neither browser's <window> nor Node's <process>).");
return 1;
}
};
var _getIdSuffix = function _getIdSuffix(id, name) {
// Try <id> or <name> props to determine elements' id suffix
if (id != undefined && id != '') return id;
if (name != undefined && name != '') return name;
// If none was passed, use global vars
var iCount = getInstanceCount();
return iCount.toString();
};
var _getInputIds = function _getInputIds(id, name, customControl) {
var _customControl$props;
var idSuffix = _getIdSuffix(id, name);
var group = "rdp-input-group-" + idSuffix;
var hidden = id != undefined ? id : "rdp-hidden-" + idSuffix;
var control = "rdp-form-control-" + idSuffix;
if (customControl != undefined && customControl != null && (_customControl$props = customControl.props) != null && _customControl$props.id) {
control = customControl.props.id;
}
var overlay = "rdp-overlay-" + idSuffix;
return [group, hidden, control, overlay];
};
var useInputIds = function useInputIds(id, name, customControl) {
var _useState = React.useState(_getInputIds(id, name, customControl)),
inputIds = _useState[0],
setInputIds = _useState[1];
React.useEffect(function () {
setInputIds(_getInputIds(id, name, customControl));
}, [id, name, customControl]);
return inputIds;
};
var _getFixedDayLabels = function _getFixedDayLabels(dayLabels, weekStartsOn) {
if (weekStartsOn > 1) {
return dayLabels.slice(weekStartsOn).concat(dayLabels.slice(0, weekStartsOn));
}
if (weekStartsOn === 1) {
return dayLabels.slice(1).concat(dayLabels.slice(0, 1));
}
return dayLabels;
};
var useFixedDayLabels = function useFixedDayLabels(dayLabels, weekStartsOn) {
var _useState = React.useState(_getFixedDayLabels(dayLabels, weekStartsOn)),
fixedDayLabels = _useState[0],
setFixedDayLabels = _useState[1];
React.useEffect(function () {
setFixedDayLabels(_getFixedDayLabels(dayLabels, weekStartsOn));
}, [dayLabels, weekStartsOn]);
return fixedDayLabels;
};
var compareMonths = function compareMonths(a, b) {
try {
var da = new Date(a);
var db = new Date(b);
var sameYear = da.getFullYear() == db.getFullYear();
var sameMonth = da.getMonth() == db.getMonth();
return sameMonth && sameYear;
} catch (e) {
console.error(e);
return true;
}
};
var _getYearList = function _getYearList(minDate, maxDate) {
var minYear = minDate ? new Date(minDate).getFullYear() : 1970;
var maxYear = maxDate ? new Date(maxDate).getFullYear() : 2045;
var yList = [];
for (var y = minYear; y <= maxYear; y++) {
yList.push(y);
}
return yList;
};
var PickMonthDefault = function PickMonthDefault(_ref) {
var displayDate = _ref.displayDate,
minDate = _ref.minDate,
maxDate = _ref.maxDate,
monthLabels = _ref.monthLabels,
onChangeMonth = _ref.onChangeMonth,
onChangeYear = _ref.onChangeYear;
var _useState = React.useState(new Date(displayDate).getMonth()),
month = _useState[0],
setMonth = _useState[1];
var _useState2 = React.useState(new Date(displayDate).getFullYear()),
year = _useState2[0],
setYear = _useState2[1];
var _useState3 = React.useState(_getYearList(minDate, maxDate)),
yearList = _useState3[0],
setYearList = _useState3[1];
React.useEffect(function () {
setMonth(new Date(displayDate).getMonth());
setYear(new Date(displayDate).getFullYear());
}, [displayDate]);
React.useEffect(function () {
setYearList(_getYearList(minDate, maxDate));
}, [minDate, maxDate]);
var handleChangeMonth = function handleChangeMonth(ev) {
var m = ev.target.value;
setMonth(m);
onChangeMonth(m);
};
var handleChangeYear = function handleChangeYear(ev) {
var y = ev.target.value;
setYear(y);
onChangeYear(y);
};
return /*#__PURE__*/React.createElement("div", {
className: "rdp-header-pick-month-default",
style: {
display: 'flex',
flexFlow: 'row',
flexWrap: 'nowrap'
}
}, /*#__PURE__*/React.createElement("div", {
className: "rdp-header-pick-month-default-month",
style: {
flex: '2 1 auto'
}
}, /*#__PURE__*/React.createElement(reactstrap.Input, {
type: "select",
name: "rdp-header-pick-month-default-month",
style: {
lineHeight: "1.5",
fontSize: "0.875rem",
padding: "0.2rem"
},
value: month,
onChange: handleChangeMonth
}, monthLabels.map(function (lmonth, lidx) {
return /*#__PURE__*/React.createElement("option", {
key: "month_" + lidx,
value: lidx
}, lmonth);
}))), /*#__PURE__*/React.createElement("div", {
className: "rdp-header-pick-month-default-year",
style: {
flex: '1 1 67px'
}
}, /*#__PURE__*/React.createElement(reactstrap.Input, {
type: "select",
name: "rdp-header-pick-month-default-year",
style: {
lineHeight: "1.5",
fontSize: "0.875rem",
padding: "0.2rem"
},
value: year,
onChange: handleChangeYear
}, yearList.map(function (lyear) {
return /*#__PURE__*/React.createElement("option", {
key: "year" + lyear,
value: lyear
}, lyear);
}))));
};
function CalendarHeader(_ref) {
var previousButtonElement = _ref.previousButtonElement,
nextButtonElement = _ref.nextButtonElement,
pickMonthElement = _ref.pickMonthElement,
displayDate = _ref.displayDate,
minDate = _ref.minDate,
maxDate = _ref.maxDate,
onChange = _ref.onChange,
monthLabels = _ref.monthLabels;
var _useState = React.useState(false),
displayingMinMonth = _useState[0],
setDisplayingMinMonth = _useState[1];
var _useState2 = React.useState(false),
displayingMaxMonth = _useState2[0],
setDisplayingMaxMonth = _useState2[1];
var _useState3 = React.useState(''),
title = _useState3[0],
setTitle = _useState3[1];
var PickMonthElement = pickMonthElement;
React.useEffect(function () {
if (displayDate == undefined) {
return;
}
if (!minDate) {
setDisplayingMinMonth(false);
} else {
setDisplayingMinMonth(compareMonths(displayDate, minDate));
}
if (!maxDate) {
setDisplayingMaxMonth(false);
} else {
setDisplayingMaxMonth(compareMonths(displayDate, maxDate));
}
try {
if (monthLabels) {
setTitle(monthLabels[displayDate.getMonth()] + " " + displayDate.getFullYear());
}
} catch (e) {
console.error(e);
}
}, [displayDate, minDate, maxDate, monthLabels]);
var handleChangeMonthIncr = function handleChangeMonthIncr(inc) {
var newDisplayDate = new Date(displayDate);
newDisplayDate.setMonth(newDisplayDate.getMonth() + inc, 1);
onChange(newDisplayDate);
};
var handleChangeMonth = function handleChangeMonth(m) {
var newDisplayDate = new Date(displayDate);
newDisplayDate.setMonth(m);
onChange(newDisplayDate);
};
var handleChangeYear = function handleChangeYear(y) {
var newDisplayDate = new Date(displayDate);
newDisplayDate.setFullYear(y);
onChange(newDisplayDate);
};
return /*#__PURE__*/React.createElement("div", {
className: "rdp-header text-center",
style: {
display: 'flex',
flexFlow: 'row',
flexWrap: 'nowrap'
}
}, /*#__PURE__*/React.createElement("div", {
className: "text-muted rdp-header-previous-wrapper",
onClick: function onClick() {
return handleChangeMonthIncr(-1);
},
style: {
cursor: 'pointer',
userSelect: 'none',
flexBasis: '1.25em',
alignSelf: 'center'
}
}, displayingMinMonth ? null : previousButtonElement), /*#__PURE__*/React.createElement("div", {
className: "rdp-header-pick-month-wrapper",
style: {
flex: '1 1 auto'
}
}, PickMonthElement == null || PickMonthElement === 'none' ? /*#__PURE__*/React.createElement("div", null, title) : PickMonthElement === 'default' ? /*#__PURE__*/React.createElement(PickMonthDefault, {
displayDate: displayDate,
monthLabels: monthLabels,
minDate: minDate,
maxDate: maxDate,
onChangeMonth: function onChangeMonth(m) {
return handleChangeMonth(m);
},
onChangeYear: function onChangeYear(y) {
return handleChangeYear(y);
}
}) : /*#__PURE__*/React.createElement(PickMonthElement, {
displayDate: displayDate,
minDate: minDate,
maxDate: maxDate,
onChangeMonth: function onChangeMonth(m) {
return handleChangeMonth(m);
},
onChangeYear: function onChangeYear(y) {
return handleChangeYear(y);
}
})), /*#__PURE__*/React.createElement("div", {
className: "text-muted rdp-header-next-wrapper",
onClick: function onClick() {
return handleChangeMonthIncr(1);
},
style: {
cursor: 'pointer',
userSelect: 'none',
flexBasis: '1.25em',
alignSelf: 'center'
}
}, displayingMaxMonth ? null : nextButtonElement));
}
var CalendarSubHeader = function CalendarSubHeader(_ref) {
var dayLabels = _ref.dayLabels,
showWeeks = _ref.showWeeks,
cellPadding = _ref.cellPadding;
return /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, showWeeks ? /*#__PURE__*/React.createElement("td", {
className: "text-muted current-week",
style: {
padding: cellPadding
}
}) : null, dayLabels.map(function (label, index) {
return /*#__PURE__*/React.createElement("td", {
key: index,
className: "text-muted",
style: {
padding: cellPadding
}
}, /*#__PURE__*/React.createElement("small", null, label));
})));
};
var CalendarDayOutOfMonth = function CalendarDayOutOfMonth() {
return /*#__PURE__*/React.createElement("td", null);
};
var CAL_DAY_CLASSNAME_BY_MODE = {
'normal': '',
'muted': 'text-muted',
'selected': 'bg-primary',
'current': 'text-primary'
};
var CalendarDayInMonth = function CalendarDayInMonth(_ref) {
var day = _ref.day,
mode = _ref.mode,
onDayClick = _ref.onDayClick,
cellPadding = _ref.cellPadding,
roundedCorners = _ref.roundedCorners;
var handleClick = function handleClick(ev) {
if (mode != 'muted') {
onDayClick(ev);
}
};
return /*#__PURE__*/React.createElement("td", {
"data-day": day,
onClick: handleClick,
style: {
cursor: mode == 'muted' ? 'default' : 'pointer',
padding: cellPadding,
borderRadius: roundedCorners ? '5px' : '0px'
},
className: CAL_DAY_CLASSNAME_BY_MODE[mode]
}, day);
};
var CalendarWeekNum = function CalendarWeekNum(_ref) {
var weekNum = _ref.weekNum,
cellPadding = _ref.cellPadding;
return /*#__PURE__*/React.createElement("td", {
style: {
padding: cellPadding,
fontSize: '0.8em',
color: 'darkgrey'
},
className: "text-muted"
}, weekNum);
};
var CalendarBody = function CalendarBody(_ref) {
var calendarDays = _ref.calendarDays,
showWeeks = _ref.showWeeks,
onDayClick = _ref.onDayClick,
cellPadding = _ref.cellPadding,
roundedCorners = _ref.roundedCorners;
if (!calendarDays) {
return /*#__PURE__*/React.createElement("tbody", null);
}
return /*#__PURE__*/React.createElement("tbody", null, calendarDays.map(function (week, weekIndex) {
return /*#__PURE__*/React.createElement("tr", {
key: "rdp_calendar_week_" + weekIndex
}, showWeeks ? /*#__PURE__*/React.createElement(CalendarWeekNum, {
key: "rdp_calendar_week_" + weekIndex + "_weeknum",
weekNum: week.weekNum,
cellPadding: cellPadding
}) : null, week.weekDays.map(function (weekDay, weekDayIndex) {
return weekDay.inMonth ? /*#__PURE__*/React.createElement(CalendarDayInMonth, {
key: "rdp_calendar_week_" + weekIndex + "_day_" + weekDayIndex,
day: weekDay.day,
mode: weekDay.mode,
onDayClick: onDayClick,
cellPadding: cellPadding,
roundedCorners: roundedCorners
}) : /*#__PURE__*/React.createElement(CalendarDayOutOfMonth, {
key: "rdp_calendar_week_" + weekIndex + "_day_" + weekDayIndex
});
}));
}));
};
var CalendarFooter = function CalendarFooter(_ref) {
var dayLabels = _ref.dayLabels,
showWeeks = _ref.showWeeks,
handleTodayClick = _ref.handleTodayClick,
showTodayButton = _ref.showTodayButton,
todayButtonLabel = _ref.todayButtonLabel;
if (!showTodayButton) {
return null;
}
return /*#__PURE__*/React.createElement("tfoot", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
colSpan: dayLabels.length + (showWeeks ? 1 : 0),
style: {
paddingTop: '9px'
}
}, /*#__PURE__*/React.createElement(reactstrap.Button, {
block: true,
size: "sm",
className: "u-today-button",
onClick: function onClick() {
return handleTodayClick();
}
}, todayButtonLabel))));
};
var DAYS_BY_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
/**
groupByWeeks: {
year,
month,
weeks: [
{weekNum: N,
wekDays: [
{inMonth: true, day: N, mode: ''}
or
{inMonth: false}
]
},...
]
}
*/
function _groupByWeeks(year, month, weekStartsOn) {
if (year == undefined || month == undefined) {
return undefined;
}
var firstDay = new Date(year, month, 1);
var startingDay = weekStartsOn > 1 ? firstDay.getDay() - weekStartsOn + 7 : weekStartsOn === 1 ? firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1 : firstDay.getDay();
var monthLength = DAYS_BY_MONTH[month];
if (month == 1) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
monthLength = 29;
}
}
var isInMonth = function isInMonth(monthDay, weekIndex, weekDay) {
if (monthDay <= monthLength && (weekIndex > 0 || weekDay >= startingDay)) {
return true;
}
return false;
};
var getWeekNumber = function getWeekNumber(monthDay) {
var date = new Date(year, month, monthDay - 1, 12, 0, 0, 0);
var target = new Date(date.valueOf());
var dayNr = (date.getDay() + 6) % 7;
target.setDate(target.getDate() - dayNr + 3);
var firstThursday = target.valueOf();
target.setMonth(0, 1);
if (target.getDay() !== 4) {
target.setMonth(0, 1 + (4 - target.getDay() + 7) % 7);
}
return 1 + Math.ceil((firstThursday - target) / 604800000);
};
var allWeeks = [];
var monthDay = 1;
for (var weekIndex = 0; weekIndex < 9; weekIndex++) {
var weekDays = [];
for (var weekDay = 0; weekDay <= 6; weekDay++) {
if (isInMonth(monthDay, weekIndex, weekDay)) {
weekDays.push({
inMonth: true,
day: monthDay
});
monthDay += 1;
} else {
weekDays.push({
inMonth: false
});
}
}
var weekNum = getWeekNumber(monthDay);
allWeeks.push({
weekDays: weekDays,
weekNum: weekNum
});
if (monthDay > monthLength) {
break;
}
}
return {
year: year,
month: month,
weeks: allWeeks
};
}
/**
calendarDays: [
{weekNum: N,
wekDays: [
{inMonth: true, day: N, mode: ''}
or
{inMonth: false}
]
},...
]
*/
function _makeCalendarDays(groupByWeeks, selectedDate, minDate, maxDate) {
if (groupByWeeks == undefined) {
return [];
}
var getDayMode = function getDayMode(day) {
var date = setTimeToNoon(new Date(groupByWeeks.year, groupByWeeks.month, day, 12, 0, 0, 0)).toISOString();
var beforeMinDate = minDate != undefined ? Date.parse(date) < Date.parse(setTimeToNoon(new Date(minDate))) : false;
var afterMaxDate = maxDate != undefined ? Date.parse(date) > Date.parse(setTimeToNoon(new Date(maxDate))) : false;
var currentDate = setTimeToNoon(new Date());
var nSelectedDate = setTimeToNoon(new Date(selectedDate));
if (beforeMinDate || afterMaxDate) {
return 'muted';
} else if (Date.parse(date) === Date.parse(nSelectedDate)) {
return 'selected';
} else if (Date.parse(date) === Date.parse(currentDate)) {
return 'current';
} else {
return 'normal';
}
};
var calendarDays = [];
groupByWeeks.weeks.map(function (week) {
var weekNum = week.weekNum;
var weekDays = week.weekDays.map(function (weekDay) {
return _extends({}, weekDay, {
mode: weekDay.inMonth ? getDayMode(weekDay.day) : undefined
});
});
calendarDays.push({
weekNum: weekNum,
weekDays: weekDays
});
});
return calendarDays;
}
function useCalendarDays(displayDate, selectedDate, minDate, maxDate, weekStartsOn) {
var _useState = React.useState(undefined),
year = _useState[0],
setYear = _useState[1];
var _useState2 = React.useState(undefined),
month = _useState2[0],
setMonth = _useState2[1];
var _useState3 = React.useState(undefined),
groupByWeeks = _useState3[0],
setGroupByWeeks = _useState3[1];
var _useState4 = React.useState([]),
calendarDays = _useState4[0],
setCalendarDays = _useState4[1];
React.useEffect(function () {
if (displayDate) {
setYear(displayDate.getFullYear());
setMonth(displayDate.getMonth());
}
}, [displayDate]);
React.useEffect(function () {
setGroupByWeeks(_groupByWeeks(year, month, weekStartsOn));
}, [year, month, weekStartsOn]);
React.useEffect(function () {
setCalendarDays(_makeCalendarDays(groupByWeeks, selectedDate, minDate, maxDate));
}, [groupByWeeks, selectedDate, minDate, maxDate]);
return calendarDays;
}
var Calendar = function Calendar(_ref) {
var popoverRef = _ref.popoverRef,
selectedDate = _ref.selectedDate,
displayDate = _ref.displayDate,
minDate = _ref.minDate,
maxDate = _ref.maxDate,
onChange = _ref.onChange,
dayLabels = _ref.dayLabels,
cellPadding = _ref.cellPadding,
weekStartsOn = _ref.weekStartsOn,
showTodayButton = _ref.showTodayButton,
todayButtonLabel = _ref.todayButtonLabel,
roundedCorners = _ref.roundedCorners,
showWeeks = _ref.showWeeks,
monthLabels = _ref.monthLabels,
previousButtonElement = _ref.previousButtonElement,
nextButtonElement = _ref.nextButtonElement,
pickMonthElement = _ref.pickMonthElement,
placement = _ref.placement,
open = _ref.open,
container = _ref.container,
target = _ref.target,
onChangeMonth = _ref.onChangeMonth;
var calendarDays = useCalendarDays(displayDate, selectedDate, minDate, maxDate, weekStartsOn);
var handleDayClick = function handleDayClick(e) {
var day = e.currentTarget.getAttribute('data-day');
var newSelectedDate = setTimeToNoon(new Date(displayDate));
newSelectedDate.setDate(day);
onChange(newSelectedDate);
};
var handleTodayClick = function handleTodayClick() {
var newSelectedDate = setTimeToNoon(new Date());
onChange(newSelectedDate);
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(reactstrap.Popover, {
innerRef: popoverRef,
className: "rdp-popover " + placement
//toggle = {() => handleHide()}
,
isOpen: open,
container: container,
target: target,
placement: placement
// delay = {200} // does not apply for us (manual triggering)
}, /*#__PURE__*/React.createElement(reactstrap.PopoverHeader, {
tag: "div"
}, /*#__PURE__*/React.createElement(CalendarHeader, {
previousButtonElement: previousButtonElement,
nextButtonElement: nextButtonElement,
pickMonthElement: pickMonthElement,
displayDate: displayDate,
minDate: minDate,
maxDate: maxDate,
onChange: function onChange(newDisplayDate) {
return onChangeMonth(newDisplayDate);
},
monthLabels: monthLabels
})), /*#__PURE__*/React.createElement(reactstrap.PopoverBody, null, /*#__PURE__*/React.createElement("table", {
className: "rdp-calendar text-center"
}, /*#__PURE__*/React.createElement(CalendarSubHeader, {
dayLabels: dayLabels,
showWeeks: showWeeks,
cellPadding: cellPadding
}), /*#__PURE__*/React.createElement(CalendarBody, {
calendarDays: calendarDays,
showWeeks: showWeeks,
onDayClick: handleDayClick,
cellPadding: cellPadding,
roundedCorners: roundedCorners
}), /*#__PURE__*/React.createElement(CalendarFooter, {
dayLabels: dayLabels,
showWeeks: showWeeks,
handleTodayClick: handleTodayClick,
showTodayButton: showTodayButton,
todayButtonLabel: todayButtonLabel
})))));
};
// NOTE: do we want to use the controlInput or the hiddenInput here?
// We were previously using the hidden one, but I see no reasons.
// 'change' events would make sense on the hidden input, but focus
// control seems to be more on the control input.
// Anyway, this is not decided here, but when calling useCustomEvents()
var useCustomEvents = function useCustomEvents(inputRef, onBlur, onFocus) {
var customOnBlur = React.useCallback(function () {
if (onBlur) {
var event = document.createEvent('CustomEvent');
event.initEvent('Change Date', true, false);
inputRef.current.dispatchEvent(event);
onBlur(event);
}
}, [inputRef, onBlur]);
var customOnFocus = React.useCallback(function () {
if (onFocus) {
var event = document.createEvent('CustomEvent');
event.initEvent('Change Date', true, false);
inputRef.current.dispatchEvent(event);
onFocus(event);
}
}, [inputRef, onFocus]);
return [customOnBlur, customOnFocus];
};
var getMaybeFuncValue = function getMaybeFuncValue(value) {
var tag = Object.prototype.toString.call(value);
var isFunction = tag === '[object AsyncFunction]' || tag === '[object Function]' || tag === '[object GeneratorFunction]' || tag === '[object Proxy]';
if (isFunction) {
return value();
} else {
return value;
}
};
// About autoFocus
// We could handle by our own through ref callbacks
// (https://blog.maisie.ink/react-ref-autofocus/)
// But let's just use react's autoFocus attribute by now
var useCalendarProps = function useCalendarProps(calendarPlacement, inputRef, autoFocus, onBlur, onFocus) {
var _useState = React.useState(false),
open = _useState[0],
setOpen = _useState[1];
var _useState2 = React.useState(getMaybeFuncValue(calendarPlacement)),
placement = _useState2[0],
setPlacement = _useState2[1];
var hiddenInputRef = React.useRef();
var overlayContainerRef = React.useRef();
var popoverRef = React.useRef();
var controlInputRef = typeof inputRef == 'object' ? inputRef : React.useRef(inputRef); // eslint-disable-line react-hooks/rules-of-hooks
// NOTE: do we want to use the controlInput or the hiddenInput here?
var _useCustomEvents = useCustomEvents(/*hiddenInputRef*/controlInputRef, onBlur, onFocus),
customOnBlur = _useCustomEvents[0],
customOnFocus = _useCustomEvents[1];
var isOutside = React.useCallback(function (event) {
var outOfCalendar = (popoverRef == null ? void 0 : popoverRef.current) == undefined || !(popoverRef != null && popoverRef.current.contains(event.target));
var outOfControlInput = (controlInputRef == null ? void 0 : controlInputRef.current) == undefined || !controlInputRef.current.contains(event.target);
var isOut = outOfCalendar && outOfControlInput;
return isOut;
}, [popoverRef, controlInputRef]);
// Control the click outside
React.useEffect(function () {
function handleClickOutside(event) {
event.stopPropagation();
if (open) {
if (isOutside(event)) {
setOpen(false);
customOnBlur();
}
}
}
document.addEventListener("mousedown", handleClickOutside);
return function () {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [open, isOutside, customOnBlur]);
//
// This callback is bound to Calendar.Popover's toggle() method,
// but seems it's unneccesary
// Leaving, by now, this testimonial comments
//
// const handleHide = () => {
// let inputFocused = false
// try {
// inputFocused= controlInputRef.current==document.activeElement
// } catch(e) {}
//
// if (inputFocused) {
// return
// }
// setOpen(false)
// customOnBlur()
// }
var handleFocus = React.useCallback(function () {
var nPlacement = getMaybeFuncValue(calendarPlacement);
setPlacement(nPlacement);
setOpen(true);
customOnFocus();
}, [calendarPlacement, customOnFocus]);
var handleBlur = React.useCallback(function (event) {
if (isOutside(event)) {
setOpen(false);
customOnBlur();
}
}, [isOutside, customOnBlur]);
return [hiddenInputRef, overlayContainerRef, popoverRef, controlInputRef, open, placement, handleFocus, handleBlur];
};
var _defaultDateFormat = function _defaultDateFormat() {
var language = typeof window !== 'undefined' && window.navigator ? (window.navigator.userLanguage || window.navigator.language || '').toLowerCase() : '';
var dateFormat = !language || language === 'en-us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY';
return dateFormat;
};
var DEFAULT_DAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var DEFAULT_MONTH_LABELS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var DatePickerBase = function DatePickerBase(props, ref) {
var value = props.value,
defaultValue = props.defaultValue,
id = props.id,
name = props.name,
_props$dateFormat = props.dateFormat,
dateFormat = _props$dateFormat === void 0 ? _defaultDateFormat() : _props$dateFormat,
minDate = props.minDate,
maxDate = props.maxDate,
_props$clearButtonEle = props.clearButtonElement,
clearButtonElement = _props$clearButtonEle === void 0 ? '×' : _props$clearButtonEle,
_props$showClearButto = props.showClearButton,
showClearButton = _props$showClearButto === void 0 ? true : _props$showClearButto,
onInvalid = props.onInvalid,
onChange = props.onChange,
onClear = props.onClear,
onBlur = props.onBlur,
onFocus = props.onFocus,
size = props.size,
valid = props.valid,
invalid = props.invalid,
customInputGroup = props.customInputGroup,
_props$autoComplete = props.autoComplete,
autoComplete = _props$autoComplete === void 0 ? 'on' : _props$autoComplete,
_props$autoFocus = props.autoFocus,
autoFocus = _props$autoFocus === void 0 ? false : _props$autoFocus,
_props$disabled = props.disabled,
disabled = _props$disabled === void 0 ? false : _props$disabled,
_props$noValidate = props.noValidate,
noValidate = _props$noValidate === void 0 ? false : _props$noValidate,
placeholder = props.placeholder,
required = props.required,
className = props.className,
_props$style = props.style,
style = _props$style === void 0 ? undefined : _props$style,
inputRef = props.inputRef,
customControl = props.customControl,
children = props.children,
calendarContainer = props.calendarContainer,
_props$dayLabels = props.dayLabels,
dayLabels = _props$dayLabels === void 0 ? DEFAULT_DAY_LABELS : _props$dayLabels,
_props$monthLabels = props.monthLabels,
monthLabels = _props$monthLabels === void 0 ? DEFAULT_MONTH_LABELS : _props$monthLabels,
weekStartsOn = props.weekStartsOn,
_props$showWeeks = props.showWeeks,
showWeeks = _props$showWeeks === void 0 ? false : _props$showWeeks,
_props$previousButton = props.previousButtonElement,
previousButtonElement = _props$previousButton === void 0 ? '<' : _props$previousButton,
_props$nextButtonElem = props.nextButtonElement,
nextButtonElement = _props$nextButtonElem === void 0 ? '>' : _props$nextButtonElem,
_props$pickMonthEleme = props.pickMonthElement,
pickMonthElement = _props$pickMonthEleme === void 0 ? undefined : _props$pickMonthEleme,
_props$showTodayButto = props.showTodayButton,
showTodayButton = _props$showTodayButto === void 0 ? false : _props$showTodayButto,
_props$todayButtonLab = props.todayButtonLabel,
todayButtonLabel = _props$todayButtonLab === void 0 ? 'Today' : _props$todayButtonLab,
_props$roundedCorners = props.roundedCorners,
roundedCorners = _props$roundedCorners === void 0 ? false : _props$roundedCorners,
_props$cellPadding = props.cellPadding,
cellPadding = _props$cellPadding === void 0 ? '5px' : _props$cellPadding,
_props$calendarPlacem = props.calendarPlacement,
calendarPlacement = _props$calendarPlacem === void 0 ? 'bottom' : _props$calendarPlacem;
var propError = useCheckProps(value, defaultValue);
if (propError != undefined) {
throw new Error(propError);
}
var _useCalendarProps = useCalendarProps(calendarPlacement, inputRef, autoFocus, onBlur, onFocus),
hiddenInputRef = _useCalendarProps[0],
overlayContainerRef = _useCalendarProps[1],
popoverRef = _useCalendarProps[2],
controlInputRef = _useCalendarProps[3],
open = _useCalendarProps[4],
placement = _useCalendarProps[5],
handleFocus = _useCalendarProps[6],
handleBlur = _useCalendarProps[7];
var _useInputValues = useInputValues(controlInputRef, value, defaultValue, minDate, maxDate, dateFormat, onClear, onChange),
innerValue = _useInputValues[0],
inputValue = _useInputValues[1],
displayDate = _useInputValues[2],
selectedDate = _useInputValues[3],
handleClear = _useInputValues[4],
handleInputChange = _useInputValues[5],
handleChangeMonth = _useInputValues[6],
handleChangeDate = _useInputValues[7],
handleBadInputOnBlur = _useInputValues[8];
var _useInputIds = useInputIds(id, name, customControl),
groupInputId = _useInputIds[0],
hiddenInputId = _useInputIds[1],
controlInputId = _useInputIds[2],
overlayId = _useInputIds[3];
React.useImperativeHandle(ref, function () {
return {
getValue: function getValue() {
return selectedDate ? selectedDate.toISOString() : null;
},
getFormattedValue: function getFormattedValue() {
return displayDate ? inputValue : null;
},
getNode: function getNode() {
return controlInputRef == null ? void 0 : controlInputRef.current;
}
};
}); //, [controlInputRef, displayDate, inputValue, selectedDate]))
var fixedDayLabels = useFixedDayLabels(dayLabels, weekStartsOn);
var handleChangeDateAndBlur = function handleChangeDateAndBlur(nSelectedDate) {
handleChangeDate(nSelectedDate);
handleBlur(true);
};
return /*#__PURE__*/React.createElement(InputGroup, {
customInputGroup: customInputGroup,
size: size,
inputId: groupInputId
}, /*#__PURE__*/React.createElement(InputControlInput, {
controlId: controlInputId,
customControl: customControl,
value: inputValue || '',
required: required,
placeholder: placeholder || '',
inputRef: controlInputRef,
disabled: disabled,
className: className,
style: style,
autoFocus: autoFocus,
autoComplete: autoComplete,
onInvalid: onInvalid,
noValidate: noValidate,
valid: valid,
invalid: invalid,
onFocus: function onFocus() {
return handleFocus();
},
onBlur: function onBlur(event) {
handleBadInputOnBlur();
handleBlur(event);
},
onChange: function onChange() {
return handleInputChange();
}
}), /*#__PURE__*/React.createElement(InputOverlay, {
overlayContainerRef: overlayContainerRef,
oid: overlayId
}, overlayContainerRef.current == undefined ? null : /*#__PURE__*/React.createElement(Calendar, {
popoverRef: popoverRef,
placement: placement,
open: open,
container: calendarContainer || overlayContainerRef,
target: controlInputId,
previousButtonElement: previousButtonElement,
nextButtonElement: nextButtonElement,
pickMonthElement: pickMonthElement,
displayDate: displayDate,
minDate: minDate,
maxDate: maxDate,
onChangeMonth: function onChangeMonth(newDisplayDate) {
return handleChangeMonth(newDisplayDate);
},
monthLabels: monthLabels,
cellPadding: cellPadding,
selectedDate: selectedDate,
onChange: function onChange(newSelectedDate) {
return handleChangeDateAndBlur(newSelectedDate);
},
dayLabels: fixedDayLabels,
weekStartsOn: weekStartsOn,
showTodayButton: showTodayButton,
todayButtonLabel: todayButtonLabel,
roundedCorners: roundedCorners,
showWeeks: showWeeks
})), /*#__PURE__*/React.createElement(InputHidden, {
inputId: hiddenInputId,
name: name,
value: innerValue || '',
formattedValue: innerValue ? inputValue : '',
hiddenInputRef: hiddenInputRef
}), showClearButton && !customControl ? /*#__PURE__*/React.createElement(InputClearButton, {
inputValue: inputValue,
disabled: disabled,
clearButtonElement: clearButtonElement,
onClick: function onClick() {
return handleClear();
}
}) : null, children);
};
var DatePicker = /*#__PURE__*/React.forwardRef(DatePickerBase);
exports.DatePicker = DatePicker;