UNPKG

react-dates

Version:

A responsive and accessible date range picker component built with React

1,394 lines (1,125 loc) 53.5 kB
Object.defineProperty(exports, "__esModule", { value: true }); var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _object = require('object.assign'); var _object2 = _interopRequireDefault(_object); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactMomentProptypes = require('react-moment-proptypes'); var _reactMomentProptypes2 = _interopRequireDefault(_reactMomentProptypes); var _airbnbPropTypes = require('airbnb-prop-types'); var _moment = require('moment'); var _moment2 = _interopRequireDefault(_moment); var _object3 = require('object.values'); var _object4 = _interopRequireDefault(_object3); var _isTouchDevice = require('is-touch-device'); var _isTouchDevice2 = _interopRequireDefault(_isTouchDevice); var _defaultPhrases = require('../defaultPhrases'); var _getPhrasePropTypes = require('../utils/getPhrasePropTypes'); var _getPhrasePropTypes2 = _interopRequireDefault(_getPhrasePropTypes); var _isInclusivelyAfterDay = require('../utils/isInclusivelyAfterDay'); var _isInclusivelyAfterDay2 = _interopRequireDefault(_isInclusivelyAfterDay); var _isNextDay = require('../utils/isNextDay'); var _isNextDay2 = _interopRequireDefault(_isNextDay); var _isSameDay = require('../utils/isSameDay'); var _isSameDay2 = _interopRequireDefault(_isSameDay); var _isAfterDay = require('../utils/isAfterDay'); var _isAfterDay2 = _interopRequireDefault(_isAfterDay); var _isBeforeDay = require('../utils/isBeforeDay'); var _isBeforeDay2 = _interopRequireDefault(_isBeforeDay); var _getVisibleDays = require('../utils/getVisibleDays'); var _getVisibleDays2 = _interopRequireDefault(_getVisibleDays); var _isDayVisible = require('../utils/isDayVisible'); var _isDayVisible2 = _interopRequireDefault(_isDayVisible); var _getSelectedDateOffset = require('../utils/getSelectedDateOffset'); var _getSelectedDateOffset2 = _interopRequireDefault(_getSelectedDateOffset); var _toISODateString = require('../utils/toISODateString'); var _toISODateString2 = _interopRequireDefault(_toISODateString); var _toISOMonthString = require('../utils/toISOMonthString'); var _toISOMonthString2 = _interopRequireDefault(_toISOMonthString); var _DisabledShape = require('../shapes/DisabledShape'); var _DisabledShape2 = _interopRequireDefault(_DisabledShape); var _FocusedInputShape = require('../shapes/FocusedInputShape'); var _FocusedInputShape2 = _interopRequireDefault(_FocusedInputShape); var _ScrollableOrientationShape = require('../shapes/ScrollableOrientationShape'); var _ScrollableOrientationShape2 = _interopRequireDefault(_ScrollableOrientationShape); var _DayOfWeekShape = require('../shapes/DayOfWeekShape'); var _DayOfWeekShape2 = _interopRequireDefault(_DayOfWeekShape); var _CalendarInfoPositionShape = require('../shapes/CalendarInfoPositionShape'); var _CalendarInfoPositionShape2 = _interopRequireDefault(_CalendarInfoPositionShape); var _constants = require('../constants'); var _DayPicker = require('./DayPicker'); var _DayPicker2 = _interopRequireDefault(_DayPicker); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var propTypes = (0, _airbnbPropTypes.forbidExtraProps)({ startDate: _reactMomentProptypes2['default'].momentObj, endDate: _reactMomentProptypes2['default'].momentObj, onDatesChange: _propTypes2['default'].func, startDateOffset: _propTypes2['default'].func, endDateOffset: _propTypes2['default'].func, focusedInput: _FocusedInputShape2['default'], onFocusChange: _propTypes2['default'].func, onClose: _propTypes2['default'].func, keepOpenOnDateSelect: _propTypes2['default'].bool, minimumNights: _propTypes2['default'].number, disabled: _DisabledShape2['default'], isOutsideRange: _propTypes2['default'].func, isDayBlocked: _propTypes2['default'].func, isDayHighlighted: _propTypes2['default'].func, // DayPicker props renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes2['default'].func, 'renderMonthText', 'renderMonthElement'), renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes2['default'].func, 'renderMonthText', 'renderMonthElement'), enableOutsideDays: _propTypes2['default'].bool, numberOfMonths: _propTypes2['default'].number, orientation: _ScrollableOrientationShape2['default'], withPortal: _propTypes2['default'].bool, initialVisibleMonth: _propTypes2['default'].func, hideKeyboardShortcutsPanel: _propTypes2['default'].bool, daySize: _airbnbPropTypes.nonNegativeInteger, noBorder: _propTypes2['default'].bool, verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, navPrev: _propTypes2['default'].node, navNext: _propTypes2['default'].node, noNavButtons: _propTypes2['default'].bool, onPrevMonthClick: _propTypes2['default'].func, onNextMonthClick: _propTypes2['default'].func, onOutsideClick: _propTypes2['default'].func, renderCalendarDay: _propTypes2['default'].func, renderDayContents: _propTypes2['default'].func, renderCalendarInfo: _propTypes2['default'].func, calendarInfoPosition: _CalendarInfoPositionShape2['default'], firstDayOfWeek: _DayOfWeekShape2['default'], verticalHeight: _airbnbPropTypes.nonNegativeInteger, transitionDuration: _airbnbPropTypes.nonNegativeInteger, // accessibility onBlur: _propTypes2['default'].func, isFocused: _propTypes2['default'].bool, showKeyboardShortcuts: _propTypes2['default'].bool, // i18n monthFormat: _propTypes2['default'].string, weekDayFormat: _propTypes2['default'].string, phrases: _propTypes2['default'].shape((0, _getPhrasePropTypes2['default'])(_defaultPhrases.DayPickerPhrases)), dayAriaLabelFormat: _propTypes2['default'].string, isRTL: _propTypes2['default'].bool }); var defaultProps = { startDate: undefined, // TODO: use null endDate: undefined, // TODO: use null onDatesChange: function () { function onDatesChange() {} return onDatesChange; }(), startDateOffset: undefined, endDateOffset: undefined, focusedInput: null, onFocusChange: function () { function onFocusChange() {} return onFocusChange; }(), onClose: function () { function onClose() {} return onClose; }(), keepOpenOnDateSelect: false, minimumNights: 1, disabled: false, isOutsideRange: function () { function isOutsideRange() {} return isOutsideRange; }(), isDayBlocked: function () { function isDayBlocked() {} return isDayBlocked; }(), isDayHighlighted: function () { function isDayHighlighted() {} return isDayHighlighted; }(), // DayPicker props renderMonthText: null, enableOutsideDays: false, numberOfMonths: 1, orientation: _constants.HORIZONTAL_ORIENTATION, withPortal: false, hideKeyboardShortcutsPanel: false, initialVisibleMonth: null, daySize: _constants.DAY_SIZE, navPrev: null, navNext: null, noNavButtons: false, onPrevMonthClick: function () { function onPrevMonthClick() {} return onPrevMonthClick; }(), onNextMonthClick: function () { function onNextMonthClick() {} return onNextMonthClick; }(), onOutsideClick: function () { function onOutsideClick() {} return onOutsideClick; }(), renderCalendarDay: undefined, renderDayContents: null, renderCalendarInfo: null, renderMonthElement: null, calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, firstDayOfWeek: null, verticalHeight: null, noBorder: false, transitionDuration: undefined, verticalBorderSpacing: undefined, // accessibility onBlur: function () { function onBlur() {} return onBlur; }(), isFocused: false, showKeyboardShortcuts: false, // i18n monthFormat: 'MMMM YYYY', weekDayFormat: 'dd', phrases: _defaultPhrases.DayPickerPhrases, dayAriaLabelFormat: undefined, isRTL: false }; var getChooseAvailableDatePhrase = function getChooseAvailableDatePhrase(phrases, focusedInput) { if (focusedInput === _constants.START_DATE) { return phrases.chooseAvailableStartDate; } else if (focusedInput === _constants.END_DATE) { return phrases.chooseAvailableEndDate; } return phrases.chooseAvailableDate; }; var DayPickerRangeController = function (_React$Component) { _inherits(DayPickerRangeController, _React$Component); function DayPickerRangeController(props) { _classCallCheck(this, DayPickerRangeController); var _this = _possibleConstructorReturn(this, (DayPickerRangeController.__proto__ || Object.getPrototypeOf(DayPickerRangeController)).call(this, props)); _this.isTouchDevice = (0, _isTouchDevice2['default'])(); _this.today = (0, _moment2['default'])(); _this.modifiers = { today: function () { function today(day) { return _this.isToday(day); } return today; }(), blocked: function () { function blocked(day) { return _this.isBlocked(day); } return blocked; }(), 'blocked-calendar': function () { function blockedCalendar(day) { return props.isDayBlocked(day); } return blockedCalendar; }(), 'blocked-out-of-range': function () { function blockedOutOfRange(day) { return props.isOutsideRange(day); } return blockedOutOfRange; }(), 'highlighted-calendar': function () { function highlightedCalendar(day) { return props.isDayHighlighted(day); } return highlightedCalendar; }(), valid: function () { function valid(day) { return !_this.isBlocked(day); } return valid; }(), 'selected-start': function () { function selectedStart(day) { return _this.isStartDate(day); } return selectedStart; }(), 'selected-end': function () { function selectedEnd(day) { return _this.isEndDate(day); } return selectedEnd; }(), 'blocked-minimum-nights': function () { function blockedMinimumNights(day) { return _this.doesNotMeetMinimumNights(day); } return blockedMinimumNights; }(), 'selected-span': function () { function selectedSpan(day) { return _this.isInSelectedSpan(day); } return selectedSpan; }(), 'last-in-range': function () { function lastInRange(day) { return _this.isLastInRange(day); } return lastInRange; }(), hovered: function () { function hovered(day) { return _this.isHovered(day); } return hovered; }(), 'hovered-span': function () { function hoveredSpan(day) { return _this.isInHoveredSpan(day); } return hoveredSpan; }(), 'hovered-offset': function () { function hoveredOffset(day) { return _this.isInHoveredSpan(day); } return hoveredOffset; }(), 'after-hovered-start': function () { function afterHoveredStart(day) { return _this.isDayAfterHoveredStartDate(day); } return afterHoveredStart; }(), 'first-day-of-week': function () { function firstDayOfWeek(day) { return _this.isFirstDayOfWeek(day); } return firstDayOfWeek; }(), 'last-day-of-week': function () { function lastDayOfWeek(day) { return _this.isLastDayOfWeek(day); } return lastDayOfWeek; }() }; var _this$getStateForNewM = _this.getStateForNewMonth(props), currentMonth = _this$getStateForNewM.currentMonth, visibleDays = _this$getStateForNewM.visibleDays; // initialize phrases // set the appropriate CalendarDay phrase based on focusedInput var chooseAvailableDate = getChooseAvailableDatePhrase(props.phrases, props.focusedInput); _this.state = { hoverDate: null, currentMonth: currentMonth, phrases: (0, _object2['default'])({}, props.phrases, { chooseAvailableDate: chooseAvailableDate }), visibleDays: visibleDays }; _this.onDayClick = _this.onDayClick.bind(_this); _this.onDayMouseEnter = _this.onDayMouseEnter.bind(_this); _this.onDayMouseLeave = _this.onDayMouseLeave.bind(_this); _this.onPrevMonthClick = _this.onPrevMonthClick.bind(_this); _this.onNextMonthClick = _this.onNextMonthClick.bind(_this); _this.onMonthChange = _this.onMonthChange.bind(_this); _this.onYearChange = _this.onYearChange.bind(_this); _this.onMultiplyScrollableMonths = _this.onMultiplyScrollableMonths.bind(_this); _this.getFirstFocusableDay = _this.getFirstFocusableDay.bind(_this); return _this; } _createClass(DayPickerRangeController, [{ key: 'componentWillReceiveProps', value: function () { function componentWillReceiveProps(nextProps) { var _this2 = this; var startDate = nextProps.startDate, endDate = nextProps.endDate, focusedInput = nextProps.focusedInput, minimumNights = nextProps.minimumNights, isOutsideRange = nextProps.isOutsideRange, isDayBlocked = nextProps.isDayBlocked, isDayHighlighted = nextProps.isDayHighlighted, phrases = nextProps.phrases, initialVisibleMonth = nextProps.initialVisibleMonth, numberOfMonths = nextProps.numberOfMonths, enableOutsideDays = nextProps.enableOutsideDays; var _props = this.props, prevStartDate = _props.startDate, prevEndDate = _props.endDate, prevFocusedInput = _props.focusedInput, prevMinimumNights = _props.minimumNights, prevIsOutsideRange = _props.isOutsideRange, prevIsDayBlocked = _props.isDayBlocked, prevIsDayHighlighted = _props.isDayHighlighted, prevPhrases = _props.phrases, prevInitialVisibleMonth = _props.initialVisibleMonth, prevNumberOfMonths = _props.numberOfMonths, prevEnableOutsideDays = _props.enableOutsideDays; var visibleDays = this.state.visibleDays; var recomputeOutsideRange = false; var recomputeDayBlocked = false; var recomputeDayHighlighted = false; if (isOutsideRange !== prevIsOutsideRange) { this.modifiers['blocked-out-of-range'] = function (day) { return isOutsideRange(day); }; recomputeOutsideRange = true; } if (isDayBlocked !== prevIsDayBlocked) { this.modifiers['blocked-calendar'] = function (day) { return isDayBlocked(day); }; recomputeDayBlocked = true; } if (isDayHighlighted !== prevIsDayHighlighted) { this.modifiers['highlighted-calendar'] = function (day) { return isDayHighlighted(day); }; recomputeDayHighlighted = true; } var recomputePropModifiers = recomputeOutsideRange || recomputeDayBlocked || recomputeDayHighlighted; var didStartDateChange = startDate !== prevStartDate; var didEndDateChange = endDate !== prevEndDate; var didFocusChange = focusedInput !== prevFocusedInput; if (numberOfMonths !== prevNumberOfMonths || enableOutsideDays !== prevEnableOutsideDays || initialVisibleMonth !== prevInitialVisibleMonth && !prevFocusedInput && didFocusChange) { var newMonthState = this.getStateForNewMonth(nextProps); var currentMonth = newMonthState.currentMonth; visibleDays = newMonthState.visibleDays; this.setState({ currentMonth: currentMonth, visibleDays: visibleDays }); } var modifiers = {}; if (didStartDateChange) { modifiers = this.deleteModifier(modifiers, prevStartDate, 'selected-start'); modifiers = this.addModifier(modifiers, startDate, 'selected-start'); if (prevStartDate) { var startSpan = prevStartDate.clone().add(1, 'day'); var endSpan = prevStartDate.clone().add(prevMinimumNights + 1, 'days'); modifiers = this.deleteModifierFromRange(modifiers, startSpan, endSpan, 'after-hovered-start'); } } if (didEndDateChange) { modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end'); modifiers = this.addModifier(modifiers, endDate, 'selected-end'); } if (didStartDateChange || didEndDateChange) { if (prevStartDate && prevEndDate) { modifiers = this.deleteModifierFromRange(modifiers, prevStartDate, prevEndDate.clone().add(1, 'day'), 'selected-span'); } if (startDate && endDate) { modifiers = this.deleteModifierFromRange(modifiers, startDate, endDate.clone().add(1, 'day'), 'hovered-span'); modifiers = this.addModifierToRange(modifiers, startDate.clone().add(1, 'day'), endDate, 'selected-span'); } } if (!this.isTouchDevice && didStartDateChange && startDate && !endDate) { var _startSpan = startDate.clone().add(1, 'day'); var _endSpan = startDate.clone().add(minimumNights + 1, 'days'); modifiers = this.addModifierToRange(modifiers, _startSpan, _endSpan, 'after-hovered-start'); } if (prevMinimumNights > 0) { if (didFocusChange || didStartDateChange || minimumNights !== prevMinimumNights) { var _startSpan2 = prevStartDate || this.today; modifiers = this.deleteModifierFromRange(modifiers, _startSpan2, _startSpan2.clone().add(prevMinimumNights, 'days'), 'blocked-minimum-nights'); modifiers = this.deleteModifierFromRange(modifiers, _startSpan2, _startSpan2.clone().add(prevMinimumNights, 'days'), 'blocked'); } } if (minimumNights > 0 && startDate && focusedInput === _constants.END_DATE) { modifiers = this.addModifierToRange(modifiers, startDate, startDate.clone().add(minimumNights, 'days'), 'blocked-minimum-nights'); } if (didFocusChange || recomputePropModifiers) { (0, _object4['default'])(visibleDays).forEach(function (days) { Object.keys(days).forEach(function (day) { var momentObj = (0, _moment2['default'])(day); if (_this2.isBlocked(momentObj)) { modifiers = _this2.addModifier(modifiers, momentObj, 'blocked'); } else { modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked'); } if (didFocusChange || recomputeOutsideRange) { if (isOutsideRange(momentObj)) { modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-out-of-range'); } else { modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-out-of-range'); } } if (didFocusChange || recomputeDayBlocked) { if (isDayBlocked(momentObj)) { modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-calendar'); } else { modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-calendar'); } } if (didFocusChange || recomputeDayHighlighted) { if (isDayHighlighted(momentObj)) { modifiers = _this2.addModifier(modifiers, momentObj, 'highlighted-calendar'); } else { modifiers = _this2.deleteModifier(modifiers, momentObj, 'highlighted-calendar'); } } }); }); } var today = (0, _moment2['default'])(); if (!(0, _isSameDay2['default'])(this.today, today)) { modifiers = this.deleteModifier(modifiers, this.today, 'today'); modifiers = this.addModifier(modifiers, today, 'today'); this.today = today; } if (Object.keys(modifiers).length > 0) { this.setState({ visibleDays: (0, _object2['default'])({}, visibleDays, modifiers) }); } if (didFocusChange || phrases !== prevPhrases) { // set the appropriate CalendarDay phrase based on focusedInput var chooseAvailableDate = getChooseAvailableDatePhrase(phrases, focusedInput); this.setState({ phrases: (0, _object2['default'])({}, phrases, { chooseAvailableDate: chooseAvailableDate }) }); } } return componentWillReceiveProps; }() }, { key: 'onDayClick', value: function () { function onDayClick(day, e) { var _props2 = this.props, keepOpenOnDateSelect = _props2.keepOpenOnDateSelect, minimumNights = _props2.minimumNights, onBlur = _props2.onBlur, focusedInput = _props2.focusedInput, onFocusChange = _props2.onFocusChange, onClose = _props2.onClose, onDatesChange = _props2.onDatesChange, startDateOffset = _props2.startDateOffset, endDateOffset = _props2.endDateOffset, disabled = _props2.disabled; if (e) e.preventDefault(); if (this.isBlocked(day)) return; var _props3 = this.props, startDate = _props3.startDate, endDate = _props3.endDate; if (startDateOffset || endDateOffset) { startDate = (0, _getSelectedDateOffset2['default'])(startDateOffset, day); endDate = (0, _getSelectedDateOffset2['default'])(endDateOffset, day); if (!keepOpenOnDateSelect) { onFocusChange(null); onClose({ startDate: startDate, endDate: endDate }); } } else if (focusedInput === _constants.START_DATE) { var lastAllowedStartDate = endDate && endDate.clone().subtract(minimumNights, 'days'); var isStartDateAfterEndDate = (0, _isBeforeDay2['default'])(lastAllowedStartDate, day) || (0, _isAfterDay2['default'])(startDate, endDate); var isEndDateDisabled = disabled === _constants.END_DATE; if (!isEndDateDisabled || !isStartDateAfterEndDate) { startDate = day; if (isStartDateAfterEndDate) { endDate = null; } } if (isEndDateDisabled && !isStartDateAfterEndDate) { onFocusChange(null); onClose({ startDate: startDate, endDate: endDate }); } else if (!isEndDateDisabled) { onFocusChange(_constants.END_DATE); } } else if (focusedInput === _constants.END_DATE) { var firstAllowedEndDate = startDate && startDate.clone().add(minimumNights, 'days'); if (!startDate) { endDate = day; onFocusChange(_constants.START_DATE); } else if ((0, _isInclusivelyAfterDay2['default'])(day, firstAllowedEndDate)) { endDate = day; if (!keepOpenOnDateSelect) { onFocusChange(null); onClose({ startDate: startDate, endDate: endDate }); } } else if (disabled !== _constants.START_DATE) { startDate = day; endDate = null; } } onDatesChange({ startDate: startDate, endDate: endDate }); onBlur(); } return onDayClick; }() }, { key: 'onDayMouseEnter', value: function () { function onDayMouseEnter(day) { if (this.isTouchDevice) return; var _props4 = this.props, startDate = _props4.startDate, endDate = _props4.endDate, focusedInput = _props4.focusedInput, minimumNights = _props4.minimumNights, startDateOffset = _props4.startDateOffset, endDateOffset = _props4.endDateOffset; var _state = this.state, hoverDate = _state.hoverDate, visibleDays = _state.visibleDays; var dateOffset = null; if (focusedInput) { var hasOffset = startDateOffset || endDateOffset; var modifiers = {}; if (hasOffset) { var start = (0, _getSelectedDateOffset2['default'])(startDateOffset, day); var end = (0, _getSelectedDateOffset2['default'])(endDateOffset, day, function (rangeDay) { return rangeDay.add(1, 'day'); }); dateOffset = { start: start, end: end }; if (this.state.dateOffset && this.state.dateOffset.start && this.state.dateOffset.end) { modifiers = this.deleteModifierFromRange(modifiers, this.state.dateOffset.start, this.state.dateOffset.end, 'hovered-offset'); } modifiers = this.addModifierToRange(modifiers, start, end, 'hovered-offset'); } if (!hasOffset) { modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered'); modifiers = this.addModifier(modifiers, day, 'hovered'); if (startDate && !endDate && focusedInput === _constants.END_DATE) { if ((0, _isAfterDay2['default'])(hoverDate, startDate)) { var endSpan = hoverDate.clone().add(1, 'day'); modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); } if (!this.isBlocked(day) && (0, _isAfterDay2['default'])(day, startDate)) { var _endSpan2 = day.clone().add(1, 'day'); modifiers = this.addModifierToRange(modifiers, startDate, _endSpan2, 'hovered-span'); } } if (!startDate && endDate && focusedInput === _constants.START_DATE) { if ((0, _isBeforeDay2['default'])(hoverDate, endDate)) { modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); } if (!this.isBlocked(day) && (0, _isBeforeDay2['default'])(day, endDate)) { modifiers = this.addModifierToRange(modifiers, day, endDate, 'hovered-span'); } } if (startDate) { var startSpan = startDate.clone().add(1, 'day'); var _endSpan3 = startDate.clone().add(minimumNights + 1, 'days'); modifiers = this.deleteModifierFromRange(modifiers, startSpan, _endSpan3, 'after-hovered-start'); if ((0, _isSameDay2['default'])(day, startDate)) { var newStartSpan = startDate.clone().add(1, 'day'); var newEndSpan = startDate.clone().add(minimumNights + 1, 'days'); modifiers = this.addModifierToRange(modifiers, newStartSpan, newEndSpan, 'after-hovered-start'); } } } this.setState({ hoverDate: day, dateOffset: dateOffset, visibleDays: (0, _object2['default'])({}, visibleDays, modifiers) }); } } return onDayMouseEnter; }() }, { key: 'onDayMouseLeave', value: function () { function onDayMouseLeave(day) { var _props5 = this.props, startDate = _props5.startDate, endDate = _props5.endDate, minimumNights = _props5.minimumNights; var _state2 = this.state, hoverDate = _state2.hoverDate, visibleDays = _state2.visibleDays, dateOffset = _state2.dateOffset; if (this.isTouchDevice || !hoverDate) return; var modifiers = {}; modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered'); if (dateOffset) { modifiers = this.deleteModifierFromRange(modifiers, this.state.dateOffset.start, this.state.dateOffset.end, 'hovered-offset'); } if (startDate && !endDate && (0, _isAfterDay2['default'])(hoverDate, startDate)) { var endSpan = hoverDate.clone().add(1, 'day'); modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); } if (!startDate && endDate && (0, _isAfterDay2['default'])(endDate, hoverDate)) { modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); } if (startDate && (0, _isSameDay2['default'])(day, startDate)) { var startSpan = startDate.clone().add(1, 'day'); var _endSpan4 = startDate.clone().add(minimumNights + 1, 'days'); modifiers = this.deleteModifierFromRange(modifiers, startSpan, _endSpan4, 'after-hovered-start'); } this.setState({ hoverDate: null, visibleDays: (0, _object2['default'])({}, visibleDays, modifiers) }); } return onDayMouseLeave; }() }, { key: 'onPrevMonthClick', value: function () { function onPrevMonthClick() { var _props6 = this.props, onPrevMonthClick = _props6.onPrevMonthClick, numberOfMonths = _props6.numberOfMonths, enableOutsideDays = _props6.enableOutsideDays; var _state3 = this.state, currentMonth = _state3.currentMonth, visibleDays = _state3.visibleDays; var newVisibleDays = {}; Object.keys(visibleDays).sort().slice(0, numberOfMonths + 1).forEach(function (month) { newVisibleDays[month] = visibleDays[month]; }); var prevMonth = currentMonth.clone().subtract(2, 'months'); var prevMonthVisibleDays = (0, _getVisibleDays2['default'])(prevMonth, 1, enableOutsideDays, true); var newCurrentMonth = currentMonth.clone().subtract(1, 'month'); this.setState({ currentMonth: newCurrentMonth, visibleDays: (0, _object2['default'])({}, newVisibleDays, this.getModifiers(prevMonthVisibleDays)) }, function () { onPrevMonthClick(newCurrentMonth.clone()); }); } return onPrevMonthClick; }() }, { key: 'onNextMonthClick', value: function () { function onNextMonthClick() { var _props7 = this.props, onNextMonthClick = _props7.onNextMonthClick, numberOfMonths = _props7.numberOfMonths, enableOutsideDays = _props7.enableOutsideDays; var _state4 = this.state, currentMonth = _state4.currentMonth, visibleDays = _state4.visibleDays; var newVisibleDays = {}; Object.keys(visibleDays).sort().slice(1).forEach(function (month) { newVisibleDays[month] = visibleDays[month]; }); var nextMonth = currentMonth.clone().add(numberOfMonths + 1, 'month'); var nextMonthVisibleDays = (0, _getVisibleDays2['default'])(nextMonth, 1, enableOutsideDays, true); var newCurrentMonth = currentMonth.clone().add(1, 'month'); this.setState({ currentMonth: newCurrentMonth, visibleDays: (0, _object2['default'])({}, newVisibleDays, this.getModifiers(nextMonthVisibleDays)) }, function () { onNextMonthClick(newCurrentMonth.clone()); }); } return onNextMonthClick; }() }, { key: 'onMonthChange', value: function () { function onMonthChange(newMonth) { var _props8 = this.props, numberOfMonths = _props8.numberOfMonths, enableOutsideDays = _props8.enableOutsideDays, orientation = _props8.orientation; var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; var newVisibleDays = (0, _getVisibleDays2['default'])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); this.setState({ currentMonth: newMonth.clone(), visibleDays: this.getModifiers(newVisibleDays) }); } return onMonthChange; }() }, { key: 'onYearChange', value: function () { function onYearChange(newMonth) { var _props9 = this.props, numberOfMonths = _props9.numberOfMonths, enableOutsideDays = _props9.enableOutsideDays, orientation = _props9.orientation; var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; var newVisibleDays = (0, _getVisibleDays2['default'])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); this.setState({ currentMonth: newMonth.clone(), visibleDays: this.getModifiers(newVisibleDays) }); } return onYearChange; }() }, { key: 'onMultiplyScrollableMonths', value: function () { function onMultiplyScrollableMonths() { var _props10 = this.props, numberOfMonths = _props10.numberOfMonths, enableOutsideDays = _props10.enableOutsideDays; var _state5 = this.state, currentMonth = _state5.currentMonth, visibleDays = _state5.visibleDays; var numberOfVisibleMonths = Object.keys(visibleDays).length; var nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month'); var newVisibleDays = (0, _getVisibleDays2['default'])(nextMonth, numberOfMonths, enableOutsideDays, true); this.setState({ visibleDays: (0, _object2['default'])({}, visibleDays, this.getModifiers(newVisibleDays)) }); } return onMultiplyScrollableMonths; }() }, { key: 'getFirstFocusableDay', value: function () { function getFirstFocusableDay(newMonth) { var _this3 = this; var _props11 = this.props, startDate = _props11.startDate, endDate = _props11.endDate, focusedInput = _props11.focusedInput, minimumNights = _props11.minimumNights, numberOfMonths = _props11.numberOfMonths; var focusedDate = newMonth.clone().startOf('month'); if (focusedInput === _constants.START_DATE && startDate) { focusedDate = startDate.clone(); } else if (focusedInput === _constants.END_DATE && !endDate && startDate) { focusedDate = startDate.clone().add(minimumNights, 'days'); } else if (focusedInput === _constants.END_DATE && endDate) { focusedDate = endDate.clone(); } if (this.isBlocked(focusedDate)) { var days = []; var lastVisibleDay = newMonth.clone().add(numberOfMonths - 1, 'months').endOf('month'); var currentDay = focusedDate.clone(); while (!(0, _isAfterDay2['default'])(currentDay, lastVisibleDay)) { currentDay = currentDay.clone().add(1, 'day'); days.push(currentDay); } var viableDays = days.filter(function (day) { return !_this3.isBlocked(day); }); if (viableDays.length > 0) { var _viableDays = _slicedToArray(viableDays, 1); focusedDate = _viableDays[0]; } } return focusedDate; } return getFirstFocusableDay; }() }, { key: 'getModifiers', value: function () { function getModifiers(visibleDays) { var _this4 = this; var modifiers = {}; Object.keys(visibleDays).forEach(function (month) { modifiers[month] = {}; visibleDays[month].forEach(function (day) { modifiers[month][(0, _toISODateString2['default'])(day)] = _this4.getModifiersForDay(day); }); }); return modifiers; } return getModifiers; }() }, { key: 'getModifiersForDay', value: function () { function getModifiersForDay(day) { var _this5 = this; return new Set(Object.keys(this.modifiers).filter(function (modifier) { return _this5.modifiers[modifier](day); })); } return getModifiersForDay; }() }, { key: 'getStateForNewMonth', value: function () { function getStateForNewMonth(nextProps) { var _this6 = this; var initialVisibleMonth = nextProps.initialVisibleMonth, numberOfMonths = nextProps.numberOfMonths, enableOutsideDays = nextProps.enableOutsideDays, orientation = nextProps.orientation, startDate = nextProps.startDate; var initialVisibleMonthThunk = initialVisibleMonth || (startDate ? function () { return startDate; } : function () { return _this6.today; }); var currentMonth = initialVisibleMonthThunk(); var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; var visibleDays = this.getModifiers((0, _getVisibleDays2['default'])(currentMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths)); return { currentMonth: currentMonth, visibleDays: visibleDays }; } return getStateForNewMonth; }() }, { key: 'addModifier', value: function () { function addModifier(updatedDays, day, modifier) { var _props12 = this.props, numberOfVisibleMonths = _props12.numberOfMonths, enableOutsideDays = _props12.enableOutsideDays, orientation = _props12.orientation; var _state6 = this.state, firstVisibleMonth = _state6.currentMonth, visibleDays = _state6.visibleDays; var currentMonth = firstVisibleMonth; var numberOfMonths = numberOfVisibleMonths; if (orientation !== _constants.VERTICAL_SCROLLABLE) { currentMonth = currentMonth.clone().subtract(1, 'month'); numberOfMonths += 2; } if (!day || !(0, _isDayVisible2['default'])(day, currentMonth, numberOfMonths, enableOutsideDays)) { return updatedDays; } var iso = (0, _toISODateString2['default'])(day); var updatedDaysAfterAddition = (0, _object2['default'])({}, updatedDays); if (enableOutsideDays) { var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; }); updatedDaysAfterAddition = monthsToUpdate.reduce(function (days, monthIso) { var month = updatedDays[monthIso] || visibleDays[monthIso]; var modifiers = new Set(month[iso]); modifiers.add(modifier); return (0, _object2['default'])({}, days, _defineProperty({}, monthIso, (0, _object2['default'])({}, month, _defineProperty({}, iso, modifiers)))); }, updatedDaysAfterAddition); } else { var monthIso = (0, _toISOMonthString2['default'])(day); var month = updatedDays[monthIso] || visibleDays[monthIso]; var modifiers = new Set(month[iso]); modifiers.add(modifier); updatedDaysAfterAddition = (0, _object2['default'])({}, updatedDaysAfterAddition, _defineProperty({}, monthIso, (0, _object2['default'])({}, month, _defineProperty({}, iso, modifiers)))); } return updatedDaysAfterAddition; } return addModifier; }() }, { key: 'addModifierToRange', value: function () { function addModifierToRange(updatedDays, start, end, modifier) { var days = updatedDays; var spanStart = start.clone(); while ((0, _isBeforeDay2['default'])(spanStart, end)) { days = this.addModifier(days, spanStart, modifier); spanStart = spanStart.clone().add(1, 'day'); } return days; } return addModifierToRange; }() }, { key: 'deleteModifier', value: function () { function deleteModifier(updatedDays, day, modifier) { var _props13 = this.props, numberOfVisibleMonths = _props13.numberOfMonths, enableOutsideDays = _props13.enableOutsideDays, orientation = _props13.orientation; var _state7 = this.state, firstVisibleMonth = _state7.currentMonth, visibleDays = _state7.visibleDays; var currentMonth = firstVisibleMonth; var numberOfMonths = numberOfVisibleMonths; if (orientation !== _constants.VERTICAL_SCROLLABLE) { currentMonth = currentMonth.clone().subtract(1, 'month'); numberOfMonths += 2; } if (!day || !(0, _isDayVisible2['default'])(day, currentMonth, numberOfMonths, enableOutsideDays)) { return updatedDays; } var iso = (0, _toISODateString2['default'])(day); var updatedDaysAfterDeletion = (0, _object2['default'])({}, updatedDays); if (enableOutsideDays) { var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; }); updatedDaysAfterDeletion = monthsToUpdate.reduce(function (days, monthIso) { var month = updatedDays[monthIso] || visibleDays[monthIso]; var modifiers = new Set(month[iso]); modifiers['delete'](modifier); return (0, _object2['default'])({}, days, _defineProperty({}, monthIso, (0, _object2['default'])({}, month, _defineProperty({}, iso, modifiers)))); }, updatedDaysAfterDeletion); } else { var monthIso = (0, _toISOMonthString2['default'])(day); var month = updatedDays[monthIso] || visibleDays[monthIso]; var modifiers = new Set(month[iso]); modifiers['delete'](modifier); updatedDaysAfterDeletion = (0, _object2['default'])({}, updatedDaysAfterDeletion, _defineProperty({}, monthIso, (0, _object2['default'])({}, month, _defineProperty({}, iso, modifiers)))); } return updatedDaysAfterDeletion; } return deleteModifier; }() }, { key: 'deleteModifierFromRange', value: function () { function deleteModifierFromRange(updatedDays, start, end, modifier) { var days = updatedDays; var spanStart = start.clone(); while ((0, _isBeforeDay2['default'])(spanStart, end)) { days = this.deleteModifier(days, spanStart, modifier); spanStart = spanStart.clone().add(1, 'day'); } return days; } return deleteModifierFromRange; }() }, { key: 'doesNotMeetMinimumNights', value: function () { function doesNotMeetMinimumNights(day) { var _props14 = this.props, startDate = _props14.startDate, isOutsideRange = _props14.isOutsideRange, focusedInput = _props14.focusedInput, minimumNights = _props14.minimumNights; if (focusedInput !== _constants.END_DATE) return false; if (startDate) { var dayDiff = day.diff(startDate.clone().startOf('day').hour(12), 'days'); return dayDiff < minimumNights && dayDiff >= 0; } return isOutsideRange((0, _moment2['default'])(day).subtract(minimumNights, 'days')); } return doesNotMeetMinimumNights; }() }, { key: 'isDayAfterHoveredStartDate', value: function () { function isDayAfterHoveredStartDate(day) { var _props15 = this.props, startDate = _props15.startDate, endDate = _props15.endDate, minimumNights = _props15.minimumNights; var _ref = this.state || {}, hoverDate = _ref.hoverDate; return !!startDate && !endDate && !this.isBlocked(day) && (0, _isNextDay2['default'])(hoverDate, day) && minimumNights > 0 && (0, _isSameDay2['default'])(hoverDate, startDate); } return isDayAfterHoveredStartDate; }() }, { key: 'isEndDate', value: function () { function isEndDate(day) { return (0, _isSameDay2['default'])(day, this.props.endDate); } return isEndDate; }() }, { key: 'isHovered', value: function () { function isHovered(day) { var _ref2 = this.state || {}, hoverDate = _ref2.hoverDate; var focusedInput = this.props.focusedInput; return !!focusedInput && (0, _isSameDay2['default'])(day, hoverDate); } return isHovered; }() }, { key: 'isInHoveredSpan', value: function () { function isInHoveredSpan(day) { var _props16 = this.props, startDate = _props16.startDate, endDate = _props16.endDate; var _ref3 = this.state || {}, hoverDate = _ref3.hoverDate; var isForwardRange = !!startDate && !endDate && (day.isBetween(startDate, hoverDate) || (0, _isSameDay2['default'])(hoverDate, day)); var isBackwardRange = !!endDate && !startDate && (day.isBetween(hoverDate, endDate) || (0, _isSameDay2['default'])(hoverDate, day)); var isValidDayHovered = hoverDate && !this.isBlocked(hoverDate); return (isForwardRange || isBackwardRange) && isValidDayHovered; } return isInHoveredSpan; }() }, { key: 'isInSelectedSpan', value: function () { function isInSelectedSpan(day) { var _props17 = this.props, startDate = _props17.startDate, endDate = _props17.endDate; return day.isBetween(startDate, endDate); } return isInSelectedSpan; }() }, { key: 'isLastInRange', value: function () { function isLastInRange(day) { return this.isInSelectedSpan(day) && (0, _isNextDay2['default'])(day, this.props.endDate); } return isLastInRange; }() }, { key: 'isStartDate', value: function () { function isStartDate(day) { return (0, _isSameDay2['default'])(day, this.props.startDate); } return isStartDate; }() }, { key: 'isBlocked', value: function () { function isBlocked(day) { var _props18 = this.props, isDayBlocked = _props18.isDayBlocked, isOutsideRange = _props18.isOutsideRange; return isDayBlocked(day) || isOutsideRange(day) || this.doesNotMeetMinimumNights(day); } return isBlocked; }() }, { key: 'isToday', value: function () { function isToday(day) { return (0, _isSameDay2['default'])(day, this.today); } return isToday; }() }, { key: 'isFirstDayOfWeek', value: function () { function isFirstDayOfWeek(day) { var firstDayOfWeek = this.props.firstDayOfWeek; return day.day() === (firstDayOfWeek || _moment2['default'].localeData().firstDayOfWeek()); } return isFirstDayOfWeek; }() }, { key: 'isLastDayOfWeek', value: function () { function isLastDayOfWeek(day) { var firstDayOfWeek = this.props.firstDayOfWeek; return day.day() === ((firstDayOfWeek || _moment2['default'].localeData().firstDayOfWeek()) + 6) % 7; } return isLastDayOfWeek; }() }, { key: 'render', value: function () { function render() { var _props19 = this.props, numberOfMonths = _props19.numberOfMonths, orientation = _props19.orientation, monthFormat = _props19.monthFormat, renderMonthText = _props19.renderMonthText, navPrev = _props19.navPrev, navNext = _props19.navNext, noNavButtons = _props19.noNavButtons, onOutsideClick = _props19.onOutsideClick, withPortal = _props19.withPortal, enableOutsideDays = _props19.enableOutsideDays, firstDayOfWeek =