react-dates
Version:
A responsive and accessible date range picker component built with React
463 lines (401 loc) • 18.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _reactAddonsShallowCompare = _interopRequireDefault(require("react-addons-shallow-compare"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _moment = _interopRequireDefault(require("moment"));
var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes"));
var _airbnbPropTypes = require("airbnb-prop-types");
var _OpenDirectionShape = _interopRequireDefault(require("../shapes/OpenDirectionShape"));
var _defaultPhrases = require("../defaultPhrases");
var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes"));
var _DateRangePickerInput = _interopRequireDefault(require("./DateRangePickerInput"));
var _IconPositionShape = _interopRequireDefault(require("../shapes/IconPositionShape"));
var _DisabledShape = _interopRequireDefault(require("../shapes/DisabledShape"));
var _toMomentObject = _interopRequireDefault(require("../utils/toMomentObject"));
var _toLocalizedDateString = _interopRequireDefault(require("../utils/toLocalizedDateString"));
var _isInclusivelyAfterDay = _interopRequireDefault(require("../utils/isInclusivelyAfterDay"));
var _isBeforeDay = _interopRequireDefault(require("../utils/isBeforeDay"));
var _constants = require("../constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function () { function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); } return _getPrototypeOf; }(); return _getPrototypeOf(o); }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function () { function _setPrototypeOf(o, p) { o.__proto__ = p; return o; } return _setPrototypeOf; }(); return _setPrototypeOf(o, p); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({
startDate: _reactMomentProptypes["default"].momentObj,
startDateId: _propTypes["default"].string,
startDatePlaceholderText: _propTypes["default"].string,
isStartDateFocused: _propTypes["default"].bool,
endDate: _reactMomentProptypes["default"].momentObj,
endDateId: _propTypes["default"].string,
endDatePlaceholderText: _propTypes["default"].string,
isEndDateFocused: _propTypes["default"].bool,
screenReaderMessage: _propTypes["default"].string,
showClearDates: _propTypes["default"].bool,
showCaret: _propTypes["default"].bool,
showDefaultInputIcon: _propTypes["default"].bool,
inputIconPosition: _IconPositionShape["default"],
disabled: _DisabledShape["default"],
required: _propTypes["default"].bool,
readOnly: _propTypes["default"].bool,
openDirection: _OpenDirectionShape["default"],
noBorder: _propTypes["default"].bool,
block: _propTypes["default"].bool,
small: _propTypes["default"].bool,
regular: _propTypes["default"].bool,
verticalSpacing: _airbnbPropTypes.nonNegativeInteger,
keepOpenOnDateSelect: _propTypes["default"].bool,
reopenPickerOnClearDates: _propTypes["default"].bool,
withFullScreenPortal: _propTypes["default"].bool,
minimumNights: _airbnbPropTypes.nonNegativeInteger,
isOutsideRange: _propTypes["default"].func,
displayFormat: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]),
onFocusChange: _propTypes["default"].func,
onClose: _propTypes["default"].func,
onDatesChange: _propTypes["default"].func,
onKeyDownArrowDown: _propTypes["default"].func,
onKeyDownQuestionMark: _propTypes["default"].func,
customInputIcon: _propTypes["default"].node,
customArrowIcon: _propTypes["default"].node,
customCloseIcon: _propTypes["default"].node,
// accessibility
isFocused: _propTypes["default"].bool,
// i18n
phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DateRangePickerInputPhrases)),
isRTL: _propTypes["default"].bool
}) : {};
var defaultProps = {
startDate: null,
startDateId: _constants.START_DATE,
startDatePlaceholderText: 'Start Date',
isStartDateFocused: false,
endDate: null,
endDateId: _constants.END_DATE,
endDatePlaceholderText: 'End Date',
isEndDateFocused: false,
screenReaderMessage: '',
showClearDates: false,
showCaret: false,
showDefaultInputIcon: false,
inputIconPosition: _constants.ICON_BEFORE_POSITION,
disabled: false,
required: false,
readOnly: false,
openDirection: _constants.OPEN_DOWN,
noBorder: false,
block: false,
small: false,
regular: false,
verticalSpacing: undefined,
keepOpenOnDateSelect: false,
reopenPickerOnClearDates: false,
withFullScreenPortal: false,
minimumNights: 1,
isOutsideRange: function () {
function isOutsideRange(day) {
return !(0, _isInclusivelyAfterDay["default"])(day, (0, _moment["default"])());
}
return isOutsideRange;
}(),
displayFormat: function () {
function displayFormat() {
return _moment["default"].localeData().longDateFormat('L');
}
return displayFormat;
}(),
onFocusChange: function () {
function onFocusChange() {}
return onFocusChange;
}(),
onClose: function () {
function onClose() {}
return onClose;
}(),
onDatesChange: function () {
function onDatesChange() {}
return onDatesChange;
}(),
onKeyDownArrowDown: function () {
function onKeyDownArrowDown() {}
return onKeyDownArrowDown;
}(),
onKeyDownQuestionMark: function () {
function onKeyDownQuestionMark() {}
return onKeyDownQuestionMark;
}(),
customInputIcon: null,
customArrowIcon: null,
customCloseIcon: null,
// accessibility
isFocused: false,
// i18n
phrases: _defaultPhrases.DateRangePickerInputPhrases,
isRTL: false
};
var DateRangePickerInputController =
/*#__PURE__*/
function (_ref) {
_inherits(DateRangePickerInputController, _ref);
_createClass(DateRangePickerInputController, [{
key: !_react["default"].PureComponent && "shouldComponentUpdate",
value: function () {
function value(nextProps, nextState) {
return (0, _reactAddonsShallowCompare["default"])(this, nextProps, nextState);
}
return value;
}()
}]);
function DateRangePickerInputController(props) {
var _this;
_classCallCheck(this, DateRangePickerInputController);
_this = _possibleConstructorReturn(this, _getPrototypeOf(DateRangePickerInputController).call(this, props));
_this.onClearFocus = _this.onClearFocus.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.onStartDateChange = _this.onStartDateChange.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.onStartDateFocus = _this.onStartDateFocus.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.onEndDateChange = _this.onEndDateChange.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.onEndDateFocus = _this.onEndDateFocus.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this.clearDates = _this.clearDates.bind(_assertThisInitialized(_assertThisInitialized(_this)));
return _this;
}
_createClass(DateRangePickerInputController, [{
key: "onClearFocus",
value: function () {
function onClearFocus() {
var _this$props = this.props,
onFocusChange = _this$props.onFocusChange,
onClose = _this$props.onClose,
startDate = _this$props.startDate,
endDate = _this$props.endDate;
onFocusChange(null);
onClose({
startDate: startDate,
endDate: endDate
});
}
return onClearFocus;
}()
}, {
key: "onEndDateChange",
value: function () {
function onEndDateChange(endDateString) {
var _this$props2 = this.props,
startDate = _this$props2.startDate,
isOutsideRange = _this$props2.isOutsideRange,
minimumNights = _this$props2.minimumNights,
keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect,
onDatesChange = _this$props2.onDatesChange;
var endDate = (0, _toMomentObject["default"])(endDateString, this.getDisplayFormat());
var isEndDateValid = endDate && !isOutsideRange(endDate) && !(startDate && (0, _isBeforeDay["default"])(endDate, startDate.clone().add(minimumNights, 'days')));
if (isEndDateValid) {
onDatesChange({
startDate: startDate,
endDate: endDate
});
if (!keepOpenOnDateSelect) this.onClearFocus();
} else {
onDatesChange({
startDate: startDate,
endDate: null
});
}
}
return onEndDateChange;
}()
}, {
key: "onEndDateFocus",
value: function () {
function onEndDateFocus() {
var _this$props3 = this.props,
startDate = _this$props3.startDate,
onFocusChange = _this$props3.onFocusChange,
withFullScreenPortal = _this$props3.withFullScreenPortal,
disabled = _this$props3.disabled;
if (!startDate && withFullScreenPortal && (!disabled || disabled === _constants.END_DATE)) {
// When the datepicker is full screen, we never want to focus the end date first
// because there's no indication that that is the case once the datepicker is open and it
// might confuse the user
onFocusChange(_constants.START_DATE);
} else if (!disabled || disabled === _constants.START_DATE) {
onFocusChange(_constants.END_DATE);
}
}
return onEndDateFocus;
}()
}, {
key: "onStartDateChange",
value: function () {
function onStartDateChange(startDateString) {
var endDate = this.props.endDate;
var _this$props4 = this.props,
isOutsideRange = _this$props4.isOutsideRange,
minimumNights = _this$props4.minimumNights,
onDatesChange = _this$props4.onDatesChange,
onFocusChange = _this$props4.onFocusChange,
disabled = _this$props4.disabled;
var startDate = (0, _toMomentObject["default"])(startDateString, this.getDisplayFormat());
var isEndDateBeforeStartDate = startDate && (0, _isBeforeDay["default"])(endDate, startDate.clone().add(minimumNights, 'days'));
var isStartDateValid = startDate && !isOutsideRange(startDate) && !(disabled === _constants.END_DATE && isEndDateBeforeStartDate);
if (isStartDateValid) {
if (isEndDateBeforeStartDate) {
endDate = null;
}
onDatesChange({
startDate: startDate,
endDate: endDate
});
onFocusChange(_constants.END_DATE);
} else {
onDatesChange({
startDate: null,
endDate: endDate
});
}
}
return onStartDateChange;
}()
}, {
key: "onStartDateFocus",
value: function () {
function onStartDateFocus() {
var _this$props5 = this.props,
disabled = _this$props5.disabled,
onFocusChange = _this$props5.onFocusChange;
if (!disabled || disabled === _constants.END_DATE) {
onFocusChange(_constants.START_DATE);
}
}
return onStartDateFocus;
}()
}, {
key: "getDisplayFormat",
value: function () {
function getDisplayFormat() {
var displayFormat = this.props.displayFormat;
return typeof displayFormat === 'string' ? displayFormat : displayFormat();
}
return getDisplayFormat;
}()
}, {
key: "getDateString",
value: function () {
function getDateString(date) {
var displayFormat = this.getDisplayFormat();
if (date && displayFormat) {
return date && date.format(displayFormat);
}
return (0, _toLocalizedDateString["default"])(date);
}
return getDateString;
}()
}, {
key: "clearDates",
value: function () {
function clearDates() {
var _this$props6 = this.props,
onDatesChange = _this$props6.onDatesChange,
reopenPickerOnClearDates = _this$props6.reopenPickerOnClearDates,
onFocusChange = _this$props6.onFocusChange;
onDatesChange({
startDate: null,
endDate: null
});
if (reopenPickerOnClearDates) {
onFocusChange(_constants.START_DATE);
}
}
return clearDates;
}()
}, {
key: "render",
value: function () {
function render() {
var _this$props7 = this.props,
startDate = _this$props7.startDate,
startDateId = _this$props7.startDateId,
startDatePlaceholderText = _this$props7.startDatePlaceholderText,
isStartDateFocused = _this$props7.isStartDateFocused,
endDate = _this$props7.endDate,
endDateId = _this$props7.endDateId,
endDatePlaceholderText = _this$props7.endDatePlaceholderText,
isEndDateFocused = _this$props7.isEndDateFocused,
screenReaderMessage = _this$props7.screenReaderMessage,
showClearDates = _this$props7.showClearDates,
showCaret = _this$props7.showCaret,
showDefaultInputIcon = _this$props7.showDefaultInputIcon,
inputIconPosition = _this$props7.inputIconPosition,
customInputIcon = _this$props7.customInputIcon,
customArrowIcon = _this$props7.customArrowIcon,
customCloseIcon = _this$props7.customCloseIcon,
disabled = _this$props7.disabled,
required = _this$props7.required,
readOnly = _this$props7.readOnly,
openDirection = _this$props7.openDirection,
isFocused = _this$props7.isFocused,
phrases = _this$props7.phrases,
onKeyDownArrowDown = _this$props7.onKeyDownArrowDown,
onKeyDownQuestionMark = _this$props7.onKeyDownQuestionMark,
isRTL = _this$props7.isRTL,
noBorder = _this$props7.noBorder,
block = _this$props7.block,
small = _this$props7.small,
regular = _this$props7.regular,
verticalSpacing = _this$props7.verticalSpacing;
var startDateString = this.getDateString(startDate);
var endDateString = this.getDateString(endDate);
return _react["default"].createElement(_DateRangePickerInput["default"], {
startDate: startDateString,
startDateId: startDateId,
startDatePlaceholderText: startDatePlaceholderText,
isStartDateFocused: isStartDateFocused,
endDate: endDateString,
endDateId: endDateId,
endDatePlaceholderText: endDatePlaceholderText,
isEndDateFocused: isEndDateFocused,
isFocused: isFocused,
disabled: disabled,
required: required,
readOnly: readOnly,
openDirection: openDirection,
showCaret: showCaret,
showDefaultInputIcon: showDefaultInputIcon,
inputIconPosition: inputIconPosition,
customInputIcon: customInputIcon,
customArrowIcon: customArrowIcon,
customCloseIcon: customCloseIcon,
phrases: phrases,
onStartDateChange: this.onStartDateChange,
onStartDateFocus: this.onStartDateFocus,
onStartDateShiftTab: this.onClearFocus,
onEndDateChange: this.onEndDateChange,
onEndDateFocus: this.onEndDateFocus,
onEndDateTab: this.onClearFocus,
showClearDates: showClearDates,
onClearDates: this.clearDates,
screenReaderMessage: screenReaderMessage,
onKeyDownArrowDown: onKeyDownArrowDown,
onKeyDownQuestionMark: onKeyDownQuestionMark,
isRTL: isRTL,
noBorder: noBorder,
block: block,
small: small,
regular: regular,
verticalSpacing: verticalSpacing
});
}
return render;
}()
}]);
return DateRangePickerInputController;
}(_react["default"].PureComponent || _react["default"].Component);
exports["default"] = DateRangePickerInputController;
DateRangePickerInputController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {};
DateRangePickerInputController.defaultProps = defaultProps;