From 870b5faabe39813dd2524b6b124ecba5b784c8d4 Mon Sep 17 00:00:00 2001 From: Karan Srivastava Date: Wed, 29 Jun 2022 15:07:05 +0530 Subject: [PATCH 1/4] React-dates enable support for building Signed-off-by: Karan Srivastava --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d6c29274c..9bce52bae 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,8 @@ "react-portal": "^4.2.1", "react-with-direction": "^1.4.0", "react-with-styles": "~4.1.0", - "react-with-styles-interface-css": "^6.0.0" + "react-with-styles-interface-css": "^6.0.0", + "sass": "^1.53.0" }, "peerDependencies": { "@babel/runtime": "^7.0.0", From 89e88109e7c77e489afbd6d43b4422826e41630e Mon Sep 17 00:00:00 2001 From: Karan Srivastava Date: Sat, 24 Jul 2021 23:03:37 +0530 Subject: [PATCH 2/4] dates: add support for shifting offset for disabled dates --- src/components/DayPickerRangeController.jsx | 34 +++++++++++++++++++-- src/utils/enumrateDatesBetween.js | 10 ++++++ stories/DayPickerRangeController.js | 12 ++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/utils/enumrateDatesBetween.js diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 6b5cb732b..225db5682 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -20,6 +20,7 @@ import getVisibleDays from '../utils/getVisibleDays'; import isDayVisible from '../utils/isDayVisible'; import getSelectedDateOffset from '../utils/getSelectedDateOffset'; +import enumrateDatesBetween from '../utils/enumrateDatesBetween'; import toISODateString from '../utils/toISODateString'; import { addModifier, deleteModifier } from '../utils/modifiers'; @@ -65,6 +66,7 @@ const propTypes = forbidExtraProps({ isDayHighlighted: PropTypes.func, getMinNightsForHoverDate: PropTypes.func, daysViolatingMinNightsCanBeClicked: PropTypes.bool, + moveOffsetForDisabledDates: PropTypes.bool, // DayPicker props renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), @@ -118,6 +120,8 @@ const propTypes = forbidExtraProps({ dayAriaLabelFormat: PropTypes.string, isRTL: PropTypes.bool, + + }); const defaultProps = { @@ -141,6 +145,7 @@ const defaultProps = { isDayHighlighted() {}, getMinNightsForHoverDate() {}, daysViolatingMinNightsCanBeClicked: false, + moveOffsetForDisabledDates: false, // DayPicker props renderMonthText: null, @@ -596,6 +601,7 @@ export default class DayPickerRangeController extends React.PureComponent { endDateOffset, disabled, daysViolatingMinNightsCanBeClicked, + moveOffsetForDisabledDates } = this.props; if (e) e.preventDefault(); @@ -605,7 +611,11 @@ export default class DayPickerRangeController extends React.PureComponent { if (startDateOffset || endDateOffset) { startDate = getSelectedDateOffset(startDateOffset, day); - endDate = getSelectedDateOffset(endDateOffset, day); + if (moveOffsetForDisabledDates) { + endDate = this.getDisabledEndDateOffset(startDate, getSelectedDateOffset(endDateOffset, day)); + } else { + endDate = getSelectedDateOffset(endDateOffset, day); + } if (this.isBlocked(startDate) || this.isBlocked(endDate)) { return; @@ -683,6 +693,7 @@ export default class DayPickerRangeController extends React.PureComponent { minimumNights, startDateOffset, endDateOffset, + moveOffsetForDisabledDates } = this.props; const { @@ -699,7 +710,14 @@ export default class DayPickerRangeController extends React.PureComponent { if (hasOffset) { const start = getSelectedDateOffset(startDateOffset, day); - const end = getSelectedDateOffset(endDateOffset, day, (rangeDay) => rangeDay.add(1, 'day')); + let end = null; + if (moveOffsetForDisabledDates) { + end = this.getDisabledEndDateOffset(start, getSelectedDateOffset( + endDateOffset, day, (rangeDay) => rangeDay.add(1, 'day'))); + } else { + end = getSelectedDateOffset( + endDateOffset, day, (rangeDay) => rangeDay.add(1, 'day')) + } nextDateOffset = { start, @@ -1192,6 +1210,18 @@ export default class DayPickerRangeController extends React.PureComponent { return false; } + getDisabledEndDateOffset(start, end) { + const dates = enumrateDatesBetween(start, end); + let daysToAdd = 0; + dates.map(d => { + if (this.isBlocked(moment(d))) { + daysToAdd++; + } + }); + + return end.add(daysToAdd, 'day'); + } + isDayAfterHoveredStartDate(day) { const { startDate, endDate, minimumNights } = this.props; const { hoverDate } = this.state || {}; diff --git a/src/utils/enumrateDatesBetween.js b/src/utils/enumrateDatesBetween.js new file mode 100644 index 000000000..01a9917d0 --- /dev/null +++ b/src/utils/enumrateDatesBetween.js @@ -0,0 +1,10 @@ +export default function enumrateDatesBetween(startDate, endDate) { + let now = startDate.clone(), dates = []; + + while (now.isSameOrBefore(endDate)) { + dates.push(now.format('M/D/YYYY')); + now.add(1, 'days'); + } + + return dates; +} diff --git a/stories/DayPickerRangeController.js b/stories/DayPickerRangeController.js index 39bb9716a..418fbd329 100644 --- a/stories/DayPickerRangeController.js +++ b/stories/DayPickerRangeController.js @@ -368,6 +368,18 @@ storiesOf('DayPickerRangeController', module) endDateOffset={(day) => day.add(4, 'days')} /> ))) + .add('with 4 days after today range selection with disabled dates', withInfo()(() => ( + { + return new Date(day1).getDay() % 6 == 0 + }} + moveOffsetForDisabledDates={false} + onOutsideClick={action('DayPickerRangeController::onOutsideClick')} + onPrevMonthClick={action('DayPickerRangeController::onPrevMonthClick')} + onNextMonthClick={action('DayPickerRangeController::onNextMonthClick')} + endDateOffset={(day) => day.add(3, 'days')} + /> + ))) .add('with current week range selection', withInfo()(() => ( Date: Wed, 29 Jun 2022 17:20:45 +0530 Subject: [PATCH 3/4] Fix Calendar offset delta --- src/components/DayPickerRangeController.jsx | 20 +++++++++++++++++--- stories/DayPickerRangeController.js | 5 +++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/DayPickerRangeController.jsx b/src/components/DayPickerRangeController.jsx index 225db5682..e424d6f0e 100644 --- a/src/components/DayPickerRangeController.jsx +++ b/src/components/DayPickerRangeController.jsx @@ -1211,15 +1211,19 @@ export default class DayPickerRangeController extends React.PureComponent { } getDisabledEndDateOffset(start, end) { + + const isSaturday = this.isSaturday(end); const dates = enumrateDatesBetween(start, end); let daysToAdd = 0; - dates.map(d => { + + dates.map((d) => { if (this.isBlocked(moment(d))) { daysToAdd++; } }); - - return end.add(daysToAdd, 'day'); + + const newEndDate = end.add(isSaturday ? 2 : daysToAdd, 'day'); + return newEndDate; } isDayAfterHoveredStartDate(day) { @@ -1282,6 +1286,16 @@ export default class DayPickerRangeController extends React.PureComponent { || (blockDaysViolatingMinNights && this.doesNotMeetMinimumNights(day)); } + isSunday(day) { + const dateDay = day.day(); + return dateDay === 0; + } + + isSaturday(day) { + const dateDay = day.day(); + return dateDay === 6; + } + isToday(day) { return isSameDay(day, this.today); } diff --git a/stories/DayPickerRangeController.js b/stories/DayPickerRangeController.js index 418fbd329..09d06d65b 100644 --- a/stories/DayPickerRangeController.js +++ b/stories/DayPickerRangeController.js @@ -371,9 +371,10 @@ storiesOf('DayPickerRangeController', module) .add('with 4 days after today range selection with disabled dates', withInfo()(() => ( { - return new Date(day1).getDay() % 6 == 0 + const dayOfweek = new Date(day1).getDay(); + return (dayOfweek === 6) || (dayOfweek === 0); }} - moveOffsetForDisabledDates={false} + moveOffsetForDisabledDates={true} onOutsideClick={action('DayPickerRangeController::onOutsideClick')} onPrevMonthClick={action('DayPickerRangeController::onPrevMonthClick')} onNextMonthClick={action('DayPickerRangeController::onNextMonthClick')} From 81d5d3268b92f96a2d8f8b7f11b0fc1ca6c34d26 Mon Sep 17 00:00:00 2001 From: Karan Srivastava Date: Wed, 29 Jun 2022 17:26:10 +0530 Subject: [PATCH 4/4] Enable the updated calendar --- .gitignore | 6 +- esm/components/CalendarDay.js | 342 ++ esm/components/CalendarIcon.js | 13 + esm/components/CalendarMonth.js | 267 + esm/components/CalendarMonthGrid.js | 393 ++ esm/components/CalendarWeek.js | 11 + esm/components/ChevronDown.js | 13 + esm/components/ChevronUp.js | 13 + esm/components/CloseButton.js | 14 + esm/components/CustomizableCalendarDay.js | 366 ++ esm/components/DateInput.js | 358 ++ esm/components/DateRangePicker.js | 693 +++ esm/components/DateRangePickerInput.js | 347 ++ .../DateRangePickerInputController.js | 374 ++ esm/components/DayPicker.js | 1300 +++++ esm/components/DayPickerKeyboardShortcuts.js | 381 ++ esm/components/DayPickerNavigation.js | 339 ++ esm/components/DayPickerRangeController.js | 1415 +++++ .../DayPickerSingleDateController.js | 765 +++ esm/components/KeyboardShortcutRow.js | 77 + esm/components/LeftArrow.js | 13 + esm/components/RightArrow.js | 13 + esm/components/SingleDatePicker.js | 647 +++ esm/components/SingleDatePickerInput.js | 271 + .../SingleDatePickerInputController.js | 281 + esm/constants.js | 28 + esm/defaultPhrases.js | 233 + esm/index.js | 20 + esm/initialize.js | 2 + esm/shapes/AnchorDirectionShape.js | 3 + esm/shapes/CalendarInfoPositionShape.js | 3 + esm/shapes/DateRangePickerShape.js | 101 + esm/shapes/DayOfWeekShape.js | 3 + esm/shapes/DisabledShape.js | 3 + esm/shapes/FocusedInputShape.js | 3 + esm/shapes/IconPositionShape.js | 3 + esm/shapes/ModifiersShape.js | 22 + esm/shapes/NavPositionShape.js | 3 + esm/shapes/OpenDirectionShape.js | 3 + esm/shapes/OrientationShape.js | 3 + esm/shapes/ScrollableOrientationShape.js | 3 + esm/shapes/SingleDatePickerShape.js | 90 + esm/theme/DefaultTheme.js | 176 + esm/utils/calculateDimension.js | 28 + esm/utils/disableScroll.js | 74 + esm/utils/enumrateDatesBetween.js | 11 + esm/utils/getActiveElement.js | 3 + esm/utils/getCalendarDaySettings.js | 58 + esm/utils/getCalendarMonthWeeks.js | 43 + esm/utils/getCalendarMonthWidth.js | 4 + esm/utils/getDetachedContainerStyles.js | 39 + esm/utils/getInputHeight.js | 49 + esm/utils/getNumberOfCalendarMonthWeeks.js | 13 + esm/utils/getPhrase.js | 9 + esm/utils/getPhrasePropTypes.js | 12 + esm/utils/getPooledMoment.js | 9 + esm/utils/getPreviousMonthMemoLast.js | 10 + esm/utils/getResponsiveContainerStyles.js | 8 + esm/utils/getSelectedDateOffset.js | 9 + esm/utils/getTransformStyles.js | 8 + esm/utils/getVisibleDays.js | 45 + esm/utils/isAfterDay.js | 7 + esm/utils/isBeforeDay.js | 13 + esm/utils/isDayVisible.js | 42 + esm/utils/isInclusivelyAfterDay.js | 6 + esm/utils/isInclusivelyBeforeDay.js | 6 + esm/utils/isNextDay.js | 7 + esm/utils/isNextMonth.js | 6 + esm/utils/isPrevMonth.js | 6 + esm/utils/isPreviousDay.js | 7 + esm/utils/isSameDay.js | 7 + esm/utils/isSameMonth.js | 7 + esm/utils/isTransitionEndSupported.js | 3 + esm/utils/modifiers.js | 115 + esm/utils/noflip.js | 9 + .../registerCSSInterfaceWithDefaultTheme.js | 5 + .../registerInterfaceWithDefaultTheme.js | 6 + esm/utils/toISODateString.js | 11 + esm/utils/toISOMonthString.js | 11 + esm/utils/toLocalizedDateString.js | 8 + esm/utils/toMomentObject.js | 7 + lib/components/CalendarDay.js | 369 ++ lib/components/CalendarIcon.js | 23 + lib/components/CalendarMonth.js | 299 + lib/components/CalendarMonthGrid.js | 429 ++ lib/components/CalendarWeek.js | 25 + lib/components/ChevronDown.js | 23 + lib/components/ChevronUp.js | 23 + lib/components/CloseButton.js | 24 + lib/components/CustomizableCalendarDay.js | 403 ++ lib/components/DateInput.js | 383 ++ lib/components/DateRangePicker.js | 732 +++ lib/components/DateRangePickerInput.js | 383 ++ .../DateRangePickerInputController.js | 401 ++ lib/components/DayPicker.js | 1351 +++++ lib/components/DayPickerKeyboardShortcuts.js | 407 ++ lib/components/DayPickerNavigation.js | 369 ++ lib/components/DayPickerRangeController.js | 1457 +++++ .../DayPickerSingleDateController.js | 799 +++ lib/components/KeyboardShortcutRow.js | 94 + lib/components/LeftArrow.js | 23 + lib/components/RightArrow.js | 23 + lib/components/SingleDatePicker.js | 687 +++ lib/components/SingleDatePickerInput.js | 302 + .../SingleDatePickerInputController.js | 307 + lib/constants.js | 61 + lib/css/_datepicker.css | 886 +++ lib/defaultPhrases.js | 248 + lib/index.js | 167 + lib/initialize.js | 7 + lib/shapes/AnchorDirectionShape.js | 16 + lib/shapes/CalendarInfoPositionShape.js | 16 + lib/shapes/DateRangePickerShape.js | 125 + lib/shapes/DayOfWeekShape.js | 16 + lib/shapes/DisabledShape.js | 16 + lib/shapes/FocusedInputShape.js | 16 + lib/shapes/IconPositionShape.js | 16 + lib/shapes/ModifiersShape.js | 35 + lib/shapes/NavPositionShape.js | 16 + lib/shapes/OpenDirectionShape.js | 16 + lib/shapes/OrientationShape.js | 16 + lib/shapes/ScrollableOrientationShape.js | 16 + lib/shapes/SingleDatePickerShape.js | 112 + lib/theme/DefaultTheme.js | 183 + lib/utils/calculateDimension.js | 35 + lib/utils/disableScroll.js | 85 + lib/utils/enumrateDatesBetween.js | 18 + lib/utils/getActiveElement.js | 10 + lib/utils/getCalendarDaySettings.js | 68 + lib/utils/getCalendarMonthWeeks.js | 54 + lib/utils/getCalendarMonthWidth.js | 11 + lib/utils/getDetachedContainerStyles.js | 46 + lib/utils/getInputHeight.js | 56 + lib/utils/getNumberOfCalendarMonthWeeks.js | 22 + lib/utils/getPhrase.js | 16 + lib/utils/getPhrasePropTypes.js | 22 + lib/utils/getPooledMoment.js | 20 + lib/utils/getPreviousMonthMemoLast.js | 17 + lib/utils/getResponsiveContainerStyles.js | 19 + lib/utils/getSelectedDateOffset.js | 16 + lib/utils/getTransformStyles.js | 15 + lib/utils/getVisibleDays.js | 56 + lib/utils/isAfterDay.js | 19 + lib/utils/isBeforeDay.js | 23 + lib/utils/isDayVisible.js | 56 + lib/utils/isInclusivelyAfterDay.js | 17 + lib/utils/isInclusivelyBeforeDay.js | 17 + lib/utils/isNextDay.js | 18 + lib/utils/isNextMonth.js | 17 + lib/utils/isPrevMonth.js | 17 + lib/utils/isPreviousDay.js | 18 + lib/utils/isSameDay.js | 17 + lib/utils/isSameMonth.js | 17 + lib/utils/isTransitionEndSupported.js | 10 + lib/utils/modifiers.js | 131 + lib/utils/noflip.js | 15 + .../registerCSSInterfaceWithDefaultTheme.js | 16 + .../registerInterfaceWithDefaultTheme.js | 18 + lib/utils/toISODateString.js | 22 + lib/utils/toISOMonthString.js | 22 + lib/utils/toLocalizedDateString.js | 20 + lib/utils/toMomentObject.js | 18 + test-build/_helpers/describeIfWindow.js | 10 + test-build/_helpers/enzymeSetup.js | 9 + .../registerReactWithStylesInterface.js | 22 + test-build/_helpers/restoreSinonStubs.js | 9 + test-build/_helpers/withTouchSupport.js | 25 + test-build/browser-main.js | 10 + test-build/components/CalendarDay_spec.js | 333 ++ .../components/CalendarMonthGrid_spec.js | 128 + test-build/components/CalendarMonth_spec.js | 108 + test-build/components/CalendarWeek_spec.js | 20 + .../CustomizableCalendarDay_spec.js | 324 ++ test-build/components/DateInput_spec.js | 391 ++ .../DateRangePickerInputController_spec.js | 955 ++++ .../components/DateRangePickerInput_spec.js | 207 + test-build/components/DateRangePicker_spec.js | 755 +++ .../DayPickerKeyboardShortcuts_spec.js | 400 ++ .../components/DayPickerNavigation_spec.js | 389 ++ .../DayPickerRangeController_spec.js | 5013 +++++++++++++++++ .../DayPickerSingleDateController_spec.js | 1578 ++++++ test-build/components/DayPicker_spec.js | 1477 +++++ .../components/KeyboardShortcutRow_spec.js | 22 + .../SingleDatePickerInputController_spec.js | 404 ++ .../components/SingleDatePickerInput_spec.js | 135 + .../components/SingleDatePicker_spec.js | 624 ++ test-build/utils/calculateDimension_spec.js | 65 + test-build/utils/disableScroll_spec.js | 187 + test-build/utils/getActiveElement_spec.js | 36 + .../utils/getCalendarDaySettings_spec.js | 202 + .../utils/getCalendarMonthWeeks_spec.js | 262 + .../utils/getCalendarMonthWidth_spec.js | 19 + .../utils/getDetachedContainerStyles_spec.js | 69 + test-build/utils/getInputHeight_spec.js | 35 + .../getNumberOfCalendarMonthWeeks_spec.js | 28 + test-build/utils/getPhrasePropTypes_spec.js | 23 + test-build/utils/getPhrase_spec.js | 40 + test-build/utils/getPooledMoment_spec.js | 27 + .../getResponsiveContainerStyles_spec.js | 39 + .../utils/getSelectedDateOffset_spec.js | 45 + test-build/utils/getTransformStyles_spec.js | 30 + test-build/utils/getVisibleDays_spec.js | 38 + test-build/utils/isAfterDay_spec.js | 37 + test-build/utils/isBeforeDay_spec.js | 37 + test-build/utils/isDayVisible_spec.js | 62 + .../utils/isInclusivelyAfterDay_spec.js | 31 + .../utils/isInclusivelyBeforeDay_spec.js | 31 + test-build/utils/isNextDay_spec.js | 28 + test-build/utils/isNextMonth_spec.js | 32 + test-build/utils/isPrevMonth_spec.js | 32 + test-build/utils/isPreviousDay_spec.js | 28 + test-build/utils/isSameDay_spec.js | 33 + test-build/utils/isSameMonth_spec.js | 28 + .../utils/isTransitionEndSupported_spec.js | 35 + test-build/utils/noflip_spec.js | 21 + test-build/utils/toISODateString_spec.js | 42 + test-build/utils/toISOMonthString_spec.js | 51 + .../utils/toLocalizedDateString_spec.js | 37 + test-build/utils/toMomentObject_spec.js | 53 + 219 files changed, 37657 insertions(+), 3 deletions(-) create mode 100644 esm/components/CalendarDay.js create mode 100644 esm/components/CalendarIcon.js create mode 100644 esm/components/CalendarMonth.js create mode 100644 esm/components/CalendarMonthGrid.js create mode 100644 esm/components/CalendarWeek.js create mode 100644 esm/components/ChevronDown.js create mode 100644 esm/components/ChevronUp.js create mode 100644 esm/components/CloseButton.js create mode 100644 esm/components/CustomizableCalendarDay.js create mode 100644 esm/components/DateInput.js create mode 100644 esm/components/DateRangePicker.js create mode 100644 esm/components/DateRangePickerInput.js create mode 100644 esm/components/DateRangePickerInputController.js create mode 100644 esm/components/DayPicker.js create mode 100644 esm/components/DayPickerKeyboardShortcuts.js create mode 100644 esm/components/DayPickerNavigation.js create mode 100644 esm/components/DayPickerRangeController.js create mode 100644 esm/components/DayPickerSingleDateController.js create mode 100644 esm/components/KeyboardShortcutRow.js create mode 100644 esm/components/LeftArrow.js create mode 100644 esm/components/RightArrow.js create mode 100644 esm/components/SingleDatePicker.js create mode 100644 esm/components/SingleDatePickerInput.js create mode 100644 esm/components/SingleDatePickerInputController.js create mode 100644 esm/constants.js create mode 100644 esm/defaultPhrases.js create mode 100644 esm/index.js create mode 100644 esm/initialize.js create mode 100644 esm/shapes/AnchorDirectionShape.js create mode 100644 esm/shapes/CalendarInfoPositionShape.js create mode 100644 esm/shapes/DateRangePickerShape.js create mode 100644 esm/shapes/DayOfWeekShape.js create mode 100644 esm/shapes/DisabledShape.js create mode 100644 esm/shapes/FocusedInputShape.js create mode 100644 esm/shapes/IconPositionShape.js create mode 100644 esm/shapes/ModifiersShape.js create mode 100644 esm/shapes/NavPositionShape.js create mode 100644 esm/shapes/OpenDirectionShape.js create mode 100644 esm/shapes/OrientationShape.js create mode 100644 esm/shapes/ScrollableOrientationShape.js create mode 100644 esm/shapes/SingleDatePickerShape.js create mode 100644 esm/theme/DefaultTheme.js create mode 100644 esm/utils/calculateDimension.js create mode 100644 esm/utils/disableScroll.js create mode 100644 esm/utils/enumrateDatesBetween.js create mode 100644 esm/utils/getActiveElement.js create mode 100644 esm/utils/getCalendarDaySettings.js create mode 100644 esm/utils/getCalendarMonthWeeks.js create mode 100644 esm/utils/getCalendarMonthWidth.js create mode 100644 esm/utils/getDetachedContainerStyles.js create mode 100644 esm/utils/getInputHeight.js create mode 100644 esm/utils/getNumberOfCalendarMonthWeeks.js create mode 100644 esm/utils/getPhrase.js create mode 100644 esm/utils/getPhrasePropTypes.js create mode 100644 esm/utils/getPooledMoment.js create mode 100644 esm/utils/getPreviousMonthMemoLast.js create mode 100644 esm/utils/getResponsiveContainerStyles.js create mode 100644 esm/utils/getSelectedDateOffset.js create mode 100644 esm/utils/getTransformStyles.js create mode 100644 esm/utils/getVisibleDays.js create mode 100644 esm/utils/isAfterDay.js create mode 100644 esm/utils/isBeforeDay.js create mode 100644 esm/utils/isDayVisible.js create mode 100644 esm/utils/isInclusivelyAfterDay.js create mode 100644 esm/utils/isInclusivelyBeforeDay.js create mode 100644 esm/utils/isNextDay.js create mode 100644 esm/utils/isNextMonth.js create mode 100644 esm/utils/isPrevMonth.js create mode 100644 esm/utils/isPreviousDay.js create mode 100644 esm/utils/isSameDay.js create mode 100644 esm/utils/isSameMonth.js create mode 100644 esm/utils/isTransitionEndSupported.js create mode 100644 esm/utils/modifiers.js create mode 100644 esm/utils/noflip.js create mode 100644 esm/utils/registerCSSInterfaceWithDefaultTheme.js create mode 100644 esm/utils/registerInterfaceWithDefaultTheme.js create mode 100644 esm/utils/toISODateString.js create mode 100644 esm/utils/toISOMonthString.js create mode 100644 esm/utils/toLocalizedDateString.js create mode 100644 esm/utils/toMomentObject.js create mode 100644 lib/components/CalendarDay.js create mode 100644 lib/components/CalendarIcon.js create mode 100644 lib/components/CalendarMonth.js create mode 100644 lib/components/CalendarMonthGrid.js create mode 100644 lib/components/CalendarWeek.js create mode 100644 lib/components/ChevronDown.js create mode 100644 lib/components/ChevronUp.js create mode 100644 lib/components/CloseButton.js create mode 100644 lib/components/CustomizableCalendarDay.js create mode 100644 lib/components/DateInput.js create mode 100644 lib/components/DateRangePicker.js create mode 100644 lib/components/DateRangePickerInput.js create mode 100644 lib/components/DateRangePickerInputController.js create mode 100644 lib/components/DayPicker.js create mode 100644 lib/components/DayPickerKeyboardShortcuts.js create mode 100644 lib/components/DayPickerNavigation.js create mode 100644 lib/components/DayPickerRangeController.js create mode 100644 lib/components/DayPickerSingleDateController.js create mode 100644 lib/components/KeyboardShortcutRow.js create mode 100644 lib/components/LeftArrow.js create mode 100644 lib/components/RightArrow.js create mode 100644 lib/components/SingleDatePicker.js create mode 100644 lib/components/SingleDatePickerInput.js create mode 100644 lib/components/SingleDatePickerInputController.js create mode 100644 lib/constants.js create mode 100644 lib/css/_datepicker.css create mode 100644 lib/defaultPhrases.js create mode 100644 lib/index.js create mode 100644 lib/initialize.js create mode 100644 lib/shapes/AnchorDirectionShape.js create mode 100644 lib/shapes/CalendarInfoPositionShape.js create mode 100644 lib/shapes/DateRangePickerShape.js create mode 100644 lib/shapes/DayOfWeekShape.js create mode 100644 lib/shapes/DisabledShape.js create mode 100644 lib/shapes/FocusedInputShape.js create mode 100644 lib/shapes/IconPositionShape.js create mode 100644 lib/shapes/ModifiersShape.js create mode 100644 lib/shapes/NavPositionShape.js create mode 100644 lib/shapes/OpenDirectionShape.js create mode 100644 lib/shapes/OrientationShape.js create mode 100644 lib/shapes/ScrollableOrientationShape.js create mode 100644 lib/shapes/SingleDatePickerShape.js create mode 100644 lib/theme/DefaultTheme.js create mode 100644 lib/utils/calculateDimension.js create mode 100644 lib/utils/disableScroll.js create mode 100644 lib/utils/enumrateDatesBetween.js create mode 100644 lib/utils/getActiveElement.js create mode 100644 lib/utils/getCalendarDaySettings.js create mode 100644 lib/utils/getCalendarMonthWeeks.js create mode 100644 lib/utils/getCalendarMonthWidth.js create mode 100644 lib/utils/getDetachedContainerStyles.js create mode 100644 lib/utils/getInputHeight.js create mode 100644 lib/utils/getNumberOfCalendarMonthWeeks.js create mode 100644 lib/utils/getPhrase.js create mode 100644 lib/utils/getPhrasePropTypes.js create mode 100644 lib/utils/getPooledMoment.js create mode 100644 lib/utils/getPreviousMonthMemoLast.js create mode 100644 lib/utils/getResponsiveContainerStyles.js create mode 100644 lib/utils/getSelectedDateOffset.js create mode 100644 lib/utils/getTransformStyles.js create mode 100644 lib/utils/getVisibleDays.js create mode 100644 lib/utils/isAfterDay.js create mode 100644 lib/utils/isBeforeDay.js create mode 100644 lib/utils/isDayVisible.js create mode 100644 lib/utils/isInclusivelyAfterDay.js create mode 100644 lib/utils/isInclusivelyBeforeDay.js create mode 100644 lib/utils/isNextDay.js create mode 100644 lib/utils/isNextMonth.js create mode 100644 lib/utils/isPrevMonth.js create mode 100644 lib/utils/isPreviousDay.js create mode 100644 lib/utils/isSameDay.js create mode 100644 lib/utils/isSameMonth.js create mode 100644 lib/utils/isTransitionEndSupported.js create mode 100644 lib/utils/modifiers.js create mode 100644 lib/utils/noflip.js create mode 100644 lib/utils/registerCSSInterfaceWithDefaultTheme.js create mode 100644 lib/utils/registerInterfaceWithDefaultTheme.js create mode 100644 lib/utils/toISODateString.js create mode 100644 lib/utils/toISOMonthString.js create mode 100644 lib/utils/toLocalizedDateString.js create mode 100644 lib/utils/toMomentObject.js create mode 100644 test-build/_helpers/describeIfWindow.js create mode 100644 test-build/_helpers/enzymeSetup.js create mode 100644 test-build/_helpers/registerReactWithStylesInterface.js create mode 100644 test-build/_helpers/restoreSinonStubs.js create mode 100644 test-build/_helpers/withTouchSupport.js create mode 100644 test-build/browser-main.js create mode 100644 test-build/components/CalendarDay_spec.js create mode 100644 test-build/components/CalendarMonthGrid_spec.js create mode 100644 test-build/components/CalendarMonth_spec.js create mode 100644 test-build/components/CalendarWeek_spec.js create mode 100644 test-build/components/CustomizableCalendarDay_spec.js create mode 100644 test-build/components/DateInput_spec.js create mode 100644 test-build/components/DateRangePickerInputController_spec.js create mode 100644 test-build/components/DateRangePickerInput_spec.js create mode 100644 test-build/components/DateRangePicker_spec.js create mode 100644 test-build/components/DayPickerKeyboardShortcuts_spec.js create mode 100644 test-build/components/DayPickerNavigation_spec.js create mode 100644 test-build/components/DayPickerRangeController_spec.js create mode 100644 test-build/components/DayPickerSingleDateController_spec.js create mode 100644 test-build/components/DayPicker_spec.js create mode 100644 test-build/components/KeyboardShortcutRow_spec.js create mode 100644 test-build/components/SingleDatePickerInputController_spec.js create mode 100644 test-build/components/SingleDatePickerInput_spec.js create mode 100644 test-build/components/SingleDatePicker_spec.js create mode 100644 test-build/utils/calculateDimension_spec.js create mode 100644 test-build/utils/disableScroll_spec.js create mode 100644 test-build/utils/getActiveElement_spec.js create mode 100644 test-build/utils/getCalendarDaySettings_spec.js create mode 100644 test-build/utils/getCalendarMonthWeeks_spec.js create mode 100644 test-build/utils/getCalendarMonthWidth_spec.js create mode 100644 test-build/utils/getDetachedContainerStyles_spec.js create mode 100644 test-build/utils/getInputHeight_spec.js create mode 100644 test-build/utils/getNumberOfCalendarMonthWeeks_spec.js create mode 100644 test-build/utils/getPhrasePropTypes_spec.js create mode 100644 test-build/utils/getPhrase_spec.js create mode 100644 test-build/utils/getPooledMoment_spec.js create mode 100644 test-build/utils/getResponsiveContainerStyles_spec.js create mode 100644 test-build/utils/getSelectedDateOffset_spec.js create mode 100644 test-build/utils/getTransformStyles_spec.js create mode 100644 test-build/utils/getVisibleDays_spec.js create mode 100644 test-build/utils/isAfterDay_spec.js create mode 100644 test-build/utils/isBeforeDay_spec.js create mode 100644 test-build/utils/isDayVisible_spec.js create mode 100644 test-build/utils/isInclusivelyAfterDay_spec.js create mode 100644 test-build/utils/isInclusivelyBeforeDay_spec.js create mode 100644 test-build/utils/isNextDay_spec.js create mode 100644 test-build/utils/isNextMonth_spec.js create mode 100644 test-build/utils/isPrevMonth_spec.js create mode 100644 test-build/utils/isPreviousDay_spec.js create mode 100644 test-build/utils/isSameDay_spec.js create mode 100644 test-build/utils/isSameMonth_spec.js create mode 100644 test-build/utils/isTransitionEndSupported_spec.js create mode 100644 test-build/utils/noflip_spec.js create mode 100644 test-build/utils/toISODateString_spec.js create mode 100644 test-build/utils/toISOMonthString_spec.js create mode 100644 test-build/utils/toLocalizedDateString_spec.js create mode 100644 test-build/utils/toMomentObject_spec.js diff --git a/.gitignore b/.gitignore index 3d7cb404f..f6b3086dd 100644 --- a/.gitignore +++ b/.gitignore @@ -33,9 +33,9 @@ node_modules .node_repl_history # build folder -lib -esm -test-build +# lib +# esm +# test-build .idea # gh-pages diff --git a/esm/components/CalendarDay.js b/esm/components/CalendarDay.js new file mode 100644 index 000000000..a7a960393 --- /dev/null +++ b/esm/components/CalendarDay.js @@ -0,0 +1,342 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import moment from 'moment'; +import raf from 'raf'; +import { CalendarDayPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import getCalendarDaySettings from '../utils/getCalendarDaySettings'; +import ModifiersShape from '../shapes/ModifiersShape'; +import { DAY_SIZE } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + day: momentPropTypes.momentObj, + daySize: nonNegativeInteger, + isOutsideDay: PropTypes.bool, + modifiers: ModifiersShape, + isFocused: PropTypes.bool, + tabIndex: PropTypes.oneOf([0, -1]), + onDayClick: PropTypes.func, + onDayMouseEnter: PropTypes.func, + onDayMouseLeave: PropTypes.func, + renderDayContents: PropTypes.func, + ariaLabelFormat: PropTypes.string, + // internationalization + phrases: PropTypes.shape(getPhrasePropTypes(CalendarDayPhrases)) +})) : {}; +var defaultProps = { + day: moment(), + daySize: DAY_SIZE, + isOutsideDay: false, + modifiers: new Set(), + isFocused: false, + tabIndex: -1, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + renderDayContents: null, + ariaLabelFormat: 'dddd, LL', + // internationalization + phrases: CalendarDayPhrases +}; + +var CalendarDay = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(CalendarDay, _ref2); + + var _proto = CalendarDay.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function CalendarDay() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + _this.setButtonRef = _this.setButtonRef.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this2 = this; + + var _this$props = this.props, + isFocused = _this$props.isFocused, + tabIndex = _this$props.tabIndex; + + if (tabIndex === 0) { + if (isFocused || tabIndex !== prevProps.tabIndex) { + raf(function () { + if (_this2.buttonRef) { + _this2.buttonRef.focus(); + } + }); + } + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var onDayClick = this.props.onDayClick; + onDayClick(day, e); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day, e) { + var onDayMouseEnter = this.props.onDayMouseEnter; + onDayMouseEnter(day, e); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day, e) { + var onDayMouseLeave = this.props.onDayMouseLeave; + onDayMouseLeave(day, e); + }; + + _proto.onKeyDown = function onKeyDown(day, e) { + var onDayClick = this.props.onDayClick; + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onDayClick(day, e); + } + }; + + _proto.setButtonRef = function setButtonRef(ref) { + this.buttonRef = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props2 = this.props, + day = _this$props2.day, + ariaLabelFormat = _this$props2.ariaLabelFormat, + daySize = _this$props2.daySize, + isOutsideDay = _this$props2.isOutsideDay, + modifiers = _this$props2.modifiers, + renderDayContents = _this$props2.renderDayContents, + tabIndex = _this$props2.tabIndex, + css = _this$props2.css, + styles = _this$props2.styles, + phrases = _this$props2.phrases; + if (!day) return /*#__PURE__*/React.createElement("td", null); + + var _getCalendarDaySettin = getCalendarDaySettings(day, ariaLabelFormat, daySize, modifiers, phrases), + daySizeStyles = _getCalendarDaySettin.daySizeStyles, + useDefaultCursor = _getCalendarDaySettin.useDefaultCursor, + selected = _getCalendarDaySettin.selected, + hoveredSpan = _getCalendarDaySettin.hoveredSpan, + isOutsideRange = _getCalendarDaySettin.isOutsideRange, + ariaLabel = _getCalendarDaySettin.ariaLabel; + + return /*#__PURE__*/React.createElement("td", _extends({}, css(styles.CalendarDay, useDefaultCursor && styles.CalendarDay__defaultCursor, styles.CalendarDay__default, isOutsideDay && styles.CalendarDay__outside, modifiers.has('today') && styles.CalendarDay__today, modifiers.has('first-day-of-week') && styles.CalendarDay__firstDayOfWeek, modifiers.has('last-day-of-week') && styles.CalendarDay__lastDayOfWeek, modifiers.has('hovered-offset') && styles.CalendarDay__hovered_offset, modifiers.has('hovered-start-first-possible-end') && styles.CalendarDay__hovered_start_first_possible_end, modifiers.has('hovered-start-blocked-minimum-nights') && styles.CalendarDay__hovered_start_blocked_min_nights, modifiers.has('highlighted-calendar') && styles.CalendarDay__highlighted_calendar, modifiers.has('blocked-minimum-nights') && styles.CalendarDay__blocked_minimum_nights, modifiers.has('blocked-calendar') && styles.CalendarDay__blocked_calendar, hoveredSpan && styles.CalendarDay__hovered_span, modifiers.has('after-hovered-start') && styles.CalendarDay__after_hovered_start, modifiers.has('selected-span') && styles.CalendarDay__selected_span, modifiers.has('selected-start') && styles.CalendarDay__selected_start, modifiers.has('selected-end') && styles.CalendarDay__selected_end, selected && !modifiers.has('selected-span') && styles.CalendarDay__selected, modifiers.has('before-hovered-end') && styles.CalendarDay__before_hovered_end, modifiers.has('no-selected-start-before-selected-end') && styles.CalendarDay__no_selected_start_before_selected_end, modifiers.has('selected-start-in-hovered-span') && styles.CalendarDay__selected_start_in_hovered_span, modifiers.has('selected-end-in-hovered-span') && styles.CalendarDay__selected_end_in_hovered_span, modifiers.has('selected-start-no-selected-end') && styles.CalendarDay__selected_start_no_selected_end, modifiers.has('selected-end-no-selected-start') && styles.CalendarDay__selected_end_no_selected_start, isOutsideRange && styles.CalendarDay__blocked_out_of_range, daySizeStyles), { + role: "button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role + , + ref: this.setButtonRef, + "aria-disabled": modifiers.has('blocked') + }, modifiers.has('today') ? { + 'aria-current': 'date' + } : {}, { + "aria-label": ariaLabel, + onMouseEnter: function onMouseEnter(e) { + _this3.onDayMouseEnter(day, e); + }, + onMouseLeave: function onMouseLeave(e) { + _this3.onDayMouseLeave(day, e); + }, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + }, + onClick: function onClick(e) { + _this3.onDayClick(day, e); + }, + onKeyDown: function onKeyDown(e) { + _this3.onKeyDown(day, e); + }, + tabIndex: tabIndex + }), renderDayContents ? renderDayContents(day, modifiers) : day.format('D')); + }; + + return CalendarDay; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +CalendarDay.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarDay.defaultProps = defaultProps; +export { CalendarDay as PureCalendarDay }; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + font = _ref3$reactDates.font; + return { + CalendarDay: { + boxSizing: 'border-box', + cursor: 'pointer', + fontSize: font.size, + textAlign: 'center', + ':active': { + outline: 0 + } + }, + CalendarDay__defaultCursor: { + cursor: 'default' + }, + CalendarDay__default: { + border: "1px solid ".concat(color.core.borderLight), + color: color.text, + background: color.background, + ':hover': { + background: color.core.borderLight, + border: "1px solid ".concat(color.core.borderLight), + color: 'inherit' + } + }, + CalendarDay__hovered_offset: { + background: color.core.borderBright, + border: "1px double ".concat(color.core.borderLight), + color: 'inherit' + }, + CalendarDay__outside: { + border: 0, + background: color.outside.backgroundColor, + color: color.outside.color, + ':hover': { + border: 0 + } + }, + CalendarDay__blocked_minimum_nights: { + background: color.minimumNights.backgroundColor, + border: "1px solid ".concat(color.minimumNights.borderColor), + color: color.minimumNights.color, + ':hover': { + background: color.minimumNights.backgroundColor_hover, + color: color.minimumNights.color_active + }, + ':active': { + background: color.minimumNights.backgroundColor_active, + color: color.minimumNights.color_active + } + }, + CalendarDay__highlighted_calendar: { + background: color.highlighted.backgroundColor, + color: color.highlighted.color, + ':hover': { + background: color.highlighted.backgroundColor_hover, + color: color.highlighted.color_active + }, + ':active': { + background: color.highlighted.backgroundColor_active, + color: color.highlighted.color_active + } + }, + CalendarDay__selected_span: { + background: color.selectedSpan.backgroundColor, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color, + ':hover': { + background: color.selectedSpan.backgroundColor_hover, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + }, + ':active': { + background: color.selectedSpan.backgroundColor_active, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + } + }, + CalendarDay__selected: { + background: color.selected.backgroundColor, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color, + ':hover': { + background: color.selected.backgroundColor_hover, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + }, + ':active': { + background: color.selected.backgroundColor_active, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + } + }, + CalendarDay__hovered_span: { + background: color.hoveredSpan.backgroundColor, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color, + ':hover': { + background: color.hoveredSpan.backgroundColor_hover, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + }, + ':active': { + background: color.hoveredSpan.backgroundColor_active, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + } + }, + CalendarDay__blocked_calendar: { + background: color.blocked_calendar.backgroundColor, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color, + ':hover': { + background: color.blocked_calendar.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + }, + ':active': { + background: color.blocked_calendar.backgroundColor_active, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + } + }, + CalendarDay__blocked_out_of_range: { + background: color.blocked_out_of_range.backgroundColor, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color, + ':hover': { + background: color.blocked_out_of_range.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + }, + ':active': { + background: color.blocked_out_of_range.backgroundColor_active, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + } + }, + CalendarDay__hovered_start_first_possible_end: { + background: color.core.borderLighter, + border: "1px double ".concat(color.core.borderLighter) + }, + CalendarDay__hovered_start_blocked_min_nights: { + background: color.core.borderLighter, + border: "1px double ".concat(color.core.borderLight) + }, + CalendarDay__selected_start: {}, + CalendarDay__selected_end: {}, + CalendarDay__today: {}, + CalendarDay__firstDayOfWeek: {}, + CalendarDay__lastDayOfWeek: {}, + CalendarDay__after_hovered_start: {}, + CalendarDay__before_hovered_end: {}, + CalendarDay__no_selected_start_before_selected_end: {}, + CalendarDay__selected_start_in_hovered_span: {}, + CalendarDay__selected_end_in_hovered_span: {}, + CalendarDay__selected_start_no_selected_end: {}, + CalendarDay__selected_end_no_selected_start: {} + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(CalendarDay); \ No newline at end of file diff --git a/esm/components/CalendarIcon.js b/esm/components/CalendarIcon.js new file mode 100644 index 000000000..5730904a1 --- /dev/null +++ b/esm/components/CalendarIcon.js @@ -0,0 +1,13 @@ +import React from "react"; + +var CalendarIcon = function CalendarIcon(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + d: "m107 1393h241v-241h-241zm295 0h268v-241h-268zm-295-295h241v-268h-241zm295 0h268v-268h-268zm-295-321h241v-241h-241zm616 616h268v-241h-268zm-321-616h268v-241h-268zm643 616h241v-241h-241zm-322-295h268v-268h-268zm-294-723v-241c0-7-3-14-8-19-6-5-12-8-19-8h-54c-7 0-13 3-19 8-5 5-8 12-8 19v241c0 7 3 14 8 19 6 5 12 8 19 8h54c7 0 13-3 19-8 5-5 8-12 8-19zm616 723h241v-268h-241zm-322-321h268v-241h-268zm322 0h241v-241h-241zm27-402v-241c0-7-3-14-8-19-6-5-12-8-19-8h-54c-7 0-13 3-19 8-5 5-8 12-8 19v241c0 7 3 14 8 19 6 5 12 8 19 8h54c7 0 13-3 19-8 5-5 8-12 8-19zm321-54v1072c0 29-11 54-32 75s-46 32-75 32h-1179c-29 0-54-11-75-32s-32-46-32-75v-1072c0-29 11-54 32-75s46-32 75-32h107v-80c0-37 13-68 40-95s57-39 94-39h54c37 0 68 13 95 39 26 26 39 58 39 95v80h321v-80c0-37 13-69 40-95 26-26 57-39 94-39h54c37 0 68 13 94 39s40 58 40 95v80h107c29 0 54 11 75 32s32 46 32 75z" + })); +}; + +CalendarIcon.defaultProps = { + focusable: "false", + viewBox: "0 0 1393.1 1500" +}; +export default CalendarIcon; \ No newline at end of file diff --git a/esm/components/CalendarMonth.js b/esm/components/CalendarMonth.js new file mode 100644 index 000000000..7ed4b3075 --- /dev/null +++ b/esm/components/CalendarMonth.js @@ -0,0 +1,267 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +/* eslint react/no-array-index-key: 0 */ +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import moment from 'moment'; +import { CalendarDayPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import CalendarWeek from './CalendarWeek'; +import CalendarDay from './CalendarDay'; +import calculateDimension from '../utils/calculateDimension'; +import getCalendarMonthWeeks from '../utils/getCalendarMonthWeeks'; +import isSameDay from '../utils/isSameDay'; +import toISODateString from '../utils/toISODateString'; +import ModifiersShape from '../shapes/ModifiersShape'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import DayOfWeekShape from '../shapes/DayOfWeekShape'; +import { HORIZONTAL_ORIENTATION, VERTICAL_SCROLLABLE, DAY_SIZE } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + month: momentPropTypes.momentObj, + horizontalMonthPadding: nonNegativeInteger, + isVisible: PropTypes.bool, + enableOutsideDays: PropTypes.bool, + modifiers: PropTypes.objectOf(ModifiersShape), + orientation: ScrollableOrientationShape, + daySize: nonNegativeInteger, + onDayClick: PropTypes.func, + onDayMouseEnter: PropTypes.func, + onDayMouseLeave: PropTypes.func, + onMonthSelect: PropTypes.func, + onYearSelect: PropTypes.func, + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + firstDayOfWeek: DayOfWeekShape, + setMonthTitleHeight: PropTypes.func, + verticalBorderSpacing: nonNegativeInteger, + focusedDate: momentPropTypes.momentObj, + // indicates focusable day + isFocused: PropTypes.bool, + // indicates whether or not to move focus to focusable day + // i18n + monthFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(CalendarDayPhrases)), + dayAriaLabelFormat: PropTypes.string +})) : {}; +var defaultProps = { + month: moment(), + horizontalMonthPadding: 13, + isVisible: true, + enableOutsideDays: false, + modifiers: {}, + orientation: HORIZONTAL_ORIENTATION, + daySize: DAY_SIZE, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + onMonthSelect: function onMonthSelect() {}, + onYearSelect: function onYearSelect() {}, + renderMonthText: null, + renderCalendarDay: function renderCalendarDay(props) { + return /*#__PURE__*/React.createElement(CalendarDay, props); + }, + renderDayContents: null, + renderMonthElement: null, + firstDayOfWeek: null, + setMonthTitleHeight: null, + focusedDate: null, + isFocused: false, + // i18n + monthFormat: 'MMMM YYYY', + // english locale + phrases: CalendarDayPhrases, + dayAriaLabelFormat: undefined, + verticalBorderSpacing: undefined +}; + +var CalendarMonth = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(CalendarMonth, _ref2); + + var _proto = CalendarMonth.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function CalendarMonth(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + weeks: getCalendarMonthWeeks(props.month, props.enableOutsideDays, props.firstDayOfWeek == null ? moment.localeData().firstDayOfWeek() : props.firstDayOfWeek) + }; + _this.setCaptionRef = _this.setCaptionRef.bind(_assertThisInitialized(_this)); + _this.setMonthTitleHeight = _this.setMonthTitleHeight.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.queueSetMonthTitleHeight(); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var month = nextProps.month, + enableOutsideDays = nextProps.enableOutsideDays, + firstDayOfWeek = nextProps.firstDayOfWeek; + var _this$props = this.props, + prevMonth = _this$props.month, + prevEnableOutsideDays = _this$props.enableOutsideDays, + prevFirstDayOfWeek = _this$props.firstDayOfWeek; + + if (!month.isSame(prevMonth) || enableOutsideDays !== prevEnableOutsideDays || firstDayOfWeek !== prevFirstDayOfWeek) { + this.setState({ + weeks: getCalendarMonthWeeks(month, enableOutsideDays, firstDayOfWeek == null ? moment.localeData().firstDayOfWeek() : firstDayOfWeek) + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var setMonthTitleHeight = this.props.setMonthTitleHeight; + + if (prevProps.setMonthTitleHeight === null && setMonthTitleHeight !== null) { + this.queueSetMonthTitleHeight(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.setMonthTitleHeightTimeout) { + clearTimeout(this.setMonthTitleHeightTimeout); + } + }; + + _proto.setMonthTitleHeight = function setMonthTitleHeight() { + var setMonthTitleHeight = this.props.setMonthTitleHeight; + + if (setMonthTitleHeight) { + var captionHeight = calculateDimension(this.captionRef, 'height', true, true); + setMonthTitleHeight(captionHeight); + } + }; + + _proto.setCaptionRef = function setCaptionRef(ref) { + this.captionRef = ref; + }; + + _proto.queueSetMonthTitleHeight = function queueSetMonthTitleHeight() { + this.setMonthTitleHeightTimeout = window.setTimeout(this.setMonthTitleHeight, 0); + }; + + _proto.render = function render() { + var _this$props2 = this.props, + dayAriaLabelFormat = _this$props2.dayAriaLabelFormat, + daySize = _this$props2.daySize, + focusedDate = _this$props2.focusedDate, + horizontalMonthPadding = _this$props2.horizontalMonthPadding, + isFocused = _this$props2.isFocused, + isVisible = _this$props2.isVisible, + modifiers = _this$props2.modifiers, + month = _this$props2.month, + monthFormat = _this$props2.monthFormat, + onDayClick = _this$props2.onDayClick, + onDayMouseEnter = _this$props2.onDayMouseEnter, + onDayMouseLeave = _this$props2.onDayMouseLeave, + onMonthSelect = _this$props2.onMonthSelect, + onYearSelect = _this$props2.onYearSelect, + orientation = _this$props2.orientation, + phrases = _this$props2.phrases, + renderCalendarDay = _this$props2.renderCalendarDay, + renderDayContents = _this$props2.renderDayContents, + renderMonthElement = _this$props2.renderMonthElement, + renderMonthText = _this$props2.renderMonthText, + css = _this$props2.css, + styles = _this$props2.styles, + verticalBorderSpacing = _this$props2.verticalBorderSpacing; + var weeks = this.state.weeks; + var monthTitle = renderMonthText ? renderMonthText(month) : month.format(monthFormat); + var verticalScrollable = orientation === VERTICAL_SCROLLABLE; + return /*#__PURE__*/React.createElement("div", _extends({}, css(styles.CalendarMonth, { + padding: "0 ".concat(horizontalMonthPadding, "px") + }), { + "data-visible": isVisible + }), /*#__PURE__*/React.createElement("div", _extends({ + ref: this.setCaptionRef + }, css(styles.CalendarMonth_caption, verticalScrollable && styles.CalendarMonth_caption__verticalScrollable)), renderMonthElement ? renderMonthElement({ + month: month, + onMonthSelect: onMonthSelect, + onYearSelect: onYearSelect, + isVisible: isVisible + }) : /*#__PURE__*/React.createElement("strong", null, monthTitle)), /*#__PURE__*/React.createElement("table", _extends({}, css(!verticalBorderSpacing && styles.CalendarMonth_table, verticalBorderSpacing && styles.CalendarMonth_verticalSpacing, verticalBorderSpacing && { + borderSpacing: "0px ".concat(verticalBorderSpacing, "px") + }), { + role: "presentation" + }), /*#__PURE__*/React.createElement("tbody", null, weeks.map(function (week, i) { + return /*#__PURE__*/React.createElement(CalendarWeek, { + key: i + }, week.map(function (day, dayOfWeek) { + return renderCalendarDay({ + key: dayOfWeek, + day: day, + daySize: daySize, + isOutsideDay: !day || day.month() !== month.month(), + tabIndex: isVisible && isSameDay(day, focusedDate) ? 0 : -1, + isFocused: isFocused, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onDayClick: onDayClick, + renderDayContents: renderDayContents, + phrases: phrases, + modifiers: modifiers[toISODateString(day)], + ariaLabelFormat: dayAriaLabelFormat + }); + })); + })))); + }; + + return CalendarMonth; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +CalendarMonth.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarMonth.defaultProps = defaultProps; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + font = _ref3$reactDates.font, + spacing = _ref3$reactDates.spacing; + return { + CalendarMonth: { + background: color.background, + textAlign: 'center', + verticalAlign: 'top', + userSelect: 'none' + }, + CalendarMonth_table: { + borderCollapse: 'collapse', + borderSpacing: 0 + }, + CalendarMonth_verticalSpacing: { + borderCollapse: 'separate' + }, + CalendarMonth_caption: { + color: color.text, + fontSize: font.captionSize, + textAlign: 'center', + paddingTop: spacing.captionPaddingTop, + paddingBottom: spacing.captionPaddingBottom, + captionSide: 'initial' + }, + CalendarMonth_caption__verticalScrollable: { + paddingTop: 12, + paddingBottom: 7 + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(CalendarMonth); \ No newline at end of file diff --git a/esm/components/CalendarMonthGrid.js b/esm/components/CalendarMonthGrid.js new file mode 100644 index 000000000..21fb545b2 --- /dev/null +++ b/esm/components/CalendarMonthGrid.js @@ -0,0 +1,393 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import moment from 'moment'; +import { addEventListener } from 'consolidated-events'; +import { CalendarDayPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import noflip from '../utils/noflip'; +import CalendarMonth from './CalendarMonth'; +import isTransitionEndSupported from '../utils/isTransitionEndSupported'; +import getTransformStyles from '../utils/getTransformStyles'; +import getCalendarMonthWidth from '../utils/getCalendarMonthWidth'; +import toISOMonthString from '../utils/toISOMonthString'; +import isPrevMonth from '../utils/isPrevMonth'; +import isNextMonth from '../utils/isNextMonth'; +import ModifiersShape from '../shapes/ModifiersShape'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import DayOfWeekShape from '../shapes/DayOfWeekShape'; +import { HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, VERTICAL_SCROLLABLE, DAY_SIZE } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + enableOutsideDays: PropTypes.bool, + firstVisibleMonthIndex: PropTypes.number, + horizontalMonthPadding: nonNegativeInteger, + initialMonth: momentPropTypes.momentObj, + isAnimating: PropTypes.bool, + numberOfMonths: PropTypes.number, + modifiers: PropTypes.objectOf(PropTypes.objectOf(ModifiersShape)), + orientation: ScrollableOrientationShape, + onDayClick: PropTypes.func, + onDayMouseEnter: PropTypes.func, + onDayMouseLeave: PropTypes.func, + onMonthTransitionEnd: PropTypes.func, + onMonthChange: PropTypes.func, + onYearChange: PropTypes.func, + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + translationValue: PropTypes.number, + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + daySize: nonNegativeInteger, + focusedDate: momentPropTypes.momentObj, + // indicates focusable day + isFocused: PropTypes.bool, + // indicates whether or not to move focus to focusable day + firstDayOfWeek: DayOfWeekShape, + setMonthTitleHeight: PropTypes.func, + isRTL: PropTypes.bool, + transitionDuration: nonNegativeInteger, + verticalBorderSpacing: nonNegativeInteger, + // i18n + monthFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(CalendarDayPhrases)), + dayAriaLabelFormat: PropTypes.string +})) : {}; +var defaultProps = { + enableOutsideDays: false, + firstVisibleMonthIndex: 0, + horizontalMonthPadding: 13, + initialMonth: moment(), + isAnimating: false, + numberOfMonths: 1, + modifiers: {}, + orientation: HORIZONTAL_ORIENTATION, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + onMonthChange: function onMonthChange() {}, + onYearChange: function onYearChange() {}, + onMonthTransitionEnd: function onMonthTransitionEnd() {}, + renderMonthText: null, + renderCalendarDay: undefined, + renderDayContents: null, + translationValue: null, + renderMonthElement: null, + daySize: DAY_SIZE, + focusedDate: null, + isFocused: false, + firstDayOfWeek: null, + setMonthTitleHeight: null, + isRTL: false, + transitionDuration: 200, + verticalBorderSpacing: undefined, + // i18n + monthFormat: 'MMMM YYYY', + // english locale + phrases: CalendarDayPhrases, + dayAriaLabelFormat: undefined +}; + +function getMonths(initialMonth, numberOfMonths, withoutTransitionMonths) { + var month = initialMonth.clone(); + if (!withoutTransitionMonths) month = month.subtract(1, 'month'); + var months = []; + + for (var i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) { + months.push(month); + month = month.clone().add(1, 'month'); + } + + return months; +} + +var CalendarMonthGrid = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(CalendarMonthGrid, _ref2); + + var _proto = CalendarMonthGrid.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function CalendarMonthGrid(props) { + var _this; + + _this = _ref2.call(this, props) || this; + var withoutTransitionMonths = props.orientation === VERTICAL_SCROLLABLE; + _this.state = { + months: getMonths(props.initialMonth, props.numberOfMonths, withoutTransitionMonths) + }; + _this.isTransitionEndSupported = isTransitionEndSupported(); + _this.onTransitionEnd = _this.onTransitionEnd.bind(_assertThisInitialized(_this)); + _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); + _this.locale = moment.locale(); + _this.onMonthSelect = _this.onMonthSelect.bind(_assertThisInitialized(_this)); + _this.onYearSelect = _this.onYearSelect.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.removeEventListener = addEventListener(this.container, 'transitionend', this.onTransitionEnd); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var initialMonth = nextProps.initialMonth, + numberOfMonths = nextProps.numberOfMonths, + orientation = nextProps.orientation; + var months = this.state.months; + var _this$props = this.props, + prevInitialMonth = _this$props.initialMonth, + prevNumberOfMonths = _this$props.numberOfMonths; + var hasMonthChanged = !prevInitialMonth.isSame(initialMonth, 'month'); + var hasNumberOfMonthsChanged = prevNumberOfMonths !== numberOfMonths; + var newMonths = months; + + if (hasMonthChanged || hasNumberOfMonthsChanged) { + if (hasMonthChanged && !hasNumberOfMonthsChanged) { + if (isNextMonth(prevInitialMonth, initialMonth)) { + newMonths = months.slice(1); + newMonths.push(months[months.length - 1].clone().add(1, 'month')); + } else if (isPrevMonth(prevInitialMonth, initialMonth)) { + newMonths = months.slice(0, months.length - 1); + newMonths.unshift(months[0].clone().subtract(1, 'month')); + } else { + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + newMonths = getMonths(initialMonth, numberOfMonths, withoutTransitionMonths); + } + } + + if (hasNumberOfMonthsChanged) { + var _withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + + newMonths = getMonths(initialMonth, numberOfMonths, _withoutTransitionMonths); + } + + var momentLocale = moment.locale(); + + if (this.locale !== momentLocale) { + this.locale = momentLocale; + newMonths = newMonths.map(function (m) { + return m.locale(_this2.locale); + }); + } + + this.setState({ + months: newMonths + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate() { + var _this$props2 = this.props, + isAnimating = _this$props2.isAnimating, + transitionDuration = _this$props2.transitionDuration, + onMonthTransitionEnd = _this$props2.onMonthTransitionEnd; // For IE9, immediately call onMonthTransitionEnd instead of + // waiting for the animation to complete. Similarly, if transitionDuration + // is set to 0, also immediately invoke the onMonthTransitionEnd callback + + if ((!this.isTransitionEndSupported || !transitionDuration) && isAnimating) { + onMonthTransitionEnd(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.removeEventListener) this.removeEventListener(); + }; + + _proto.onTransitionEnd = function onTransitionEnd() { + var onMonthTransitionEnd = this.props.onMonthTransitionEnd; + onMonthTransitionEnd(); + }; + + _proto.onMonthSelect = function onMonthSelect(currentMonth, newMonthVal) { + var newMonth = currentMonth.clone(); + var _this$props3 = this.props, + onMonthChange = _this$props3.onMonthChange, + orientation = _this$props3.orientation; + var months = this.state.months; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var initialMonthSubtraction = months.indexOf(currentMonth); + + if (!withoutTransitionMonths) { + initialMonthSubtraction -= 1; + } + + newMonth.set('month', newMonthVal).subtract(initialMonthSubtraction, 'months'); + onMonthChange(newMonth); + }; + + _proto.onYearSelect = function onYearSelect(currentMonth, newYearVal) { + var newMonth = currentMonth.clone(); + var _this$props4 = this.props, + onYearChange = _this$props4.onYearChange, + orientation = _this$props4.orientation; + var months = this.state.months; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var initialMonthSubtraction = months.indexOf(currentMonth); + + if (!withoutTransitionMonths) { + initialMonthSubtraction -= 1; + } + + newMonth.set('year', newYearVal).subtract(initialMonthSubtraction, 'months'); + onYearChange(newMonth); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props5 = this.props, + enableOutsideDays = _this$props5.enableOutsideDays, + firstVisibleMonthIndex = _this$props5.firstVisibleMonthIndex, + horizontalMonthPadding = _this$props5.horizontalMonthPadding, + isAnimating = _this$props5.isAnimating, + modifiers = _this$props5.modifiers, + numberOfMonths = _this$props5.numberOfMonths, + monthFormat = _this$props5.monthFormat, + orientation = _this$props5.orientation, + translationValue = _this$props5.translationValue, + daySize = _this$props5.daySize, + onDayMouseEnter = _this$props5.onDayMouseEnter, + onDayMouseLeave = _this$props5.onDayMouseLeave, + onDayClick = _this$props5.onDayClick, + renderMonthText = _this$props5.renderMonthText, + renderCalendarDay = _this$props5.renderCalendarDay, + renderDayContents = _this$props5.renderDayContents, + renderMonthElement = _this$props5.renderMonthElement, + onMonthTransitionEnd = _this$props5.onMonthTransitionEnd, + firstDayOfWeek = _this$props5.firstDayOfWeek, + focusedDate = _this$props5.focusedDate, + isFocused = _this$props5.isFocused, + isRTL = _this$props5.isRTL, + css = _this$props5.css, + styles = _this$props5.styles, + phrases = _this$props5.phrases, + dayAriaLabelFormat = _this$props5.dayAriaLabelFormat, + transitionDuration = _this$props5.transitionDuration, + verticalBorderSpacing = _this$props5.verticalBorderSpacing, + setMonthTitleHeight = _this$props5.setMonthTitleHeight; + var months = this.state.months; + var isVertical = orientation === VERTICAL_ORIENTATION; + var isVerticalScrollable = orientation === VERTICAL_SCROLLABLE; + var isHorizontal = orientation === HORIZONTAL_ORIENTATION; + var calendarMonthWidth = getCalendarMonthWidth(daySize, horizontalMonthPadding); + var width = isVertical || isVerticalScrollable ? calendarMonthWidth : (numberOfMonths + 2) * calendarMonthWidth; + var transformType = isVertical || isVerticalScrollable ? 'translateY' : 'translateX'; + var transformValue = "".concat(transformType, "(").concat(translationValue, "px)"); + return /*#__PURE__*/React.createElement("div", _extends({}, css(styles.CalendarMonthGrid, isHorizontal && styles.CalendarMonthGrid__horizontal, isVertical && styles.CalendarMonthGrid__vertical, isVerticalScrollable && styles.CalendarMonthGrid__vertical_scrollable, isAnimating && styles.CalendarMonthGrid__animating, isAnimating && transitionDuration && { + transition: "transform ".concat(transitionDuration, "ms ease-in-out 0.1s") + }, _objectSpread(_objectSpread({}, getTransformStyles(transformValue)), {}, { + width: width + })), { + ref: this.setContainerRef, + onTransitionEnd: onMonthTransitionEnd + }), months.map(function (month, i) { + var isVisible = i >= firstVisibleMonthIndex && i < firstVisibleMonthIndex + numberOfMonths; + var hideForAnimation = i === 0 && !isVisible; + var showForAnimation = i === 0 && isAnimating && isVisible; + var monthString = toISOMonthString(month); + return /*#__PURE__*/React.createElement("div", _extends({ + key: monthString + }, css(isHorizontal && styles.CalendarMonthGrid_month__horizontal, hideForAnimation && styles.CalendarMonthGrid_month__hideForAnimation, showForAnimation && !isVertical && !isRTL && { + position: 'absolute', + left: -calendarMonthWidth + }, showForAnimation && !isVertical && isRTL && { + position: 'absolute', + right: 0 + }, showForAnimation && isVertical && { + position: 'absolute', + top: -translationValue + }, !isVisible && !isAnimating && styles.CalendarMonthGrid_month__hidden)), /*#__PURE__*/React.createElement(CalendarMonth, { + month: month, + isVisible: isVisible, + enableOutsideDays: enableOutsideDays, + modifiers: modifiers[monthString], + monthFormat: monthFormat, + orientation: orientation, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onDayClick: onDayClick, + onMonthSelect: _this3.onMonthSelect, + onYearSelect: _this3.onYearSelect, + renderMonthText: renderMonthText, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderMonthElement: renderMonthElement, + firstDayOfWeek: firstDayOfWeek, + daySize: daySize, + focusedDate: isVisible ? focusedDate : null, + isFocused: isFocused, + phrases: phrases, + setMonthTitleHeight: setMonthTitleHeight, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + })); + })); + }; + + return CalendarMonthGrid; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +CalendarMonthGrid.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarMonthGrid.defaultProps = defaultProps; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + spacing = _ref3$reactDates.spacing, + zIndex = _ref3$reactDates.zIndex; + return { + CalendarMonthGrid: { + background: color.background, + textAlign: noflip('left'), + zIndex: zIndex + }, + CalendarMonthGrid__animating: { + zIndex: zIndex + 1 + }, + CalendarMonthGrid__horizontal: { + position: 'absolute', + left: noflip(spacing.dayPickerHorizontalPadding) + }, + CalendarMonthGrid__vertical: { + margin: '0 auto' + }, + CalendarMonthGrid__vertical_scrollable: { + margin: '0 auto' + }, + CalendarMonthGrid_month__horizontal: { + display: 'inline-block', + verticalAlign: 'top', + minHeight: '100%' + }, + CalendarMonthGrid_month__hideForAnimation: { + position: 'absolute', + zIndex: zIndex - 1, + opacity: 0, + pointerEvents: 'none' + }, + CalendarMonthGrid_month__hidden: { + visibility: 'hidden' + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(CalendarMonthGrid); \ No newline at end of file diff --git a/esm/components/CalendarWeek.js b/esm/components/CalendarWeek.js new file mode 100644 index 000000000..7bca374c7 --- /dev/null +++ b/esm/components/CalendarWeek.js @@ -0,0 +1,11 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps } from 'airbnb-prop-types'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps({ + children: PropTypes.node.isRequired +}) : {}; +export default function CalendarWeek(_ref) { + var children = _ref.children; + return /*#__PURE__*/React.createElement("tr", null, children); +} +CalendarWeek.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; \ No newline at end of file diff --git a/esm/components/ChevronDown.js b/esm/components/ChevronDown.js new file mode 100644 index 000000000..e89c38260 --- /dev/null +++ b/esm/components/ChevronDown.js @@ -0,0 +1,13 @@ +import React from "react"; + +var ChevronDown = function ChevronDown(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + d: "M968 289L514 741c-11 11-21 11-32 0L29 289c-4-5-6-11-6-16 0-13 10-23 23-23 6 0 11 2 15 7l437 436 438-436c4-5 9-7 16-7 6 0 11 2 16 7 9 10 9 21 0 32z" + })); +}; + +ChevronDown.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +export default ChevronDown; \ No newline at end of file diff --git a/esm/components/ChevronUp.js b/esm/components/ChevronUp.js new file mode 100644 index 000000000..66f9e3b2c --- /dev/null +++ b/esm/components/ChevronUp.js @@ -0,0 +1,13 @@ +import React from "react"; + +var ChevronUp = function ChevronUp(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + d: "M32 713l453-453c11-11 21-11 32 0l453 453c5 5 7 10 7 16 0 13-10 23-22 23-7 0-12-2-16-7L501 309 64 745c-4 5-9 7-15 7-7 0-12-2-17-7-9-11-9-21 0-32z" + })); +}; + +ChevronUp.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +export default ChevronUp; \ No newline at end of file diff --git a/esm/components/CloseButton.js b/esm/components/CloseButton.js new file mode 100644 index 000000000..1b39d2e09 --- /dev/null +++ b/esm/components/CloseButton.js @@ -0,0 +1,14 @@ +import React from "react"; + +var CloseButton = function CloseButton(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + fillRule: "evenodd", + d: "M11.53.47a.75.75 0 0 0-1.061 0l-4.47 4.47L1.529.47A.75.75 0 1 0 .468 1.531l4.47 4.47-4.47 4.47a.75.75 0 1 0 1.061 1.061l4.47-4.47 4.47 4.47a.75.75 0 1 0 1.061-1.061l-4.47-4.47 4.47-4.47a.75.75 0 0 0 0-1.061z" + })); +}; + +CloseButton.defaultProps = { + focusable: "false", + viewBox: "0 0 12 12" +}; +export default CloseButton; \ No newline at end of file diff --git a/esm/components/CustomizableCalendarDay.js b/esm/components/CustomizableCalendarDay.js new file mode 100644 index 000000000..a678b79a8 --- /dev/null +++ b/esm/components/CustomizableCalendarDay.js @@ -0,0 +1,366 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, nonNegativeInteger, or } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import moment from 'moment'; +import raf from 'raf'; +import { CalendarDayPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import getCalendarDaySettings from '../utils/getCalendarDaySettings'; +import { DAY_SIZE } from '../constants'; +import DefaultTheme from '../theme/DefaultTheme'; +var color = DefaultTheme.reactDates.color; + +function getStyles(stylesObj, isHovered) { + if (!stylesObj) return null; + var hover = stylesObj.hover; + + if (isHovered && hover) { + return hover; + } + + return stylesObj; +} + +var DayStyleShape = process.env.NODE_ENV !== "production" ? PropTypes.shape({ + background: PropTypes.string, + border: or([PropTypes.string, PropTypes.number]), + color: PropTypes.string, + hover: PropTypes.shape({ + background: PropTypes.string, + border: or([PropTypes.string, PropTypes.number]), + color: PropTypes.string + }) +}) : {}; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + day: momentPropTypes.momentObj, + daySize: nonNegativeInteger, + isOutsideDay: PropTypes.bool, + modifiers: PropTypes.instanceOf(Set), + isFocused: PropTypes.bool, + tabIndex: PropTypes.oneOf([0, -1]), + onDayClick: PropTypes.func, + onDayMouseEnter: PropTypes.func, + onDayMouseLeave: PropTypes.func, + renderDayContents: PropTypes.func, + ariaLabelFormat: PropTypes.string, + // style overrides + defaultStyles: DayStyleShape, + outsideStyles: DayStyleShape, + todayStyles: DayStyleShape, + firstDayOfWeekStyles: DayStyleShape, + lastDayOfWeekStyles: DayStyleShape, + highlightedCalendarStyles: DayStyleShape, + blockedMinNightsStyles: DayStyleShape, + blockedCalendarStyles: DayStyleShape, + blockedOutOfRangeStyles: DayStyleShape, + hoveredSpanStyles: DayStyleShape, + selectedSpanStyles: DayStyleShape, + lastInRangeStyles: DayStyleShape, + selectedStyles: DayStyleShape, + selectedStartStyles: DayStyleShape, + selectedEndStyles: DayStyleShape, + afterHoveredStartStyles: DayStyleShape, + hoveredStartFirstPossibleEndStyles: DayStyleShape, + hoveredStartBlockedMinNightsStyles: DayStyleShape, + // internationalization + phrases: PropTypes.shape(getPhrasePropTypes(CalendarDayPhrases)) +})) : {}; +export var defaultStyles = { + border: "1px solid ".concat(color.core.borderLight), + color: color.text, + background: color.background, + hover: { + background: color.core.borderLight, + border: "1px solid ".concat(color.core.borderLight), + color: 'inherit' + } +}; +export var outsideStyles = { + background: color.outside.backgroundColor, + border: 0, + color: color.outside.color +}; +export var highlightedCalendarStyles = { + background: color.highlighted.backgroundColor, + color: color.highlighted.color, + hover: { + background: color.highlighted.backgroundColor_hover, + color: color.highlighted.color_active + } +}; +export var blockedMinNightsStyles = { + background: color.minimumNights.backgroundColor, + border: "1px solid ".concat(color.minimumNights.borderColor), + color: color.minimumNights.color, + hover: { + background: color.minimumNights.backgroundColor_hover, + color: color.minimumNights.color_active + } +}; +export var blockedCalendarStyles = { + background: color.blocked_calendar.backgroundColor, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color, + hover: { + background: color.blocked_calendar.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + } +}; +export var blockedOutOfRangeStyles = { + background: color.blocked_out_of_range.backgroundColor, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color, + hover: { + background: color.blocked_out_of_range.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + } +}; +export var hoveredSpanStyles = { + background: color.hoveredSpan.backgroundColor, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color, + hover: { + background: color.hoveredSpan.backgroundColor_hover, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + } +}; +export var selectedSpanStyles = { + background: color.selectedSpan.backgroundColor, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color, + hover: { + background: color.selectedSpan.backgroundColor_hover, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + } +}; +export var lastInRangeStyles = {}; +export var selectedStyles = { + background: color.selected.backgroundColor, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color, + hover: { + background: color.selected.backgroundColor_hover, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + } +}; +var defaultProps = { + day: moment(), + daySize: DAY_SIZE, + isOutsideDay: false, + modifiers: new Set(), + isFocused: false, + tabIndex: -1, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + renderDayContents: null, + ariaLabelFormat: 'dddd, LL', + // style defaults + defaultStyles: defaultStyles, + outsideStyles: outsideStyles, + todayStyles: {}, + highlightedCalendarStyles: highlightedCalendarStyles, + blockedMinNightsStyles: blockedMinNightsStyles, + blockedCalendarStyles: blockedCalendarStyles, + blockedOutOfRangeStyles: blockedOutOfRangeStyles, + hoveredSpanStyles: hoveredSpanStyles, + selectedSpanStyles: selectedSpanStyles, + lastInRangeStyles: lastInRangeStyles, + selectedStyles: selectedStyles, + selectedStartStyles: {}, + selectedEndStyles: {}, + afterHoveredStartStyles: {}, + firstDayOfWeekStyles: {}, + lastDayOfWeekStyles: {}, + hoveredStartFirstPossibleEndStyles: {}, + hoveredStartBlockedMinNightsStyles: {}, + // internationalization + phrases: CalendarDayPhrases +}; + +var CustomizableCalendarDay = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(CustomizableCalendarDay, _ref2); + + var _proto = CustomizableCalendarDay.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function CustomizableCalendarDay() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + _this.state = { + isHovered: false + }; + _this.setButtonRef = _this.setButtonRef.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this2 = this; + + var _this$props = this.props, + isFocused = _this$props.isFocused, + tabIndex = _this$props.tabIndex; + + if (tabIndex === 0) { + if (isFocused || tabIndex !== prevProps.tabIndex) { + raf(function () { + if (_this2.buttonRef) { + _this2.buttonRef.focus(); + } + }); + } + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var onDayClick = this.props.onDayClick; + onDayClick(day, e); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day, e) { + var onDayMouseEnter = this.props.onDayMouseEnter; + this.setState({ + isHovered: true + }); + onDayMouseEnter(day, e); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day, e) { + var onDayMouseLeave = this.props.onDayMouseLeave; + this.setState({ + isHovered: false + }); + onDayMouseLeave(day, e); + }; + + _proto.onKeyDown = function onKeyDown(day, e) { + var onDayClick = this.props.onDayClick; + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onDayClick(day, e); + } + }; + + _proto.setButtonRef = function setButtonRef(ref) { + this.buttonRef = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props2 = this.props, + day = _this$props2.day, + ariaLabelFormat = _this$props2.ariaLabelFormat, + daySize = _this$props2.daySize, + isOutsideDay = _this$props2.isOutsideDay, + modifiers = _this$props2.modifiers, + tabIndex = _this$props2.tabIndex, + renderDayContents = _this$props2.renderDayContents, + css = _this$props2.css, + styles = _this$props2.styles, + phrases = _this$props2.phrases, + defaultStylesWithHover = _this$props2.defaultStyles, + outsideStylesWithHover = _this$props2.outsideStyles, + todayStylesWithHover = _this$props2.todayStyles, + firstDayOfWeekStylesWithHover = _this$props2.firstDayOfWeekStyles, + lastDayOfWeekStylesWithHover = _this$props2.lastDayOfWeekStyles, + highlightedCalendarStylesWithHover = _this$props2.highlightedCalendarStyles, + blockedMinNightsStylesWithHover = _this$props2.blockedMinNightsStyles, + blockedCalendarStylesWithHover = _this$props2.blockedCalendarStyles, + blockedOutOfRangeStylesWithHover = _this$props2.blockedOutOfRangeStyles, + hoveredSpanStylesWithHover = _this$props2.hoveredSpanStyles, + selectedSpanStylesWithHover = _this$props2.selectedSpanStyles, + lastInRangeStylesWithHover = _this$props2.lastInRangeStyles, + selectedStylesWithHover = _this$props2.selectedStyles, + selectedStartStylesWithHover = _this$props2.selectedStartStyles, + selectedEndStylesWithHover = _this$props2.selectedEndStyles, + afterHoveredStartStylesWithHover = _this$props2.afterHoveredStartStyles, + hoveredStartFirstPossibleEndStylesWithHover = _this$props2.hoveredStartFirstPossibleEndStyles, + hoveredStartBlockedMinNightsStylesWithHover = _this$props2.hoveredStartBlockedMinNightsStyles; + var isHovered = this.state.isHovered; + if (!day) return /*#__PURE__*/React.createElement("td", null); + + var _getCalendarDaySettin = getCalendarDaySettings(day, ariaLabelFormat, daySize, modifiers, phrases), + daySizeStyles = _getCalendarDaySettin.daySizeStyles, + useDefaultCursor = _getCalendarDaySettin.useDefaultCursor, + selected = _getCalendarDaySettin.selected, + hoveredSpan = _getCalendarDaySettin.hoveredSpan, + isOutsideRange = _getCalendarDaySettin.isOutsideRange, + ariaLabel = _getCalendarDaySettin.ariaLabel; + + return /*#__PURE__*/React.createElement("td", _extends({}, css(styles.CalendarDay, useDefaultCursor && styles.CalendarDay__defaultCursor, daySizeStyles, getStyles(defaultStylesWithHover, isHovered), isOutsideDay && getStyles(outsideStylesWithHover, isHovered), modifiers.has('today') && getStyles(todayStylesWithHover, isHovered), modifiers.has('first-day-of-week') && getStyles(firstDayOfWeekStylesWithHover, isHovered), modifiers.has('last-day-of-week') && getStyles(lastDayOfWeekStylesWithHover, isHovered), modifiers.has('hovered-start-first-possible-end') && getStyles(hoveredStartFirstPossibleEndStylesWithHover, isHovered), modifiers.has('hovered-start-blocked-minimum-nights') && getStyles(hoveredStartBlockedMinNightsStylesWithHover, isHovered), modifiers.has('highlighted-calendar') && getStyles(highlightedCalendarStylesWithHover, isHovered), modifiers.has('blocked-minimum-nights') && getStyles(blockedMinNightsStylesWithHover, isHovered), modifiers.has('blocked-calendar') && getStyles(blockedCalendarStylesWithHover, isHovered), hoveredSpan && getStyles(hoveredSpanStylesWithHover, isHovered), modifiers.has('after-hovered-start') && getStyles(afterHoveredStartStylesWithHover, isHovered), modifiers.has('selected-span') && getStyles(selectedSpanStylesWithHover, isHovered), modifiers.has('last-in-range') && getStyles(lastInRangeStylesWithHover, isHovered), selected && getStyles(selectedStylesWithHover, isHovered), modifiers.has('selected-start') && getStyles(selectedStartStylesWithHover, isHovered), modifiers.has('selected-end') && getStyles(selectedEndStylesWithHover, isHovered), isOutsideRange && getStyles(blockedOutOfRangeStylesWithHover, isHovered)), { + role: "button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role + , + ref: this.setButtonRef, + "aria-disabled": modifiers.has('blocked'), + "aria-label": ariaLabel, + onMouseEnter: function onMouseEnter(e) { + _this3.onDayMouseEnter(day, e); + }, + onMouseLeave: function onMouseLeave(e) { + _this3.onDayMouseLeave(day, e); + }, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + }, + onClick: function onClick(e) { + _this3.onDayClick(day, e); + }, + onKeyDown: function onKeyDown(e) { + _this3.onKeyDown(day, e); + }, + tabIndex: tabIndex + }), renderDayContents ? renderDayContents(day, modifiers) : day.format('D')); + }; + + return CustomizableCalendarDay; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +CustomizableCalendarDay.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CustomizableCalendarDay.defaultProps = defaultProps; +export { CustomizableCalendarDay as PureCustomizableCalendarDay }; +export default withStyles(function (_ref3) { + var font = _ref3.reactDates.font; + return { + CalendarDay: { + boxSizing: 'border-box', + cursor: 'pointer', + fontSize: font.size, + textAlign: 'center', + ':active': { + outline: 0 + } + }, + CalendarDay__defaultCursor: { + cursor: 'default' + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(CustomizableCalendarDay); \ No newline at end of file diff --git a/esm/components/DateInput.js b/esm/components/DateInput.js new file mode 100644 index 000000000..a6e77a7f1 --- /dev/null +++ b/esm/components/DateInput.js @@ -0,0 +1,358 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import throttle from 'lodash/throttle'; +import isTouchDevice from 'is-touch-device'; +import noflip from '../utils/noflip'; +import getInputHeight from '../utils/getInputHeight'; +import openDirectionShape from '../shapes/OpenDirectionShape'; +import { OPEN_DOWN, OPEN_UP, FANG_HEIGHT_PX, FANG_WIDTH_PX, DEFAULT_VERTICAL_SPACING, MODIFIER_KEY_NAMES } from '../constants'; +var FANG_PATH_TOP = "M0,".concat(FANG_HEIGHT_PX, " ").concat(FANG_WIDTH_PX, ",").concat(FANG_HEIGHT_PX, " ").concat(FANG_WIDTH_PX / 2, ",0z"); +var FANG_STROKE_TOP = "M0,".concat(FANG_HEIGHT_PX, " ").concat(FANG_WIDTH_PX / 2, ",0 ").concat(FANG_WIDTH_PX, ",").concat(FANG_HEIGHT_PX); +var FANG_PATH_BOTTOM = "M0,0 ".concat(FANG_WIDTH_PX, ",0 ").concat(FANG_WIDTH_PX / 2, ",").concat(FANG_HEIGHT_PX, "z"); +var FANG_STROKE_BOTTOM = "M0,0 ".concat(FANG_WIDTH_PX / 2, ",").concat(FANG_HEIGHT_PX, " ").concat(FANG_WIDTH_PX, ",0"); +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + id: PropTypes.string.isRequired, + placeholder: PropTypes.string, + displayValue: PropTypes.string, + ariaLabel: PropTypes.string, + autoComplete: PropTypes.string, + titleText: PropTypes.string, + screenReaderMessage: PropTypes.string, + focused: PropTypes.bool, + disabled: PropTypes.bool, + required: PropTypes.bool, + readOnly: PropTypes.bool, + openDirection: openDirectionShape, + showCaret: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + small: PropTypes.bool, + block: PropTypes.bool, + regular: PropTypes.bool, + onChange: PropTypes.func, + onFocus: PropTypes.func, + onKeyDownShiftTab: PropTypes.func, + onKeyDownTab: PropTypes.func, + onKeyDownArrowDown: PropTypes.func, + onKeyDownQuestionMark: PropTypes.func, + // accessibility + isFocused: PropTypes.bool // describes actual DOM focus + +})) : {}; +var defaultProps = { + placeholder: 'Select Date', + displayValue: '', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + screenReaderMessage: '', + focused: false, + disabled: false, + required: false, + readOnly: null, + openDirection: OPEN_DOWN, + showCaret: false, + verticalSpacing: DEFAULT_VERTICAL_SPACING, + small: false, + block: false, + regular: false, + onChange: function onChange() {}, + onFocus: function onFocus() {}, + onKeyDownShiftTab: function onKeyDownShiftTab() {}, + onKeyDownTab: function onKeyDownTab() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + // accessibility + isFocused: false +}; + +var DateInput = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DateInput, _ref2); + + var _proto = DateInput.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DateInput(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + dateString: '', + isTouchDevice: false + }; + _this.onChange = _this.onChange.bind(_assertThisInitialized(_this)); + _this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this)); + _this.setInputRef = _this.setInputRef.bind(_assertThisInitialized(_this)); + _this.throttledKeyDown = throttle(_this.onFinalKeyDown, 300, { + trailing: false + }); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.setState({ + isTouchDevice: isTouchDevice() + }); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var dateString = this.state.dateString; + + if (dateString && nextProps.displayValue) { + this.setState({ + dateString: '' + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this$props = this.props, + focused = _this$props.focused, + isFocused = _this$props.isFocused; + if (prevProps.focused === focused && prevProps.isFocused === isFocused) return; + + if (focused && isFocused) { + this.inputRef.focus(); + } + }; + + _proto.onChange = function onChange(e) { + var _this$props2 = this.props, + onChange = _this$props2.onChange, + onKeyDownQuestionMark = _this$props2.onKeyDownQuestionMark; + var dateString = e.target.value; // In Safari, onKeyDown does not consistently fire ahead of onChange. As a result, we need to + // special case the `?` key so that it always triggers the appropriate callback, instead of + // modifying the input value + + if (dateString[dateString.length - 1] === '?') { + onKeyDownQuestionMark(e); + } else { + this.setState({ + dateString: dateString + }, function () { + return onChange(dateString); + }); + } + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + + if (!MODIFIER_KEY_NAMES.has(e.key)) { + this.throttledKeyDown(e); + } + }; + + _proto.onFinalKeyDown = function onFinalKeyDown(e) { + var _this$props3 = this.props, + onKeyDownShiftTab = _this$props3.onKeyDownShiftTab, + onKeyDownTab = _this$props3.onKeyDownTab, + onKeyDownArrowDown = _this$props3.onKeyDownArrowDown, + onKeyDownQuestionMark = _this$props3.onKeyDownQuestionMark; + var key = e.key; + + if (key === 'Tab') { + if (e.shiftKey) { + onKeyDownShiftTab(e); + } else { + onKeyDownTab(e); + } + } else if (key === 'ArrowDown') { + onKeyDownArrowDown(e); + } else if (key === '?') { + e.preventDefault(); + onKeyDownQuestionMark(e); + } + }; + + _proto.setInputRef = function setInputRef(ref) { + this.inputRef = ref; + }; + + _proto.render = function render() { + var _this$state = this.state, + dateString = _this$state.dateString, + isTouch = _this$state.isTouchDevice; + var _this$props4 = this.props, + id = _this$props4.id, + placeholder = _this$props4.placeholder, + ariaLabel = _this$props4.ariaLabel, + autoComplete = _this$props4.autoComplete, + titleText = _this$props4.titleText, + displayValue = _this$props4.displayValue, + screenReaderMessage = _this$props4.screenReaderMessage, + focused = _this$props4.focused, + showCaret = _this$props4.showCaret, + onFocus = _this$props4.onFocus, + disabled = _this$props4.disabled, + required = _this$props4.required, + readOnly = _this$props4.readOnly, + openDirection = _this$props4.openDirection, + verticalSpacing = _this$props4.verticalSpacing, + small = _this$props4.small, + regular = _this$props4.regular, + block = _this$props4.block, + css = _this$props4.css, + styles = _this$props4.styles, + reactDates = _this$props4.theme.reactDates; + var value = dateString || displayValue || ''; + var screenReaderMessageId = "DateInput__screen-reader-message-".concat(id); + var withFang = showCaret && focused; + var inputHeight = getInputHeight(reactDates, small); + return /*#__PURE__*/React.createElement("div", css(styles.DateInput, small && styles.DateInput__small, block && styles.DateInput__block, withFang && styles.DateInput__withFang, disabled && styles.DateInput__disabled, withFang && openDirection === OPEN_DOWN && styles.DateInput__openDown, withFang && openDirection === OPEN_UP && styles.DateInput__openUp), /*#__PURE__*/React.createElement("input", _extends({}, css(styles.DateInput_input, small && styles.DateInput_input__small, regular && styles.DateInput_input__regular, readOnly && styles.DateInput_input__readOnly, focused && styles.DateInput_input__focused, disabled && styles.DateInput_input__disabled), { + "aria-label": ariaLabel === undefined ? placeholder : ariaLabel, + title: titleText, + type: "text", + id: id, + name: id, + ref: this.setInputRef, + value: value, + onChange: this.onChange, + onKeyDown: this.onKeyDown, + onFocus: onFocus, + placeholder: placeholder, + autoComplete: autoComplete, + disabled: disabled, + readOnly: typeof readOnly === 'boolean' ? readOnly : isTouch, + required: required, + "aria-describedby": screenReaderMessage && screenReaderMessageId + })), withFang && /*#__PURE__*/React.createElement("svg", _extends({ + role: "presentation", + focusable: "false" + }, css(styles.DateInput_fang, openDirection === OPEN_DOWN && { + top: inputHeight + verticalSpacing - FANG_HEIGHT_PX - 1 + }, openDirection === OPEN_UP && { + bottom: inputHeight + verticalSpacing - FANG_HEIGHT_PX - 1 + })), /*#__PURE__*/React.createElement("path", _extends({}, css(styles.DateInput_fangShape), { + d: openDirection === OPEN_DOWN ? FANG_PATH_TOP : FANG_PATH_BOTTOM + })), /*#__PURE__*/React.createElement("path", _extends({}, css(styles.DateInput_fangStroke), { + d: openDirection === OPEN_DOWN ? FANG_STROKE_TOP : FANG_STROKE_BOTTOM + }))), screenReaderMessage && /*#__PURE__*/React.createElement("p", _extends({}, css(styles.DateInput_screenReaderMessage), { + id: screenReaderMessageId + }), screenReaderMessage)); + }; + + return DateInput; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +DateInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateInput.defaultProps = defaultProps; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + border = _ref3$reactDates.border, + color = _ref3$reactDates.color, + sizing = _ref3$reactDates.sizing, + spacing = _ref3$reactDates.spacing, + font = _ref3$reactDates.font, + zIndex = _ref3$reactDates.zIndex; + return { + DateInput: { + margin: 0, + padding: spacing.inputPadding, + background: color.background, + position: 'relative', + display: 'inline-block', + width: sizing.inputWidth, + verticalAlign: 'middle' + }, + DateInput__small: { + width: sizing.inputWidth_small + }, + DateInput__block: { + width: '100%' + }, + DateInput__disabled: { + background: color.disabled, + color: color.textDisabled + }, + DateInput_input: { + fontWeight: font.input.weight, + fontSize: font.input.size, + lineHeight: font.input.lineHeight, + color: color.text, + backgroundColor: color.background, + width: '100%', + padding: "".concat(spacing.displayTextPaddingVertical, "px ").concat(spacing.displayTextPaddingHorizontal, "px"), + paddingTop: spacing.displayTextPaddingTop, + paddingBottom: spacing.displayTextPaddingBottom, + paddingLeft: noflip(spacing.displayTextPaddingLeft), + paddingRight: noflip(spacing.displayTextPaddingRight), + border: border.input.border, + borderTop: border.input.borderTop, + borderRight: noflip(border.input.borderRight), + borderBottom: border.input.borderBottom, + borderLeft: noflip(border.input.borderLeft), + borderRadius: border.input.borderRadius + }, + DateInput_input__small: { + fontSize: font.input.size_small, + lineHeight: font.input.lineHeight_small, + letterSpacing: font.input.letterSpacing_small, + padding: "".concat(spacing.displayTextPaddingVertical_small, "px ").concat(spacing.displayTextPaddingHorizontal_small, "px"), + paddingTop: spacing.displayTextPaddingTop_small, + paddingBottom: spacing.displayTextPaddingBottom_small, + paddingLeft: noflip(spacing.displayTextPaddingLeft_small), + paddingRight: noflip(spacing.displayTextPaddingRight_small) + }, + DateInput_input__regular: { + fontWeight: 'inherit' + }, + DateInput_input__readOnly: { + userSelect: 'none' + }, + DateInput_input__focused: { + outline: border.input.outlineFocused, + background: color.backgroundFocused, + border: border.input.borderFocused, + borderTop: border.input.borderTopFocused, + borderRight: noflip(border.input.borderRightFocused), + borderBottom: border.input.borderBottomFocused, + borderLeft: noflip(border.input.borderLeftFocused) + }, + DateInput_input__disabled: { + background: color.disabled, + fontStyle: font.input.styleDisabled + }, + DateInput_screenReaderMessage: { + border: 0, + clip: 'rect(0, 0, 0, 0)', + height: 1, + margin: -1, + overflow: 'hidden', + padding: 0, + position: 'absolute', + width: 1 + }, + DateInput_fang: { + position: 'absolute', + width: FANG_WIDTH_PX, + height: FANG_HEIGHT_PX, + left: 22, + // TODO: should be noflip wrapped and handled by an isRTL prop + zIndex: zIndex + 2 + }, + DateInput_fangShape: { + fill: color.background + }, + DateInput_fangStroke: { + stroke: color.core.border, + fill: 'transparent' + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DateInput); \ No newline at end of file diff --git a/esm/components/DateRangePicker.js b/esm/components/DateRangePicker.js new file mode 100644 index 000000000..83c7be354 --- /dev/null +++ b/esm/components/DateRangePicker.js @@ -0,0 +1,693 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import moment from 'moment'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { Portal } from 'react-portal'; +import { forbidExtraProps } from 'airbnb-prop-types'; +import { addEventListener } from 'consolidated-events'; +import isTouchDevice from 'is-touch-device'; +import OutsideClickHandler from 'react-outside-click-handler'; +import { darken } from 'color2k'; +import DateRangePickerShape from '../shapes/DateRangePickerShape'; +import { DateRangePickerPhrases } from '../defaultPhrases'; +import getResponsiveContainerStyles from '../utils/getResponsiveContainerStyles'; +import getDetachedContainerStyles from '../utils/getDetachedContainerStyles'; +import getInputHeight from '../utils/getInputHeight'; +import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay'; +import _disableScroll from '../utils/disableScroll'; +import noflip from '../utils/noflip'; +import DateRangePickerInputController from './DateRangePickerInputController'; +import DayPickerRangeController from './DayPickerRangeController'; +import CloseButton from './CloseButton'; +import { START_DATE, END_DATE, HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, ANCHOR_LEFT, ANCHOR_RIGHT, OPEN_DOWN, OPEN_UP, DAY_SIZE, ICON_BEFORE_POSITION, INFO_POSITION_BOTTOM, FANG_HEIGHT_PX, DEFAULT_VERTICAL_SPACING, NAV_POSITION_TOP } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), DateRangePickerShape)) : {}; +var defaultProps = { + // required props for a functional interactive DateRangePicker + startDate: null, + endDate: null, + focusedInput: null, + // input related props + startDatePlaceholderText: 'Start Date', + endDatePlaceholderText: 'End Date', + startDateAriaLabel: undefined, + endDateAriaLabel: undefined, + startDateTitleText: undefined, + endDateTitleText: undefined, + startDateOffset: undefined, + endDateOffset: undefined, + disabled: false, + required: false, + readOnly: false, + screenReaderInputMessage: '', + showClearDates: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + keepFocusOnInput: false, + // calendar presentation and interaction related props + renderMonthText: null, + renderWeekHeaderElement: null, + orientation: HORIZONTAL_ORIENTATION, + anchorDirection: ANCHOR_LEFT, + openDirection: OPEN_DOWN, + horizontalMargin: 0, + withPortal: false, + withFullScreenPortal: false, + appendToBody: false, + disableScroll: false, + initialVisibleMonth: null, + numberOfMonths: 2, + keepOpenOnDateSelect: false, + reopenPickerOnClearDates: false, + renderCalendarInfo: null, + calendarInfoPosition: INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: DAY_SIZE, + isRTL: false, + firstDayOfWeek: null, + verticalHeight: null, + transitionDuration: undefined, + verticalSpacing: DEFAULT_VERTICAL_SPACING, + autoComplete: 'off', + horizontalMonthPadding: undefined, + // navigation related props + dayPickerNavigationInlineStyles: null, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onClose: function onClose() {}, + // day presentation and interaction related props + renderCalendarDay: undefined, + renderDayContents: null, + renderMonthElement: null, + minimumNights: 1, + enableOutsideDays: false, + isDayBlocked: function isDayBlocked() { + return false; + }, + isOutsideRange: function isOutsideRange(day) { + return !isInclusivelyAfterDay(day, moment()); + }, + isDayHighlighted: function isDayHighlighted() { + return false; + }, + minDate: undefined, + maxDate: undefined, + // internationalization + displayFormat: function displayFormat() { + return moment.localeData().longDateFormat('L'); + }, + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: DateRangePickerPhrases, + dayAriaLabelFormat: undefined +}; + +var DateRangePicker = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DateRangePicker, _ref2); + + var _proto = DateRangePicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DateRangePicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + dayPickerContainerStyles: {}, + isDateRangePickerInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }; + _this.isTouchDevice = false; + _this.onOutsideClick = _this.onOutsideClick.bind(_assertThisInitialized(_this)); + _this.onDateRangePickerInputFocus = _this.onDateRangePickerInputFocus.bind(_assertThisInitialized(_this)); + _this.onDayPickerFocus = _this.onDayPickerFocus.bind(_assertThisInitialized(_this)); + _this.onDayPickerFocusOut = _this.onDayPickerFocusOut.bind(_assertThisInitialized(_this)); + _this.onDayPickerBlur = _this.onDayPickerBlur.bind(_assertThisInitialized(_this)); + _this.showKeyboardShortcutsPanel = _this.showKeyboardShortcutsPanel.bind(_assertThisInitialized(_this)); + _this.responsivizePickerPosition = _this.responsivizePickerPosition.bind(_assertThisInitialized(_this)); + _this.disableScroll = _this.disableScroll.bind(_assertThisInitialized(_this)); + _this.setDayPickerContainerRef = _this.setDayPickerContainerRef.bind(_assertThisInitialized(_this)); + _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.removeEventListener = addEventListener(window, 'resize', this.responsivizePickerPosition, { + passive: true + }); + this.responsivizePickerPosition(); + this.disableScroll(); + var focusedInput = this.props.focusedInput; + + if (focusedInput) { + this.setState({ + isDateRangePickerInputFocused: true + }); + } + + this.isTouchDevice = isTouchDevice(); + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var focusedInput = this.props.focusedInput; + + if (!prevProps.focusedInput && focusedInput && this.isOpened()) { + // The date picker just changed from being closed to being open. + this.responsivizePickerPosition(); + this.disableScroll(); + } else if (prevProps.focusedInput && !focusedInput && !this.isOpened()) { + // The date picker just changed from being open to being closed. + if (this.enableScroll) this.enableScroll(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + this.removeDayPickerEventListeners(); + if (this.removeEventListener) this.removeEventListener(); + if (this.enableScroll) this.enableScroll(); + }; + + _proto.onOutsideClick = function onOutsideClick(event) { + var _this$props = this.props, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose, + startDate = _this$props.startDate, + endDate = _this$props.endDate, + appendToBody = _this$props.appendToBody; + if (!this.isOpened()) return; + if (appendToBody && this.dayPickerContainer.contains(event.target)) return; + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + }; + + _proto.onDateRangePickerInputFocus = function onDateRangePickerInputFocus(focusedInput) { + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + readOnly = _this$props2.readOnly, + withPortal = _this$props2.withPortal, + withFullScreenPortal = _this$props2.withFullScreenPortal, + keepFocusOnInput = _this$props2.keepFocusOnInput; + + if (focusedInput) { + var withAnyPortal = withPortal || withFullScreenPortal; + var moveFocusToDayPicker = withAnyPortal || readOnly && !keepFocusOnInput || this.isTouchDevice && !keepFocusOnInput; + + if (moveFocusToDayPicker) { + this.onDayPickerFocus(); + } else { + this.onDayPickerBlur(); + } + } + + onFocusChange(focusedInput); + }; + + _proto.onDayPickerFocus = function onDayPickerFocus() { + var _this$props3 = this.props, + focusedInput = _this$props3.focusedInput, + onFocusChange = _this$props3.onFocusChange; + if (!focusedInput) onFocusChange(START_DATE); + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: false + }); + }; + + _proto.onDayPickerFocusOut = function onDayPickerFocusOut(event) { + // In cases where **relatedTarget** is not null, it points to the right + // element here. However, in cases where it is null (such as clicking on a + // specific day) or it is **document.body** (IE11), the appropriate value is **event.target**. + // + // We handle both situations here by using the ` || ` operator to fallback + // to *event.target** when **relatedTarget** is not provided. + var relatedTarget = event.relatedTarget === document.body ? event.target : event.relatedTarget || event.target; + if (this.dayPickerContainer.contains(relatedTarget)) return; + this.onOutsideClick(event); + }; + + _proto.onDayPickerBlur = function onDayPickerBlur() { + this.setState({ + isDateRangePickerInputFocused: true, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + }; + + _proto.setDayPickerContainerRef = function setDayPickerContainerRef(ref) { + if (ref === this.dayPickerContainer) return; + if (this.dayPickerContainer) this.removeDayPickerEventListeners(); + this.dayPickerContainer = ref; + if (!ref) return; + this.addDayPickerEventListeners(); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.addDayPickerEventListeners = function addDayPickerEventListeners() { + // NOTE: We are using a manual event listener here, because React doesn't + // provide FocusOut, while blur and keydown don't provide the information + // needed in order to know whether we have left focus or not. + // + // For reference, this issue is further described here: + // - https://github.com/facebook/react/issues/6410 + this.removeDayPickerFocusOut = addEventListener(this.dayPickerContainer, 'focusout', this.onDayPickerFocusOut); + }; + + _proto.removeDayPickerEventListeners = function removeDayPickerEventListeners() { + if (this.removeDayPickerFocusOut) this.removeDayPickerFocusOut(); + }; + + _proto.isOpened = function isOpened() { + var focusedInput = this.props.focusedInput; + return focusedInput === START_DATE || focusedInput === END_DATE; + }; + + _proto.disableScroll = function disableScroll() { + var _this$props4 = this.props, + appendToBody = _this$props4.appendToBody, + propDisableScroll = _this$props4.disableScroll; + if (!appendToBody && !propDisableScroll) return; + if (!this.isOpened()) return; // Disable scroll for every ancestor of this DateRangePicker up to the + // document level. This ensures the input and the picker never move. Other + // sibling elements or the picker itself can scroll. + + this.enableScroll = _disableScroll(this.container); + }; + + _proto.responsivizePickerPosition = function responsivizePickerPosition() { + // It's possible the portal props have been changed in response to window resizes + // So let's ensure we reset this back to the base state each time + var dayPickerContainerStyles = this.state.dayPickerContainerStyles; + + if (Object.keys(dayPickerContainerStyles).length > 0) { + this.setState({ + dayPickerContainerStyles: {} + }); + } + + if (!this.isOpened()) { + return; + } + + var _this$props5 = this.props, + openDirection = _this$props5.openDirection, + anchorDirection = _this$props5.anchorDirection, + horizontalMargin = _this$props5.horizontalMargin, + withPortal = _this$props5.withPortal, + withFullScreenPortal = _this$props5.withFullScreenPortal, + appendToBody = _this$props5.appendToBody; + var isAnchoredLeft = anchorDirection === ANCHOR_LEFT; + + if (!withPortal && !withFullScreenPortal) { + var containerRect = this.dayPickerContainer.getBoundingClientRect(); + var currentOffset = dayPickerContainerStyles[anchorDirection] || 0; + var containerEdge = isAnchoredLeft ? containerRect[ANCHOR_RIGHT] : containerRect[ANCHOR_LEFT]; + this.setState({ + dayPickerContainerStyles: _objectSpread(_objectSpread({}, getResponsiveContainerStyles(anchorDirection, currentOffset, containerEdge, horizontalMargin)), appendToBody && getDetachedContainerStyles(openDirection, anchorDirection, this.container)) + }); + } + }; + + _proto.showKeyboardShortcutsPanel = function showKeyboardShortcutsPanel() { + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: true + }); + }; + + _proto.maybeRenderDayPickerWithPortal = function maybeRenderDayPickerWithPortal() { + var _this$props6 = this.props, + withPortal = _this$props6.withPortal, + withFullScreenPortal = _this$props6.withFullScreenPortal, + appendToBody = _this$props6.appendToBody; + + if (!this.isOpened()) { + return null; + } + + if (withPortal || withFullScreenPortal || appendToBody) { + return /*#__PURE__*/React.createElement(Portal, null, this.renderDayPicker()); + } + + return this.renderDayPicker(); + }; + + _proto.renderDayPicker = function renderDayPicker() { + var _this$props7 = this.props, + anchorDirection = _this$props7.anchorDirection, + openDirection = _this$props7.openDirection, + isDayBlocked = _this$props7.isDayBlocked, + isDayHighlighted = _this$props7.isDayHighlighted, + isOutsideRange = _this$props7.isOutsideRange, + numberOfMonths = _this$props7.numberOfMonths, + orientation = _this$props7.orientation, + monthFormat = _this$props7.monthFormat, + renderMonthText = _this$props7.renderMonthText, + renderWeekHeaderElement = _this$props7.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props7.dayPickerNavigationInlineStyles, + navPosition = _this$props7.navPosition, + navPrev = _this$props7.navPrev, + navNext = _this$props7.navNext, + renderNavPrevButton = _this$props7.renderNavPrevButton, + renderNavNextButton = _this$props7.renderNavNextButton, + onPrevMonthClick = _this$props7.onPrevMonthClick, + onNextMonthClick = _this$props7.onNextMonthClick, + onDatesChange = _this$props7.onDatesChange, + onFocusChange = _this$props7.onFocusChange, + withPortal = _this$props7.withPortal, + withFullScreenPortal = _this$props7.withFullScreenPortal, + daySize = _this$props7.daySize, + enableOutsideDays = _this$props7.enableOutsideDays, + focusedInput = _this$props7.focusedInput, + startDate = _this$props7.startDate, + startDateOffset = _this$props7.startDateOffset, + endDate = _this$props7.endDate, + endDateOffset = _this$props7.endDateOffset, + minDate = _this$props7.minDate, + maxDate = _this$props7.maxDate, + minimumNights = _this$props7.minimumNights, + keepOpenOnDateSelect = _this$props7.keepOpenOnDateSelect, + renderCalendarDay = _this$props7.renderCalendarDay, + renderDayContents = _this$props7.renderDayContents, + renderCalendarInfo = _this$props7.renderCalendarInfo, + renderMonthElement = _this$props7.renderMonthElement, + calendarInfoPosition = _this$props7.calendarInfoPosition, + firstDayOfWeek = _this$props7.firstDayOfWeek, + initialVisibleMonth = _this$props7.initialVisibleMonth, + hideKeyboardShortcutsPanel = _this$props7.hideKeyboardShortcutsPanel, + customCloseIcon = _this$props7.customCloseIcon, + onClose = _this$props7.onClose, + phrases = _this$props7.phrases, + dayAriaLabelFormat = _this$props7.dayAriaLabelFormat, + isRTL = _this$props7.isRTL, + weekDayFormat = _this$props7.weekDayFormat, + css = _this$props7.css, + styles = _this$props7.styles, + verticalHeight = _this$props7.verticalHeight, + noBorder = _this$props7.noBorder, + transitionDuration = _this$props7.transitionDuration, + verticalSpacing = _this$props7.verticalSpacing, + horizontalMonthPadding = _this$props7.horizontalMonthPadding, + small = _this$props7.small, + disabled = _this$props7.disabled, + reactDates = _this$props7.theme.reactDates; + var _this$state = this.state, + dayPickerContainerStyles = _this$state.dayPickerContainerStyles, + isDayPickerFocused = _this$state.isDayPickerFocused, + showKeyboardShortcuts = _this$state.showKeyboardShortcuts; + var onOutsideClick = !withFullScreenPortal && withPortal ? this.onOutsideClick : undefined; + + var initialVisibleMonthThunk = initialVisibleMonth || function () { + return startDate || endDate || moment(); + }; + + var closeIcon = customCloseIcon || /*#__PURE__*/React.createElement(CloseButton, css(styles.DateRangePicker_closeButton_svg)); + var inputHeight = getInputHeight(reactDates, small); + var withAnyPortal = withPortal || withFullScreenPortal; + /* eslint-disable jsx-a11y/no-static-element-interactions */ + + /* eslint-disable jsx-a11y/click-events-have-key-events */ + + return /*#__PURE__*/React.createElement("div", _extends({ + key: "day-picker", + ref: this.setDayPickerContainerRef + }, css(styles.DateRangePicker_picker, anchorDirection === ANCHOR_LEFT && styles.DateRangePicker_picker__directionLeft, anchorDirection === ANCHOR_RIGHT && styles.DateRangePicker_picker__directionRight, orientation === HORIZONTAL_ORIENTATION && styles.DateRangePicker_picker__horizontal, orientation === VERTICAL_ORIENTATION && styles.DateRangePicker_picker__vertical, !withAnyPortal && openDirection === OPEN_DOWN && { + top: inputHeight + verticalSpacing + }, !withAnyPortal && openDirection === OPEN_UP && { + bottom: inputHeight + verticalSpacing + }, withAnyPortal && styles.DateRangePicker_picker__portal, withFullScreenPortal && styles.DateRangePicker_picker__fullScreenPortal, isRTL && styles.DateRangePicker_picker__rtl, dayPickerContainerStyles), { + onClick: onOutsideClick + }), /*#__PURE__*/React.createElement(DayPickerRangeController, { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + numberOfMonths: numberOfMonths, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + onDatesChange: onDatesChange, + onFocusChange: onFocusChange, + onClose: onClose, + focusedInput: focusedInput, + startDate: startDate, + startDateOffset: startDateOffset, + endDate: endDate, + endDateOffset: endDateOffset, + minDate: minDate, + maxDate: maxDate, + monthFormat: monthFormat, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + withPortal: withAnyPortal, + daySize: daySize, + initialVisibleMonth: initialVisibleMonthThunk, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + minimumNights: minimumNights, + isOutsideRange: isOutsideRange, + isDayHighlighted: isDayHighlighted, + isDayBlocked: isDayBlocked, + keepOpenOnDateSelect: keepOpenOnDateSelect, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isDayPickerFocused, + showKeyboardShortcuts: showKeyboardShortcuts, + onBlur: this.onDayPickerBlur, + phrases: phrases, + dayAriaLabelFormat: dayAriaLabelFormat, + isRTL: isRTL, + firstDayOfWeek: firstDayOfWeek, + weekDayFormat: weekDayFormat, + verticalHeight: verticalHeight, + noBorder: noBorder, + transitionDuration: transitionDuration, + disabled: disabled, + horizontalMonthPadding: horizontalMonthPadding + }), withFullScreenPortal && /*#__PURE__*/React.createElement("button", _extends({}, css(styles.DateRangePicker_closeButton), { + type: "button", + onClick: this.onOutsideClick, + "aria-label": phrases.closeDatePicker, + tabIndex: "-1" + }), closeIcon)); + /* eslint-enable jsx-a11y/no-static-element-interactions */ + + /* eslint-enable jsx-a11y/click-events-have-key-events */ + }; + + _proto.render = function render() { + var _this$props8 = this.props, + startDate = _this$props8.startDate, + startDateId = _this$props8.startDateId, + startDatePlaceholderText = _this$props8.startDatePlaceholderText, + startDateAriaLabel = _this$props8.startDateAriaLabel, + startDateTitleText = _this$props8.startDateTitleText, + endDate = _this$props8.endDate, + endDateId = _this$props8.endDateId, + endDatePlaceholderText = _this$props8.endDatePlaceholderText, + endDateAriaLabel = _this$props8.endDateAriaLabel, + endDateTitleText = _this$props8.endDateTitleText, + focusedInput = _this$props8.focusedInput, + screenReaderInputMessage = _this$props8.screenReaderInputMessage, + showClearDates = _this$props8.showClearDates, + showDefaultInputIcon = _this$props8.showDefaultInputIcon, + inputIconPosition = _this$props8.inputIconPosition, + customInputIcon = _this$props8.customInputIcon, + customArrowIcon = _this$props8.customArrowIcon, + customCloseIcon = _this$props8.customCloseIcon, + disabled = _this$props8.disabled, + required = _this$props8.required, + readOnly = _this$props8.readOnly, + autoComplete = _this$props8.autoComplete, + openDirection = _this$props8.openDirection, + phrases = _this$props8.phrases, + isOutsideRange = _this$props8.isOutsideRange, + isDayBlocked = _this$props8.isDayBlocked, + minimumNights = _this$props8.minimumNights, + withPortal = _this$props8.withPortal, + withFullScreenPortal = _this$props8.withFullScreenPortal, + displayFormat = _this$props8.displayFormat, + reopenPickerOnClearDates = _this$props8.reopenPickerOnClearDates, + keepOpenOnDateSelect = _this$props8.keepOpenOnDateSelect, + onDatesChange = _this$props8.onDatesChange, + onClose = _this$props8.onClose, + isRTL = _this$props8.isRTL, + noBorder = _this$props8.noBorder, + block = _this$props8.block, + verticalSpacing = _this$props8.verticalSpacing, + small = _this$props8.small, + regular = _this$props8.regular, + css = _this$props8.css, + styles = _this$props8.styles; + var isDateRangePickerInputFocused = this.state.isDateRangePickerInputFocused; + var enableOutsideClick = !withPortal && !withFullScreenPortal; + var hideFang = verticalSpacing < FANG_HEIGHT_PX; + var input = /*#__PURE__*/React.createElement(DateRangePickerInputController, { + startDate: startDate, + startDateId: startDateId, + startDatePlaceholderText: startDatePlaceholderText, + isStartDateFocused: focusedInput === START_DATE, + startDateAriaLabel: startDateAriaLabel, + startDateTitleText: startDateTitleText, + endDate: endDate, + endDateId: endDateId, + endDatePlaceholderText: endDatePlaceholderText, + isEndDateFocused: focusedInput === END_DATE, + endDateAriaLabel: endDateAriaLabel, + endDateTitleText: endDateTitleText, + displayFormat: displayFormat, + showClearDates: showClearDates, + showCaret: !withPortal && !withFullScreenPortal && !hideFang, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + customInputIcon: customInputIcon, + customArrowIcon: customArrowIcon, + customCloseIcon: customCloseIcon, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + reopenPickerOnClearDates: reopenPickerOnClearDates, + keepOpenOnDateSelect: keepOpenOnDateSelect, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + minimumNights: minimumNights, + withFullScreenPortal: withFullScreenPortal, + onDatesChange: onDatesChange, + onFocusChange: this.onDateRangePickerInputFocus, + onKeyDownArrowDown: this.onDayPickerFocus, + onKeyDownQuestionMark: this.showKeyboardShortcutsPanel, + onClose: onClose, + phrases: phrases, + screenReaderMessage: screenReaderInputMessage, + isFocused: isDateRangePickerInputFocused, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + autoComplete: autoComplete + }, this.maybeRenderDayPickerWithPortal()); + return /*#__PURE__*/React.createElement("div", _extends({ + ref: this.setContainerRef + }, css(styles.DateRangePicker, block && styles.DateRangePicker__block)), enableOutsideClick && /*#__PURE__*/React.createElement(OutsideClickHandler, { + onOutsideClick: this.onOutsideClick + }, input), enableOutsideClick || input); + }; + + return DateRangePicker; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +DateRangePicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePicker.defaultProps = defaultProps; +export { DateRangePicker as PureDateRangePicker }; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + zIndex = _ref3$reactDates.zIndex; + return { + DateRangePicker: { + position: 'relative', + display: 'inline-block' + }, + DateRangePicker__block: { + display: 'block' + }, + DateRangePicker_picker: { + zIndex: zIndex + 1, + backgroundColor: color.background, + position: 'absolute' + }, + DateRangePicker_picker__rtl: { + direction: noflip('rtl') + }, + DateRangePicker_picker__directionLeft: { + left: noflip(0) + }, + DateRangePicker_picker__directionRight: { + right: noflip(0) + }, + DateRangePicker_picker__portal: { + backgroundColor: 'rgba(0, 0, 0, 0.3)', + position: 'fixed', + top: 0, + left: noflip(0), + height: '100%', + width: '100%' + }, + DateRangePicker_picker__fullScreenPortal: { + backgroundColor: color.background + }, + DateRangePicker_closeButton: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + position: 'absolute', + top: 0, + right: noflip(0), + padding: 15, + zIndex: zIndex + 2, + ':hover': { + color: darken(color.core.grayLighter, 0.1), + textDecoration: 'none' + }, + ':focus': { + color: darken(color.core.grayLighter, 0.1), + textDecoration: 'none' + } + }, + DateRangePicker_closeButton_svg: { + height: 15, + width: 15, + fill: color.core.grayLighter + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DateRangePicker); \ No newline at end of file diff --git a/esm/components/DateRangePickerInput.js b/esm/components/DateRangePickerInput.js new file mode 100644 index 000000000..99855a636 --- /dev/null +++ b/esm/components/DateRangePickerInput.js @@ -0,0 +1,347 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { DateRangePickerInputPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import noflip from '../utils/noflip'; +import openDirectionShape from '../shapes/OpenDirectionShape'; +import DateInput from './DateInput'; +import IconPositionShape from '../shapes/IconPositionShape'; +import DisabledShape from '../shapes/DisabledShape'; +import RightArrow from './RightArrow'; +import LeftArrow from './LeftArrow'; +import CloseButton from './CloseButton'; +import CalendarIcon from './CalendarIcon'; +import { START_DATE, END_DATE, ICON_BEFORE_POSITION, ICON_AFTER_POSITION, OPEN_DOWN } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + children: PropTypes.node, + startDateId: PropTypes.string, + startDatePlaceholderText: PropTypes.string, + startDateAriaLabel: PropTypes.string, + startDateTitleText: PropTypes.string, + screenReaderMessage: PropTypes.string, + endDateId: PropTypes.string, + endDatePlaceholderText: PropTypes.string, + endDateAriaLabel: PropTypes.string, + endDateTitleText: PropTypes.string, + onStartDateFocus: PropTypes.func, + onEndDateFocus: PropTypes.func, + onStartDateChange: PropTypes.func, + onEndDateChange: PropTypes.func, + onStartDateShiftTab: PropTypes.func, + onEndDateTab: PropTypes.func, + onClearDates: PropTypes.func, + onKeyDownArrowDown: PropTypes.func, + onKeyDownQuestionMark: PropTypes.func, + startDate: PropTypes.string, + endDate: PropTypes.string, + isStartDateFocused: PropTypes.bool, + isEndDateFocused: PropTypes.bool, + showClearDates: PropTypes.bool, + disabled: DisabledShape, + required: PropTypes.bool, + readOnly: PropTypes.bool, + openDirection: openDirectionShape, + showCaret: PropTypes.bool, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + customInputIcon: PropTypes.node, + customArrowIcon: PropTypes.node, + customCloseIcon: PropTypes.node, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + autoComplete: PropTypes.string, + // accessibility + isFocused: PropTypes.bool, + // describes actual DOM focus + // i18n + phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerInputPhrases)), + isRTL: PropTypes.bool +})) : {}; +var defaultProps = { + children: null, + startDateId: START_DATE, + endDateId: END_DATE, + startDatePlaceholderText: 'Start Date', + endDatePlaceholderText: 'End Date', + startDateAriaLabel: undefined, + endDateAriaLabel: undefined, + startDateTitleText: undefined, + endDateTitleText: undefined, + screenReaderMessage: '', + autoComplete: 'off', + onStartDateFocus: function onStartDateFocus() {}, + onEndDateFocus: function onEndDateFocus() {}, + onStartDateChange: function onStartDateChange() {}, + onEndDateChange: function onEndDateChange() {}, + onStartDateShiftTab: function onStartDateShiftTab() {}, + onEndDateTab: function onEndDateTab() {}, + onClearDates: function onClearDates() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + startDate: '', + endDate: '', + isStartDateFocused: false, + isEndDateFocused: false, + showClearDates: false, + disabled: false, + required: false, + readOnly: false, + openDirection: OPEN_DOWN, + showCaret: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + // accessibility + isFocused: false, + // i18n + phrases: DateRangePickerInputPhrases, + isRTL: false +}; + +function DateRangePickerInput(_ref) { + var children = _ref.children, + startDate = _ref.startDate, + startDateId = _ref.startDateId, + startDatePlaceholderText = _ref.startDatePlaceholderText, + screenReaderMessage = _ref.screenReaderMessage, + isStartDateFocused = _ref.isStartDateFocused, + onStartDateChange = _ref.onStartDateChange, + onStartDateFocus = _ref.onStartDateFocus, + onStartDateShiftTab = _ref.onStartDateShiftTab, + startDateAriaLabel = _ref.startDateAriaLabel, + startDateTitleText = _ref.startDateTitleText, + endDate = _ref.endDate, + endDateId = _ref.endDateId, + endDatePlaceholderText = _ref.endDatePlaceholderText, + isEndDateFocused = _ref.isEndDateFocused, + onEndDateChange = _ref.onEndDateChange, + onEndDateFocus = _ref.onEndDateFocus, + onEndDateTab = _ref.onEndDateTab, + endDateAriaLabel = _ref.endDateAriaLabel, + endDateTitleText = _ref.endDateTitleText, + onKeyDownArrowDown = _ref.onKeyDownArrowDown, + onKeyDownQuestionMark = _ref.onKeyDownQuestionMark, + onClearDates = _ref.onClearDates, + showClearDates = _ref.showClearDates, + disabled = _ref.disabled, + required = _ref.required, + readOnly = _ref.readOnly, + autoComplete = _ref.autoComplete, + showCaret = _ref.showCaret, + openDirection = _ref.openDirection, + showDefaultInputIcon = _ref.showDefaultInputIcon, + inputIconPosition = _ref.inputIconPosition, + customInputIcon = _ref.customInputIcon, + customArrowIcon = _ref.customArrowIcon, + customCloseIcon = _ref.customCloseIcon, + isFocused = _ref.isFocused, + phrases = _ref.phrases, + isRTL = _ref.isRTL, + noBorder = _ref.noBorder, + block = _ref.block, + verticalSpacing = _ref.verticalSpacing, + small = _ref.small, + regular = _ref.regular, + css = _ref.css, + styles = _ref.styles; + var calendarIcon = customInputIcon || /*#__PURE__*/React.createElement(CalendarIcon, css(styles.DateRangePickerInput_calendarIcon_svg)); + var arrowIcon = /*#__PURE__*/React.createElement(RightArrow, css(styles.DateRangePickerInput_arrow_svg)); + if (isRTL) arrowIcon = /*#__PURE__*/React.createElement(LeftArrow, css(styles.DateRangePickerInput_arrow_svg)); + if (small) arrowIcon = '-'; + if (customArrowIcon) arrowIcon = customArrowIcon; + var closeIcon = customCloseIcon || /*#__PURE__*/React.createElement(CloseButton, css(styles.DateRangePickerInput_clearDates_svg, small && styles.DateRangePickerInput_clearDates_svg__small)); + var screenReaderStartDateText = screenReaderMessage || phrases.keyboardForwardNavigationInstructions; + var screenReaderEndDateText = screenReaderMessage || phrases.keyboardBackwardNavigationInstructions; + var inputIcon = (showDefaultInputIcon || customInputIcon !== null) && /*#__PURE__*/React.createElement("button", _extends({}, css(styles.DateRangePickerInput_calendarIcon), { + type: "button", + disabled: disabled, + "aria-label": phrases.focusStartDate, + onClick: onKeyDownArrowDown + }), calendarIcon); + var startDateDisabled = disabled === START_DATE || disabled === true; + var endDateDisabled = disabled === END_DATE || disabled === true; + return /*#__PURE__*/React.createElement("div", css(styles.DateRangePickerInput, disabled && styles.DateRangePickerInput__disabled, isRTL && styles.DateRangePickerInput__rtl, !noBorder && styles.DateRangePickerInput__withBorder, block && styles.DateRangePickerInput__block, showClearDates && styles.DateRangePickerInput__showClearDates), inputIconPosition === ICON_BEFORE_POSITION && inputIcon, /*#__PURE__*/React.createElement(DateInput, { + id: startDateId, + placeholder: startDatePlaceholderText, + ariaLabel: startDateAriaLabel, + autoComplete: autoComplete, + titleText: startDateTitleText, + displayValue: startDate, + screenReaderMessage: screenReaderStartDateText, + focused: isStartDateFocused, + isFocused: isFocused, + disabled: startDateDisabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + openDirection: openDirection, + onChange: onStartDateChange, + onFocus: onStartDateFocus, + onKeyDownShiftTab: onStartDateShiftTab, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + verticalSpacing: verticalSpacing, + small: small, + regular: regular + }), !isEndDateFocused && children, /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DateRangePickerInput_arrow), { + "aria-hidden": "true", + role: "presentation" + }), arrowIcon), /*#__PURE__*/React.createElement(DateInput, { + id: endDateId, + placeholder: endDatePlaceholderText, + ariaLabel: endDateAriaLabel, + autoComplete: autoComplete, + titleText: endDateTitleText, + displayValue: endDate, + screenReaderMessage: screenReaderEndDateText, + focused: isEndDateFocused, + isFocused: isFocused, + disabled: endDateDisabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + openDirection: openDirection, + onChange: onEndDateChange, + onFocus: onEndDateFocus, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + onKeyDownTab: onEndDateTab, + verticalSpacing: verticalSpacing, + small: small, + regular: regular + }), isEndDateFocused && children, showClearDates && /*#__PURE__*/React.createElement("button", _extends({ + type: "button", + "aria-label": phrases.clearDates + }, css(styles.DateRangePickerInput_clearDates, small && styles.DateRangePickerInput_clearDates__small, !customCloseIcon && styles.DateRangePickerInput_clearDates_default, !(startDate || endDate) && styles.DateRangePickerInput_clearDates__hide), { + onClick: onClearDates, + disabled: disabled + }), closeIcon), inputIconPosition === ICON_AFTER_POSITION && inputIcon); +} + +DateRangePickerInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePickerInput.defaultProps = defaultProps; +export default withStyles(function (_ref2) { + var _ref2$reactDates = _ref2.reactDates, + border = _ref2$reactDates.border, + color = _ref2$reactDates.color, + sizing = _ref2$reactDates.sizing; + return { + DateRangePickerInput: { + backgroundColor: color.background, + display: 'inline-block' + }, + DateRangePickerInput__disabled: { + background: color.disabled + }, + DateRangePickerInput__withBorder: { + borderColor: color.border, + borderWidth: border.pickerInput.borderWidth, + borderStyle: border.pickerInput.borderStyle, + borderRadius: border.pickerInput.borderRadius + }, + DateRangePickerInput__rtl: { + direction: noflip('rtl') + }, + DateRangePickerInput__block: { + display: 'block' + }, + DateRangePickerInput__showClearDates: { + paddingRight: 30 // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + DateRangePickerInput_arrow: { + display: 'inline-block', + verticalAlign: 'middle', + color: color.text + }, + DateRangePickerInput_arrow_svg: { + verticalAlign: 'middle', + fill: color.text, + height: sizing.arrowWidth, + width: sizing.arrowWidth + }, + DateRangePickerInput_clearDates: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + padding: 10, + margin: '0 10px 0 5px', + // TODO: should be noflip wrapped and handled by an isRTL prop + position: 'absolute', + right: 0, + // TODO: should be noflip wrapped and handled by an isRTL prop + top: '50%', + transform: 'translateY(-50%)' + }, + DateRangePickerInput_clearDates__small: { + padding: 6 + }, + DateRangePickerInput_clearDates_default: { + ':focus': { + background: color.core.border, + borderRadius: '50%' + }, + ':hover': { + background: color.core.border, + borderRadius: '50%' + } + }, + DateRangePickerInput_clearDates__hide: { + visibility: 'hidden' + }, + DateRangePickerInput_clearDates_svg: { + fill: color.core.grayLight, + height: 12, + width: 15, + verticalAlign: 'middle' + }, + DateRangePickerInput_clearDates_svg__small: { + height: 9 + }, + DateRangePickerInput_calendarIcon: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + display: 'inline-block', + verticalAlign: 'middle', + padding: 10, + margin: '0 5px 0 10px' // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + DateRangePickerInput_calendarIcon_svg: { + fill: color.core.grayLight, + height: 15, + width: 14, + verticalAlign: 'middle' + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DateRangePickerInput); \ No newline at end of file diff --git a/esm/components/DateRangePickerInputController.js b/esm/components/DateRangePickerInputController.js new file mode 100644 index 000000000..7a66e7a8c --- /dev/null +++ b/esm/components/DateRangePickerInputController.js @@ -0,0 +1,374 @@ +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import shallowEqual from "enzyme-shallow-equal"; +import React from 'react'; +import PropTypes from 'prop-types'; +import moment from 'moment'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import openDirectionShape from '../shapes/OpenDirectionShape'; +import { DateRangePickerInputPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import DateRangePickerInput from './DateRangePickerInput'; +import IconPositionShape from '../shapes/IconPositionShape'; +import DisabledShape from '../shapes/DisabledShape'; +import toMomentObject from '../utils/toMomentObject'; +import toLocalizedDateString from '../utils/toLocalizedDateString'; +import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay'; +import isBeforeDay from '../utils/isBeforeDay'; +import { START_DATE, END_DATE, ICON_BEFORE_POSITION, OPEN_DOWN } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps({ + children: PropTypes.node, + startDate: momentPropTypes.momentObj, + startDateId: PropTypes.string, + startDatePlaceholderText: PropTypes.string, + isStartDateFocused: PropTypes.bool, + startDateAriaLabel: PropTypes.string, + startDateTitleText: PropTypes.string, + endDate: momentPropTypes.momentObj, + endDateId: PropTypes.string, + endDatePlaceholderText: PropTypes.string, + isEndDateFocused: PropTypes.bool, + endDateAriaLabel: PropTypes.string, + endDateTitleText: PropTypes.string, + screenReaderMessage: PropTypes.string, + showClearDates: PropTypes.bool, + showCaret: PropTypes.bool, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + disabled: DisabledShape, + required: PropTypes.bool, + readOnly: PropTypes.bool, + openDirection: openDirectionShape, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + autoComplete: PropTypes.string, + keepOpenOnDateSelect: PropTypes.bool, + reopenPickerOnClearDates: PropTypes.bool, + withFullScreenPortal: PropTypes.bool, + minimumNights: nonNegativeInteger, + isOutsideRange: PropTypes.func, + isDayBlocked: PropTypes.func, + displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + onFocusChange: PropTypes.func, + onClose: PropTypes.func, + onDatesChange: PropTypes.func, + onKeyDownArrowDown: PropTypes.func, + onKeyDownQuestionMark: PropTypes.func, + customInputIcon: PropTypes.node, + customArrowIcon: PropTypes.node, + customCloseIcon: PropTypes.node, + // accessibility + isFocused: PropTypes.bool, + // i18n + phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerInputPhrases)), + isRTL: PropTypes.bool +}) : {}; +var defaultProps = { + children: null, + startDate: null, + startDateId: START_DATE, + startDatePlaceholderText: 'Start Date', + isStartDateFocused: false, + startDateAriaLabel: undefined, + startDateTitleText: undefined, + endDate: null, + endDateId: END_DATE, + endDatePlaceholderText: 'End Date', + isEndDateFocused: false, + endDateAriaLabel: undefined, + endDateTitleText: undefined, + screenReaderMessage: '', + showClearDates: false, + showCaret: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + disabled: false, + required: false, + readOnly: false, + openDirection: OPEN_DOWN, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + autoComplete: 'off', + keepOpenOnDateSelect: false, + reopenPickerOnClearDates: false, + withFullScreenPortal: false, + minimumNights: 1, + isOutsideRange: function isOutsideRange(day) { + return !isInclusivelyAfterDay(day, moment()); + }, + isDayBlocked: function isDayBlocked() { + return false; + }, + displayFormat: function displayFormat() { + return moment.localeData().longDateFormat('L'); + }, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + onDatesChange: function onDatesChange() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + // accessibility + isFocused: false, + // i18n + phrases: DateRangePickerInputPhrases, + isRTL: false +}; + +var DateRangePickerInputController = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DateRangePickerInputController, _ref2); + + var _proto = DateRangePickerInputController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DateRangePickerInputController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.onClearFocus = _this.onClearFocus.bind(_assertThisInitialized(_this)); + _this.onStartDateChange = _this.onStartDateChange.bind(_assertThisInitialized(_this)); + _this.onStartDateFocus = _this.onStartDateFocus.bind(_assertThisInitialized(_this)); + _this.onEndDateChange = _this.onEndDateChange.bind(_assertThisInitialized(_this)); + _this.onEndDateFocus = _this.onEndDateFocus.bind(_assertThisInitialized(_this)); + _this.clearDates = _this.clearDates.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.onClearFocus = 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 + }); + }; + + _proto.onEndDateChange = function onEndDateChange(endDateString) { + var _this$props2 = this.props, + startDate = _this$props2.startDate, + isOutsideRange = _this$props2.isOutsideRange, + isDayBlocked = _this$props2.isDayBlocked, + minimumNights = _this$props2.minimumNights, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + onDatesChange = _this$props2.onDatesChange, + onClose = _this$props2.onClose, + onFocusChange = _this$props2.onFocusChange; + var endDate = toMomentObject(endDateString, this.getDisplayFormat()); + var isEndDateValid = endDate && !isOutsideRange(endDate) && !isDayBlocked(endDate) && !(startDate && isBeforeDay(endDate, startDate.clone().add(minimumNights, 'days'))); + + if (isEndDateValid) { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (!keepOpenOnDateSelect) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } + } else { + onDatesChange({ + startDate: startDate, + endDate: null + }); + } + }; + + _proto.onEndDateFocus = 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 === 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(START_DATE); + } else if (!disabled || disabled === START_DATE) { + onFocusChange(END_DATE); + } + }; + + _proto.onStartDateChange = function onStartDateChange(startDateString) { + var endDate = this.props.endDate; + var _this$props4 = this.props, + isOutsideRange = _this$props4.isOutsideRange, + isDayBlocked = _this$props4.isDayBlocked, + minimumNights = _this$props4.minimumNights, + onDatesChange = _this$props4.onDatesChange, + onFocusChange = _this$props4.onFocusChange, + disabled = _this$props4.disabled; + var startDate = toMomentObject(startDateString, this.getDisplayFormat()); + var isEndDateBeforeStartDate = startDate && isBeforeDay(endDate, startDate.clone().add(minimumNights, 'days')); + var isStartDateValid = startDate && !isOutsideRange(startDate) && !isDayBlocked(startDate) && !(disabled === END_DATE && isEndDateBeforeStartDate); + + if (isStartDateValid) { + if (isEndDateBeforeStartDate) { + endDate = null; + } + + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + onFocusChange(END_DATE); + } else { + onDatesChange({ + startDate: null, + endDate: endDate + }); + } + }; + + _proto.onStartDateFocus = function onStartDateFocus() { + var _this$props5 = this.props, + disabled = _this$props5.disabled, + onFocusChange = _this$props5.onFocusChange; + + if (!disabled || disabled === END_DATE) { + onFocusChange(START_DATE); + } + }; + + _proto.getDisplayFormat = function getDisplayFormat() { + var displayFormat = this.props.displayFormat; + return typeof displayFormat === 'string' ? displayFormat : displayFormat(); + }; + + _proto.getDateString = function getDateString(date) { + var displayFormat = this.getDisplayFormat(); + + if (date && displayFormat) { + return date && date.format(displayFormat); + } + + return toLocalizedDateString(date); + }; + + _proto.clearDates = 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(START_DATE); + } + }; + + _proto.render = function render() { + var _this$props7 = this.props, + children = _this$props7.children, + startDate = _this$props7.startDate, + startDateId = _this$props7.startDateId, + startDatePlaceholderText = _this$props7.startDatePlaceholderText, + isStartDateFocused = _this$props7.isStartDateFocused, + startDateAriaLabel = _this$props7.startDateAriaLabel, + startDateTitleText = _this$props7.startDateTitleText, + endDate = _this$props7.endDate, + endDateId = _this$props7.endDateId, + endDatePlaceholderText = _this$props7.endDatePlaceholderText, + endDateAriaLabel = _this$props7.endDateAriaLabel, + endDateTitleText = _this$props7.endDateTitleText, + 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, + autoComplete = _this$props7.autoComplete; + var startDateString = this.getDateString(startDate); + var endDateString = this.getDateString(endDate); + return /*#__PURE__*/React.createElement(DateRangePickerInput, { + startDate: startDateString, + startDateId: startDateId, + startDatePlaceholderText: startDatePlaceholderText, + isStartDateFocused: isStartDateFocused, + startDateAriaLabel: startDateAriaLabel, + startDateTitleText: startDateTitleText, + endDate: endDateString, + endDateId: endDateId, + endDatePlaceholderText: endDatePlaceholderText, + isEndDateFocused: isEndDateFocused, + endDateAriaLabel: endDateAriaLabel, + endDateTitleText: endDateTitleText, + 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, + showClearDates: showClearDates, + onClearDates: this.clearDates, + screenReaderMessage: screenReaderMessage, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + autoComplete: autoComplete + }, children); + }; + + return DateRangePickerInputController; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +export { DateRangePickerInputController as default }; +DateRangePickerInputController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePickerInputController.defaultProps = defaultProps; \ No newline at end of file diff --git a/esm/components/DayPicker.js b/esm/components/DayPicker.js new file mode 100644 index 000000000..d5bbbd058 --- /dev/null +++ b/esm/components/DayPicker.js @@ -0,0 +1,1300 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import moment from 'moment'; +import throttle from 'lodash/throttle'; +import isTouchDevice from 'is-touch-device'; +import OutsideClickHandler from 'react-outside-click-handler'; +import { DayPickerPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import noflip from '../utils/noflip'; +import CalendarMonthGrid from './CalendarMonthGrid'; +import DayPickerNavigation from './DayPickerNavigation'; +import DayPickerKeyboardShortcuts, { TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT } from './DayPickerKeyboardShortcuts'; +import getNumberOfCalendarMonthWeeks from '../utils/getNumberOfCalendarMonthWeeks'; +import getCalendarMonthWidth from '../utils/getCalendarMonthWidth'; +import calculateDimension from '../utils/calculateDimension'; +import getActiveElement from '../utils/getActiveElement'; +import isDayVisible from '../utils/isDayVisible'; +import isSameMonth from '../utils/isSameMonth'; +import ModifiersShape from '../shapes/ModifiersShape'; +import NavPositionShape from '../shapes/NavPositionShape'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import DayOfWeekShape from '../shapes/DayOfWeekShape'; +import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape'; +import { HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, VERTICAL_SCROLLABLE, DAY_SIZE, INFO_POSITION_TOP, INFO_POSITION_BOTTOM, INFO_POSITION_BEFORE, INFO_POSITION_AFTER, MODIFIER_KEY_NAMES, NAV_POSITION_TOP, NAV_POSITION_BOTTOM } from '../constants'; +var MONTH_PADDING = 23; +var PREV_TRANSITION = 'prev'; +var NEXT_TRANSITION = 'next'; +var MONTH_SELECTION_TRANSITION = 'month_selection'; +var YEAR_SELECTION_TRANSITION = 'year_selection'; +var PREV_NAV = 'prev_nav'; +var NEXT_NAV = 'next_nav'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + // calendar presentation props + enableOutsideDays: PropTypes.bool, + numberOfMonths: PropTypes.number, + orientation: ScrollableOrientationShape, + withPortal: PropTypes.bool, + onOutsideClick: PropTypes.func, + hidden: PropTypes.bool, + initialVisibleMonth: PropTypes.func, + firstDayOfWeek: DayOfWeekShape, + renderCalendarInfo: PropTypes.func, + calendarInfoPosition: CalendarInfoPositionShape, + hideKeyboardShortcutsPanel: PropTypes.bool, + daySize: nonNegativeInteger, + isRTL: PropTypes.bool, + verticalHeight: nonNegativeInteger, + noBorder: PropTypes.bool, + transitionDuration: nonNegativeInteger, + verticalBorderSpacing: nonNegativeInteger, + horizontalMonthPadding: nonNegativeInteger, + renderKeyboardShortcutsButton: PropTypes.func, + renderKeyboardShortcutsPanel: PropTypes.func, + // navigation props + dayPickerNavigationInlineStyles: PropTypes.object, + disablePrev: PropTypes.bool, + disableNext: PropTypes.bool, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + noNavButtons: PropTypes.bool, + noNavNextButton: PropTypes.bool, + noNavPrevButton: PropTypes.bool, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + onMonthChange: PropTypes.func, + onYearChange: PropTypes.func, + onGetNextScrollableMonths: PropTypes.func, + // VERTICAL_SCROLLABLE daypickers only + onGetPrevScrollableMonths: PropTypes.func, + // VERTICAL_SCROLLABLE daypickers only + // month props + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: PropTypes.func, + // day props + modifiers: PropTypes.objectOf(PropTypes.objectOf(ModifiersShape)), + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + onDayClick: PropTypes.func, + onDayMouseEnter: PropTypes.func, + onDayMouseLeave: PropTypes.func, + // accessibility props + isFocused: PropTypes.bool, + getFirstFocusableDay: PropTypes.func, + onBlur: PropTypes.func, + showKeyboardShortcuts: PropTypes.bool, + onTab: PropTypes.func, + onShiftTab: PropTypes.func, + // internationalization + monthFormat: PropTypes.string, + weekDayFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)), + dayAriaLabelFormat: PropTypes.string +})) : {}; +export var defaultProps = { + // calendar presentation props + enableOutsideDays: false, + numberOfMonths: 2, + orientation: HORIZONTAL_ORIENTATION, + withPortal: false, + onOutsideClick: function onOutsideClick() {}, + hidden: false, + initialVisibleMonth: function initialVisibleMonth() { + return moment(); + }, + firstDayOfWeek: null, + renderCalendarInfo: null, + calendarInfoPosition: INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: DAY_SIZE, + isRTL: false, + verticalHeight: null, + noBorder: false, + transitionDuration: undefined, + verticalBorderSpacing: undefined, + horizontalMonthPadding: 13, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined, + // navigation props + dayPickerNavigationInlineStyles: null, + disablePrev: false, + disableNext: false, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onMonthChange: function onMonthChange() {}, + onYearChange: function onYearChange() {}, + onGetNextScrollableMonths: function onGetNextScrollableMonths() {}, + onGetPrevScrollableMonths: function onGetPrevScrollableMonths() {}, + // month props + renderMonthText: null, + renderMonthElement: null, + renderWeekHeaderElement: null, + // day props + modifiers: {}, + renderCalendarDay: undefined, + renderDayContents: null, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + // accessibility props + isFocused: false, + getFirstFocusableDay: null, + onBlur: function onBlur() {}, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // internationalization + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: DayPickerPhrases, + dayAriaLabelFormat: undefined +}; + +var DayPicker = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DayPicker, _ref2); + + var _proto = DayPicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DayPicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + var currentMonth = props.hidden ? moment() : props.initialVisibleMonth(); + var focusedDate = currentMonth.clone().startOf('month').hour(12); + + if (props.getFirstFocusableDay) { + focusedDate = props.getFirstFocusableDay(currentMonth); + } + + var horizontalMonthPadding = props.horizontalMonthPadding; + var translationValue = props.isRTL && _this.isHorizontal() ? -getCalendarMonthWidth(props.daySize, horizontalMonthPadding) : 0; + _this.hasSetInitialVisibleMonth = !props.hidden; + _this.state = { + currentMonthScrollTop: null, + currentMonth: currentMonth, + monthTransition: null, + translationValue: translationValue, + scrollableMonthMultiple: 1, + calendarMonthWidth: getCalendarMonthWidth(props.daySize, horizontalMonthPadding), + focusedDate: !props.hidden || props.isFocused ? focusedDate : null, + nextFocusedDate: null, + showKeyboardShortcuts: props.showKeyboardShortcuts, + onKeyboardShortcutsPanelClose: function onKeyboardShortcutsPanelClose() {}, + isTouchDevice: isTouchDevice(), + withMouseInteractions: true, + calendarInfoWidth: 0, + monthTitleHeight: null, + hasSetHeight: false + }; + + _this.setCalendarMonthWeeks(currentMonth); + + _this.calendarMonthGridHeight = 0; + _this.setCalendarInfoWidthTimeout = null; + _this.setCalendarMonthGridHeightTimeout = null; + _this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this)); + _this.throttledKeyDown = throttle(_this.onFinalKeyDown, 200, { + trailing: false + }); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind(_assertThisInitialized(_this)); + _this.onPrevMonthTransition = _this.onPrevMonthTransition.bind(_assertThisInitialized(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind(_assertThisInitialized(_this)); + _this.onNextMonthTransition = _this.onNextMonthTransition.bind(_assertThisInitialized(_this)); + _this.onMonthChange = _this.onMonthChange.bind(_assertThisInitialized(_this)); + _this.onYearChange = _this.onYearChange.bind(_assertThisInitialized(_this)); + _this.getNextScrollableMonths = _this.getNextScrollableMonths.bind(_assertThisInitialized(_this)); + _this.getPrevScrollableMonths = _this.getPrevScrollableMonths.bind(_assertThisInitialized(_this)); + _this.updateStateAfterMonthTransition = _this.updateStateAfterMonthTransition.bind(_assertThisInitialized(_this)); + _this.openKeyboardShortcutsPanel = _this.openKeyboardShortcutsPanel.bind(_assertThisInitialized(_this)); + _this.closeKeyboardShortcutsPanel = _this.closeKeyboardShortcutsPanel.bind(_assertThisInitialized(_this)); + _this.setCalendarInfoRef = _this.setCalendarInfoRef.bind(_assertThisInitialized(_this)); + _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); + _this.setTransitionContainerRef = _this.setTransitionContainerRef.bind(_assertThisInitialized(_this)); + _this.setMonthTitleHeight = _this.setMonthTitleHeight.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + var orientation = this.props.orientation; + var currentMonth = this.state.currentMonth; + var calendarInfoWidth = this.calendarInfo ? calculateDimension(this.calendarInfo, 'width', true, true) : 0; + var currentMonthScrollTop = this.transitionContainer && orientation === VERTICAL_SCROLLABLE ? this.transitionContainer.scrollHeight - this.transitionContainer.scrollTop : null; + this.setState({ + isTouchDevice: isTouchDevice(), + calendarInfoWidth: calendarInfoWidth, + currentMonthScrollTop: currentMonthScrollTop + }); + this.setCalendarMonthWeeks(currentMonth); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps, nextState) { + var hidden = nextProps.hidden, + isFocused = nextProps.isFocused, + showKeyboardShortcuts = nextProps.showKeyboardShortcuts, + onBlur = nextProps.onBlur, + orientation = nextProps.orientation, + renderMonthText = nextProps.renderMonthText, + horizontalMonthPadding = nextProps.horizontalMonthPadding; + var currentMonth = this.state.currentMonth; + var nextCurrentMonth = nextState.currentMonth; + + if (!hidden) { + if (!this.hasSetInitialVisibleMonth) { + this.hasSetInitialVisibleMonth = true; + this.setState({ + currentMonth: nextProps.initialVisibleMonth() + }); + } else { + var numberOfMonths = this.props.numberOfMonths; + var newDate = nextProps.initialVisibleMonth(); + + if (!isDayVisible(newDate, currentMonth, numberOfMonths)) { + this.onMonthChange(newDate); + } + } + } + + var _this$props = this.props, + daySize = _this$props.daySize, + prevIsFocused = _this$props.isFocused, + prevRenderMonthText = _this$props.renderMonthText; + + if (nextProps.daySize !== daySize) { + this.setState({ + calendarMonthWidth: getCalendarMonthWidth(nextProps.daySize, horizontalMonthPadding) + }); + } + + if (isFocused !== prevIsFocused) { + if (isFocused) { + var focusedDate = this.getFocusedDay(currentMonth); + var onKeyboardShortcutsPanelClose = this.state.onKeyboardShortcutsPanelClose; + + if (nextProps.showKeyboardShortcuts) { + // the ? shortcut came from the input and we should return input there once it is close + onKeyboardShortcutsPanelClose = onBlur; + } + + this.setState({ + showKeyboardShortcuts: showKeyboardShortcuts, + onKeyboardShortcutsPanelClose: onKeyboardShortcutsPanelClose, + focusedDate: focusedDate, + withMouseInteractions: false + }); + } else { + this.setState({ + focusedDate: null + }); + } + } + + if (renderMonthText !== null && prevRenderMonthText !== null && renderMonthText(currentMonth) !== prevRenderMonthText(currentMonth)) { + this.setState({ + monthTitleHeight: null + }); + } // Capture the scroll position so when previous months are rendered above the current month + // we can adjust scroll after the component has updated and the previous current month + // stays in view. + + + if (orientation === VERTICAL_SCROLLABLE && this.transitionContainer && !isSameMonth(currentMonth, nextCurrentMonth)) { + this.setState({ + currentMonthScrollTop: this.transitionContainer.scrollHeight - this.transitionContainer.scrollTop + }); + } + }; + + _proto.componentWillUpdate = function componentWillUpdate() { + var _this2 = this; + + var transitionDuration = this.props.transitionDuration; // Calculating the dimensions trigger a DOM repaint which + // breaks the CSS transition. + // The setTimeout will wait until the transition ends. + + if (this.calendarInfo) { + this.setCalendarInfoWidthTimeout = setTimeout(function () { + var calendarInfoWidth = _this2.state.calendarInfoWidth; + var calendarInfoPanelWidth = calculateDimension(_this2.calendarInfo, 'width', true, true); + + if (calendarInfoWidth !== calendarInfoPanelWidth) { + _this2.setState({ + calendarInfoWidth: calendarInfoPanelWidth + }); + } + }, transitionDuration); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { + var _this$props2 = this.props, + orientation = _this$props2.orientation, + daySize = _this$props2.daySize, + isFocused = _this$props2.isFocused, + numberOfMonths = _this$props2.numberOfMonths; + var _this$state = this.state, + currentMonth = _this$state.currentMonth, + currentMonthScrollTop = _this$state.currentMonthScrollTop, + focusedDate = _this$state.focusedDate, + monthTitleHeight = _this$state.monthTitleHeight; + var shouldAdjustHeight = false; + + if (numberOfMonths !== prevProps.numberOfMonths) { + this.setCalendarMonthWeeks(currentMonth); + shouldAdjustHeight = true; + } + + if (this.isHorizontal() && (orientation !== prevProps.orientation || daySize !== prevProps.daySize)) { + shouldAdjustHeight = true; + } + + if (shouldAdjustHeight) { + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1); + var calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat(_toConsumableArray(visibleCalendarWeeks))) * (daySize - 1); + var newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + if (!prevProps.isFocused && isFocused && !focusedDate) { + this.container.focus(); + } // If orientation is VERTICAL_SCROLLABLE and currentMonth has changed adjust scrollTop so the + // new months rendered above the current month don't push the current month out of view. + + + if (orientation === VERTICAL_SCROLLABLE && !isSameMonth(prevState.currentMonth, currentMonth) && currentMonthScrollTop && this.transitionContainer) { + this.transitionContainer.scrollTop = this.transitionContainer.scrollHeight - currentMonthScrollTop; + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + clearTimeout(this.setCalendarInfoWidthTimeout); + clearTimeout(this.setCalendarMonthGridHeightTimeout); + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + + if (!MODIFIER_KEY_NAMES.has(e.key)) { + this.throttledKeyDown(e); + } + }; + + _proto.onFinalKeyDown = function onFinalKeyDown(e) { + this.setState({ + withMouseInteractions: false + }); + var _this$props3 = this.props, + onBlur = _this$props3.onBlur, + onTab = _this$props3.onTab, + onShiftTab = _this$props3.onShiftTab, + isRTL = _this$props3.isRTL; + var _this$state2 = this.state, + focusedDate = _this$state2.focusedDate, + showKeyboardShortcuts = _this$state2.showKeyboardShortcuts; + if (!focusedDate) return; + var newFocusedDate = focusedDate.clone(); + var didTransitionMonth = false; // focus might be anywhere when the keyboard shortcuts panel is opened so we want to + // return it to wherever it was before when the panel was opened + + var activeElement = getActiveElement(); + + var onKeyboardShortcutsPanelClose = function onKeyboardShortcutsPanelClose() { + if (activeElement) activeElement.focus(); + }; + + switch (e.key) { + case 'ArrowUp': + e.preventDefault(); + newFocusedDate.subtract(1, 'week'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'ArrowLeft': + e.preventDefault(); + + if (isRTL) { + newFocusedDate.add(1, 'day'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + } else { + newFocusedDate.subtract(1, 'day'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + } + + break; + + case 'Home': + e.preventDefault(); + newFocusedDate.startOf('week').hour(12); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'PageUp': + e.preventDefault(); + newFocusedDate.subtract(1, 'month'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'ArrowDown': + e.preventDefault(); + newFocusedDate.add(1, 'week'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case 'ArrowRight': + e.preventDefault(); + + if (isRTL) { + newFocusedDate.subtract(1, 'day'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + } else { + newFocusedDate.add(1, 'day'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + } + + break; + + case 'End': + e.preventDefault(); + newFocusedDate.endOf('week'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case 'PageDown': + e.preventDefault(); + newFocusedDate.add(1, 'month'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case '?': + this.openKeyboardShortcutsPanel(onKeyboardShortcutsPanelClose); + break; + + case 'Escape': + if (showKeyboardShortcuts) { + this.closeKeyboardShortcutsPanel(); + } else { + onBlur(e); + } + + break; + + case 'Tab': + if (e.shiftKey) { + onShiftTab(); + } else { + onTab(e); + } + + break; + + default: + break; + } // If there was a month transition, do not update the focused date until the transition has + // completed. Otherwise, attempting to focus on a DOM node may interrupt the CSS animation. If + // didTransitionMonth is true, the focusedDate gets updated in #updateStateAfterMonthTransition + + + if (!didTransitionMonth) { + this.setState({ + focusedDate: newFocusedDate + }); + } + }; + + _proto.onPrevMonthClick = function onPrevMonthClick(e) { + if (e) e.preventDefault(); + this.onPrevMonthTransition(); + }; + + _proto.onPrevMonthTransition = function onPrevMonthTransition(nextFocusedDate) { + var _this$props4 = this.props, + daySize = _this$props4.daySize, + isRTL = _this$props4.isRTL, + numberOfMonths = _this$props4.numberOfMonths; + var _this$state3 = this.state, + calendarMonthWidth = _this$state3.calendarMonthWidth, + monthTitleHeight = _this$state3.monthTitleHeight; + var translationValue; + + if (this.isVertical()) { + var calendarMonthWeeksHeight = this.calendarMonthWeeks[0] * (daySize - 1); + translationValue = monthTitleHeight + calendarMonthWeeksHeight + 1; + } else if (this.isHorizontal()) { + translationValue = calendarMonthWidth; + + if (isRTL) { + translationValue = -2 * calendarMonthWidth; + } + + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(0, numberOfMonths); + + var _calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat(_toConsumableArray(visibleCalendarWeeks))) * (daySize - 1); + + var newMonthHeight = monthTitleHeight + _calendarMonthWeeksHeight + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + this.setState({ + monthTransition: PREV_TRANSITION, + translationValue: translationValue, + focusedDate: null, + nextFocusedDate: nextFocusedDate + }); + }; + + _proto.onMonthChange = function onMonthChange(currentMonth) { + this.setCalendarMonthWeeks(currentMonth); + this.calculateAndSetDayPickerHeight(); // Translation value is a hack to force an invisible transition that + // properly rerenders the CalendarMonthGrid + + this.setState({ + monthTransition: MONTH_SELECTION_TRANSITION, + translationValue: 0.00001, + focusedDate: null, + nextFocusedDate: currentMonth, + currentMonth: currentMonth + }); + }; + + _proto.onYearChange = function onYearChange(currentMonth) { + this.setCalendarMonthWeeks(currentMonth); + this.calculateAndSetDayPickerHeight(); // Translation value is a hack to force an invisible transition that + // properly rerenders the CalendarMonthGrid + + this.setState({ + monthTransition: YEAR_SELECTION_TRANSITION, + translationValue: 0.0001, + focusedDate: null, + nextFocusedDate: currentMonth, + currentMonth: currentMonth + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick(e) { + if (e) e.preventDefault(); + this.onNextMonthTransition(); + }; + + _proto.onNextMonthTransition = function onNextMonthTransition(nextFocusedDate) { + var _this$props5 = this.props, + isRTL = _this$props5.isRTL, + numberOfMonths = _this$props5.numberOfMonths, + daySize = _this$props5.daySize; + var _this$state4 = this.state, + calendarMonthWidth = _this$state4.calendarMonthWidth, + monthTitleHeight = _this$state4.monthTitleHeight; + var translationValue; + + if (this.isVertical()) { + var firstVisibleMonthWeeks = this.calendarMonthWeeks[1]; + var calendarMonthWeeksHeight = firstVisibleMonthWeeks * (daySize - 1); + translationValue = -(monthTitleHeight + calendarMonthWeeksHeight + 1); + } + + if (this.isHorizontal()) { + translationValue = -calendarMonthWidth; + + if (isRTL) { + translationValue = 0; + } + + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(2, numberOfMonths + 2); + + var _calendarMonthWeeksHeight2 = Math.max.apply(Math, [0].concat(_toConsumableArray(visibleCalendarWeeks))) * (daySize - 1); + + var newMonthHeight = monthTitleHeight + _calendarMonthWeeksHeight2 + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + this.setState({ + monthTransition: NEXT_TRANSITION, + translationValue: translationValue, + focusedDate: null, + nextFocusedDate: nextFocusedDate + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return moment.localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getWeekHeaders = function getWeekHeaders() { + var weekDayFormat = this.props.weekDayFormat; + var currentMonth = this.state.currentMonth; + var firstDayOfWeek = this.getFirstDayOfWeek(); + var weekHeaders = []; + + for (var i = 0; i < 7; i += 1) { + weekHeaders.push(currentMonth.clone().day((i + firstDayOfWeek) % 7).format(weekDayFormat)); + } + + return weekHeaders; + }; + + _proto.getFirstVisibleIndex = function getFirstVisibleIndex() { + var orientation = this.props.orientation; + var monthTransition = this.state.monthTransition; + if (orientation === VERTICAL_SCROLLABLE) return 0; + var firstVisibleMonthIndex = 1; + + if (monthTransition === PREV_TRANSITION) { + firstVisibleMonthIndex -= 1; + } else if (monthTransition === NEXT_TRANSITION) { + firstVisibleMonthIndex += 1; + } + + return firstVisibleMonthIndex; + }; + + _proto.getFocusedDay = function getFocusedDay(newMonth) { + var _this$props6 = this.props, + getFirstFocusableDay = _this$props6.getFirstFocusableDay, + numberOfMonths = _this$props6.numberOfMonths; + var focusedDate; + + if (getFirstFocusableDay) { + focusedDate = getFirstFocusableDay(newMonth); + } + + if (newMonth && (!focusedDate || !isDayVisible(focusedDate, newMonth, numberOfMonths))) { + focusedDate = newMonth.clone().startOf('month').hour(12); + } + + return focusedDate; + }; + + _proto.setMonthTitleHeight = function setMonthTitleHeight(monthTitleHeight) { + var _this3 = this; + + this.setState({ + monthTitleHeight: monthTitleHeight + }, function () { + _this3.calculateAndSetDayPickerHeight(); + }); + }; + + _proto.setCalendarMonthWeeks = function setCalendarMonthWeeks(currentMonth) { + var numberOfMonths = this.props.numberOfMonths; + this.calendarMonthWeeks = []; + var month = currentMonth.clone().subtract(1, 'months'); + var firstDayOfWeek = this.getFirstDayOfWeek(); + + for (var i = 0; i < numberOfMonths + 2; i += 1) { + var numberOfWeeks = getNumberOfCalendarMonthWeeks(month, firstDayOfWeek); + this.calendarMonthWeeks.push(numberOfWeeks); + month = month.add(1, 'months'); + } + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.setCalendarInfoRef = function setCalendarInfoRef(ref) { + this.calendarInfo = ref; + }; + + _proto.setTransitionContainerRef = function setTransitionContainerRef(ref) { + this.transitionContainer = ref; + }; + + _proto.getNextScrollableMonths = function getNextScrollableMonths(e) { + var onGetNextScrollableMonths = this.props.onGetNextScrollableMonths; + if (e) e.preventDefault(); + if (onGetNextScrollableMonths) onGetNextScrollableMonths(e); + this.setState(function (_ref3) { + var scrollableMonthMultiple = _ref3.scrollableMonthMultiple; + return { + scrollableMonthMultiple: scrollableMonthMultiple + 1 + }; + }); + }; + + _proto.getPrevScrollableMonths = function getPrevScrollableMonths(e) { + var _this$props7 = this.props, + numberOfMonths = _this$props7.numberOfMonths, + onGetPrevScrollableMonths = _this$props7.onGetPrevScrollableMonths; + if (e) e.preventDefault(); + if (onGetPrevScrollableMonths) onGetPrevScrollableMonths(e); + this.setState(function (_ref4) { + var currentMonth = _ref4.currentMonth, + scrollableMonthMultiple = _ref4.scrollableMonthMultiple; + return { + currentMonth: currentMonth.clone().subtract(numberOfMonths, 'month'), + scrollableMonthMultiple: scrollableMonthMultiple + 1 + }; + }); + }; + + _proto.maybeTransitionNextMonth = function maybeTransitionNextMonth(newFocusedDate) { + var numberOfMonths = this.props.numberOfMonths; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + focusedDate = _this$state5.focusedDate; + var newFocusedDateMonth = newFocusedDate.month(); + var focusedDateMonth = focusedDate.month(); + var isNewFocusedDateVisible = isDayVisible(newFocusedDate, currentMonth, numberOfMonths); + + if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) { + this.onNextMonthTransition(newFocusedDate); + return true; + } + + return false; + }; + + _proto.maybeTransitionPrevMonth = function maybeTransitionPrevMonth(newFocusedDate) { + var numberOfMonths = this.props.numberOfMonths; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + focusedDate = _this$state6.focusedDate; + var newFocusedDateMonth = newFocusedDate.month(); + var focusedDateMonth = focusedDate.month(); + var isNewFocusedDateVisible = isDayVisible(newFocusedDate, currentMonth, numberOfMonths); + + if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) { + this.onPrevMonthTransition(newFocusedDate); + return true; + } + + return false; + }; + + _proto.isHorizontal = function isHorizontal() { + var orientation = this.props.orientation; + return orientation === HORIZONTAL_ORIENTATION; + }; + + _proto.isVertical = function isVertical() { + var orientation = this.props.orientation; + return orientation === VERTICAL_ORIENTATION || orientation === VERTICAL_SCROLLABLE; + }; + + _proto.updateStateAfterMonthTransition = function updateStateAfterMonthTransition() { + var _this4 = this; + + var _this$props8 = this.props, + onPrevMonthClick = _this$props8.onPrevMonthClick, + onNextMonthClick = _this$props8.onNextMonthClick, + numberOfMonths = _this$props8.numberOfMonths, + onMonthChange = _this$props8.onMonthChange, + onYearChange = _this$props8.onYearChange, + isRTL = _this$props8.isRTL; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + monthTransition = _this$state7.monthTransition, + focusedDate = _this$state7.focusedDate, + nextFocusedDate = _this$state7.nextFocusedDate, + withMouseInteractions = _this$state7.withMouseInteractions, + calendarMonthWidth = _this$state7.calendarMonthWidth; + if (!monthTransition) return; + var newMonth = currentMonth.clone(); + var firstDayOfWeek = this.getFirstDayOfWeek(); + + if (monthTransition === PREV_TRANSITION) { + newMonth.subtract(1, 'month'); + if (onPrevMonthClick) onPrevMonthClick(newMonth); + var newInvisibleMonth = newMonth.clone().subtract(1, 'month'); + var numberOfWeeks = getNumberOfCalendarMonthWeeks(newInvisibleMonth, firstDayOfWeek); + this.calendarMonthWeeks = [numberOfWeeks].concat(_toConsumableArray(this.calendarMonthWeeks.slice(0, -1))); + } else if (monthTransition === NEXT_TRANSITION) { + newMonth.add(1, 'month'); + if (onNextMonthClick) onNextMonthClick(newMonth); + + var _newInvisibleMonth = newMonth.clone().add(numberOfMonths, 'month'); + + var _numberOfWeeks = getNumberOfCalendarMonthWeeks(_newInvisibleMonth, firstDayOfWeek); + + this.calendarMonthWeeks = [].concat(_toConsumableArray(this.calendarMonthWeeks.slice(1)), [_numberOfWeeks]); + } else if (monthTransition === MONTH_SELECTION_TRANSITION) { + if (onMonthChange) onMonthChange(newMonth); + } else if (monthTransition === YEAR_SELECTION_TRANSITION) { + if (onYearChange) onYearChange(newMonth); + } + + var newFocusedDate = null; + + if (nextFocusedDate) { + newFocusedDate = nextFocusedDate; + } else if (!focusedDate && !withMouseInteractions) { + newFocusedDate = this.getFocusedDay(newMonth); + } + + this.setState({ + currentMonth: newMonth, + monthTransition: null, + translationValue: isRTL && this.isHorizontal() ? -calendarMonthWidth : 0, + nextFocusedDate: null, + focusedDate: newFocusedDate + }, function () { + // we don't want to focus on the relevant calendar day after a month transition + // if the user is navigating around using a mouse + if (withMouseInteractions) { + var activeElement = getActiveElement(); + + if (activeElement && activeElement !== document.body && _this4.container.contains(activeElement) && activeElement.blur) { + activeElement.blur(); + } + } + }); + }; + + _proto.adjustDayPickerHeight = function adjustDayPickerHeight(newMonthHeight) { + var _this5 = this; + + var monthHeight = newMonthHeight + MONTH_PADDING; + + if (monthHeight !== this.calendarMonthGridHeight) { + this.transitionContainer.style.height = "".concat(monthHeight, "px"); + + if (!this.calendarMonthGridHeight) { + this.setCalendarMonthGridHeightTimeout = setTimeout(function () { + _this5.setState({ + hasSetHeight: true + }); + }, 0); + } + + this.calendarMonthGridHeight = monthHeight; + } + }; + + _proto.calculateAndSetDayPickerHeight = function calculateAndSetDayPickerHeight() { + var _this$props9 = this.props, + daySize = _this$props9.daySize, + numberOfMonths = _this$props9.numberOfMonths; + var monthTitleHeight = this.state.monthTitleHeight; + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1); + var calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat(_toConsumableArray(visibleCalendarWeeks))) * (daySize - 1); + var newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1; + + if (this.isHorizontal()) { + this.adjustDayPickerHeight(newMonthHeight); + } + }; + + _proto.openKeyboardShortcutsPanel = function openKeyboardShortcutsPanel(onCloseCallBack) { + this.setState({ + showKeyboardShortcuts: true, + onKeyboardShortcutsPanelClose: onCloseCallBack + }); + }; + + _proto.closeKeyboardShortcutsPanel = function closeKeyboardShortcutsPanel() { + var onKeyboardShortcutsPanelClose = this.state.onKeyboardShortcutsPanelClose; + + if (onKeyboardShortcutsPanelClose) { + onKeyboardShortcutsPanelClose(); + } + + this.setState({ + onKeyboardShortcutsPanelClose: null, + showKeyboardShortcuts: false + }); + }; + + _proto.renderNavigation = function renderNavigation(navDirection) { + var _this$props10 = this.props, + dayPickerNavigationInlineStyles = _this$props10.dayPickerNavigationInlineStyles, + disablePrev = _this$props10.disablePrev, + disableNext = _this$props10.disableNext, + navPosition = _this$props10.navPosition, + navPrev = _this$props10.navPrev, + navNext = _this$props10.navNext, + noNavButtons = _this$props10.noNavButtons, + noNavNextButton = _this$props10.noNavNextButton, + noNavPrevButton = _this$props10.noNavPrevButton, + orientation = _this$props10.orientation, + phrases = _this$props10.phrases, + renderNavPrevButton = _this$props10.renderNavPrevButton, + renderNavNextButton = _this$props10.renderNavNextButton, + isRTL = _this$props10.isRTL; + + if (noNavButtons) { + return null; + } + + var onPrevMonthClick = orientation === VERTICAL_SCROLLABLE ? this.getPrevScrollableMonths : this.onPrevMonthClick; + var onNextMonthClick = orientation === VERTICAL_SCROLLABLE ? this.getNextScrollableMonths : this.onNextMonthClick; + return /*#__PURE__*/React.createElement(DayPickerNavigation, { + disablePrev: disablePrev, + disableNext: disableNext, + inlineStyles: dayPickerNavigationInlineStyles, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + orientation: orientation, + phrases: phrases, + isRTL: isRTL, + showNavNextButton: !(noNavNextButton || orientation === VERTICAL_SCROLLABLE && navDirection === PREV_NAV), + showNavPrevButton: !(noNavPrevButton || orientation === VERTICAL_SCROLLABLE && navDirection === NEXT_NAV) + }); + }; + + _proto.renderWeekHeader = function renderWeekHeader(index) { + var _this$props11 = this.props, + daySize = _this$props11.daySize, + horizontalMonthPadding = _this$props11.horizontalMonthPadding, + orientation = _this$props11.orientation, + renderWeekHeaderElement = _this$props11.renderWeekHeaderElement, + css = _this$props11.css, + styles = _this$props11.styles; + var calendarMonthWidth = this.state.calendarMonthWidth; + var verticalScrollable = orientation === VERTICAL_SCROLLABLE; + var horizontalStyle = { + left: index * calendarMonthWidth + }; + var verticalStyle = { + marginLeft: -calendarMonthWidth / 2 + }; + var weekHeaderStyle = {}; // no styles applied to the vertical-scrollable orientation + + if (this.isHorizontal()) { + weekHeaderStyle = horizontalStyle; + } else if (this.isVertical() && !verticalScrollable) { + weekHeaderStyle = verticalStyle; + } + + var weekHeaders = this.getWeekHeaders(); + var header = weekHeaders.map(function (day) { + return /*#__PURE__*/React.createElement("li", _extends({ + key: day + }, css(styles.DayPicker_weekHeader_li, { + width: daySize + })), renderWeekHeaderElement ? renderWeekHeaderElement(day) : /*#__PURE__*/React.createElement("small", null, day)); + }); + return /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPicker_weekHeader, this.isVertical() && styles.DayPicker_weekHeader__vertical, verticalScrollable && styles.DayPicker_weekHeader__verticalScrollable, weekHeaderStyle, { + padding: "0 ".concat(horizontalMonthPadding, "px") + }), { + key: "week-".concat(index) + }), /*#__PURE__*/React.createElement("ul", css(styles.DayPicker_weekHeader_ul), header)); + }; + + _proto.render = function render() { + var _this6 = this; + + var _this$state8 = this.state, + calendarMonthWidth = _this$state8.calendarMonthWidth, + currentMonth = _this$state8.currentMonth, + monthTransition = _this$state8.monthTransition, + translationValue = _this$state8.translationValue, + scrollableMonthMultiple = _this$state8.scrollableMonthMultiple, + focusedDate = _this$state8.focusedDate, + showKeyboardShortcuts = _this$state8.showKeyboardShortcuts, + isTouch = _this$state8.isTouchDevice, + hasSetHeight = _this$state8.hasSetHeight, + calendarInfoWidth = _this$state8.calendarInfoWidth, + monthTitleHeight = _this$state8.monthTitleHeight; + var _this$props12 = this.props, + enableOutsideDays = _this$props12.enableOutsideDays, + numberOfMonths = _this$props12.numberOfMonths, + orientation = _this$props12.orientation, + modifiers = _this$props12.modifiers, + withPortal = _this$props12.withPortal, + onDayClick = _this$props12.onDayClick, + onDayMouseEnter = _this$props12.onDayMouseEnter, + onDayMouseLeave = _this$props12.onDayMouseLeave, + firstDayOfWeek = _this$props12.firstDayOfWeek, + renderMonthText = _this$props12.renderMonthText, + renderCalendarDay = _this$props12.renderCalendarDay, + renderDayContents = _this$props12.renderDayContents, + renderCalendarInfo = _this$props12.renderCalendarInfo, + renderMonthElement = _this$props12.renderMonthElement, + renderKeyboardShortcutsButton = _this$props12.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props12.renderKeyboardShortcutsPanel, + calendarInfoPosition = _this$props12.calendarInfoPosition, + hideKeyboardShortcutsPanel = _this$props12.hideKeyboardShortcutsPanel, + onOutsideClick = _this$props12.onOutsideClick, + monthFormat = _this$props12.monthFormat, + daySize = _this$props12.daySize, + isFocused = _this$props12.isFocused, + isRTL = _this$props12.isRTL, + css = _this$props12.css, + styles = _this$props12.styles, + theme = _this$props12.theme, + phrases = _this$props12.phrases, + verticalHeight = _this$props12.verticalHeight, + dayAriaLabelFormat = _this$props12.dayAriaLabelFormat, + noBorder = _this$props12.noBorder, + transitionDuration = _this$props12.transitionDuration, + verticalBorderSpacing = _this$props12.verticalBorderSpacing, + horizontalMonthPadding = _this$props12.horizontalMonthPadding, + navPosition = _this$props12.navPosition; + var dayPickerHorizontalPadding = theme.reactDates.spacing.dayPickerHorizontalPadding; + var isHorizontal = this.isHorizontal(); + var numOfWeekHeaders = this.isVertical() ? 1 : numberOfMonths; + var weekHeaders = []; + + for (var i = 0; i < numOfWeekHeaders; i += 1) { + weekHeaders.push(this.renderWeekHeader(i)); + } + + var verticalScrollable = orientation === VERTICAL_SCROLLABLE; + var height; + + if (isHorizontal) { + height = this.calendarMonthGridHeight; + } else if (this.isVertical() && !verticalScrollable && !withPortal) { + // If the user doesn't set a desired height, + // we default back to this kind of made-up value that generally looks good + height = verticalHeight || 1.75 * calendarMonthWidth; + } + + var isCalendarMonthGridAnimating = monthTransition !== null; + var shouldFocusDate = !isCalendarMonthGridAnimating && isFocused; + var keyboardShortcutButtonLocation = BOTTOM_RIGHT; + + if (this.isVertical()) { + keyboardShortcutButtonLocation = withPortal ? TOP_LEFT : TOP_RIGHT; + } + + var shouldAnimateHeight = isHorizontal && hasSetHeight; + var calendarInfoPositionTop = calendarInfoPosition === INFO_POSITION_TOP; + var calendarInfoPositionBottom = calendarInfoPosition === INFO_POSITION_BOTTOM; + var calendarInfoPositionBefore = calendarInfoPosition === INFO_POSITION_BEFORE; + var calendarInfoPositionAfter = calendarInfoPosition === INFO_POSITION_AFTER; + var calendarInfoIsInline = calendarInfoPositionBefore || calendarInfoPositionAfter; + var calendarInfo = renderCalendarInfo && /*#__PURE__*/React.createElement("div", _extends({ + ref: this.setCalendarInfoRef + }, css(calendarInfoIsInline && styles.DayPicker_calendarInfo__horizontal)), renderCalendarInfo()); + var calendarInfoPanelWidth = renderCalendarInfo && calendarInfoIsInline ? calendarInfoWidth : 0; + var firstVisibleMonthIndex = this.getFirstVisibleIndex(); + var wrapperHorizontalWidth = calendarMonthWidth * numberOfMonths + 2 * dayPickerHorizontalPadding; // Adding `1px` because of whitespace between 2 inline-block + + var fullHorizontalWidth = wrapperHorizontalWidth + calendarInfoPanelWidth + 1; + var transitionContainerStyle = { + width: isHorizontal && wrapperHorizontalWidth, + height: height + }; + var dayPickerWrapperStyle = { + width: isHorizontal && wrapperHorizontalWidth + }; + var dayPickerStyle = { + width: isHorizontal && fullHorizontalWidth, + // These values are to center the datepicker (approximately) on the page + marginLeft: isHorizontal && withPortal ? -fullHorizontalWidth / 2 : null, + marginTop: isHorizontal && withPortal ? -calendarMonthWidth / 2 : null + }; + return /*#__PURE__*/React.createElement("div", css(styles.DayPicker, isHorizontal && styles.DayPicker__horizontal, verticalScrollable && styles.DayPicker__verticalScrollable, isHorizontal && withPortal && styles.DayPicker_portal__horizontal, this.isVertical() && withPortal && styles.DayPicker_portal__vertical, dayPickerStyle, !monthTitleHeight && styles.DayPicker__hidden, !noBorder && styles.DayPicker__withBorder), /*#__PURE__*/React.createElement(OutsideClickHandler, { + onOutsideClick: onOutsideClick + }, (calendarInfoPositionTop || calendarInfoPositionBefore) && calendarInfo, /*#__PURE__*/React.createElement("div", css(dayPickerWrapperStyle, calendarInfoIsInline && isHorizontal && styles.DayPicker_wrapper__horizontal), /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPicker_weekHeaders, isHorizontal && styles.DayPicker_weekHeaders__horizontal), { + "aria-hidden": "true", + role: "presentation" + }), weekHeaders), /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPicker_focusRegion), { + ref: this.setContainerRef, + onClick: function onClick(e) { + e.stopPropagation(); + }, + onKeyDown: this.onKeyDown, + onMouseUp: function onMouseUp() { + _this6.setState({ + withMouseInteractions: true + }); + }, + tabIndex: -1, + role: "application", + "aria-roledescription": phrases.roleDescription, + "aria-label": phrases.calendarLabel + }), !verticalScrollable && navPosition === NAV_POSITION_TOP && this.renderNavigation(), /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPicker_transitionContainer, shouldAnimateHeight && styles.DayPicker_transitionContainer__horizontal, this.isVertical() && styles.DayPicker_transitionContainer__vertical, verticalScrollable && styles.DayPicker_transitionContainer__verticalScrollable, transitionContainerStyle), { + ref: this.setTransitionContainerRef + }), verticalScrollable && this.renderNavigation(PREV_NAV), /*#__PURE__*/React.createElement(CalendarMonthGrid, { + setMonthTitleHeight: !monthTitleHeight ? this.setMonthTitleHeight : undefined, + translationValue: translationValue, + enableOutsideDays: enableOutsideDays, + firstVisibleMonthIndex: firstVisibleMonthIndex, + initialMonth: currentMonth, + isAnimating: isCalendarMonthGridAnimating, + modifiers: modifiers, + orientation: orientation, + numberOfMonths: numberOfMonths * scrollableMonthMultiple, + onDayClick: onDayClick, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onMonthChange: this.onMonthChange, + onYearChange: this.onYearChange, + renderMonthText: renderMonthText, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderMonthElement: renderMonthElement, + onMonthTransitionEnd: this.updateStateAfterMonthTransition, + monthFormat: monthFormat, + daySize: daySize, + firstDayOfWeek: firstDayOfWeek, + isFocused: shouldFocusDate, + focusedDate: focusedDate, + phrases: phrases, + isRTL: isRTL, + dayAriaLabelFormat: dayAriaLabelFormat, + transitionDuration: transitionDuration, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + }), verticalScrollable && this.renderNavigation(NEXT_NAV)), !verticalScrollable && navPosition === NAV_POSITION_BOTTOM && this.renderNavigation(), !isTouch && !hideKeyboardShortcutsPanel && /*#__PURE__*/React.createElement(DayPickerKeyboardShortcuts, { + block: this.isVertical() && !withPortal, + buttonLocation: keyboardShortcutButtonLocation, + showKeyboardShortcutsPanel: showKeyboardShortcuts, + openKeyboardShortcutsPanel: this.openKeyboardShortcutsPanel, + closeKeyboardShortcutsPanel: this.closeKeyboardShortcutsPanel, + phrases: phrases, + renderKeyboardShortcutsButton: renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel: renderKeyboardShortcutsPanel + }))), (calendarInfoPositionBottom || calendarInfoPositionAfter) && calendarInfo)); + }; + + return DayPicker; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +DayPicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPicker.defaultProps = defaultProps; +export { DayPicker as PureDayPicker }; +export default withStyles(function (_ref5) { + var _ref5$reactDates = _ref5.reactDates, + color = _ref5$reactDates.color, + font = _ref5$reactDates.font, + noScrollBarOnVerticalScrollable = _ref5$reactDates.noScrollBarOnVerticalScrollable, + spacing = _ref5$reactDates.spacing, + zIndex = _ref5$reactDates.zIndex; + return { + DayPicker: { + background: color.background, + position: 'relative', + textAlign: noflip('left') + }, + DayPicker__horizontal: { + background: color.background + }, + DayPicker__verticalScrollable: { + height: '100%' + }, + DayPicker__hidden: { + visibility: 'hidden' + }, + DayPicker__withBorder: { + boxShadow: noflip('0 2px 6px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.07)'), + borderRadius: 3 + }, + DayPicker_portal__horizontal: { + boxShadow: 'none', + position: 'absolute', + left: noflip('50%'), + top: '50%' + }, + DayPicker_portal__vertical: { + position: 'initial' + }, + DayPicker_focusRegion: { + outline: 'none' + }, + DayPicker_calendarInfo__horizontal: { + display: 'inline-block', + verticalAlign: 'top' + }, + DayPicker_wrapper__horizontal: { + display: 'inline-block', + verticalAlign: 'top' + }, + DayPicker_weekHeaders: { + position: 'relative' + }, + DayPicker_weekHeaders__horizontal: { + marginLeft: noflip(spacing.dayPickerHorizontalPadding) + }, + DayPicker_weekHeader: { + color: color.placeholderText, + position: 'absolute', + top: 62, + zIndex: zIndex + 2, + textAlign: noflip('left') + }, + DayPicker_weekHeader__vertical: { + left: noflip('50%') + }, + DayPicker_weekHeader__verticalScrollable: { + top: 0, + display: 'table-row', + borderBottom: "1px solid ".concat(color.core.border), + background: color.background, + marginLeft: noflip(0), + left: noflip(0), + width: '100%', + textAlign: 'center' + }, + DayPicker_weekHeader_ul: { + listStyle: 'none', + margin: '1px 0', + paddingLeft: noflip(0), + paddingRight: noflip(0), + fontSize: font.size + }, + DayPicker_weekHeader_li: { + display: 'inline-block', + textAlign: 'center' + }, + DayPicker_transitionContainer: { + position: 'relative', + overflow: 'hidden', + borderRadius: 3 + }, + DayPicker_transitionContainer__horizontal: { + transition: 'height 0.2s ease-in-out' + }, + DayPicker_transitionContainer__vertical: { + width: '100%' + }, + DayPicker_transitionContainer__verticalScrollable: _objectSpread({ + paddingTop: 20, + height: '100%', + position: 'absolute', + top: 0, + bottom: 0, + right: noflip(0), + left: noflip(0), + overflowY: 'scroll' + }, noScrollBarOnVerticalScrollable && { + '-webkitOverflowScrolling': 'touch', + '::-webkit-scrollbar': { + '-webkit-appearance': 'none', + display: 'none' + } + }) + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DayPicker); \ No newline at end of file diff --git a/esm/components/DayPickerKeyboardShortcuts.js b/esm/components/DayPickerKeyboardShortcuts.js new file mode 100644 index 000000000..754bd74ce --- /dev/null +++ b/esm/components/DayPickerKeyboardShortcuts.js @@ -0,0 +1,381 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { DayPickerKeyboardShortcutsPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import KeyboardShortcutRow from './KeyboardShortcutRow'; +import CloseButton from './CloseButton'; +export var TOP_LEFT = 'top-left'; +export var TOP_RIGHT = 'top-right'; +export var BOTTOM_RIGHT = 'bottom-right'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + block: PropTypes.bool, + // TODO: rename button location to be direction-agnostic + buttonLocation: PropTypes.oneOf([TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT]), + showKeyboardShortcutsPanel: PropTypes.bool, + openKeyboardShortcutsPanel: PropTypes.func, + closeKeyboardShortcutsPanel: PropTypes.func, + phrases: PropTypes.shape(getPhrasePropTypes(DayPickerKeyboardShortcutsPhrases)), + renderKeyboardShortcutsButton: PropTypes.func, + renderKeyboardShortcutsPanel: PropTypes.func +})) : {}; +var defaultProps = { + block: false, + buttonLocation: BOTTOM_RIGHT, + showKeyboardShortcutsPanel: false, + openKeyboardShortcutsPanel: function openKeyboardShortcutsPanel() {}, + closeKeyboardShortcutsPanel: function closeKeyboardShortcutsPanel() {}, + phrases: DayPickerKeyboardShortcutsPhrases, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined +}; + +function getKeyboardShortcuts(phrases) { + return [{ + unicode: '↵', + label: phrases.enterKey, + action: phrases.selectFocusedDate + }, { + unicode: '←/→', + label: phrases.leftArrowRightArrow, + action: phrases.moveFocusByOneDay + }, { + unicode: '↑/↓', + label: phrases.upArrowDownArrow, + action: phrases.moveFocusByOneWeek + }, { + unicode: 'PgUp/PgDn', + label: phrases.pageUpPageDown, + action: phrases.moveFocusByOneMonth + }, { + unicode: 'Home/End', + label: phrases.homeEnd, + action: phrases.moveFocustoStartAndEndOfWeek + }, { + unicode: 'Esc', + label: phrases.escape, + action: phrases.returnFocusToInput + }, { + unicode: '?', + label: phrases.questionMark, + action: phrases.openThisPanel + }]; +} + +var DayPickerKeyboardShortcuts = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DayPickerKeyboardShortcuts, _ref2); + + var _proto = DayPickerKeyboardShortcuts.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DayPickerKeyboardShortcuts() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + var phrases = _this.props.phrases; + _this.keyboardShortcuts = getKeyboardShortcuts(phrases); + _this.onShowKeyboardShortcutsButtonClick = _this.onShowKeyboardShortcutsButtonClick.bind(_assertThisInitialized(_this)); + _this.setShowKeyboardShortcutsButtonRef = _this.setShowKeyboardShortcutsButtonRef.bind(_assertThisInitialized(_this)); + _this.setHideKeyboardShortcutsButtonRef = _this.setHideKeyboardShortcutsButtonRef.bind(_assertThisInitialized(_this)); + _this.handleFocus = _this.handleFocus.bind(_assertThisInitialized(_this)); + _this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var phrases = this.props.phrases; + + if (nextProps.phrases !== phrases) { + this.keyboardShortcuts = getKeyboardShortcuts(nextProps.phrases); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate() { + this.handleFocus(); + }; + + _proto.handleFocus = function handleFocus() { + if (this.hideKeyboardShortcutsButton) { + // automatically move focus into the dialog by moving + // to the only interactive element, the hide button + this.hideKeyboardShortcutsButton.focus(); + } + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + var closeKeyboardShortcutsPanel = this.props.closeKeyboardShortcutsPanel; // Because the close button is the only focusable element inside of the panel, this + // amounts to a very basic focus trap. The user can exit the panel by "pressing" the + // close button or hitting escape + + switch (e.key) { + case 'Escape': + closeKeyboardShortcutsPanel(); + break; + // do nothing - this allows the up and down arrows continue their + // default behavior of scrolling the content of the Keyboard Shortcuts Panel + // which is needed when only a single month is shown for instance. + + case 'ArrowUp': + case 'ArrowDown': + break; + // completely block the rest of the keys that have functionality outside of this panel + + case 'Tab': + case 'Home': + case 'End': + case 'PageUp': + case 'PageDown': + case 'ArrowLeft': + case 'ArrowRight': + e.preventDefault(); + break; + + default: + break; + } + }; + + _proto.onShowKeyboardShortcutsButtonClick = function onShowKeyboardShortcutsButtonClick() { + var _this2 = this; + + var openKeyboardShortcutsPanel = this.props.openKeyboardShortcutsPanel; // we want to return focus to this button after closing the keyboard shortcuts panel + + openKeyboardShortcutsPanel(function () { + _this2.showKeyboardShortcutsButton.focus(); + }); + }; + + _proto.setShowKeyboardShortcutsButtonRef = function setShowKeyboardShortcutsButtonRef(ref) { + this.showKeyboardShortcutsButton = ref; + }; + + _proto.setHideKeyboardShortcutsButtonRef = function setHideKeyboardShortcutsButtonRef(ref) { + this.hideKeyboardShortcutsButton = ref; + }; + + _proto.render = function render() { + var _this$props = this.props, + block = _this$props.block, + buttonLocation = _this$props.buttonLocation, + showKeyboardShortcutsPanel = _this$props.showKeyboardShortcutsPanel, + closeKeyboardShortcutsPanel = _this$props.closeKeyboardShortcutsPanel, + css = _this$props.css, + styles = _this$props.styles, + phrases = _this$props.phrases, + renderKeyboardShortcutsButton = _this$props.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props.renderKeyboardShortcutsPanel; + var toggleButtonText = showKeyboardShortcutsPanel ? phrases.hideKeyboardShortcutsPanel : phrases.showKeyboardShortcutsPanel; + var bottomRight = buttonLocation === BOTTOM_RIGHT; + var topRight = buttonLocation === TOP_RIGHT; + var topLeft = buttonLocation === TOP_LEFT; + return /*#__PURE__*/React.createElement("div", null, renderKeyboardShortcutsButton && renderKeyboardShortcutsButton({ + // passing in context-specific props + ref: this.setShowKeyboardShortcutsButtonRef, + onClick: this.onShowKeyboardShortcutsButtonClick, + ariaLabel: toggleButtonText + }), !renderKeyboardShortcutsButton && /*#__PURE__*/React.createElement("button", _extends({ + ref: this.setShowKeyboardShortcutsButtonRef + }, css(styles.DayPickerKeyboardShortcuts_buttonReset, styles.DayPickerKeyboardShortcuts_show, bottomRight && styles.DayPickerKeyboardShortcuts_show__bottomRight, topRight && styles.DayPickerKeyboardShortcuts_show__topRight, topLeft && styles.DayPickerKeyboardShortcuts_show__topLeft), { + type: "button", + "aria-label": toggleButtonText, + onClick: this.onShowKeyboardShortcutsButtonClick, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + } + }), /*#__PURE__*/React.createElement("span", css(styles.DayPickerKeyboardShortcuts_showSpan, bottomRight && styles.DayPickerKeyboardShortcuts_showSpan__bottomRight, topRight && styles.DayPickerKeyboardShortcuts_showSpan__topRight, topLeft && styles.DayPickerKeyboardShortcuts_showSpan__topLeft), "?")), showKeyboardShortcutsPanel && (renderKeyboardShortcutsPanel ? renderKeyboardShortcutsPanel({ + closeButtonAriaLabel: phrases.hideKeyboardShortcutsPanel, + keyboardShortcuts: this.keyboardShortcuts, + onCloseButtonClick: closeKeyboardShortcutsPanel, + onKeyDown: this.onKeyDown, + title: phrases.keyboardShortcuts + }) : /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPickerKeyboardShortcuts_panel), { + role: "dialog", + "aria-labelledby": "DayPickerKeyboardShortcuts_title", + "aria-describedby": "DayPickerKeyboardShortcuts_description" + }), /*#__PURE__*/React.createElement("div", _extends({}, css(styles.DayPickerKeyboardShortcuts_title), { + id: "DayPickerKeyboardShortcuts_title" + }), phrases.keyboardShortcuts), /*#__PURE__*/React.createElement("button", _extends({ + ref: this.setHideKeyboardShortcutsButtonRef + }, css(styles.DayPickerKeyboardShortcuts_buttonReset, styles.DayPickerKeyboardShortcuts_close), { + type: "button", + tabIndex: "0", + "aria-label": phrases.hideKeyboardShortcutsPanel, + onClick: closeKeyboardShortcutsPanel, + onKeyDown: this.onKeyDown + }), /*#__PURE__*/React.createElement(CloseButton, css(styles.DayPickerKeyboardShortcuts_closeSvg))), /*#__PURE__*/React.createElement("ul", _extends({}, css(styles.DayPickerKeyboardShortcuts_list), { + id: "DayPickerKeyboardShortcuts_description" + }), this.keyboardShortcuts.map(function (_ref3) { + var unicode = _ref3.unicode, + label = _ref3.label, + action = _ref3.action; + return /*#__PURE__*/React.createElement(KeyboardShortcutRow, { + key: label, + unicode: unicode, + label: label, + action: action, + block: block + }); + }))))); + }; + + return DayPickerKeyboardShortcuts; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +DayPickerKeyboardShortcuts.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerKeyboardShortcuts.defaultProps = defaultProps; +export default withStyles(function (_ref4) { + var _ref4$reactDates = _ref4.reactDates, + color = _ref4$reactDates.color, + font = _ref4$reactDates.font, + zIndex = _ref4$reactDates.zIndex; + return { + DayPickerKeyboardShortcuts_buttonReset: { + background: 'none', + border: 0, + borderRadius: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + padding: 0, + cursor: 'pointer', + fontSize: font.size, + ':active': { + outline: 'none' + } + }, + DayPickerKeyboardShortcuts_show: { + width: 33, + height: 26, + position: 'absolute', + zIndex: zIndex + 2, + '::before': { + content: '""', + display: 'block', + position: 'absolute' + } + }, + DayPickerKeyboardShortcuts_show__bottomRight: { + bottom: 0, + right: 0, + '::before': { + borderTop: '26px solid transparent', + borderRight: "33px solid ".concat(color.core.primary), + bottom: 0, + right: 0 + }, + ':hover::before': { + borderRight: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_show__topRight: { + top: 0, + right: 0, + '::before': { + borderBottom: '26px solid transparent', + borderRight: "33px solid ".concat(color.core.primary), + top: 0, + right: 0 + }, + ':hover::before': { + borderRight: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_show__topLeft: { + top: 0, + left: 0, + '::before': { + borderBottom: '26px solid transparent', + borderLeft: "33px solid ".concat(color.core.primary), + top: 0, + left: 0 + }, + ':hover::before': { + borderLeft: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_showSpan: { + color: color.core.white, + position: 'absolute' + }, + DayPickerKeyboardShortcuts_showSpan__bottomRight: { + bottom: 0, + right: 5 + }, + DayPickerKeyboardShortcuts_showSpan__topRight: { + top: 1, + right: 5 + }, + DayPickerKeyboardShortcuts_showSpan__topLeft: { + top: 1, + left: 5 + }, + DayPickerKeyboardShortcuts_panel: { + overflow: 'auto', + background: color.background, + border: "1px solid ".concat(color.core.border), + borderRadius: 2, + position: 'absolute', + top: 0, + bottom: 0, + right: 0, + left: 0, + zIndex: zIndex + 2, + padding: 22, + margin: 33, + textAlign: 'left' // TODO: investigate use of text-align throughout the library + + }, + DayPickerKeyboardShortcuts_title: { + fontSize: 16, + fontWeight: 'bold', + margin: 0 + }, + DayPickerKeyboardShortcuts_list: { + listStyle: 'none', + padding: 0, + fontSize: font.size + }, + DayPickerKeyboardShortcuts_close: { + position: 'absolute', + right: 22, + top: 22, + zIndex: zIndex + 2, + ':active': { + outline: 'none' + } + }, + DayPickerKeyboardShortcuts_closeSvg: { + height: 15, + width: 15, + fill: color.core.grayLighter, + ':hover': { + fill: color.core.grayLight + }, + ':focus': { + fill: color.core.grayLight + } + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DayPickerKeyboardShortcuts); \ No newline at end of file diff --git a/esm/components/DayPickerNavigation.js b/esm/components/DayPickerNavigation.js new file mode 100644 index 000000000..f88039bc9 --- /dev/null +++ b/esm/components/DayPickerNavigation.js @@ -0,0 +1,339 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { DayPickerNavigationPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import noflip from '../utils/noflip'; +import LeftArrow from './LeftArrow'; +import RightArrow from './RightArrow'; +import ChevronUp from './ChevronUp'; +import ChevronDown from './ChevronDown'; +import NavPositionShape from '../shapes/NavPositionShape'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import { HORIZONTAL_ORIENTATION, NAV_POSITION_BOTTOM, NAV_POSITION_TOP, VERTICAL_SCROLLABLE } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + disablePrev: PropTypes.bool, + disableNext: PropTypes.bool, + inlineStyles: PropTypes.object, + isRTL: PropTypes.bool, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + orientation: ScrollableOrientationShape, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + // internationalization + phrases: PropTypes.shape(getPhrasePropTypes(DayPickerNavigationPhrases)), + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + showNavPrevButton: PropTypes.bool, + showNavNextButton: PropTypes.bool +})) : {}; +var defaultProps = { + disablePrev: false, + disableNext: false, + inlineStyles: null, + isRTL: false, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + orientation: HORIZONTAL_ORIENTATION, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + // internationalization + phrases: DayPickerNavigationPhrases, + renderNavPrevButton: null, + renderNavNextButton: null, + showNavPrevButton: true, + showNavNextButton: true +}; + +var DayPickerNavigation = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DayPickerNavigation, _ref2); + + function DayPickerNavigation() { + return _ref2.apply(this, arguments) || this; + } + + var _proto = DayPickerNavigation.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + _proto.render = function render() { + var _this$props = this.props, + inlineStyles = _this$props.inlineStyles, + isRTL = _this$props.isRTL, + disablePrev = _this$props.disablePrev, + disableNext = _this$props.disableNext, + navPosition = _this$props.navPosition, + navPrev = _this$props.navPrev, + navNext = _this$props.navNext, + onPrevMonthClick = _this$props.onPrevMonthClick, + onNextMonthClick = _this$props.onNextMonthClick, + orientation = _this$props.orientation, + phrases = _this$props.phrases, + renderNavPrevButton = _this$props.renderNavPrevButton, + renderNavNextButton = _this$props.renderNavNextButton, + showNavPrevButton = _this$props.showNavPrevButton, + showNavNextButton = _this$props.showNavNextButton, + css = _this$props.css, + styles = _this$props.styles; + + if (!showNavNextButton && !showNavPrevButton) { + return null; + } + + var isHorizontal = orientation === HORIZONTAL_ORIENTATION; + var isVertical = orientation !== HORIZONTAL_ORIENTATION; + var isVerticalScrollable = orientation === VERTICAL_SCROLLABLE; + var isBottomNavPosition = navPosition === NAV_POSITION_BOTTOM; + var hasInlineStyles = !!inlineStyles; + var navPrevIcon = navPrev; + var navNextIcon = navNext; + var isDefaultNavPrev = false; + var isDefaultNavNext = false; + var navPrevTabIndex = {}; + var navNextTabIndex = {}; + + if (!navPrevIcon && !renderNavPrevButton && showNavPrevButton) { + navPrevTabIndex = { + tabIndex: '0' + }; + isDefaultNavPrev = true; + var Icon = isVertical ? ChevronUp : LeftArrow; + + if (isRTL && !isVertical) { + Icon = RightArrow; + } + + navPrevIcon = /*#__PURE__*/React.createElement(Icon, css(isHorizontal && styles.DayPickerNavigation_svg__horizontal, isVertical && styles.DayPickerNavigation_svg__vertical, disablePrev && styles.DayPickerNavigation_svg__disabled)); + } + + if (!navNextIcon && !renderNavNextButton && showNavNextButton) { + navNextTabIndex = { + tabIndex: '0' + }; + isDefaultNavNext = true; + + var _Icon = isVertical ? ChevronDown : RightArrow; + + if (isRTL && !isVertical) { + _Icon = LeftArrow; + } + + navNextIcon = /*#__PURE__*/React.createElement(_Icon, css(isHorizontal && styles.DayPickerNavigation_svg__horizontal, isVertical && styles.DayPickerNavigation_svg__vertical, disableNext && styles.DayPickerNavigation_svg__disabled)); + } + + var isDefaultNav = isDefaultNavNext || isDefaultNavPrev; + return /*#__PURE__*/React.createElement("div", css.apply(void 0, [styles.DayPickerNavigation, isHorizontal && styles.DayPickerNavigation__horizontal].concat(_toConsumableArray(isVertical ? [styles.DayPickerNavigation__vertical, isDefaultNav && styles.DayPickerNavigation__verticalDefault] : []), _toConsumableArray(isVerticalScrollable ? [styles.DayPickerNavigation__verticalScrollable, isDefaultNav && styles.DayPickerNavigation__verticalScrollableDefault, showNavPrevButton && styles.DayPickerNavigation__verticalScrollable_prevNav] : []), _toConsumableArray(isBottomNavPosition ? [styles.DayPickerNavigation__bottom, isDefaultNav && styles.DayPickerNavigation__bottomDefault] : []), [hasInlineStyles && inlineStyles])), showNavPrevButton && (renderNavPrevButton ? renderNavPrevButton({ + ariaLabel: phrases.jumpToPrevMonth, + disabled: disablePrev, + onClick: disablePrev ? undefined : onPrevMonthClick, + onKeyUp: disablePrev ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onPrevMonthClick(e); + } + }, + onMouseUp: disablePrev ? undefined : function (e) { + e.currentTarget.blur(); + } + }) : /*#__PURE__*/React.createElement("div", _extends({ + // eslint-disable-line jsx-a11y/interactive-supports-focus + role: "button" + }, navPrevTabIndex, css.apply(void 0, [styles.DayPickerNavigation_button, isDefaultNavPrev && styles.DayPickerNavigation_button__default, disablePrev && styles.DayPickerNavigation_button__disabled].concat(_toConsumableArray(isHorizontal ? [styles.DayPickerNavigation_button__horizontal].concat(_toConsumableArray(isDefaultNavPrev ? [styles.DayPickerNavigation_button__horizontalDefault, isBottomNavPosition && styles.DayPickerNavigation_bottomButton__horizontalDefault, !isRTL && styles.DayPickerNavigation_leftButton__horizontalDefault, isRTL && styles.DayPickerNavigation_rightButton__horizontalDefault] : [])) : []), _toConsumableArray(isVertical ? [styles.DayPickerNavigation_button__vertical].concat(_toConsumableArray(isDefaultNavPrev ? [styles.DayPickerNavigation_button__verticalDefault, styles.DayPickerNavigation_prevButton__verticalDefault, isVerticalScrollable && styles.DayPickerNavigation_prevButton__verticalScrollableDefault] : [])) : []))), { + "aria-disabled": disablePrev ? true : undefined, + "aria-label": phrases.jumpToPrevMonth, + onClick: disablePrev ? undefined : onPrevMonthClick, + onKeyUp: disablePrev ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onPrevMonthClick(e); + } + }, + onMouseUp: disablePrev ? undefined : function (e) { + e.currentTarget.blur(); + } + }), navPrevIcon)), showNavNextButton && (renderNavNextButton ? renderNavNextButton({ + ariaLabel: phrases.jumpToNextMonth, + disabled: disableNext, + onClick: disableNext ? undefined : onNextMonthClick, + onKeyUp: disableNext ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onNextMonthClick(e); + } + }, + onMouseUp: disableNext ? undefined : function (e) { + e.currentTarget.blur(); + } + }) : /*#__PURE__*/React.createElement("div", _extends({ + // eslint-disable-line jsx-a11y/interactive-supports-focus + role: "button" + }, navNextTabIndex, css.apply(void 0, [styles.DayPickerNavigation_button, isDefaultNavNext && styles.DayPickerNavigation_button__default, disableNext && styles.DayPickerNavigation_button__disabled].concat(_toConsumableArray(isHorizontal ? [styles.DayPickerNavigation_button__horizontal].concat(_toConsumableArray(isDefaultNavNext ? [styles.DayPickerNavigation_button__horizontalDefault, isBottomNavPosition && styles.DayPickerNavigation_bottomButton__horizontalDefault, isRTL && styles.DayPickerNavigation_leftButton__horizontalDefault, !isRTL && styles.DayPickerNavigation_rightButton__horizontalDefault] : [])) : []), _toConsumableArray(isVertical ? [styles.DayPickerNavigation_button__vertical].concat(_toConsumableArray(isDefaultNavNext ? [styles.DayPickerNavigation_button__verticalDefault, styles.DayPickerNavigation_nextButton__verticalDefault, isVerticalScrollable && styles.DayPickerNavigation_nextButton__verticalScrollableDefault] : [])) : []))), { + "aria-disabled": disableNext ? true : undefined, + "aria-label": phrases.jumpToNextMonth, + onClick: disableNext ? undefined : onNextMonthClick, + onKeyUp: disableNext ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onNextMonthClick(e); + } + }, + onMouseUp: disableNext ? undefined : function (e) { + e.currentTarget.blur(); + } + }), navNextIcon))); + }; + + return DayPickerNavigation; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +DayPickerNavigation.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerNavigation.defaultProps = defaultProps; +export default withStyles(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + zIndex = _ref3$reactDates.zIndex; + return { + DayPickerNavigation: { + position: 'relative', + zIndex: zIndex + 2 + }, + DayPickerNavigation__horizontal: { + height: 0 + }, + DayPickerNavigation__vertical: {}, + DayPickerNavigation__verticalScrollable: {}, + DayPickerNavigation__verticalScrollable_prevNav: { + zIndex: zIndex + 1 // zIndex + 2 causes the button to show on top of the day of week headers + + }, + DayPickerNavigation__verticalDefault: { + position: 'absolute', + width: '100%', + height: 52, + bottom: 0, + left: noflip(0) + }, + DayPickerNavigation__verticalScrollableDefault: { + position: 'relative' + }, + DayPickerNavigation__bottom: { + height: 'auto' + }, + DayPickerNavigation__bottomDefault: { + display: 'flex', + justifyContent: 'space-between' + }, + DayPickerNavigation_button: { + cursor: 'pointer', + userSelect: 'none', + border: 0, + padding: 0, + margin: 0 + }, + DayPickerNavigation_button__default: { + border: "1px solid ".concat(color.core.borderLight), + backgroundColor: color.background, + color: color.placeholderText, + ':focus': { + border: "1px solid ".concat(color.core.borderMedium) + }, + ':hover': { + border: "1px solid ".concat(color.core.borderMedium) + }, + ':active': { + background: color.backgroundDark + } + }, + DayPickerNavigation_button__disabled: { + cursor: 'default', + border: "1px solid ".concat(color.disabled), + ':focus': { + border: "1px solid ".concat(color.disabled) + }, + ':hover': { + border: "1px solid ".concat(color.disabled) + }, + ':active': { + background: 'none' + } + }, + DayPickerNavigation_button__horizontal: {}, + DayPickerNavigation_button__horizontalDefault: { + position: 'absolute', + top: 18, + lineHeight: 0.78, + borderRadius: 3, + padding: '6px 9px' + }, + DayPickerNavigation_bottomButton__horizontalDefault: { + position: 'static', + marginLeft: 22, + marginRight: 22, + marginBottom: 30, + marginTop: -10 + }, + DayPickerNavigation_leftButton__horizontalDefault: { + left: noflip(22) + }, + DayPickerNavigation_rightButton__horizontalDefault: { + right: noflip(22) + }, + DayPickerNavigation_button__vertical: {}, + DayPickerNavigation_button__verticalDefault: { + padding: 5, + background: color.background, + boxShadow: noflip('0 0 5px 2px rgba(0, 0, 0, 0.1)'), + position: 'relative', + display: 'inline-block', + textAlign: 'center', + height: '100%', + width: '50%' + }, + DayPickerNavigation_prevButton__verticalDefault: {}, + DayPickerNavigation_nextButton__verticalDefault: { + borderLeft: noflip(0) + }, + DayPickerNavigation_nextButton__verticalScrollableDefault: { + width: '100%' + }, + DayPickerNavigation_prevButton__verticalScrollableDefault: { + width: '100%' + }, + DayPickerNavigation_svg__horizontal: { + height: 19, + width: 19, + fill: color.core.grayLight, + display: 'block' + }, + DayPickerNavigation_svg__vertical: { + height: 42, + width: 42, + fill: color.text + }, + DayPickerNavigation_svg__disabled: { + fill: color.disabled + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(DayPickerNavigation); \ No newline at end of file diff --git a/esm/components/DayPickerRangeController.js b/esm/components/DayPickerRangeController.js new file mode 100644 index 000000000..2653199d2 --- /dev/null +++ b/esm/components/DayPickerRangeController.js @@ -0,0 +1,1415 @@ +import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import moment from 'moment'; +import values from 'object.values'; +import isTouchDevice from 'is-touch-device'; +import { DayPickerPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay'; +import isNextDay from '../utils/isNextDay'; +import isSameDay from '../utils/isSameDay'; +import isAfterDay from '../utils/isAfterDay'; +import isBeforeDay from '../utils/isBeforeDay'; +import isPreviousDay from '../utils/isPreviousDay'; +import getVisibleDays from '../utils/getVisibleDays'; +import isDayVisible from '../utils/isDayVisible'; +import getSelectedDateOffset from '../utils/getSelectedDateOffset'; +import enumrateDatesBetween from '../utils/enumrateDatesBetween'; +import toISODateString from '../utils/toISODateString'; +import { addModifier as _addModifier, deleteModifier as _deleteModifier } from '../utils/modifiers'; +import DisabledShape from '../shapes/DisabledShape'; +import FocusedInputShape from '../shapes/FocusedInputShape'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import DayOfWeekShape from '../shapes/DayOfWeekShape'; +import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape'; +import NavPositionShape from '../shapes/NavPositionShape'; +import { START_DATE, END_DATE, HORIZONTAL_ORIENTATION, VERTICAL_SCROLLABLE, DAY_SIZE, INFO_POSITION_BOTTOM, NAV_POSITION_TOP } from '../constants'; +import DayPicker from './DayPicker'; +import getPooledMoment from '../utils/getPooledMoment'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps({ + startDate: momentPropTypes.momentObj, + endDate: momentPropTypes.momentObj, + onDatesChange: PropTypes.func, + startDateOffset: PropTypes.func, + endDateOffset: PropTypes.func, + minDate: momentPropTypes.momentObj, + maxDate: momentPropTypes.momentObj, + focusedInput: FocusedInputShape, + onFocusChange: PropTypes.func, + onClose: PropTypes.func, + keepOpenOnDateSelect: PropTypes.bool, + minimumNights: PropTypes.number, + disabled: DisabledShape, + isOutsideRange: PropTypes.func, + isDayBlocked: PropTypes.func, + isDayHighlighted: PropTypes.func, + getMinNightsForHoverDate: PropTypes.func, + daysViolatingMinNightsCanBeClicked: PropTypes.bool, + moveOffsetForDisabledDates: PropTypes.bool, + // DayPicker props + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: PropTypes.func, + enableOutsideDays: PropTypes.bool, + numberOfMonths: PropTypes.number, + orientation: ScrollableOrientationShape, + withPortal: PropTypes.bool, + initialVisibleMonth: PropTypes.func, + hideKeyboardShortcutsPanel: PropTypes.bool, + daySize: nonNegativeInteger, + noBorder: PropTypes.bool, + verticalBorderSpacing: nonNegativeInteger, + horizontalMonthPadding: nonNegativeInteger, + dayPickerNavigationInlineStyles: PropTypes.object, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + noNavButtons: PropTypes.bool, + noNavNextButton: PropTypes.bool, + noNavPrevButton: PropTypes.bool, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + onOutsideClick: PropTypes.func, + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + renderCalendarInfo: PropTypes.func, + renderKeyboardShortcutsButton: PropTypes.func, + renderKeyboardShortcutsPanel: PropTypes.func, + calendarInfoPosition: CalendarInfoPositionShape, + firstDayOfWeek: DayOfWeekShape, + verticalHeight: nonNegativeInteger, + transitionDuration: nonNegativeInteger, + // accessibility + onBlur: PropTypes.func, + isFocused: PropTypes.bool, + showKeyboardShortcuts: PropTypes.bool, + onTab: PropTypes.func, + onShiftTab: PropTypes.func, + // i18n + monthFormat: PropTypes.string, + weekDayFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)), + dayAriaLabelFormat: PropTypes.string, + isRTL: PropTypes.bool +}) : {}; +var defaultProps = { + startDate: undefined, + // TODO: use null + endDate: undefined, + // TODO: use null + minDate: null, + maxDate: null, + onDatesChange: function onDatesChange() {}, + startDateOffset: undefined, + endDateOffset: undefined, + focusedInput: null, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + keepOpenOnDateSelect: false, + minimumNights: 1, + disabled: false, + isOutsideRange: function isOutsideRange() {}, + isDayBlocked: function isDayBlocked() {}, + isDayHighlighted: function isDayHighlighted() {}, + getMinNightsForHoverDate: function getMinNightsForHoverDate() {}, + daysViolatingMinNightsCanBeClicked: false, + moveOffsetForDisabledDates: false, + // DayPicker props + renderMonthText: null, + renderWeekHeaderElement: null, + enableOutsideDays: false, + numberOfMonths: 1, + orientation: HORIZONTAL_ORIENTATION, + withPortal: false, + hideKeyboardShortcutsPanel: false, + initialVisibleMonth: null, + daySize: DAY_SIZE, + dayPickerNavigationInlineStyles: null, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onOutsideClick: function onOutsideClick() {}, + renderCalendarDay: undefined, + renderDayContents: null, + renderCalendarInfo: null, + renderMonthElement: null, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined, + calendarInfoPosition: INFO_POSITION_BOTTOM, + firstDayOfWeek: null, + verticalHeight: null, + noBorder: false, + transitionDuration: undefined, + verticalBorderSpacing: undefined, + horizontalMonthPadding: 13, + // accessibility + onBlur: function onBlur() {}, + isFocused: false, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // i18n + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: DayPickerPhrases, + dayAriaLabelFormat: undefined, + isRTL: false +}; + +var getChooseAvailableDatePhrase = function getChooseAvailableDatePhrase(phrases, focusedInput) { + if (focusedInput === START_DATE) { + return phrases.chooseAvailableStartDate; + } + + if (focusedInput === END_DATE) { + return phrases.chooseAvailableEndDate; + } + + return phrases.chooseAvailableDate; +}; + +var DayPickerRangeController = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DayPickerRangeController, _ref2); + + var _proto = DayPickerRangeController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DayPickerRangeController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = isTouchDevice(); + _this.today = moment(); + _this.modifiers = { + today: function today(day) { + return _this.isToday(day); + }, + blocked: function blocked(day) { + return _this.isBlocked(day); + }, + 'blocked-calendar': function blockedCalendar(day) { + return props.isDayBlocked(day); + }, + 'blocked-out-of-range': function blockedOutOfRange(day) { + return props.isOutsideRange(day); + }, + 'highlighted-calendar': function highlightedCalendar(day) { + return props.isDayHighlighted(day); + }, + valid: function valid(day) { + return !_this.isBlocked(day); + }, + 'selected-start': function selectedStart(day) { + return _this.isStartDate(day); + }, + 'selected-end': function selectedEnd(day) { + return _this.isEndDate(day); + }, + 'blocked-minimum-nights': function blockedMinimumNights(day) { + return _this.doesNotMeetMinimumNights(day); + }, + 'selected-span': function selectedSpan(day) { + return _this.isInSelectedSpan(day); + }, + 'last-in-range': function lastInRange(day) { + return _this.isLastInRange(day); + }, + hovered: function hovered(day) { + return _this.isHovered(day); + }, + 'hovered-span': function hoveredSpan(day) { + return _this.isInHoveredSpan(day); + }, + 'hovered-offset': function hoveredOffset(day) { + return _this.isInHoveredSpan(day); + }, + 'after-hovered-start': function afterHoveredStart(day) { + return _this.isDayAfterHoveredStartDate(day); + }, + 'first-day-of-week': function firstDayOfWeek(day) { + return _this.isFirstDayOfWeek(day); + }, + 'last-day-of-week': function lastDayOfWeek(day) { + return _this.isLastDayOfWeek(day); + }, + 'hovered-start-first-possible-end': function hoveredStartFirstPossibleEnd(day, hoverDate) { + return _this.isFirstPossibleEndDateForHoveredStartDate(day, hoverDate); + }, + 'hovered-start-blocked-minimum-nights': function hoveredStartBlockedMinimumNights(day, hoverDate) { + return _this.doesNotMeetMinNightsForHoveredStartDate(day, hoverDate); + }, + 'before-hovered-end': function beforeHoveredEnd(day) { + return _this.isDayBeforeHoveredEndDate(day); + }, + 'no-selected-start-before-selected-end': function noSelectedStartBeforeSelectedEnd(day) { + return _this.beforeSelectedEnd(day) && !props.startDate; + }, + 'selected-start-in-hovered-span': function selectedStartInHoveredSpan(day, hoverDate) { + return _this.isStartDate(day) && isAfterDay(hoverDate, day); + }, + 'selected-start-no-selected-end': function selectedStartNoSelectedEnd(day) { + return _this.isStartDate(day) && !props.endDate; + }, + 'selected-end-no-selected-start': function selectedEndNoSelectedStart(day) { + return _this.isEndDate(day) && !props.startDate; + } + }; + + 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: _objectSpread(_objectSpread({}, props.phrases), {}, { + chooseAvailableDate: chooseAvailableDate + }), + visibleDays: visibleDays, + disablePrev: _this.shouldDisableMonthNavigation(props.minDate, currentMonth), + disableNext: _this.shouldDisableMonthNavigation(props.maxDate, currentMonth) + }; + _this.onDayClick = _this.onDayClick.bind(_assertThisInitialized(_this)); + _this.onDayMouseEnter = _this.onDayMouseEnter.bind(_assertThisInitialized(_this)); + _this.onDayMouseLeave = _this.onDayMouseLeave.bind(_assertThisInitialized(_this)); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind(_assertThisInitialized(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind(_assertThisInitialized(_this)); + _this.onMonthChange = _this.onMonthChange.bind(_assertThisInitialized(_this)); + _this.onYearChange = _this.onYearChange.bind(_assertThisInitialized(_this)); + _this.onGetNextScrollableMonths = _this.onGetNextScrollableMonths.bind(_assertThisInitialized(_this)); + _this.onGetPrevScrollableMonths = _this.onGetPrevScrollableMonths.bind(_assertThisInitialized(_this)); + _this.getFirstFocusableDay = _this.getFirstFocusableDay.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var startDate = nextProps.startDate, + endDate = nextProps.endDate, + focusedInput = nextProps.focusedInput, + getMinNightsForHoverDate = nextProps.getMinNightsForHoverDate, + 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 _this$props = this.props, + prevStartDate = _this$props.startDate, + prevEndDate = _this$props.endDate, + prevFocusedInput = _this$props.focusedInput, + prevMinimumNights = _this$props.minimumNights, + prevIsOutsideRange = _this$props.isOutsideRange, + prevIsDayBlocked = _this$props.isDayBlocked, + prevIsDayHighlighted = _this$props.isDayHighlighted, + prevPhrases = _this$props.phrases, + prevInitialVisibleMonth = _this$props.initialVisibleMonth, + prevNumberOfMonths = _this$props.numberOfMonths, + prevEnableOutsideDays = _this$props.enableOutsideDays; + var hoverDate = this.state.hoverDate; + 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 (!endDate || !prevEndDate) { + modifiers = this.deleteModifier(modifiers, prevStartDate, 'selected-start-no-selected-end'); + } + } + + if (!prevStartDate && endDate && startDate) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-no-selected-start'); + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + values(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = moment(day); + modifiers = _this2.deleteModifier(modifiers, momentObj, 'no-selected-start-before-selected-end'); + }); + }); + } + } + + if (didEndDateChange) { + modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end'); + modifiers = this.addModifier(modifiers, endDate, 'selected-end'); + + if (prevEndDate && (!startDate || !prevStartDate)) { + modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end-no-selected-start'); + } + } + + 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 (startDate && !endDate) { + modifiers = this.addModifier(modifiers, startDate, 'selected-start-no-selected-end'); + } + + if (endDate && !startDate) { + modifiers = this.addModifier(modifiers, endDate, 'selected-end-no-selected-start'); + } + + if (!startDate && endDate) { + values(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = moment(day); + + if (isBeforeDay(momentObj, endDate)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'no-selected-start-before-selected-end'); + } + }); + }); + } + } + + 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 (!this.isTouchDevice && didEndDateChange && !startDate && endDate) { + var _startSpan2 = endDate.clone().subtract(minimumNights, 'days'); + + var _endSpan2 = endDate.clone(); + + modifiers = this.addModifierToRange(modifiers, _startSpan2, _endSpan2, 'before-hovered-end'); + } + + if (prevMinimumNights > 0) { + if (didFocusChange || didStartDateChange || minimumNights !== prevMinimumNights) { + var _startSpan3 = prevStartDate || this.today; + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan3, _startSpan3.clone().add(prevMinimumNights, 'days'), 'blocked-minimum-nights'); + modifiers = this.deleteModifierFromRange(modifiers, _startSpan3, _startSpan3.clone().add(prevMinimumNights, 'days'), 'blocked'); + } + } + + if (didFocusChange || recomputePropModifiers) { + values(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = getPooledMoment(day); + var isBlocked = false; + + if (didFocusChange || recomputeOutsideRange) { + if (isOutsideRange(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-out-of-range'); + isBlocked = true; + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-out-of-range'); + } + } + + if (didFocusChange || recomputeDayBlocked) { + if (isDayBlocked(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-calendar'); + isBlocked = true; + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-calendar'); + } + } + + if (isBlocked) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked'); + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked'); + } + + if (didFocusChange || recomputeDayHighlighted) { + if (isDayHighlighted(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'highlighted-calendar'); + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'highlighted-calendar'); + } + } + }); + }); + } + + if (!this.isTouchDevice && didFocusChange && hoverDate && !this.isBlocked(hoverDate)) { + var minNightsForHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForHoverDate > 0 && focusedInput === END_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + + if (minNightsForHoverDate > 0 && focusedInput === START_DATE) { + modifiers = this.addModifierToRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.addModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + if (minimumNights > 0 && startDate && focusedInput === END_DATE) { + modifiers = this.addModifierToRange(modifiers, startDate, startDate.clone().add(minimumNights, 'days'), 'blocked-minimum-nights'); + modifiers = this.addModifierToRange(modifiers, startDate, startDate.clone().add(minimumNights, 'days'), 'blocked'); + } + + var today = moment(); + + if (!isSameDay(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: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + + if (didFocusChange || phrases !== prevPhrases) { + // set the appropriate CalendarDay phrase based on focusedInput + var chooseAvailableDate = getChooseAvailableDatePhrase(phrases, focusedInput); + this.setState({ + phrases: _objectSpread(_objectSpread({}, phrases), {}, { + chooseAvailableDate: chooseAvailableDate + }) + }); + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var _this$props2 = this.props, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + minimumNights = _this$props2.minimumNights, + onBlur = _this$props2.onBlur, + focusedInput = _this$props2.focusedInput, + onFocusChange = _this$props2.onFocusChange, + onClose = _this$props2.onClose, + onDatesChange = _this$props2.onDatesChange, + startDateOffset = _this$props2.startDateOffset, + endDateOffset = _this$props2.endDateOffset, + disabled = _this$props2.disabled, + daysViolatingMinNightsCanBeClicked = _this$props2.daysViolatingMinNightsCanBeClicked, + moveOffsetForDisabledDates = _this$props2.moveOffsetForDisabledDates; + if (e) e.preventDefault(); + if (this.isBlocked(day, !daysViolatingMinNightsCanBeClicked)) return; + var _this$props3 = this.props, + startDate = _this$props3.startDate, + endDate = _this$props3.endDate; + + if (startDateOffset || endDateOffset) { + startDate = getSelectedDateOffset(startDateOffset, day); + + if (moveOffsetForDisabledDates) { + endDate = this.getDisabledEndDateOffset(startDate, getSelectedDateOffset(endDateOffset, day)); + } else { + endDate = getSelectedDateOffset(endDateOffset, day); + } + + if (this.isBlocked(startDate) || this.isBlocked(endDate)) { + return; + } + + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (!keepOpenOnDateSelect) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } + } else if (focusedInput === START_DATE) { + var lastAllowedStartDate = endDate && endDate.clone().subtract(minimumNights, 'days'); + var isStartDateAfterEndDate = isBeforeDay(lastAllowedStartDate, day) || isAfterDay(startDate, endDate); + var isEndDateDisabled = disabled === END_DATE; + + if (!isEndDateDisabled || !isStartDateAfterEndDate) { + startDate = day; + + if (isStartDateAfterEndDate) { + endDate = null; + } + } + + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (isEndDateDisabled && !isStartDateAfterEndDate) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } else if (!isEndDateDisabled) { + onFocusChange(END_DATE); + } + } else if (focusedInput === END_DATE) { + var firstAllowedEndDate = startDate && startDate.clone().add(minimumNights, 'days'); + + if (!startDate) { + endDate = day; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + onFocusChange(START_DATE); + } else if (isInclusivelyAfterDay(day, firstAllowedEndDate)) { + endDate = day; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (!keepOpenOnDateSelect) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } + } else if (daysViolatingMinNightsCanBeClicked && this.doesNotMeetMinimumNights(day)) { + endDate = day; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } else if (disabled !== START_DATE) { + startDate = day; + endDate = null; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } else { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } + } else { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } + + onBlur(); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day) { + /* eslint react/destructuring-assignment: 1 */ + if (this.isTouchDevice) return; + var _this$props4 = this.props, + startDate = _this$props4.startDate, + endDate = _this$props4.endDate, + focusedInput = _this$props4.focusedInput, + getMinNightsForHoverDate = _this$props4.getMinNightsForHoverDate, + minimumNights = _this$props4.minimumNights, + startDateOffset = _this$props4.startDateOffset, + endDateOffset = _this$props4.endDateOffset, + moveOffsetForDisabledDates = _this$props4.moveOffsetForDisabledDates; + var _this$state = this.state, + hoverDate = _this$state.hoverDate, + visibleDays = _this$state.visibleDays, + dateOffset = _this$state.dateOffset; + var nextDateOffset = null; + + if (focusedInput) { + var hasOffset = startDateOffset || endDateOffset; + var modifiers = {}; + + if (hasOffset) { + var start = getSelectedDateOffset(startDateOffset, day); + var end = null; + + if (moveOffsetForDisabledDates) { + end = this.getDisabledEndDateOffset(start, getSelectedDateOffset(endDateOffset, day, function (rangeDay) { + return rangeDay.add(1, 'day'); + })); + } else { + end = getSelectedDateOffset(endDateOffset, day, function (rangeDay) { + return rangeDay.add(1, 'day'); + }); + } + + nextDateOffset = { + start: start, + end: end + }; // eslint-disable-next-line react/destructuring-assignment + + if (dateOffset && dateOffset.start && dateOffset.end) { + modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, 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 === END_DATE) { + if (isAfterDay(hoverDate, startDate)) { + var endSpan = hoverDate.clone().add(1, 'day'); + modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); + } + + if (isBeforeDay(day, startDate) || isSameDay(day, startDate)) { + modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + + if (!this.isBlocked(day) && isAfterDay(day, startDate)) { + var _endSpan3 = day.clone().add(1, 'day'); + + modifiers = this.addModifierToRange(modifiers, startDate, _endSpan3, 'hovered-span'); + modifiers = this.addModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + } + + if (!startDate && endDate && focusedInput === START_DATE) { + if (isBeforeDay(hoverDate, endDate)) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); + } + + if (isAfterDay(day, endDate) || isSameDay(day, endDate)) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + + if (!this.isBlocked(day) && isBeforeDay(day, endDate)) { + modifiers = this.addModifierToRange(modifiers, day, endDate, 'hovered-span'); + modifiers = this.addModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + } + + if (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'); + + if (isSameDay(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'); + } + } + + if (endDate) { + var _startSpan4 = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan4, endDate, 'before-hovered-end'); + + if (isSameDay(day, endDate)) { + var _newStartSpan = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.addModifierToRange(modifiers, _newStartSpan, endDate, 'before-hovered-end'); + } + } + + if (hoverDate && !this.isBlocked(hoverDate)) { + var minNightsForPrevHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForPrevHoverDate > 0 && focusedInput === START_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForPrevHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForPrevHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + if (!this.isBlocked(day)) { + var minNightsForHoverDate = getMinNightsForHoverDate(day); + + if (minNightsForHoverDate > 0 && focusedInput === START_DATE) { + modifiers = this.addModifierToRange(modifiers, day.clone().add(1, 'days'), day.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.addModifier(modifiers, day.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + } + + this.setState({ + hoverDate: day, + dateOffset: nextDateOffset, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day) { + var _this$props5 = this.props, + startDate = _this$props5.startDate, + endDate = _this$props5.endDate, + focusedInput = _this$props5.focusedInput, + getMinNightsForHoverDate = _this$props5.getMinNightsForHoverDate, + minimumNights = _this$props5.minimumNights; + var _this$state2 = this.state, + hoverDate = _this$state2.hoverDate, + visibleDays = _this$state2.visibleDays, + dateOffset = _this$state2.dateOffset; + if (this.isTouchDevice || !hoverDate) return; + var modifiers = {}; + modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered'); + + if (dateOffset) { + modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, dateOffset.end, 'hovered-offset'); + } + + if (startDate && !endDate) { + if (isAfterDay(hoverDate, startDate)) { + var endSpan = hoverDate.clone().add(1, 'day'); + modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); + } + + if (isAfterDay(day, startDate)) { + modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + } + + if (!startDate && endDate) { + if (isAfterDay(endDate, hoverDate)) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); + } + + if (isBeforeDay(day, endDate)) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + } + + if (startDate && isSameDay(day, startDate)) { + var startSpan = startDate.clone().add(1, 'day'); + + var _endSpan5 = startDate.clone().add(minimumNights + 1, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, startSpan, _endSpan5, 'after-hovered-start'); + } + + if (endDate && isSameDay(day, endDate)) { + var _startSpan5 = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan5, endDate, 'before-hovered-end'); + } + + if (!this.isBlocked(hoverDate)) { + var minNightsForHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForHoverDate > 0 && focusedInput === START_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + this.setState({ + hoverDate: null, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onPrevMonthClick = function onPrevMonthClick() { + var _this$props6 = this.props, + enableOutsideDays = _this$props6.enableOutsideDays, + maxDate = _this$props6.maxDate, + minDate = _this$props6.minDate, + numberOfMonths = _this$props6.numberOfMonths, + onPrevMonthClick = _this$props6.onPrevMonthClick; + var _this$state3 = this.state, + currentMonth = _this$state3.currentMonth, + visibleDays = _this$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 = getVisibleDays(prevMonth, 1, enableOutsideDays, true); + var newCurrentMonth = currentMonth.clone().subtract(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(prevMonthVisibleDays)) + }, function () { + onPrevMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick() { + var _this$props7 = this.props, + enableOutsideDays = _this$props7.enableOutsideDays, + maxDate = _this$props7.maxDate, + minDate = _this$props7.minDate, + numberOfMonths = _this$props7.numberOfMonths, + onNextMonthClick = _this$props7.onNextMonthClick; + var _this$state4 = this.state, + currentMonth = _this$state4.currentMonth, + visibleDays = _this$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 = getVisibleDays(nextMonth, 1, enableOutsideDays, true); + var newCurrentMonth = currentMonth.clone().add(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(nextMonthVisibleDays)) + }, function () { + onNextMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onMonthChange = function onMonthChange(newMonth) { + var _this$props8 = this.props, + numberOfMonths = _this$props8.numberOfMonths, + enableOutsideDays = _this$props8.enableOutsideDays, + orientation = _this$props8.orientation; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var newVisibleDays = getVisibleDays(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onYearChange = function onYearChange(newMonth) { + var _this$props9 = this.props, + numberOfMonths = _this$props9.numberOfMonths, + enableOutsideDays = _this$props9.enableOutsideDays, + orientation = _this$props9.orientation; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var newVisibleDays = getVisibleDays(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onGetNextScrollableMonths = function onGetNextScrollableMonths() { + var _this$props10 = this.props, + numberOfMonths = _this$props10.numberOfMonths, + enableOutsideDays = _this$props10.enableOutsideDays; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + visibleDays = _this$state5.visibleDays; + var numberOfVisibleMonths = Object.keys(visibleDays).length; + var nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month'); + var newVisibleDays = getVisibleDays(nextMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.onGetPrevScrollableMonths = function onGetPrevScrollableMonths() { + var _this$props11 = this.props, + numberOfMonths = _this$props11.numberOfMonths, + enableOutsideDays = _this$props11.enableOutsideDays; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + visibleDays = _this$state6.visibleDays; + var firstPreviousMonth = currentMonth.clone().subtract(numberOfMonths, 'month'); + var newVisibleDays = getVisibleDays(firstPreviousMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + currentMonth: firstPreviousMonth.clone(), + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return moment.localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getFirstFocusableDay = function getFirstFocusableDay(newMonth) { + var _this3 = this; + + var _this$props12 = this.props, + startDate = _this$props12.startDate, + endDate = _this$props12.endDate, + focusedInput = _this$props12.focusedInput, + minimumNights = _this$props12.minimumNights, + numberOfMonths = _this$props12.numberOfMonths; + var focusedDate = newMonth.clone().startOf('month').hour(12); + + if (focusedInput === START_DATE && startDate) { + focusedDate = startDate.clone(); + } else if (focusedInput === END_DATE && !endDate && startDate) { + focusedDate = startDate.clone().add(minimumNights, 'days'); + } else if (focusedInput === 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 (!isAfterDay(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; + }; + + _proto.getModifiers = function getModifiers(visibleDays) { + var _this4 = this; + + var modifiers = {}; + Object.keys(visibleDays).forEach(function (month) { + modifiers[month] = {}; + visibleDays[month].forEach(function (day) { + modifiers[month][toISODateString(day)] = _this4.getModifiersForDay(day); + }); + }); + return modifiers; + }; + + _proto.getModifiersForDay = function getModifiersForDay(day) { + var _this5 = this; + + return new Set(Object.keys(this.modifiers).filter(function (modifier) { + return _this5.modifiers[modifier](day); + })); + }; + + _proto.getStateForNewMonth = 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 === VERTICAL_SCROLLABLE; + var visibleDays = this.getModifiers(getVisibleDays(currentMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths)); + return { + currentMonth: currentMonth, + visibleDays: visibleDays + }; + }; + + _proto.shouldDisableMonthNavigation = function shouldDisableMonthNavigation(date, visibleMonth) { + if (!date) return false; + var _this$props13 = this.props, + numberOfMonths = _this$props13.numberOfMonths, + enableOutsideDays = _this$props13.enableOutsideDays; + return isDayVisible(date, visibleMonth, numberOfMonths, enableOutsideDays); + }; + + _proto.addModifier = function addModifier(updatedDays, day, modifier) { + return _addModifier(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.addModifierToRange = function addModifierToRange(updatedDays, start, end, modifier) { + var days = updatedDays; + var spanStart = start.clone(); + + while (isBeforeDay(spanStart, end)) { + days = this.addModifier(days, spanStart, modifier); + spanStart = spanStart.clone().add(1, 'day'); + } + + return days; + }; + + _proto.deleteModifier = function deleteModifier(updatedDays, day, modifier) { + return _deleteModifier(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.deleteModifierFromRange = function deleteModifierFromRange(updatedDays, start, end, modifier) { + var days = updatedDays; + var spanStart = start.clone(); + + while (isBeforeDay(spanStart, end)) { + days = this.deleteModifier(days, spanStart, modifier); + spanStart = spanStart.clone().add(1, 'day'); + } + + return days; + }; + + _proto.doesNotMeetMinimumNights = function doesNotMeetMinimumNights(day) { + var _this$props14 = this.props, + startDate = _this$props14.startDate, + isOutsideRange = _this$props14.isOutsideRange, + focusedInput = _this$props14.focusedInput, + minimumNights = _this$props14.minimumNights; + if (focusedInput !== END_DATE) return false; + + if (startDate) { + var dayDiff = day.diff(startDate.clone().startOf('day').hour(12), 'days'); + return dayDiff < minimumNights && dayDiff >= 0; + } + + return isOutsideRange(moment(day).subtract(minimumNights, 'days')); + }; + + _proto.doesNotMeetMinNightsForHoveredStartDate = function doesNotMeetMinNightsForHoveredStartDate(day, hoverDate) { + var _this$props15 = this.props, + focusedInput = _this$props15.focusedInput, + getMinNightsForHoverDate = _this$props15.getMinNightsForHoverDate; + if (focusedInput !== END_DATE) return false; + + if (hoverDate && !this.isBlocked(hoverDate)) { + var minNights = getMinNightsForHoverDate(hoverDate); + var dayDiff = day.diff(hoverDate.clone().startOf('day').hour(12), 'days'); + return dayDiff < minNights && dayDiff >= 0; + } + + return false; + }; + + _proto.getDisabledEndDateOffset = function getDisabledEndDateOffset(start, end) { + var _this7 = this; + + var isSaturday = this.isSaturday(end); + var dates = enumrateDatesBetween(start, end); + var daysToAdd = 0; + dates.map(function (d) { + if (_this7.isBlocked(moment(d))) { + daysToAdd++; + } + }); + var newEndDate = end.add(isSaturday ? 2 : daysToAdd, 'day'); + return newEndDate; + }; + + _proto.isDayAfterHoveredStartDate = function isDayAfterHoveredStartDate(day) { + var _this$props16 = this.props, + startDate = _this$props16.startDate, + endDate = _this$props16.endDate, + minimumNights = _this$props16.minimumNights; + + var _ref3 = this.state || {}, + hoverDate = _ref3.hoverDate; + + return !!startDate && !endDate && !this.isBlocked(day) && isNextDay(hoverDate, day) && minimumNights > 0 && isSameDay(hoverDate, startDate); + }; + + _proto.isEndDate = function isEndDate(day) { + var endDate = this.props.endDate; + return isSameDay(day, endDate); + }; + + _proto.isHovered = function isHovered(day) { + var _ref4 = this.state || {}, + hoverDate = _ref4.hoverDate; + + var focusedInput = this.props.focusedInput; + return !!focusedInput && isSameDay(day, hoverDate); + }; + + _proto.isInHoveredSpan = function isInHoveredSpan(day) { + var _this$props17 = this.props, + startDate = _this$props17.startDate, + endDate = _this$props17.endDate; + + var _ref5 = this.state || {}, + hoverDate = _ref5.hoverDate; + + var isForwardRange = !!startDate && !endDate && (day.isBetween(startDate, hoverDate) || isSameDay(hoverDate, day)); + var isBackwardRange = !!endDate && !startDate && (day.isBetween(hoverDate, endDate) || isSameDay(hoverDate, day)); + var isValidDayHovered = hoverDate && !this.isBlocked(hoverDate); + return (isForwardRange || isBackwardRange) && isValidDayHovered; + }; + + _proto.isInSelectedSpan = function isInSelectedSpan(day) { + var _this$props18 = this.props, + startDate = _this$props18.startDate, + endDate = _this$props18.endDate; + return day.isBetween(startDate, endDate, 'days'); + }; + + _proto.isLastInRange = function isLastInRange(day) { + var endDate = this.props.endDate; + return this.isInSelectedSpan(day) && isNextDay(day, endDate); + }; + + _proto.isStartDate = function isStartDate(day) { + var startDate = this.props.startDate; + return isSameDay(day, startDate); + }; + + _proto.isBlocked = function isBlocked(day) { + var blockDaysViolatingMinNights = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _this$props19 = this.props, + isDayBlocked = _this$props19.isDayBlocked, + isOutsideRange = _this$props19.isOutsideRange; + return isDayBlocked(day) || isOutsideRange(day) || blockDaysViolatingMinNights && this.doesNotMeetMinimumNights(day); + }; + + _proto.isSunday = function isSunday(day) { + var dateDay = day.day(); + return dateDay === 0; + }; + + _proto.isSaturday = function isSaturday(day) { + var dateDay = day.day(); + return dateDay === 6; + }; + + _proto.isToday = function isToday(day) { + return isSameDay(day, this.today); + }; + + _proto.isFirstDayOfWeek = function isFirstDayOfWeek(day) { + return day.day() === this.getFirstDayOfWeek(); + }; + + _proto.isLastDayOfWeek = function isLastDayOfWeek(day) { + return day.day() === (this.getFirstDayOfWeek() + 6) % 7; + }; + + _proto.isFirstPossibleEndDateForHoveredStartDate = function isFirstPossibleEndDateForHoveredStartDate(day, hoverDate) { + var _this$props20 = this.props, + focusedInput = _this$props20.focusedInput, + getMinNightsForHoverDate = _this$props20.getMinNightsForHoverDate; + if (focusedInput !== END_DATE || !hoverDate || this.isBlocked(hoverDate)) return false; + var minNights = getMinNightsForHoverDate(hoverDate); + var firstAvailableEndDate = hoverDate.clone().add(minNights, 'days'); + return isSameDay(day, firstAvailableEndDate); + }; + + _proto.beforeSelectedEnd = function beforeSelectedEnd(day) { + var endDate = this.props.endDate; + return isBeforeDay(day, endDate); + }; + + _proto.isDayBeforeHoveredEndDate = function isDayBeforeHoveredEndDate(day) { + var _this$props21 = this.props, + startDate = _this$props21.startDate, + endDate = _this$props21.endDate, + minimumNights = _this$props21.minimumNights; + + var _ref6 = this.state || {}, + hoverDate = _ref6.hoverDate; + + return !!endDate && !startDate && !this.isBlocked(day) && isPreviousDay(hoverDate, day) && minimumNights > 0 && isSameDay(hoverDate, endDate); + }; + + _proto.render = function render() { + var _this$props22 = this.props, + numberOfMonths = _this$props22.numberOfMonths, + orientation = _this$props22.orientation, + monthFormat = _this$props22.monthFormat, + renderMonthText = _this$props22.renderMonthText, + renderWeekHeaderElement = _this$props22.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props22.dayPickerNavigationInlineStyles, + navPosition = _this$props22.navPosition, + navPrev = _this$props22.navPrev, + navNext = _this$props22.navNext, + renderNavPrevButton = _this$props22.renderNavPrevButton, + renderNavNextButton = _this$props22.renderNavNextButton, + noNavButtons = _this$props22.noNavButtons, + noNavNextButton = _this$props22.noNavNextButton, + noNavPrevButton = _this$props22.noNavPrevButton, + onOutsideClick = _this$props22.onOutsideClick, + withPortal = _this$props22.withPortal, + enableOutsideDays = _this$props22.enableOutsideDays, + firstDayOfWeek = _this$props22.firstDayOfWeek, + renderKeyboardShortcutsButton = _this$props22.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props22.renderKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel = _this$props22.hideKeyboardShortcutsPanel, + daySize = _this$props22.daySize, + focusedInput = _this$props22.focusedInput, + renderCalendarDay = _this$props22.renderCalendarDay, + renderDayContents = _this$props22.renderDayContents, + renderCalendarInfo = _this$props22.renderCalendarInfo, + renderMonthElement = _this$props22.renderMonthElement, + calendarInfoPosition = _this$props22.calendarInfoPosition, + onBlur = _this$props22.onBlur, + onShiftTab = _this$props22.onShiftTab, + onTab = _this$props22.onTab, + isFocused = _this$props22.isFocused, + showKeyboardShortcuts = _this$props22.showKeyboardShortcuts, + isRTL = _this$props22.isRTL, + weekDayFormat = _this$props22.weekDayFormat, + dayAriaLabelFormat = _this$props22.dayAriaLabelFormat, + verticalHeight = _this$props22.verticalHeight, + noBorder = _this$props22.noBorder, + transitionDuration = _this$props22.transitionDuration, + verticalBorderSpacing = _this$props22.verticalBorderSpacing, + horizontalMonthPadding = _this$props22.horizontalMonthPadding; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + phrases = _this$state7.phrases, + visibleDays = _this$state7.visibleDays, + disablePrev = _this$state7.disablePrev, + disableNext = _this$state7.disableNext; + return /*#__PURE__*/React.createElement(DayPicker, { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + modifiers: visibleDays, + numberOfMonths: numberOfMonths, + onDayClick: this.onDayClick, + onDayMouseEnter: this.onDayMouseEnter, + onDayMouseLeave: this.onDayMouseLeave, + onPrevMonthClick: this.onPrevMonthClick, + onNextMonthClick: this.onNextMonthClick, + onMonthChange: this.onMonthChange, + onTab: onTab, + onShiftTab: onShiftTab, + onYearChange: this.onYearChange, + onGetNextScrollableMonths: this.onGetNextScrollableMonths, + onGetPrevScrollableMonths: this.onGetPrevScrollableMonths, + monthFormat: monthFormat, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + withPortal: withPortal, + hidden: !focusedInput, + initialVisibleMonth: function initialVisibleMonth() { + return currentMonth; + }, + daySize: daySize, + onOutsideClick: onOutsideClick, + disablePrev: disablePrev, + disableNext: disableNext, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + noNavButtons: noNavButtons, + noNavPrevButton: noNavPrevButton, + noNavNextButton: noNavNextButton, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + renderKeyboardShortcutsButton: renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel: renderKeyboardShortcutsPanel, + calendarInfoPosition: calendarInfoPosition, + firstDayOfWeek: firstDayOfWeek, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + isFocused: isFocused, + getFirstFocusableDay: this.getFirstFocusableDay, + onBlur: onBlur, + showKeyboardShortcuts: showKeyboardShortcuts, + phrases: phrases, + isRTL: isRTL, + weekDayFormat: weekDayFormat, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalHeight: verticalHeight, + verticalBorderSpacing: verticalBorderSpacing, + noBorder: noBorder, + transitionDuration: transitionDuration, + horizontalMonthPadding: horizontalMonthPadding + }); + }; + + return DayPickerRangeController; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +export { DayPickerRangeController as default }; +DayPickerRangeController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerRangeController.defaultProps = defaultProps; \ No newline at end of file diff --git a/esm/components/DayPickerSingleDateController.js b/esm/components/DayPickerSingleDateController.js new file mode 100644 index 000000000..dc278f2a6 --- /dev/null +++ b/esm/components/DayPickerSingleDateController.js @@ -0,0 +1,765 @@ +import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import moment from 'moment'; +import values from 'object.values'; +import isTouchDevice from 'is-touch-device'; +import { DayPickerPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import isSameDay from '../utils/isSameDay'; +import isAfterDay from '../utils/isAfterDay'; +import isDayVisible from '../utils/isDayVisible'; +import getVisibleDays from '../utils/getVisibleDays'; +import toISODateString from '../utils/toISODateString'; +import { addModifier as _addModifier, deleteModifier as _deleteModifier } from '../utils/modifiers'; +import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape'; +import DayOfWeekShape from '../shapes/DayOfWeekShape'; +import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape'; +import NavPositionShape from '../shapes/NavPositionShape'; +import { HORIZONTAL_ORIENTATION, VERTICAL_SCROLLABLE, DAY_SIZE, INFO_POSITION_BOTTOM, NAV_POSITION_TOP } from '../constants'; +import DayPicker from './DayPicker'; +import getPooledMoment from '../utils/getPooledMoment'; // Default value of the date property. Represents the state +// when there is no date selected. +// TODO: use null + +var DATE_UNSET_VALUE = undefined; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps({ + date: momentPropTypes.momentObj, + minDate: momentPropTypes.momentObj, + maxDate: momentPropTypes.momentObj, + onDateChange: PropTypes.func, + allowUnselect: PropTypes.bool, + focused: PropTypes.bool, + onFocusChange: PropTypes.func, + onClose: PropTypes.func, + keepOpenOnDateSelect: PropTypes.bool, + isOutsideRange: PropTypes.func, + isDayBlocked: PropTypes.func, + isDayHighlighted: PropTypes.func, + // DayPicker props + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: PropTypes.func, + enableOutsideDays: PropTypes.bool, + numberOfMonths: PropTypes.number, + orientation: ScrollableOrientationShape, + withPortal: PropTypes.bool, + initialVisibleMonth: PropTypes.func, + firstDayOfWeek: DayOfWeekShape, + hideKeyboardShortcutsPanel: PropTypes.bool, + daySize: nonNegativeInteger, + verticalHeight: nonNegativeInteger, + noBorder: PropTypes.bool, + verticalBorderSpacing: nonNegativeInteger, + transitionDuration: nonNegativeInteger, + horizontalMonthPadding: nonNegativeInteger, + dayPickerNavigationInlineStyles: PropTypes.object, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + noNavButtons: PropTypes.bool, + noNavNextButton: PropTypes.bool, + noNavPrevButton: PropTypes.bool, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + onOutsideClick: PropTypes.func, + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + renderCalendarInfo: PropTypes.func, + calendarInfoPosition: CalendarInfoPositionShape, + // accessibility + onBlur: PropTypes.func, + isFocused: PropTypes.bool, + showKeyboardShortcuts: PropTypes.bool, + onTab: PropTypes.func, + onShiftTab: PropTypes.func, + // i18n + monthFormat: PropTypes.string, + weekDayFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)), + dayAriaLabelFormat: PropTypes.string, + isRTL: PropTypes.bool +}) : {}; +var defaultProps = { + date: DATE_UNSET_VALUE, + minDate: null, + maxDate: null, + onDateChange: function onDateChange() {}, + allowUnselect: false, + focused: false, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + keepOpenOnDateSelect: false, + isOutsideRange: function isOutsideRange() {}, + isDayBlocked: function isDayBlocked() {}, + isDayHighlighted: function isDayHighlighted() {}, + // DayPicker props + renderMonthText: null, + renderWeekHeaderElement: null, + enableOutsideDays: false, + numberOfMonths: 1, + orientation: HORIZONTAL_ORIENTATION, + withPortal: false, + hideKeyboardShortcutsPanel: false, + initialVisibleMonth: null, + firstDayOfWeek: null, + daySize: DAY_SIZE, + verticalHeight: null, + noBorder: false, + verticalBorderSpacing: undefined, + transitionDuration: undefined, + horizontalMonthPadding: 13, + dayPickerNavigationInlineStyles: null, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onOutsideClick: function onOutsideClick() {}, + renderCalendarDay: undefined, + renderDayContents: null, + renderCalendarInfo: null, + renderMonthElement: null, + calendarInfoPosition: INFO_POSITION_BOTTOM, + // accessibility + onBlur: function onBlur() {}, + isFocused: false, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // i18n + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: DayPickerPhrases, + dayAriaLabelFormat: undefined, + isRTL: false +}; + +var DayPickerSingleDateController = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(DayPickerSingleDateController, _ref2); + + var _proto = DayPickerSingleDateController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function DayPickerSingleDateController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = false; + _this.today = moment(); + _this.modifiers = { + today: function today(day) { + return _this.isToday(day); + }, + blocked: function blocked(day) { + return _this.isBlocked(day); + }, + 'blocked-calendar': function blockedCalendar(day) { + return props.isDayBlocked(day); + }, + 'blocked-out-of-range': function blockedOutOfRange(day) { + return props.isOutsideRange(day); + }, + 'highlighted-calendar': function highlightedCalendar(day) { + return props.isDayHighlighted(day); + }, + valid: function valid(day) { + return !_this.isBlocked(day); + }, + hovered: function hovered(day) { + return _this.isHovered(day); + }, + selected: function selected(day) { + return _this.isSelected(day); + }, + 'first-day-of-week': function firstDayOfWeek(day) { + return _this.isFirstDayOfWeek(day); + }, + 'last-day-of-week': function lastDayOfWeek(day) { + return _this.isLastDayOfWeek(day); + } + }; + + var _this$getStateForNewM = _this.getStateForNewMonth(props), + currentMonth = _this$getStateForNewM.currentMonth, + visibleDays = _this$getStateForNewM.visibleDays; + + _this.state = { + hoverDate: null, + currentMonth: currentMonth, + visibleDays: visibleDays, + disablePrev: _this.shouldDisableMonthNavigation(props.minDate, currentMonth), + disableNext: _this.shouldDisableMonthNavigation(props.maxDate, currentMonth) + }; + _this.onDayMouseEnter = _this.onDayMouseEnter.bind(_assertThisInitialized(_this)); + _this.onDayMouseLeave = _this.onDayMouseLeave.bind(_assertThisInitialized(_this)); + _this.onDayClick = _this.onDayClick.bind(_assertThisInitialized(_this)); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind(_assertThisInitialized(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind(_assertThisInitialized(_this)); + _this.onMonthChange = _this.onMonthChange.bind(_assertThisInitialized(_this)); + _this.onYearChange = _this.onYearChange.bind(_assertThisInitialized(_this)); + _this.onGetNextScrollableMonths = _this.onGetNextScrollableMonths.bind(_assertThisInitialized(_this)); + _this.onGetPrevScrollableMonths = _this.onGetPrevScrollableMonths.bind(_assertThisInitialized(_this)); + _this.getFirstFocusableDay = _this.getFirstFocusableDay.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.isTouchDevice = isTouchDevice(); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var date = nextProps.date, + focused = nextProps.focused, + isOutsideRange = nextProps.isOutsideRange, + isDayBlocked = nextProps.isDayBlocked, + isDayHighlighted = nextProps.isDayHighlighted, + initialVisibleMonth = nextProps.initialVisibleMonth, + numberOfMonths = nextProps.numberOfMonths, + enableOutsideDays = nextProps.enableOutsideDays; + var _this$props = this.props, + prevIsOutsideRange = _this$props.isOutsideRange, + prevIsDayBlocked = _this$props.isDayBlocked, + prevIsDayHighlighted = _this$props.isDayHighlighted, + prevNumberOfMonths = _this$props.numberOfMonths, + prevEnableOutsideDays = _this$props.enableOutsideDays, + prevInitialVisibleMonth = _this$props.initialVisibleMonth, + prevFocused = _this$props.focused, + prevDate = _this$props.date; + 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 prevCurrentMonth = this.state.currentMonth; + + if (numberOfMonths !== prevNumberOfMonths || enableOutsideDays !== prevEnableOutsideDays || initialVisibleMonth !== prevInitialVisibleMonth && !prevFocused && focused || prevDate && prevDate.diff(date) && !isDayVisible(date, prevCurrentMonth, numberOfMonths)) { + var newMonthState = this.getStateForNewMonth(nextProps); + var currentMonth = newMonthState.currentMonth; + visibleDays = newMonthState.visibleDays; + this.setState({ + currentMonth: currentMonth, + visibleDays: visibleDays + }); + } + + var didDateChange = date !== prevDate; + var didFocusChange = focused !== prevFocused; + var modifiers = {}; + + if (didDateChange) { + modifiers = this.deleteModifier(modifiers, prevDate, 'selected'); + modifiers = this.addModifier(modifiers, date, 'selected'); + } + + if (didFocusChange || recomputePropModifiers) { + values(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = getPooledMoment(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 = moment(); + + if (!isSameDay(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: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + }; + + _proto.componentWillUpdate = function componentWillUpdate() { + this.today = moment(); + }; + + _proto.onDayClick = function onDayClick(day, e) { + if (e) e.preventDefault(); + if (this.isBlocked(day)) return; + var _this$props2 = this.props, + allowUnselect = _this$props2.allowUnselect, + onDateChange = _this$props2.onDateChange, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + onFocusChange = _this$props2.onFocusChange, + onClose = _this$props2.onClose; + var clickedDay = allowUnselect && this.isSelected(day) ? DATE_UNSET_VALUE : day; + onDateChange(clickedDay); + + if (!keepOpenOnDateSelect) { + onFocusChange({ + focused: false + }); + onClose({ + date: clickedDay + }); + } + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day) { + if (this.isTouchDevice) return; + var _this$state = this.state, + hoverDate = _this$state.hoverDate, + visibleDays = _this$state.visibleDays; + var modifiers = this.deleteModifier({}, hoverDate, 'hovered'); + modifiers = this.addModifier(modifiers, day, 'hovered'); + this.setState({ + hoverDate: day, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave() { + var _this$state2 = this.state, + hoverDate = _this$state2.hoverDate, + visibleDays = _this$state2.visibleDays; + if (this.isTouchDevice || !hoverDate) return; + var modifiers = this.deleteModifier({}, hoverDate, 'hovered'); + this.setState({ + hoverDate: null, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onPrevMonthClick = function onPrevMonthClick() { + var _this$props3 = this.props, + enableOutsideDays = _this$props3.enableOutsideDays, + maxDate = _this$props3.maxDate, + minDate = _this$props3.minDate, + numberOfMonths = _this$props3.numberOfMonths, + onPrevMonthClick = _this$props3.onPrevMonthClick; + var _this$state3 = this.state, + currentMonth = _this$state3.currentMonth, + visibleDays = _this$state3.visibleDays; + var newVisibleDays = {}; + Object.keys(visibleDays).sort().slice(0, numberOfMonths + 1).forEach(function (month) { + newVisibleDays[month] = visibleDays[month]; + }); + var prevMonth = currentMonth.clone().subtract(1, 'month'); + var prevMonthVisibleDays = getVisibleDays(prevMonth, 1, enableOutsideDays); + var newCurrentMonth = currentMonth.clone().subtract(1, 'month'); + this.setState({ + currentMonth: prevMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(prevMonthVisibleDays)) + }, function () { + onPrevMonthClick(prevMonth.clone()); + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick() { + var _this$props4 = this.props, + enableOutsideDays = _this$props4.enableOutsideDays, + maxDate = _this$props4.maxDate, + minDate = _this$props4.minDate, + numberOfMonths = _this$props4.numberOfMonths, + onNextMonthClick = _this$props4.onNextMonthClick; + var _this$state4 = this.state, + currentMonth = _this$state4.currentMonth, + visibleDays = _this$state4.visibleDays; + var newVisibleDays = {}; + Object.keys(visibleDays).sort().slice(1).forEach(function (month) { + newVisibleDays[month] = visibleDays[month]; + }); + var nextMonth = currentMonth.clone().add(numberOfMonths, 'month'); + var nextMonthVisibleDays = getVisibleDays(nextMonth, 1, enableOutsideDays); + var newCurrentMonth = currentMonth.clone().add(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(nextMonthVisibleDays)) + }, function () { + onNextMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onMonthChange = function onMonthChange(newMonth) { + var _this$props5 = this.props, + numberOfMonths = _this$props5.numberOfMonths, + enableOutsideDays = _this$props5.enableOutsideDays, + orientation = _this$props5.orientation; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var newVisibleDays = getVisibleDays(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onYearChange = function onYearChange(newMonth) { + var _this$props6 = this.props, + numberOfMonths = _this$props6.numberOfMonths, + enableOutsideDays = _this$props6.enableOutsideDays, + orientation = _this$props6.orientation; + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var newVisibleDays = getVisibleDays(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onGetNextScrollableMonths = function onGetNextScrollableMonths() { + var _this$props7 = this.props, + numberOfMonths = _this$props7.numberOfMonths, + enableOutsideDays = _this$props7.enableOutsideDays; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + visibleDays = _this$state5.visibleDays; + var numberOfVisibleMonths = Object.keys(visibleDays).length; + var nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month'); + var newVisibleDays = getVisibleDays(nextMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.onGetPrevScrollableMonths = function onGetPrevScrollableMonths() { + var _this$props8 = this.props, + numberOfMonths = _this$props8.numberOfMonths, + enableOutsideDays = _this$props8.enableOutsideDays; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + visibleDays = _this$state6.visibleDays; + var firstPreviousMonth = currentMonth.clone().subtract(numberOfMonths, 'month'); + var newVisibleDays = getVisibleDays(firstPreviousMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + currentMonth: firstPreviousMonth.clone(), + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return moment.localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getFirstFocusableDay = function getFirstFocusableDay(newMonth) { + var _this3 = this; + + var _this$props9 = this.props, + date = _this$props9.date, + numberOfMonths = _this$props9.numberOfMonths; + var focusedDate = newMonth.clone().startOf('month').hour(12); + + if (date) { + focusedDate = date.clone(); + } + + if (this.isBlocked(focusedDate)) { + var days = []; + var lastVisibleDay = newMonth.clone().add(numberOfMonths - 1, 'months').endOf('month'); + var currentDay = focusedDate.clone(); + + while (!isAfterDay(currentDay, lastVisibleDay)) { + currentDay = currentDay.clone().add(1, 'day'); + days.push(currentDay); + } + + var viableDays = days.filter(function (day) { + return !_this3.isBlocked(day) && isAfterDay(day, focusedDate); + }); + + if (viableDays.length > 0) { + var _viableDays = _slicedToArray(viableDays, 1); + + focusedDate = _viableDays[0]; + } + } + + return focusedDate; + }; + + _proto.getModifiers = function getModifiers(visibleDays) { + var _this4 = this; + + var modifiers = {}; + Object.keys(visibleDays).forEach(function (month) { + modifiers[month] = {}; + visibleDays[month].forEach(function (day) { + modifiers[month][toISODateString(day)] = _this4.getModifiersForDay(day); + }); + }); + return modifiers; + }; + + _proto.getModifiersForDay = function getModifiersForDay(day) { + var _this5 = this; + + return new Set(Object.keys(this.modifiers).filter(function (modifier) { + return _this5.modifiers[modifier](day); + })); + }; + + _proto.getStateForNewMonth = function getStateForNewMonth(nextProps) { + var _this6 = this; + + var initialVisibleMonth = nextProps.initialVisibleMonth, + date = nextProps.date, + numberOfMonths = nextProps.numberOfMonths, + orientation = nextProps.orientation, + enableOutsideDays = nextProps.enableOutsideDays; + var initialVisibleMonthThunk = initialVisibleMonth || (date ? function () { + return date; + } : function () { + return _this6.today; + }); + var currentMonth = initialVisibleMonthThunk(); + var withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE; + var visibleDays = this.getModifiers(getVisibleDays(currentMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths)); + return { + currentMonth: currentMonth, + visibleDays: visibleDays + }; + }; + + _proto.shouldDisableMonthNavigation = function shouldDisableMonthNavigation(date, visibleMonth) { + if (!date) return false; + var _this$props10 = this.props, + numberOfMonths = _this$props10.numberOfMonths, + enableOutsideDays = _this$props10.enableOutsideDays; + return isDayVisible(date, visibleMonth, numberOfMonths, enableOutsideDays); + }; + + _proto.addModifier = function addModifier(updatedDays, day, modifier) { + return _addModifier(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.deleteModifier = function deleteModifier(updatedDays, day, modifier) { + return _deleteModifier(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.isBlocked = function isBlocked(day) { + var _this$props11 = this.props, + isDayBlocked = _this$props11.isDayBlocked, + isOutsideRange = _this$props11.isOutsideRange; + return isDayBlocked(day) || isOutsideRange(day); + }; + + _proto.isHovered = function isHovered(day) { + var _ref3 = this.state || {}, + hoverDate = _ref3.hoverDate; + + return isSameDay(day, hoverDate); + }; + + _proto.isSelected = function isSelected(day) { + var date = this.props.date; + return isSameDay(day, date); + }; + + _proto.isToday = function isToday(day) { + return isSameDay(day, this.today); + }; + + _proto.isFirstDayOfWeek = function isFirstDayOfWeek(day) { + return day.day() === this.getFirstDayOfWeek(); + }; + + _proto.isLastDayOfWeek = function isLastDayOfWeek(day) { + return day.day() === (this.getFirstDayOfWeek() + 6) % 7; + }; + + _proto.render = function render() { + var _this$props12 = this.props, + numberOfMonths = _this$props12.numberOfMonths, + orientation = _this$props12.orientation, + monthFormat = _this$props12.monthFormat, + renderMonthText = _this$props12.renderMonthText, + renderWeekHeaderElement = _this$props12.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props12.dayPickerNavigationInlineStyles, + navPosition = _this$props12.navPosition, + navPrev = _this$props12.navPrev, + navNext = _this$props12.navNext, + renderNavPrevButton = _this$props12.renderNavPrevButton, + renderNavNextButton = _this$props12.renderNavNextButton, + noNavButtons = _this$props12.noNavButtons, + noNavPrevButton = _this$props12.noNavPrevButton, + noNavNextButton = _this$props12.noNavNextButton, + onOutsideClick = _this$props12.onOutsideClick, + onShiftTab = _this$props12.onShiftTab, + onTab = _this$props12.onTab, + withPortal = _this$props12.withPortal, + focused = _this$props12.focused, + enableOutsideDays = _this$props12.enableOutsideDays, + hideKeyboardShortcutsPanel = _this$props12.hideKeyboardShortcutsPanel, + daySize = _this$props12.daySize, + firstDayOfWeek = _this$props12.firstDayOfWeek, + renderCalendarDay = _this$props12.renderCalendarDay, + renderDayContents = _this$props12.renderDayContents, + renderCalendarInfo = _this$props12.renderCalendarInfo, + renderMonthElement = _this$props12.renderMonthElement, + calendarInfoPosition = _this$props12.calendarInfoPosition, + isFocused = _this$props12.isFocused, + isRTL = _this$props12.isRTL, + phrases = _this$props12.phrases, + dayAriaLabelFormat = _this$props12.dayAriaLabelFormat, + onBlur = _this$props12.onBlur, + showKeyboardShortcuts = _this$props12.showKeyboardShortcuts, + weekDayFormat = _this$props12.weekDayFormat, + verticalHeight = _this$props12.verticalHeight, + noBorder = _this$props12.noBorder, + transitionDuration = _this$props12.transitionDuration, + verticalBorderSpacing = _this$props12.verticalBorderSpacing, + horizontalMonthPadding = _this$props12.horizontalMonthPadding; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + disableNext = _this$state7.disableNext, + disablePrev = _this$state7.disablePrev, + visibleDays = _this$state7.visibleDays; + return /*#__PURE__*/React.createElement(DayPicker, { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + modifiers: visibleDays, + numberOfMonths: numberOfMonths, + onDayClick: this.onDayClick, + onDayMouseEnter: this.onDayMouseEnter, + onDayMouseLeave: this.onDayMouseLeave, + onPrevMonthClick: this.onPrevMonthClick, + onNextMonthClick: this.onNextMonthClick, + onMonthChange: this.onMonthChange, + onYearChange: this.onYearChange, + onGetNextScrollableMonths: this.onGetNextScrollableMonths, + onGetPrevScrollableMonths: this.onGetPrevScrollableMonths, + monthFormat: monthFormat, + withPortal: withPortal, + hidden: !focused, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + initialVisibleMonth: function initialVisibleMonth() { + return currentMonth; + }, + firstDayOfWeek: firstDayOfWeek, + onOutsideClick: onOutsideClick, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + disablePrev: disablePrev, + disableNext: disableNext, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + noNavButtons: noNavButtons, + noNavNextButton: noNavNextButton, + noNavPrevButton: noNavPrevButton, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isFocused, + getFirstFocusableDay: this.getFirstFocusableDay, + onBlur: onBlur, + onTab: onTab, + onShiftTab: onShiftTab, + phrases: phrases, + daySize: daySize, + isRTL: isRTL, + showKeyboardShortcuts: showKeyboardShortcuts, + weekDayFormat: weekDayFormat, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalHeight: verticalHeight, + noBorder: noBorder, + transitionDuration: transitionDuration, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + }); + }; + + return DayPickerSingleDateController; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +export { DayPickerSingleDateController as default }; +DayPickerSingleDateController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerSingleDateController.defaultProps = defaultProps; \ No newline at end of file diff --git a/esm/components/KeyboardShortcutRow.js b/esm/components/KeyboardShortcutRow.js new file mode 100644 index 000000000..4f4216be5 --- /dev/null +++ b/esm/components/KeyboardShortcutRow.js @@ -0,0 +1,77 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + unicode: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + action: PropTypes.string.isRequired, + block: PropTypes.bool +})) : {}; +var defaultProps = { + block: false +}; + +function KeyboardShortcutRow(_ref) { + var unicode = _ref.unicode, + label = _ref.label, + action = _ref.action, + block = _ref.block, + css = _ref.css, + styles = _ref.styles; + return /*#__PURE__*/React.createElement("li", css(styles.KeyboardShortcutRow, block && styles.KeyboardShortcutRow__block), /*#__PURE__*/React.createElement("div", css(styles.KeyboardShortcutRow_keyContainer, block && styles.KeyboardShortcutRow_keyContainer__block), /*#__PURE__*/React.createElement("span", _extends({}, css(styles.KeyboardShortcutRow_key), { + role: "img", + "aria-label": "".concat(label, ",") // add comma so screen readers will pause before reading action + + }), unicode)), /*#__PURE__*/React.createElement("div", css(styles.KeyboardShortcutRow_action), action)); +} + +KeyboardShortcutRow.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +KeyboardShortcutRow.defaultProps = defaultProps; +export default withStyles(function (_ref2) { + var color = _ref2.reactDates.color; + return { + KeyboardShortcutRow: { + listStyle: 'none', + margin: '6px 0' + }, + KeyboardShortcutRow__block: { + marginBottom: 16 + }, + KeyboardShortcutRow_keyContainer: { + display: 'inline-block', + whiteSpace: 'nowrap', + textAlign: 'right', + // is not handled by isRTL + marginRight: 6 // is not handled by isRTL + + }, + KeyboardShortcutRow_keyContainer__block: { + textAlign: 'left', + // is not handled by isRTL + display: 'inline' + }, + KeyboardShortcutRow_key: { + fontFamily: 'monospace', + fontSize: 12, + textTransform: 'uppercase', + background: color.core.grayLightest, + padding: '2px 6px' + }, + KeyboardShortcutRow_action: { + display: 'inline', + wordBreak: 'break-word', + marginLeft: 8 // is not handled by isRTL + + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(KeyboardShortcutRow); \ No newline at end of file diff --git a/esm/components/LeftArrow.js b/esm/components/LeftArrow.js new file mode 100644 index 000000000..2d0b69fa2 --- /dev/null +++ b/esm/components/LeftArrow.js @@ -0,0 +1,13 @@ +import React from "react"; + +var LeftArrow = function LeftArrow(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + d: "M336 275L126 485h806c13 0 23 10 23 23s-10 23-23 23H126l210 210c11 11 11 21 0 32-5 5-10 7-16 7s-11-2-16-7L55 524c-11-11-11-21 0-32l249-249c21-22 53 10 32 32z" + })); +}; + +LeftArrow.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +export default LeftArrow; \ No newline at end of file diff --git a/esm/components/RightArrow.js b/esm/components/RightArrow.js new file mode 100644 index 000000000..eb9cffd0e --- /dev/null +++ b/esm/components/RightArrow.js @@ -0,0 +1,13 @@ +import React from "react"; + +var RightArrow = function RightArrow(props) { + return /*#__PURE__*/React.createElement("svg", props, /*#__PURE__*/React.createElement("path", { + d: "M694 242l249 250c12 11 12 21 1 32L694 773c-5 5-10 7-16 7s-11-2-16-7c-11-11-11-21 0-32l210-210H68c-13 0-23-10-23-23s10-23 23-23h806L662 275c-21-22 11-54 32-33z" + })); +}; + +RightArrow.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +export default RightArrow; \ No newline at end of file diff --git a/esm/components/SingleDatePicker.js b/esm/components/SingleDatePicker.js new file mode 100644 index 000000000..395a0976e --- /dev/null +++ b/esm/components/SingleDatePicker.js @@ -0,0 +1,647 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import shallowEqual from "enzyme-shallow-equal"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import moment from 'moment'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { Portal } from 'react-portal'; +import { forbidExtraProps } from 'airbnb-prop-types'; +import { addEventListener } from 'consolidated-events'; +import isTouchDevice from 'is-touch-device'; +import OutsideClickHandler from 'react-outside-click-handler'; +import { darken } from 'color2k'; +import SingleDatePickerShape from '../shapes/SingleDatePickerShape'; +import { SingleDatePickerPhrases } from '../defaultPhrases'; +import getResponsiveContainerStyles from '../utils/getResponsiveContainerStyles'; +import getDetachedContainerStyles from '../utils/getDetachedContainerStyles'; +import getInputHeight from '../utils/getInputHeight'; +import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay'; +import _disableScroll from '../utils/disableScroll'; +import noflip from '../utils/noflip'; +import SingleDatePickerInputController from './SingleDatePickerInputController'; +import DayPickerSingleDateController from './DayPickerSingleDateController'; +import CloseButton from './CloseButton'; +import { HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, ANCHOR_LEFT, ANCHOR_RIGHT, OPEN_DOWN, OPEN_UP, DAY_SIZE, ICON_BEFORE_POSITION, INFO_POSITION_BOTTOM, FANG_HEIGHT_PX, DEFAULT_VERTICAL_SPACING, NAV_POSITION_TOP } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), SingleDatePickerShape)) : {}; +var defaultProps = { + // required props for a functional interactive SingleDatePicker + date: null, + focused: false, + minDate: null, + maxDate: null, + // input related props + id: 'date', + placeholder: 'Date', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + disabled: false, + required: false, + readOnly: false, + screenReaderInputMessage: '', + showClearDate: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + customInputIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: DEFAULT_VERTICAL_SPACING, + keepFocusOnInput: false, + // calendar presentation and interaction related props + orientation: HORIZONTAL_ORIENTATION, + anchorDirection: ANCHOR_LEFT, + openDirection: OPEN_DOWN, + horizontalMargin: 0, + withPortal: false, + withFullScreenPortal: false, + appendToBody: false, + disableScroll: false, + initialVisibleMonth: null, + firstDayOfWeek: null, + numberOfMonths: 2, + keepOpenOnDateSelect: false, + reopenPickerOnClearDate: false, + renderCalendarInfo: null, + calendarInfoPosition: INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: DAY_SIZE, + isRTL: false, + verticalHeight: null, + transitionDuration: undefined, + horizontalMonthPadding: 13, + // navigation related props + dayPickerNavigationInlineStyles: null, + navPosition: NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onClose: function onClose() {}, + // month presentation and interaction related props + renderMonthText: null, + renderWeekHeaderElement: null, + // day presentation and interaction related props + renderCalendarDay: undefined, + renderDayContents: null, + renderMonthElement: null, + enableOutsideDays: false, + isDayBlocked: function isDayBlocked() { + return false; + }, + isOutsideRange: function isOutsideRange(day) { + return !isInclusivelyAfterDay(day, moment()); + }, + isDayHighlighted: function isDayHighlighted() {}, + // internationalization props + displayFormat: function displayFormat() { + return moment.localeData().longDateFormat('L'); + }, + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: SingleDatePickerPhrases, + dayAriaLabelFormat: undefined +}; + +var SingleDatePicker = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(SingleDatePicker, _ref2); + + var _proto = SingleDatePicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function SingleDatePicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = false; + _this.state = { + dayPickerContainerStyles: {}, + isDayPickerFocused: false, + isInputFocused: false, + showKeyboardShortcuts: false + }; + _this.onFocusOut = _this.onFocusOut.bind(_assertThisInitialized(_this)); + _this.onOutsideClick = _this.onOutsideClick.bind(_assertThisInitialized(_this)); + _this.onInputFocus = _this.onInputFocus.bind(_assertThisInitialized(_this)); + _this.onDayPickerFocus = _this.onDayPickerFocus.bind(_assertThisInitialized(_this)); + _this.onDayPickerBlur = _this.onDayPickerBlur.bind(_assertThisInitialized(_this)); + _this.showKeyboardShortcutsPanel = _this.showKeyboardShortcutsPanel.bind(_assertThisInitialized(_this)); + _this.responsivizePickerPosition = _this.responsivizePickerPosition.bind(_assertThisInitialized(_this)); + _this.disableScroll = _this.disableScroll.bind(_assertThisInitialized(_this)); + _this.setDayPickerContainerRef = _this.setDayPickerContainerRef.bind(_assertThisInitialized(_this)); + _this.setContainerRef = _this.setContainerRef.bind(_assertThisInitialized(_this)); + return _this; + } + /* istanbul ignore next */ + + + _proto.componentDidMount = function componentDidMount() { + this.removeResizeEventListener = addEventListener(window, 'resize', this.responsivizePickerPosition, { + passive: true + }); + this.responsivizePickerPosition(); + this.disableScroll(); + var focused = this.props.focused; + + if (focused) { + this.setState({ + isInputFocused: true + }); + } + + this.isTouchDevice = isTouchDevice(); + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var focused = this.props.focused; + + if (!prevProps.focused && focused) { + this.responsivizePickerPosition(); + this.disableScroll(); + } else if (prevProps.focused && !focused) { + if (this.enableScroll) this.enableScroll(); + } + } + /* istanbul ignore next */ + ; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.removeResizeEventListener) this.removeResizeEventListener(); + if (this.removeFocusOutEventListener) this.removeFocusOutEventListener(); + if (this.enableScroll) this.enableScroll(); + }; + + _proto.onOutsideClick = function onOutsideClick(event) { + var _this$props = this.props, + focused = _this$props.focused, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose, + date = _this$props.date, + appendToBody = _this$props.appendToBody; + if (!focused) return; + if (appendToBody && this.dayPickerContainer.contains(event.target)) return; + this.setState({ + isInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + onFocusChange({ + focused: false + }); + onClose({ + date: date + }); + }; + + _proto.onInputFocus = function onInputFocus(_ref3) { + var focused = _ref3.focused; + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + readOnly = _this$props2.readOnly, + withPortal = _this$props2.withPortal, + withFullScreenPortal = _this$props2.withFullScreenPortal, + keepFocusOnInput = _this$props2.keepFocusOnInput; + + if (focused) { + var withAnyPortal = withPortal || withFullScreenPortal; + var moveFocusToDayPicker = withAnyPortal || readOnly && !keepFocusOnInput || this.isTouchDevice && !keepFocusOnInput; + + if (moveFocusToDayPicker) { + this.onDayPickerFocus(); + } else { + this.onDayPickerBlur(); + } + } + + onFocusChange({ + focused: focused + }); + }; + + _proto.onDayPickerFocus = function onDayPickerFocus() { + this.setState({ + isInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: false + }); + }; + + _proto.onDayPickerBlur = function onDayPickerBlur() { + this.setState({ + isInputFocused: true, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + }; + + _proto.onFocusOut = function onFocusOut(e) { + var onFocusChange = this.props.onFocusChange; // In cases where **relatedTarget** is not null, it points to the right + // element here. However, in cases where it is null (such as clicking on a + // specific day) or it is **document.body** (IE11), the appropriate value is **event.target**. + // + // We handle both situations here by using the ` || ` operator to fallback + // to *event.target** when **relatedTarget** is not provided. + + var relatedTarget = e.relatedTarget === document.body ? e.target : e.relatedTarget || e.target; + if (this.dayPickerContainer.contains(relatedTarget)) return; + onFocusChange({ + focused: false + }); + }; + + _proto.setDayPickerContainerRef = function setDayPickerContainerRef(ref) { + if (ref === this.dayPickerContainer) return; + this.removeEventListeners(); + this.dayPickerContainer = ref; + if (!ref) return; + this.addEventListeners(); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.addEventListeners = function addEventListeners() { + // We manually set event because React has not implemented onFocusIn/onFocusOut. + // Keep an eye on https://github.com/facebook/react/issues/6410 for updates + // We use "blur w/ useCapture param" vs "onfocusout" for FF browser support + this.removeFocusOutEventListener = addEventListener(this.dayPickerContainer, 'focusout', this.onFocusOut); + }; + + _proto.removeEventListeners = function removeEventListeners() { + if (this.removeFocusOutEventListener) this.removeFocusOutEventListener(); + }; + + _proto.disableScroll = function disableScroll() { + var _this$props3 = this.props, + appendToBody = _this$props3.appendToBody, + propDisableScroll = _this$props3.disableScroll, + focused = _this$props3.focused; + if (!appendToBody && !propDisableScroll) return; + if (!focused) return; // Disable scroll for every ancestor of this up to the + // document level. This ensures the input and the picker never move. Other + // sibling elements or the picker itself can scroll. + + this.enableScroll = _disableScroll(this.container); + } + /* istanbul ignore next */ + ; + + _proto.responsivizePickerPosition = function responsivizePickerPosition() { + // It's possible the portal props have been changed in response to window resizes + // So let's ensure we reset this back to the base state each time + this.setState({ + dayPickerContainerStyles: {} + }); + var _this$props4 = this.props, + openDirection = _this$props4.openDirection, + anchorDirection = _this$props4.anchorDirection, + horizontalMargin = _this$props4.horizontalMargin, + withPortal = _this$props4.withPortal, + withFullScreenPortal = _this$props4.withFullScreenPortal, + appendToBody = _this$props4.appendToBody, + focused = _this$props4.focused; + var dayPickerContainerStyles = this.state.dayPickerContainerStyles; + + if (!focused) { + return; + } + + var isAnchoredLeft = anchorDirection === ANCHOR_LEFT; + + if (!withPortal && !withFullScreenPortal) { + var containerRect = this.dayPickerContainer.getBoundingClientRect(); + var currentOffset = dayPickerContainerStyles[anchorDirection] || 0; + var containerEdge = isAnchoredLeft ? containerRect[ANCHOR_RIGHT] : containerRect[ANCHOR_LEFT]; + this.setState({ + dayPickerContainerStyles: _objectSpread(_objectSpread({}, getResponsiveContainerStyles(anchorDirection, currentOffset, containerEdge, horizontalMargin)), appendToBody && getDetachedContainerStyles(openDirection, anchorDirection, this.container)) + }); + } + }; + + _proto.showKeyboardShortcutsPanel = function showKeyboardShortcutsPanel() { + this.setState({ + isInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: true + }); + }; + + _proto.maybeRenderDayPickerWithPortal = function maybeRenderDayPickerWithPortal() { + var _this$props5 = this.props, + focused = _this$props5.focused, + withPortal = _this$props5.withPortal, + withFullScreenPortal = _this$props5.withFullScreenPortal, + appendToBody = _this$props5.appendToBody; + + if (!focused) { + return null; + } + + if (withPortal || withFullScreenPortal || appendToBody) { + return /*#__PURE__*/React.createElement(Portal, null, this.renderDayPicker()); + } + + return this.renderDayPicker(); + }; + + _proto.renderDayPicker = function renderDayPicker() { + var _this$props6 = this.props, + anchorDirection = _this$props6.anchorDirection, + openDirection = _this$props6.openDirection, + onDateChange = _this$props6.onDateChange, + date = _this$props6.date, + minDate = _this$props6.minDate, + maxDate = _this$props6.maxDate, + onFocusChange = _this$props6.onFocusChange, + focused = _this$props6.focused, + enableOutsideDays = _this$props6.enableOutsideDays, + numberOfMonths = _this$props6.numberOfMonths, + orientation = _this$props6.orientation, + monthFormat = _this$props6.monthFormat, + dayPickerNavigationInlineStyles = _this$props6.dayPickerNavigationInlineStyles, + navPosition = _this$props6.navPosition, + navPrev = _this$props6.navPrev, + navNext = _this$props6.navNext, + renderNavPrevButton = _this$props6.renderNavPrevButton, + renderNavNextButton = _this$props6.renderNavNextButton, + onPrevMonthClick = _this$props6.onPrevMonthClick, + onNextMonthClick = _this$props6.onNextMonthClick, + onClose = _this$props6.onClose, + withPortal = _this$props6.withPortal, + withFullScreenPortal = _this$props6.withFullScreenPortal, + keepOpenOnDateSelect = _this$props6.keepOpenOnDateSelect, + initialVisibleMonth = _this$props6.initialVisibleMonth, + renderMonthText = _this$props6.renderMonthText, + renderWeekHeaderElement = _this$props6.renderWeekHeaderElement, + renderCalendarDay = _this$props6.renderCalendarDay, + renderDayContents = _this$props6.renderDayContents, + renderCalendarInfo = _this$props6.renderCalendarInfo, + renderMonthElement = _this$props6.renderMonthElement, + calendarInfoPosition = _this$props6.calendarInfoPosition, + hideKeyboardShortcutsPanel = _this$props6.hideKeyboardShortcutsPanel, + firstDayOfWeek = _this$props6.firstDayOfWeek, + customCloseIcon = _this$props6.customCloseIcon, + phrases = _this$props6.phrases, + dayAriaLabelFormat = _this$props6.dayAriaLabelFormat, + daySize = _this$props6.daySize, + isRTL = _this$props6.isRTL, + isOutsideRange = _this$props6.isOutsideRange, + isDayBlocked = _this$props6.isDayBlocked, + isDayHighlighted = _this$props6.isDayHighlighted, + weekDayFormat = _this$props6.weekDayFormat, + css = _this$props6.css, + styles = _this$props6.styles, + verticalHeight = _this$props6.verticalHeight, + transitionDuration = _this$props6.transitionDuration, + verticalSpacing = _this$props6.verticalSpacing, + horizontalMonthPadding = _this$props6.horizontalMonthPadding, + small = _this$props6.small, + reactDates = _this$props6.theme.reactDates; + var _this$state = this.state, + dayPickerContainerStyles = _this$state.dayPickerContainerStyles, + isDayPickerFocused = _this$state.isDayPickerFocused, + showKeyboardShortcuts = _this$state.showKeyboardShortcuts; + var onOutsideClick = !withFullScreenPortal && withPortal ? this.onOutsideClick : undefined; + var closeIcon = customCloseIcon || /*#__PURE__*/React.createElement(CloseButton, null); + var inputHeight = getInputHeight(reactDates, small); + var withAnyPortal = withPortal || withFullScreenPortal; + /* eslint-disable jsx-a11y/no-static-element-interactions */ + + /* eslint-disable jsx-a11y/click-events-have-key-events */ + + return /*#__PURE__*/React.createElement("div", _extends({ + ref: this.setDayPickerContainerRef + }, css(styles.SingleDatePicker_picker, anchorDirection === ANCHOR_LEFT && styles.SingleDatePicker_picker__directionLeft, anchorDirection === ANCHOR_RIGHT && styles.SingleDatePicker_picker__directionRight, openDirection === OPEN_DOWN && styles.SingleDatePicker_picker__openDown, openDirection === OPEN_UP && styles.SingleDatePicker_picker__openUp, !withAnyPortal && openDirection === OPEN_DOWN && { + top: inputHeight + verticalSpacing + }, !withAnyPortal && openDirection === OPEN_UP && { + bottom: inputHeight + verticalSpacing + }, orientation === HORIZONTAL_ORIENTATION && styles.SingleDatePicker_picker__horizontal, orientation === VERTICAL_ORIENTATION && styles.SingleDatePicker_picker__vertical, withAnyPortal && styles.SingleDatePicker_picker__portal, withFullScreenPortal && styles.SingleDatePicker_picker__fullScreenPortal, isRTL && styles.SingleDatePicker_picker__rtl, dayPickerContainerStyles), { + onClick: onOutsideClick + }), /*#__PURE__*/React.createElement(DayPickerSingleDateController, { + date: date, + minDate: minDate, + maxDate: maxDate, + onDateChange: onDateChange, + onFocusChange: onFocusChange, + orientation: orientation, + enableOutsideDays: enableOutsideDays, + numberOfMonths: numberOfMonths, + monthFormat: monthFormat, + withPortal: withAnyPortal, + focused: focused, + keepOpenOnDateSelect: keepOpenOnDateSelect, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + initialVisibleMonth: initialVisibleMonth, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + onClose: onClose, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isDayPickerFocused, + showKeyboardShortcuts: showKeyboardShortcuts, + onBlur: this.onDayPickerBlur, + phrases: phrases, + dayAriaLabelFormat: dayAriaLabelFormat, + daySize: daySize, + isRTL: isRTL, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + isDayHighlighted: isDayHighlighted, + firstDayOfWeek: firstDayOfWeek, + weekDayFormat: weekDayFormat, + verticalHeight: verticalHeight, + transitionDuration: transitionDuration, + horizontalMonthPadding: horizontalMonthPadding + }), withFullScreenPortal && /*#__PURE__*/React.createElement("button", _extends({}, css(styles.SingleDatePicker_closeButton), { + "aria-label": phrases.closeDatePicker, + type: "button", + onClick: this.onOutsideClick + }), /*#__PURE__*/React.createElement("div", css(styles.SingleDatePicker_closeButton_svg), closeIcon))); + /* eslint-enable jsx-a11y/no-static-element-interactions */ + + /* eslint-enable jsx-a11y/click-events-have-key-events */ + }; + + _proto.render = function render() { + var _this$props7 = this.props, + id = _this$props7.id, + placeholder = _this$props7.placeholder, + ariaLabel = _this$props7.ariaLabel, + autoComplete = _this$props7.autoComplete, + titleText = _this$props7.titleText, + disabled = _this$props7.disabled, + focused = _this$props7.focused, + required = _this$props7.required, + readOnly = _this$props7.readOnly, + openDirection = _this$props7.openDirection, + showClearDate = _this$props7.showClearDate, + showDefaultInputIcon = _this$props7.showDefaultInputIcon, + inputIconPosition = _this$props7.inputIconPosition, + customCloseIcon = _this$props7.customCloseIcon, + customInputIcon = _this$props7.customInputIcon, + date = _this$props7.date, + onDateChange = _this$props7.onDateChange, + displayFormat = _this$props7.displayFormat, + phrases = _this$props7.phrases, + withPortal = _this$props7.withPortal, + withFullScreenPortal = _this$props7.withFullScreenPortal, + screenReaderInputMessage = _this$props7.screenReaderInputMessage, + isRTL = _this$props7.isRTL, + noBorder = _this$props7.noBorder, + block = _this$props7.block, + small = _this$props7.small, + regular = _this$props7.regular, + verticalSpacing = _this$props7.verticalSpacing, + reopenPickerOnClearDate = _this$props7.reopenPickerOnClearDate, + keepOpenOnDateSelect = _this$props7.keepOpenOnDateSelect, + css = _this$props7.css, + styles = _this$props7.styles, + isOutsideRange = _this$props7.isOutsideRange, + isDayBlocked = _this$props7.isDayBlocked; + var isInputFocused = this.state.isInputFocused; + var enableOutsideClick = !withPortal && !withFullScreenPortal; + var hideFang = verticalSpacing < FANG_HEIGHT_PX; + var input = /*#__PURE__*/React.createElement(SingleDatePickerInputController, { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + focused: focused, + isFocused: isInputFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + showCaret: !withPortal && !withFullScreenPortal && !hideFang, + showClearDate: showClearDate, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + customCloseIcon: customCloseIcon, + customInputIcon: customInputIcon, + date: date, + onDateChange: onDateChange, + displayFormat: displayFormat, + onFocusChange: this.onInputFocus, + onKeyDownArrowDown: this.onDayPickerFocus, + onKeyDownQuestionMark: this.showKeyboardShortcutsPanel, + screenReaderMessage: screenReaderInputMessage, + phrases: phrases, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + reopenPickerOnClearDate: reopenPickerOnClearDate, + keepOpenOnDateSelect: keepOpenOnDateSelect + }, this.maybeRenderDayPickerWithPortal()); + return /*#__PURE__*/React.createElement("div", _extends({ + ref: this.setContainerRef + }, css(styles.SingleDatePicker, block && styles.SingleDatePicker__block)), enableOutsideClick && /*#__PURE__*/React.createElement(OutsideClickHandler, { + onOutsideClick: this.onOutsideClick + }, input), enableOutsideClick || input); + }; + + return SingleDatePicker; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +SingleDatePicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePicker.defaultProps = defaultProps; +export { SingleDatePicker as PureSingleDatePicker }; +export default withStyles(function (_ref4) { + var _ref4$reactDates = _ref4.reactDates, + color = _ref4$reactDates.color, + zIndex = _ref4$reactDates.zIndex; + return { + SingleDatePicker: { + position: 'relative', + display: 'inline-block' + }, + SingleDatePicker__block: { + display: 'block' + }, + SingleDatePicker_picker: { + zIndex: zIndex + 1, + backgroundColor: color.background, + position: 'absolute' + }, + SingleDatePicker_picker__rtl: { + direction: noflip('rtl') + }, + SingleDatePicker_picker__directionLeft: { + left: noflip(0) + }, + SingleDatePicker_picker__directionRight: { + right: noflip(0) + }, + SingleDatePicker_picker__portal: { + backgroundColor: 'rgba(0, 0, 0, 0.3)', + position: 'fixed', + top: 0, + left: noflip(0), + height: '100%', + width: '100%' + }, + SingleDatePicker_picker__fullScreenPortal: { + backgroundColor: color.background + }, + SingleDatePicker_closeButton: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + position: 'absolute', + top: 0, + right: noflip(0), + padding: 15, + zIndex: zIndex + 2, + ':hover': { + color: darken(color.core.grayLighter, 0.1), + textDecoration: 'none' + }, + ':focus': { + color: darken(color.core.grayLighter, 0.1), + textDecoration: 'none' + } + }, + SingleDatePicker_closeButton_svg: { + height: 15, + width: 15, + fill: color.core.grayLighter + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(SingleDatePicker); \ No newline at end of file diff --git a/esm/components/SingleDatePickerInput.js b/esm/components/SingleDatePickerInput.js new file mode 100644 index 000000000..9f11871ad --- /dev/null +++ b/esm/components/SingleDatePickerInput.js @@ -0,0 +1,271 @@ +import _extends from "@babel/runtime/helpers/esm/extends"; +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import React from 'react'; +import PropTypes from 'prop-types'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { withStyles, withStylesPropTypes } from 'react-with-styles'; +import { SingleDatePickerInputPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import noflip from '../utils/noflip'; +import DateInput from './DateInput'; +import IconPositionShape from '../shapes/IconPositionShape'; +import CloseButton from './CloseButton'; +import CalendarIcon from './CalendarIcon'; +import openDirectionShape from '../shapes/OpenDirectionShape'; +import { ICON_BEFORE_POSITION, ICON_AFTER_POSITION, OPEN_DOWN } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps(_objectSpread(_objectSpread({}, withStylesPropTypes), {}, { + id: PropTypes.string.isRequired, + children: PropTypes.node, + placeholder: PropTypes.string, + ariaLabel: PropTypes.string, + autoComplete: PropTypes.string, + titleText: PropTypes.string, + displayValue: PropTypes.string, + screenReaderMessage: PropTypes.string, + focused: PropTypes.bool, + isFocused: PropTypes.bool, + // describes actual DOM focus + disabled: PropTypes.bool, + required: PropTypes.bool, + readOnly: PropTypes.bool, + openDirection: openDirectionShape, + showCaret: PropTypes.bool, + showClearDate: PropTypes.bool, + customCloseIcon: PropTypes.node, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + customInputIcon: PropTypes.node, + isRTL: PropTypes.bool, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + onChange: PropTypes.func, + onClearDate: PropTypes.func, + onFocus: PropTypes.func, + onKeyDownShiftTab: PropTypes.func, + onKeyDownTab: PropTypes.func, + onKeyDownArrowDown: PropTypes.func, + onKeyDownQuestionMark: PropTypes.func, + // i18n + phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerInputPhrases)) +})) : {}; +var defaultProps = { + children: null, + placeholder: 'Select Date', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + displayValue: '', + screenReaderMessage: '', + focused: false, + isFocused: false, + disabled: false, + required: false, + readOnly: false, + openDirection: OPEN_DOWN, + showCaret: false, + showClearDate: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + customCloseIcon: null, + customInputIcon: null, + isRTL: false, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + onChange: function onChange() {}, + onClearDate: function onClearDate() {}, + onFocus: function onFocus() {}, + onKeyDownShiftTab: function onKeyDownShiftTab() {}, + onKeyDownTab: function onKeyDownTab() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + // i18n + phrases: SingleDatePickerInputPhrases +}; + +function SingleDatePickerInput(_ref) { + var id = _ref.id, + children = _ref.children, + placeholder = _ref.placeholder, + ariaLabel = _ref.ariaLabel, + autoComplete = _ref.autoComplete, + titleText = _ref.titleText, + displayValue = _ref.displayValue, + focused = _ref.focused, + isFocused = _ref.isFocused, + disabled = _ref.disabled, + required = _ref.required, + readOnly = _ref.readOnly, + showCaret = _ref.showCaret, + showClearDate = _ref.showClearDate, + showDefaultInputIcon = _ref.showDefaultInputIcon, + inputIconPosition = _ref.inputIconPosition, + phrases = _ref.phrases, + onClearDate = _ref.onClearDate, + onChange = _ref.onChange, + onFocus = _ref.onFocus, + onKeyDownShiftTab = _ref.onKeyDownShiftTab, + onKeyDownTab = _ref.onKeyDownTab, + onKeyDownArrowDown = _ref.onKeyDownArrowDown, + onKeyDownQuestionMark = _ref.onKeyDownQuestionMark, + screenReaderMessage = _ref.screenReaderMessage, + customCloseIcon = _ref.customCloseIcon, + customInputIcon = _ref.customInputIcon, + openDirection = _ref.openDirection, + isRTL = _ref.isRTL, + noBorder = _ref.noBorder, + block = _ref.block, + small = _ref.small, + regular = _ref.regular, + verticalSpacing = _ref.verticalSpacing, + css = _ref.css, + styles = _ref.styles; + var calendarIcon = customInputIcon || /*#__PURE__*/React.createElement(CalendarIcon, css(styles.SingleDatePickerInput_calendarIcon_svg)); + var closeIcon = customCloseIcon || /*#__PURE__*/React.createElement(CloseButton, css(styles.SingleDatePickerInput_clearDate_svg, small && styles.SingleDatePickerInput_clearDate_svg__small)); + var screenReaderText = screenReaderMessage || phrases.keyboardForwardNavigationInstructions; + var inputIcon = (showDefaultInputIcon || customInputIcon !== null) && /*#__PURE__*/React.createElement("button", _extends({}, css(styles.SingleDatePickerInput_calendarIcon), { + type: "button", + disabled: disabled, + "aria-label": phrases.focusStartDate, + onClick: onFocus, + tabIndex: "-1" + }), calendarIcon); + return /*#__PURE__*/React.createElement("div", css(styles.SingleDatePickerInput, disabled && styles.SingleDatePickerInput__disabled, isRTL && styles.SingleDatePickerInput__rtl, !noBorder && styles.SingleDatePickerInput__withBorder, block && styles.SingleDatePickerInput__block, showClearDate && styles.SingleDatePickerInput__showClearDate), inputIconPosition === ICON_BEFORE_POSITION && inputIcon, /*#__PURE__*/React.createElement(DateInput, { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + displayValue: displayValue, + screenReaderMessage: screenReaderText, + focused: focused, + isFocused: isFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + onChange: onChange, + onFocus: onFocus, + onKeyDownShiftTab: onKeyDownShiftTab, + onKeyDownTab: onKeyDownTab, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + openDirection: openDirection, + verticalSpacing: verticalSpacing, + small: small, + regular: regular, + block: block + }), children, showClearDate && /*#__PURE__*/React.createElement("button", _extends({}, css(styles.SingleDatePickerInput_clearDate, small && styles.SingleDatePickerInput_clearDate__small, !customCloseIcon && styles.SingleDatePickerInput_clearDate__default, !displayValue && styles.SingleDatePickerInput_clearDate__hide), { + type: "button", + "aria-label": phrases.clearDate, + disabled: disabled, + onClick: onClearDate + }), closeIcon), inputIconPosition === ICON_AFTER_POSITION && inputIcon); +} + +SingleDatePickerInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePickerInput.defaultProps = defaultProps; +export default withStyles(function (_ref2) { + var _ref2$reactDates = _ref2.reactDates, + border = _ref2$reactDates.border, + color = _ref2$reactDates.color; + return { + SingleDatePickerInput: { + display: 'inline-block', + backgroundColor: color.background + }, + SingleDatePickerInput__withBorder: { + borderColor: color.border, + borderWidth: border.pickerInput.borderWidth, + borderStyle: border.pickerInput.borderStyle, + borderRadius: border.pickerInput.borderRadius + }, + SingleDatePickerInput__rtl: { + direction: noflip('rtl') + }, + SingleDatePickerInput__disabled: { + backgroundColor: color.disabled + }, + SingleDatePickerInput__block: { + display: 'block' + }, + SingleDatePickerInput__showClearDate: { + paddingRight: 30 // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + SingleDatePickerInput_clearDate: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + padding: 10, + margin: '0 10px 0 5px', + // TODO: should be noflip wrapped and handled by an isRTL prop + position: 'absolute', + right: 0, + // TODO: should be noflip wrapped and handled by an isRTL prop + top: '50%', + transform: 'translateY(-50%)' + }, + SingleDatePickerInput_clearDate__default: { + ':focus': { + background: color.core.border, + borderRadius: '50%' + }, + ':hover': { + background: color.core.border, + borderRadius: '50%' + } + }, + SingleDatePickerInput_clearDate__small: { + padding: 6 + }, + SingleDatePickerInput_clearDate__hide: { + visibility: 'hidden' + }, + SingleDatePickerInput_clearDate_svg: { + fill: color.core.grayLight, + height: 12, + width: 15, + verticalAlign: 'middle' + }, + SingleDatePickerInput_clearDate_svg__small: { + height: 9 + }, + SingleDatePickerInput_calendarIcon: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + display: 'inline-block', + verticalAlign: 'middle', + padding: 10, + margin: '0 5px 0 10px' // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + SingleDatePickerInput_calendarIcon_svg: { + fill: color.core.grayLight, + height: 15, + width: 14, + verticalAlign: 'middle' + } + }; +}, { + pureComponent: typeof React.PureComponent !== 'undefined' +})(SingleDatePickerInput); \ No newline at end of file diff --git a/esm/components/SingleDatePickerInputController.js b/esm/components/SingleDatePickerInputController.js new file mode 100644 index 000000000..e50e574f1 --- /dev/null +++ b/esm/components/SingleDatePickerInputController.js @@ -0,0 +1,281 @@ +import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; +import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; +import shallowEqual from "enzyme-shallow-equal"; +import React from 'react'; +import PropTypes from 'prop-types'; +import moment from 'moment'; +import momentPropTypes from 'react-moment-proptypes'; +import { forbidExtraProps, nonNegativeInteger } from 'airbnb-prop-types'; +import openDirectionShape from '../shapes/OpenDirectionShape'; +import { SingleDatePickerInputPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import SingleDatePickerInput from './SingleDatePickerInput'; +import IconPositionShape from '../shapes/IconPositionShape'; +import DisabledShape from '../shapes/DisabledShape'; +import toMomentObject from '../utils/toMomentObject'; +import toLocalizedDateString from '../utils/toLocalizedDateString'; +import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay'; +import { ICON_BEFORE_POSITION, OPEN_DOWN } from '../constants'; +var propTypes = process.env.NODE_ENV !== "production" ? forbidExtraProps({ + children: PropTypes.node, + date: momentPropTypes.momentObj, + onDateChange: PropTypes.func.isRequired, + focused: PropTypes.bool, + onFocusChange: PropTypes.func.isRequired, + id: PropTypes.string.isRequired, + placeholder: PropTypes.string, + ariaLabel: PropTypes.string, + autoComplete: PropTypes.string, + titleText: PropTypes.string, + screenReaderMessage: PropTypes.string, + showClearDate: PropTypes.bool, + showCaret: PropTypes.bool, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + disabled: DisabledShape, + required: PropTypes.bool, + readOnly: PropTypes.bool, + openDirection: openDirectionShape, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + keepOpenOnDateSelect: PropTypes.bool, + reopenPickerOnClearDate: PropTypes.bool, + isOutsideRange: PropTypes.func, + isDayBlocked: PropTypes.func, + displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + onClose: PropTypes.func, + onKeyDownArrowDown: PropTypes.func, + onKeyDownQuestionMark: PropTypes.func, + customInputIcon: PropTypes.node, + customCloseIcon: PropTypes.node, + // accessibility + isFocused: PropTypes.bool, + // i18n + phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerInputPhrases)), + isRTL: PropTypes.bool +}) : {}; +var defaultProps = { + children: null, + date: null, + focused: false, + placeholder: '', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + screenReaderMessage: 'Date', + showClearDate: false, + showCaret: false, + showDefaultInputIcon: false, + inputIconPosition: ICON_BEFORE_POSITION, + disabled: false, + required: false, + readOnly: false, + openDirection: OPEN_DOWN, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + keepOpenOnDateSelect: false, + reopenPickerOnClearDate: false, + isOutsideRange: function isOutsideRange(day) { + return !isInclusivelyAfterDay(day, moment()); + }, + isDayBlocked: function isDayBlocked() { + return false; + }, + displayFormat: function displayFormat() { + return moment.localeData().longDateFormat('L'); + }, + onClose: function onClose() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + customInputIcon: null, + customCloseIcon: null, + // accessibility + isFocused: false, + // i18n + phrases: SingleDatePickerInputPhrases, + isRTL: false +}; + +var SingleDatePickerInputController = /*#__PURE__*/function (_ref2, _ref) { + _inheritsLoose(SingleDatePickerInputController, _ref2); + + var _proto = SingleDatePickerInputController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState); + }; + + function SingleDatePickerInputController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.onChange = _this.onChange.bind(_assertThisInitialized(_this)); + _this.onFocus = _this.onFocus.bind(_assertThisInitialized(_this)); + _this.onClearFocus = _this.onClearFocus.bind(_assertThisInitialized(_this)); + _this.clearDate = _this.clearDate.bind(_assertThisInitialized(_this)); + return _this; + } + + _proto.onChange = function onChange(dateString) { + var _this$props = this.props, + isOutsideRange = _this$props.isOutsideRange, + isDayBlocked = _this$props.isDayBlocked, + keepOpenOnDateSelect = _this$props.keepOpenOnDateSelect, + onDateChange = _this$props.onDateChange, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose; + var newDate = toMomentObject(dateString, this.getDisplayFormat()); + var isValid = newDate && !isOutsideRange(newDate) && !isDayBlocked(newDate); + + if (isValid) { + onDateChange(newDate); + + if (!keepOpenOnDateSelect) { + onFocusChange({ + focused: false + }); + onClose({ + date: newDate + }); + } + } else { + onDateChange(null); + } + }; + + _proto.onFocus = function onFocus() { + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + disabled = _this$props2.disabled; + + if (!disabled) { + onFocusChange({ + focused: true + }); + } + }; + + _proto.onClearFocus = function onClearFocus() { + var _this$props3 = this.props, + focused = _this$props3.focused, + onFocusChange = _this$props3.onFocusChange, + onClose = _this$props3.onClose, + date = _this$props3.date; + if (!focused) return; + onFocusChange({ + focused: false + }); + onClose({ + date: date + }); + }; + + _proto.getDisplayFormat = function getDisplayFormat() { + var displayFormat = this.props.displayFormat; + return typeof displayFormat === 'string' ? displayFormat : displayFormat(); + }; + + _proto.getDateString = function getDateString(date) { + var displayFormat = this.getDisplayFormat(); + + if (date && displayFormat) { + return date && date.format(displayFormat); + } + + return toLocalizedDateString(date); + }; + + _proto.clearDate = function clearDate() { + var _this$props4 = this.props, + onDateChange = _this$props4.onDateChange, + reopenPickerOnClearDate = _this$props4.reopenPickerOnClearDate, + onFocusChange = _this$props4.onFocusChange; + onDateChange(null); + + if (reopenPickerOnClearDate) { + onFocusChange({ + focused: true + }); + } + }; + + _proto.render = function render() { + var _this$props5 = this.props, + children = _this$props5.children, + id = _this$props5.id, + placeholder = _this$props5.placeholder, + ariaLabel = _this$props5.ariaLabel, + autoComplete = _this$props5.autoComplete, + titleText = _this$props5.titleText, + disabled = _this$props5.disabled, + focused = _this$props5.focused, + isFocused = _this$props5.isFocused, + required = _this$props5.required, + readOnly = _this$props5.readOnly, + openDirection = _this$props5.openDirection, + showClearDate = _this$props5.showClearDate, + showCaret = _this$props5.showCaret, + showDefaultInputIcon = _this$props5.showDefaultInputIcon, + inputIconPosition = _this$props5.inputIconPosition, + customCloseIcon = _this$props5.customCloseIcon, + customInputIcon = _this$props5.customInputIcon, + date = _this$props5.date, + phrases = _this$props5.phrases, + onKeyDownArrowDown = _this$props5.onKeyDownArrowDown, + onKeyDownQuestionMark = _this$props5.onKeyDownQuestionMark, + screenReaderMessage = _this$props5.screenReaderMessage, + isRTL = _this$props5.isRTL, + noBorder = _this$props5.noBorder, + block = _this$props5.block, + small = _this$props5.small, + regular = _this$props5.regular, + verticalSpacing = _this$props5.verticalSpacing; + var displayValue = this.getDateString(date); + return /*#__PURE__*/React.createElement(SingleDatePickerInput, { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + focused: focused, + isFocused: isFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + showCaret: showCaret, + onClearDate: this.clearDate, + showClearDate: showClearDate, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + customCloseIcon: customCloseIcon, + customInputIcon: customInputIcon, + displayValue: displayValue, + onChange: this.onChange, + onFocus: this.onFocus, + onKeyDownShiftTab: this.onClearFocus, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + screenReaderMessage: screenReaderMessage, + phrases: phrases, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing + }, children); + }; + + return SingleDatePickerInputController; +}(React.PureComponent || React.Component, !React.PureComponent && "shouldComponentUpdate"); + +export { SingleDatePickerInputController as default }; +SingleDatePickerInputController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePickerInputController.defaultProps = defaultProps; \ No newline at end of file diff --git a/esm/constants.js b/esm/constants.js new file mode 100644 index 000000000..ed6b12cba --- /dev/null +++ b/esm/constants.js @@ -0,0 +1,28 @@ +export var DISPLAY_FORMAT = 'L'; +export var ISO_FORMAT = 'YYYY-MM-DD'; +export var ISO_MONTH_FORMAT = 'YYYY-MM'; // TODO delete this line of dead code on next breaking change + +export var START_DATE = 'startDate'; +export var END_DATE = 'endDate'; +export var HORIZONTAL_ORIENTATION = 'horizontal'; +export var VERTICAL_ORIENTATION = 'vertical'; +export var VERTICAL_SCROLLABLE = 'verticalScrollable'; +export var NAV_POSITION_BOTTOM = 'navPositionBottom'; +export var NAV_POSITION_TOP = 'navPositionTop'; +export var ICON_BEFORE_POSITION = 'before'; +export var ICON_AFTER_POSITION = 'after'; +export var INFO_POSITION_TOP = 'top'; +export var INFO_POSITION_BOTTOM = 'bottom'; +export var INFO_POSITION_BEFORE = 'before'; +export var INFO_POSITION_AFTER = 'after'; +export var ANCHOR_LEFT = 'left'; +export var ANCHOR_RIGHT = 'right'; +export var OPEN_DOWN = 'down'; +export var OPEN_UP = 'up'; +export var DAY_SIZE = 39; +export var BLOCKED_MODIFIER = 'blocked'; +export var WEEKDAYS = [0, 1, 2, 3, 4, 5, 6]; +export var FANG_WIDTH_PX = 20; +export var FANG_HEIGHT_PX = 10; +export var DEFAULT_VERTICAL_SPACING = 22; +export var MODIFIER_KEY_NAMES = new Set(['Shift', 'Control', 'Alt', 'Meta']); \ No newline at end of file diff --git a/esm/defaultPhrases.js b/esm/defaultPhrases.js new file mode 100644 index 000000000..f4d20def7 --- /dev/null +++ b/esm/defaultPhrases.js @@ -0,0 +1,233 @@ +var calendarLabel = 'Calendar'; +var roleDescription = 'datepicker'; +var closeDatePicker = 'Close'; +var focusStartDate = 'Interact with the calendar and add the check-in date for your trip.'; +var clearDate = 'Clear Date'; +var clearDates = 'Clear Dates'; +var jumpToPrevMonth = 'Move backward to switch to the previous month.'; +var jumpToNextMonth = 'Move forward to switch to the next month.'; +var keyboardShortcuts = 'Keyboard Shortcuts'; +var showKeyboardShortcutsPanel = 'Open the keyboard shortcuts panel.'; +var hideKeyboardShortcutsPanel = 'Close the shortcuts panel.'; +var openThisPanel = 'Open this panel.'; +var enterKey = 'Enter key'; +var leftArrowRightArrow = 'Right and left arrow keys'; +var upArrowDownArrow = 'up and down arrow keys'; +var pageUpPageDown = 'page up and page down keys'; +var homeEnd = 'Home and end keys'; +var escape = 'Escape key'; +var questionMark = 'Question mark'; +var selectFocusedDate = 'Select the date in focus.'; +var moveFocusByOneDay = 'Move backward (left) and forward (right) by one day.'; +var moveFocusByOneWeek = 'Move backward (up) and forward (down) by one week.'; +var moveFocusByOneMonth = 'Switch months.'; +var moveFocustoStartAndEndOfWeek = 'Go to the first or last day of a week.'; +var returnFocusToInput = 'Return to the date input field.'; +var keyboardForwardNavigationInstructions = 'Navigate forward to interact with the calendar and select a date. Press the question mark key to get the keyboard shortcuts for changing dates.'; +var keyboardBackwardNavigationInstructions = 'Navigate backward to interact with the calendar and select a date. Press the question mark key to get the keyboard shortcuts for changing dates.'; + +var chooseAvailableStartDate = function chooseAvailableStartDate(_ref) { + var date = _ref.date; + return "Choose ".concat(date, " as your check-in date. It\u2019s available."); +}; + +var chooseAvailableEndDate = function chooseAvailableEndDate(_ref2) { + var date = _ref2.date; + return "Choose ".concat(date, " as your check-out date. It\u2019s available."); +}; + +var chooseAvailableDate = function chooseAvailableDate(_ref3) { + var date = _ref3.date; + return date; +}; + +var dateIsUnavailable = function dateIsUnavailable(_ref4) { + var date = _ref4.date; + return "Not available. ".concat(date); +}; + +var dateIsSelected = function dateIsSelected(_ref5) { + var date = _ref5.date; + return "Selected. ".concat(date); +}; + +var dateIsSelectedAsStartDate = function dateIsSelectedAsStartDate(_ref6) { + var date = _ref6.date; + return "Selected as start date. ".concat(date); +}; + +var dateIsSelectedAsEndDate = function dateIsSelectedAsEndDate(_ref7) { + var date = _ref7.date; + return "Selected as end date. ".concat(date); +}; + +export default { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + focusStartDate: focusStartDate, + clearDate: clearDate, + clearDates: clearDates, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +export var DateRangePickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + clearDates: clearDates, + focusStartDate: focusStartDate, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +export var DateRangePickerInputPhrases = { + focusStartDate: focusStartDate, + clearDates: clearDates, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions +}; +export var SingleDatePickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + clearDate: clearDate, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected +}; +export var SingleDatePickerInputPhrases = { + clearDate: clearDate, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions +}; +export var DayPickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +export var DayPickerKeyboardShortcutsPhrases = { + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput +}; +export var DayPickerNavigationPhrases = { + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth +}; +export var CalendarDayPhrases = { + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; \ No newline at end of file diff --git a/esm/index.js b/esm/index.js new file mode 100644 index 000000000..c19d268b7 --- /dev/null +++ b/esm/index.js @@ -0,0 +1,20 @@ +export { default as CalendarDay } from './components/CalendarDay'; +export { default as CalendarMonth } from './components/CalendarMonth'; +export { default as CalendarMonthGrid } from './components/CalendarMonthGrid'; +export { default as DateRangePicker } from './components/DateRangePicker'; +export { default as DateRangePickerInput } from './components/DateRangePickerInput'; +export { default as DateRangePickerInputController } from './components/DateRangePickerInputController'; +export { default as DateRangePickerShape } from './shapes/DateRangePickerShape'; +export { default as DayPicker } from './components/DayPicker'; +export { default as DayPickerRangeController } from './components/DayPickerRangeController'; +export { default as DayPickerSingleDateController } from './components/DayPickerSingleDateController'; +export { default as SingleDatePicker } from './components/SingleDatePicker'; +export { default as SingleDatePickerInput } from './components/SingleDatePickerInput'; +export { default as SingleDatePickerShape } from './shapes/SingleDatePickerShape'; +export { default as isInclusivelyAfterDay } from './utils/isInclusivelyAfterDay'; +export { default as isInclusivelyBeforeDay } from './utils/isInclusivelyBeforeDay'; +export { default as isNextDay } from './utils/isNextDay'; +export { default as isSameDay } from './utils/isSameDay'; +export { default as toISODateString } from './utils/toISODateString'; +export { default as toLocalizedDateString } from './utils/toLocalizedDateString'; +export { default as toMomentObject } from './utils/toMomentObject'; \ No newline at end of file diff --git a/esm/initialize.js b/esm/initialize.js new file mode 100644 index 000000000..c16cdbf34 --- /dev/null +++ b/esm/initialize.js @@ -0,0 +1,2 @@ +import registerCSSInterfaceWithDefaultTheme from './utils/registerCSSInterfaceWithDefaultTheme'; +registerCSSInterfaceWithDefaultTheme(); \ No newline at end of file diff --git a/esm/shapes/AnchorDirectionShape.js b/esm/shapes/AnchorDirectionShape.js new file mode 100644 index 000000000..069eceb45 --- /dev/null +++ b/esm/shapes/AnchorDirectionShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { ANCHOR_LEFT, ANCHOR_RIGHT } from '../constants'; +export default PropTypes.oneOf([ANCHOR_LEFT, ANCHOR_RIGHT]); \ No newline at end of file diff --git a/esm/shapes/CalendarInfoPositionShape.js b/esm/shapes/CalendarInfoPositionShape.js new file mode 100644 index 000000000..1d18a3778 --- /dev/null +++ b/esm/shapes/CalendarInfoPositionShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { INFO_POSITION_TOP, INFO_POSITION_BOTTOM, INFO_POSITION_BEFORE, INFO_POSITION_AFTER } from '../constants'; +export default PropTypes.oneOf([INFO_POSITION_TOP, INFO_POSITION_BOTTOM, INFO_POSITION_BEFORE, INFO_POSITION_AFTER]); \ No newline at end of file diff --git a/esm/shapes/DateRangePickerShape.js b/esm/shapes/DateRangePickerShape.js new file mode 100644 index 000000000..df336f593 --- /dev/null +++ b/esm/shapes/DateRangePickerShape.js @@ -0,0 +1,101 @@ +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { DateRangePickerPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import FocusedInputShape from './FocusedInputShape'; +import IconPositionShape from './IconPositionShape'; +import OrientationShape from './OrientationShape'; +import DisabledShape from './DisabledShape'; +import anchorDirectionShape from './AnchorDirectionShape'; +import openDirectionShape from './OpenDirectionShape'; +import DayOfWeekShape from './DayOfWeekShape'; +import CalendarInfoPositionShape from './CalendarInfoPositionShape'; +import NavPositionShape from './NavPositionShape'; +export default { + // required props for a functional interactive DateRangePicker + startDate: momentPropTypes.momentObj, + endDate: momentPropTypes.momentObj, + onDatesChange: PropTypes.func.isRequired, + focusedInput: FocusedInputShape, + onFocusChange: PropTypes.func.isRequired, + onClose: PropTypes.func, + // input related props + startDateId: PropTypes.string.isRequired, + startDatePlaceholderText: PropTypes.string, + startDateOffset: PropTypes.func, + endDateOffset: PropTypes.func, + endDateId: PropTypes.string.isRequired, + endDatePlaceholderText: PropTypes.string, + startDateAriaLabel: PropTypes.string, + endDateAriaLabel: PropTypes.string, + startDateTitleText: PropTypes.string, + endDateTitleText: PropTypes.string, + disabled: DisabledShape, + required: PropTypes.bool, + readOnly: PropTypes.bool, + screenReaderInputMessage: PropTypes.string, + showClearDates: PropTypes.bool, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + customInputIcon: PropTypes.node, + customArrowIcon: PropTypes.node, + customCloseIcon: PropTypes.node, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + keepFocusOnInput: PropTypes.bool, + autoComplete: PropTypes.string, + // calendar presentation and interaction related props + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: PropTypes.func, + orientation: OrientationShape, + anchorDirection: anchorDirectionShape, + openDirection: openDirectionShape, + horizontalMargin: PropTypes.number, + withPortal: PropTypes.bool, + withFullScreenPortal: PropTypes.bool, + appendToBody: PropTypes.bool, + disableScroll: PropTypes.bool, + daySize: nonNegativeInteger, + isRTL: PropTypes.bool, + firstDayOfWeek: DayOfWeekShape, + initialVisibleMonth: PropTypes.func, + numberOfMonths: PropTypes.number, + keepOpenOnDateSelect: PropTypes.bool, + reopenPickerOnClearDates: PropTypes.bool, + renderCalendarInfo: PropTypes.func, + calendarInfoPosition: CalendarInfoPositionShape, + hideKeyboardShortcutsPanel: PropTypes.bool, + verticalHeight: nonNegativeInteger, + transitionDuration: nonNegativeInteger, + verticalSpacing: nonNegativeInteger, + horizontalMonthPadding: nonNegativeInteger, + // navigation related props + dayPickerNavigationInlineStyles: PropTypes.object, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + // day presentation and interaction related props + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + minimumNights: PropTypes.number, + minDate: momentPropTypes.momentObj, + maxDate: momentPropTypes.momentObj, + enableOutsideDays: PropTypes.bool, + isDayBlocked: PropTypes.func, + isOutsideRange: PropTypes.func, + isDayHighlighted: PropTypes.func, + // internationalization props + displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + monthFormat: PropTypes.string, + weekDayFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(DateRangePickerPhrases)), + dayAriaLabelFormat: PropTypes.string +}; \ No newline at end of file diff --git a/esm/shapes/DayOfWeekShape.js b/esm/shapes/DayOfWeekShape.js new file mode 100644 index 000000000..b9392379a --- /dev/null +++ b/esm/shapes/DayOfWeekShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { WEEKDAYS } from '../constants'; +export default PropTypes.oneOf(WEEKDAYS); \ No newline at end of file diff --git a/esm/shapes/DisabledShape.js b/esm/shapes/DisabledShape.js new file mode 100644 index 000000000..83244699c --- /dev/null +++ b/esm/shapes/DisabledShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { START_DATE, END_DATE } from '../constants'; +export default PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf([START_DATE, END_DATE])]); \ No newline at end of file diff --git a/esm/shapes/FocusedInputShape.js b/esm/shapes/FocusedInputShape.js new file mode 100644 index 000000000..067df1b8c --- /dev/null +++ b/esm/shapes/FocusedInputShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { START_DATE, END_DATE } from '../constants'; +export default PropTypes.oneOf([START_DATE, END_DATE]); \ No newline at end of file diff --git a/esm/shapes/IconPositionShape.js b/esm/shapes/IconPositionShape.js new file mode 100644 index 000000000..6b603c979 --- /dev/null +++ b/esm/shapes/IconPositionShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { ICON_BEFORE_POSITION, ICON_AFTER_POSITION } from '../constants'; +export default PropTypes.oneOf([ICON_BEFORE_POSITION, ICON_AFTER_POSITION]); \ No newline at end of file diff --git a/esm/shapes/ModifiersShape.js b/esm/shapes/ModifiersShape.js new file mode 100644 index 000000000..80b394752 --- /dev/null +++ b/esm/shapes/ModifiersShape.js @@ -0,0 +1,22 @@ +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; +import PropTypes from 'prop-types'; +import { and } from 'airbnb-prop-types'; +export default and([PropTypes.instanceOf(Set), function modifiers(props, propName) { + for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + rest[_key - 2] = arguments[_key]; + } + + var propValue = props[propName]; + var firstError; + + _toConsumableArray(propValue).some(function (v, i) { + var _PropTypes$string; + + var fakePropName = "".concat(propName, ": index ").concat(i); + firstError = (_PropTypes$string = PropTypes.string).isRequired.apply(_PropTypes$string, [_defineProperty({}, fakePropName, v), fakePropName].concat(rest)); + return firstError != null; + }); + + return firstError == null ? null : firstError; +}], 'Modifiers (Set of Strings)'); \ No newline at end of file diff --git a/esm/shapes/NavPositionShape.js b/esm/shapes/NavPositionShape.js new file mode 100644 index 000000000..9fcd57ee0 --- /dev/null +++ b/esm/shapes/NavPositionShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { NAV_POSITION_BOTTOM, NAV_POSITION_TOP } from '../constants'; +export default PropTypes.oneOf([NAV_POSITION_BOTTOM, NAV_POSITION_TOP]); \ No newline at end of file diff --git a/esm/shapes/OpenDirectionShape.js b/esm/shapes/OpenDirectionShape.js new file mode 100644 index 000000000..0951663d2 --- /dev/null +++ b/esm/shapes/OpenDirectionShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { OPEN_DOWN, OPEN_UP } from '../constants'; +export default PropTypes.oneOf([OPEN_DOWN, OPEN_UP]); \ No newline at end of file diff --git a/esm/shapes/OrientationShape.js b/esm/shapes/OrientationShape.js new file mode 100644 index 000000000..868d1ce78 --- /dev/null +++ b/esm/shapes/OrientationShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION } from '../constants'; +export default PropTypes.oneOf([HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION]); \ No newline at end of file diff --git a/esm/shapes/ScrollableOrientationShape.js b/esm/shapes/ScrollableOrientationShape.js new file mode 100644 index 000000000..f0442bb14 --- /dev/null +++ b/esm/shapes/ScrollableOrientationShape.js @@ -0,0 +1,3 @@ +import PropTypes from 'prop-types'; +import { HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, VERTICAL_SCROLLABLE } from '../constants'; +export default PropTypes.oneOf([HORIZONTAL_ORIENTATION, VERTICAL_ORIENTATION, VERTICAL_SCROLLABLE]); \ No newline at end of file diff --git a/esm/shapes/SingleDatePickerShape.js b/esm/shapes/SingleDatePickerShape.js new file mode 100644 index 000000000..96979b71f --- /dev/null +++ b/esm/shapes/SingleDatePickerShape.js @@ -0,0 +1,90 @@ +import PropTypes from 'prop-types'; +import momentPropTypes from 'react-moment-proptypes'; +import { mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types'; +import { SingleDatePickerPhrases } from '../defaultPhrases'; +import getPhrasePropTypes from '../utils/getPhrasePropTypes'; +import IconPositionShape from './IconPositionShape'; +import OrientationShape from './OrientationShape'; +import anchorDirectionShape from './AnchorDirectionShape'; +import openDirectionShape from './OpenDirectionShape'; +import DayOfWeekShape from './DayOfWeekShape'; +import CalendarInfoPositionShape from './CalendarInfoPositionShape'; +import NavPositionShape from './NavPositionShape'; +export default { + // required props for a functional interactive SingleDatePicker + date: momentPropTypes.momentObj, + onDateChange: PropTypes.func.isRequired, + focused: PropTypes.bool, + onFocusChange: PropTypes.func.isRequired, + // input related props + id: PropTypes.string.isRequired, + placeholder: PropTypes.string, + ariaLabel: PropTypes.string, + titleText: PropTypes.string, + disabled: PropTypes.bool, + required: PropTypes.bool, + readOnly: PropTypes.bool, + screenReaderInputMessage: PropTypes.string, + showClearDate: PropTypes.bool, + customCloseIcon: PropTypes.node, + showDefaultInputIcon: PropTypes.bool, + inputIconPosition: IconPositionShape, + customInputIcon: PropTypes.node, + noBorder: PropTypes.bool, + block: PropTypes.bool, + small: PropTypes.bool, + regular: PropTypes.bool, + verticalSpacing: nonNegativeInteger, + keepFocusOnInput: PropTypes.bool, + autoComplete: PropTypes.string, + // calendar presentation and interaction related props + renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: PropTypes.func, + orientation: OrientationShape, + anchorDirection: anchorDirectionShape, + openDirection: openDirectionShape, + horizontalMargin: PropTypes.number, + withPortal: PropTypes.bool, + withFullScreenPortal: PropTypes.bool, + appendToBody: PropTypes.bool, + disableScroll: PropTypes.bool, + initialVisibleMonth: PropTypes.func, + firstDayOfWeek: DayOfWeekShape, + numberOfMonths: PropTypes.number, + keepOpenOnDateSelect: PropTypes.bool, + reopenPickerOnClearDate: PropTypes.bool, + renderCalendarInfo: PropTypes.func, + calendarInfoPosition: CalendarInfoPositionShape, + hideKeyboardShortcutsPanel: PropTypes.bool, + daySize: nonNegativeInteger, + isRTL: PropTypes.bool, + verticalHeight: nonNegativeInteger, + transitionDuration: nonNegativeInteger, + horizontalMonthPadding: nonNegativeInteger, + // navigation related props + dayPickerNavigationInlineStyles: PropTypes.object, + navPosition: NavPositionShape, + navPrev: PropTypes.node, + navNext: PropTypes.node, + renderNavPrevButton: PropTypes.func, + renderNavNextButton: PropTypes.func, + onPrevMonthClick: PropTypes.func, + onNextMonthClick: PropTypes.func, + onClose: PropTypes.func, + // day presentation and interaction related props + renderCalendarDay: PropTypes.func, + renderDayContents: PropTypes.func, + enableOutsideDays: PropTypes.bool, + isDayBlocked: PropTypes.func, + isOutsideRange: PropTypes.func, + isDayHighlighted: PropTypes.func, + minDate: momentPropTypes.momentObj, + maxDate: momentPropTypes.momentObj, + // internationalization props + displayFormat: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + monthFormat: PropTypes.string, + weekDayFormat: PropTypes.string, + phrases: PropTypes.shape(getPhrasePropTypes(SingleDatePickerPhrases)), + dayAriaLabelFormat: PropTypes.string +}; \ No newline at end of file diff --git a/esm/theme/DefaultTheme.js b/esm/theme/DefaultTheme.js new file mode 100644 index 000000000..130edc39e --- /dev/null +++ b/esm/theme/DefaultTheme.js @@ -0,0 +1,176 @@ +var core = { + white: '#fff', + gray: '#484848', + grayLight: '#82888a', + grayLighter: '#cacccd', + grayLightest: '#f2f2f2', + borderMedium: '#c4c4c4', + border: '#dbdbdb', + borderLight: '#e4e7e7', + borderLighter: '#eceeee', + borderBright: '#f4f5f5', + primary: '#00a699', + primaryShade_1: '#33dacd', + primaryShade_2: '#66e2da', + primaryShade_3: '#80e8e0', + primaryShade_4: '#b2f1ec', + primary_dark: '#008489', + secondary: '#007a87', + yellow: '#ffe8bc', + yellow_dark: '#ffce71' +}; +export default { + reactDates: { + zIndex: 0, + border: { + input: { + border: 0, + borderTop: 0, + borderRight: 0, + borderBottom: '2px solid transparent', + borderLeft: 0, + outlineFocused: 0, + borderFocused: 0, + borderTopFocused: 0, + borderLeftFocused: 0, + borderBottomFocused: "2px solid ".concat(core.primary_dark), + borderRightFocused: 0, + borderRadius: 0 + }, + pickerInput: { + borderWidth: 1, + borderStyle: 'solid', + borderRadius: 2 + } + }, + color: { + core: core, + disabled: core.grayLightest, + background: core.white, + backgroundDark: '#f2f2f2', + backgroundFocused: core.white, + border: 'rgb(219, 219, 219)', + text: core.gray, + textDisabled: core.border, + textFocused: '#007a87', + placeholderText: '#757575', + outside: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + color: core.gray, + color_active: core.gray, + color_hover: core.gray + }, + highlighted: { + backgroundColor: core.yellow, + backgroundColor_active: core.yellow_dark, + backgroundColor_hover: core.yellow_dark, + color: core.gray, + color_active: core.gray, + color_hover: core.gray + }, + minimumNights: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + borderColor: core.borderLighter, + color: core.grayLighter, + color_active: core.grayLighter, + color_hover: core.grayLighter + }, + hoveredSpan: { + backgroundColor: core.primaryShade_4, + backgroundColor_active: core.primaryShade_3, + backgroundColor_hover: core.primaryShade_4, + borderColor: core.primaryShade_3, + borderColor_active: core.primaryShade_3, + borderColor_hover: core.primaryShade_3, + color: core.secondary, + color_active: core.secondary, + color_hover: core.secondary + }, + selectedSpan: { + backgroundColor: core.primaryShade_2, + backgroundColor_active: core.primaryShade_1, + backgroundColor_hover: core.primaryShade_1, + borderColor: core.primaryShade_1, + borderColor_active: core.primary, + borderColor_hover: core.primary, + color: core.white, + color_active: core.white, + color_hover: core.white + }, + selected: { + backgroundColor: core.primary, + backgroundColor_active: core.primary, + backgroundColor_hover: core.primary, + borderColor: core.primary, + borderColor_active: core.primary, + borderColor_hover: core.primary, + color: core.white, + color_active: core.white, + color_hover: core.white + }, + blocked_calendar: { + backgroundColor: core.grayLighter, + backgroundColor_active: core.grayLighter, + backgroundColor_hover: core.grayLighter, + borderColor: core.grayLighter, + borderColor_active: core.grayLighter, + borderColor_hover: core.grayLighter, + color: core.grayLight, + color_active: core.grayLight, + color_hover: core.grayLight + }, + blocked_out_of_range: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + borderColor: core.borderLight, + borderColor_active: core.borderLight, + borderColor_hover: core.borderLight, + color: core.grayLighter, + color_active: core.grayLighter, + color_hover: core.grayLighter + } + }, + spacing: { + dayPickerHorizontalPadding: 9, + captionPaddingTop: 22, + captionPaddingBottom: 37, + inputPadding: 0, + displayTextPaddingVertical: undefined, + displayTextPaddingTop: 11, + displayTextPaddingBottom: 9, + displayTextPaddingHorizontal: undefined, + displayTextPaddingLeft: 11, + displayTextPaddingRight: 11, + displayTextPaddingVertical_small: undefined, + displayTextPaddingTop_small: 7, + displayTextPaddingBottom_small: 5, + displayTextPaddingHorizontal_small: undefined, + displayTextPaddingLeft_small: 7, + displayTextPaddingRight_small: 7 + }, + sizing: { + inputWidth: 130, + inputWidth_small: 97, + arrowWidth: 24 + }, + noScrollBarOnVerticalScrollable: false, + font: { + size: 14, + captionSize: 18, + input: { + size: 19, + weight: 200, + lineHeight: '24px', + size_small: 15, + lineHeight_small: '18px', + letterSpacing_small: '0.2px', + styleDisabled: 'italic' + } + } + } +}; \ No newline at end of file diff --git a/esm/utils/calculateDimension.js b/esm/utils/calculateDimension.js new file mode 100644 index 000000000..801a07379 --- /dev/null +++ b/esm/utils/calculateDimension.js @@ -0,0 +1,28 @@ +export default function calculateDimension(el, axis) { + var borderBox = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var withMargin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + if (!el) { + return 0; + } + + var axisStart = axis === 'width' ? 'Left' : 'Top'; + var axisEnd = axis === 'width' ? 'Right' : 'Bottom'; // Only read styles if we need to + + var style = !borderBox || withMargin ? window.getComputedStyle(el) : null; // Offset includes border and padding + + var offsetWidth = el.offsetWidth, + offsetHeight = el.offsetHeight; + var size = axis === 'width' ? offsetWidth : offsetHeight; // Get the inner size + + if (!borderBox) { + size -= parseFloat(style["padding".concat(axisStart)]) + parseFloat(style["padding".concat(axisEnd)]) + parseFloat(style["border".concat(axisStart, "Width")]) + parseFloat(style["border".concat(axisEnd, "Width")]); + } // Apply margin + + + if (withMargin) { + size += parseFloat(style["margin".concat(axisStart)]) + parseFloat(style["margin".concat(axisEnd)]); + } + + return size; +} \ No newline at end of file diff --git a/esm/utils/disableScroll.js b/esm/utils/disableScroll.js new file mode 100644 index 000000000..2ea0e6dac --- /dev/null +++ b/esm/utils/disableScroll.js @@ -0,0 +1,74 @@ +var getScrollingRoot = function getScrollingRoot() { + return document.scrollingElement || document.documentElement; +}; +/** + * Recursively finds the scroll parent of a node. The scroll parrent of a node + * is the closest node that is scrollable. A node is scrollable if: + * - it is allowed to scroll via CSS ('overflow-y' not visible or hidden); + * - and its children/content are "bigger" than the node's box height. + * + * The root of the document always scrolls by default. + * + * @param {HTMLElement} node Any DOM element. + * @return {HTMLElement} The scroll parent element. + */ + + +export function getScrollParent(node) { + var parent = node.parentElement; + if (parent == null) return getScrollingRoot(); + + var _window$getComputedSt = window.getComputedStyle(parent), + overflowY = _window$getComputedSt.overflowY; + + var canScroll = overflowY !== 'visible' && overflowY !== 'hidden'; + + if (canScroll && parent.scrollHeight > parent.clientHeight) { + return parent; + } + + return getScrollParent(parent); +} +/** + * Recursively traverses the tree upwards from the given node, capturing all + * ancestor nodes that scroll along with their current 'overflow-y' CSS + * property. + * + * @param {HTMLElement} node Any DOM element. + * @param {Map} [acc] Accumulator map. + * @return {Map} Map of ancestors with their 'overflow-y' value. + */ + +export function getScrollAncestorsOverflowY(node) { + var acc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Map(); + var scrollingRoot = getScrollingRoot(); + var scrollParent = getScrollParent(node); + acc.set(scrollParent, scrollParent.style.overflowY); + if (scrollParent === scrollingRoot) return acc; + return getScrollAncestorsOverflowY(scrollParent, acc); +} +/** + * Disabling the scroll on a node involves finding all the scrollable ancestors + * and set their 'overflow-y' CSS property to 'hidden'. When all ancestors have + * 'overflow-y: hidden' (up to the document element) there is no scroll + * container, thus all the scroll outside of the node is disabled. In order to + * enable scroll again, we store the previous value of the 'overflow-y' for + * every ancestor in a closure and reset it back. + * + * @param {HTMLElement} node Any DOM element. + */ + +export default function disableScroll(node) { + var scrollAncestorsOverflowY = getScrollAncestorsOverflowY(node); + + var toggle = function toggle(on) { + return scrollAncestorsOverflowY.forEach(function (overflowY, ancestor) { + ancestor.style.setProperty('overflow-y', on ? 'hidden' : overflowY); + }); + }; + + toggle(true); + return function () { + return toggle(false); + }; +} \ No newline at end of file diff --git a/esm/utils/enumrateDatesBetween.js b/esm/utils/enumrateDatesBetween.js new file mode 100644 index 000000000..9408705bc --- /dev/null +++ b/esm/utils/enumrateDatesBetween.js @@ -0,0 +1,11 @@ +export default function enumrateDatesBetween(startDate, endDate) { + var now = startDate.clone(), + dates = []; + + while (now.isSameOrBefore(endDate)) { + dates.push(now.format('M/D/YYYY')); + now.add(1, 'days'); + } + + return dates; +} \ No newline at end of file diff --git a/esm/utils/getActiveElement.js b/esm/utils/getActiveElement.js new file mode 100644 index 000000000..21803dbd9 --- /dev/null +++ b/esm/utils/getActiveElement.js @@ -0,0 +1,3 @@ +export default function getActiveElement() { + return typeof document !== 'undefined' && document.activeElement; +} \ No newline at end of file diff --git a/esm/utils/getCalendarDaySettings.js b/esm/utils/getCalendarDaySettings.js new file mode 100644 index 000000000..b4f4f9db8 --- /dev/null +++ b/esm/utils/getCalendarDaySettings.js @@ -0,0 +1,58 @@ +import getPhrase from './getPhrase'; +import { BLOCKED_MODIFIER } from '../constants'; + +function isSelected(modifiers) { + return modifiers.has('selected') || modifiers.has('selected-span') || modifiers.has('selected-start') || modifiers.has('selected-end'); +} + +function shouldUseDefaultCursor(modifiers) { + return modifiers.has('blocked-minimum-nights') || modifiers.has('blocked-calendar') || modifiers.has('blocked-out-of-range'); +} + +function isHoveredSpan(modifiers) { + if (isSelected(modifiers)) return false; + return modifiers.has('hovered-span') || modifiers.has('after-hovered-start') || modifiers.has('before-hovered-end'); +} + +function getAriaLabel(phrases, modifiers, day, ariaLabelFormat) { + var chooseAvailableDate = phrases.chooseAvailableDate, + dateIsUnavailable = phrases.dateIsUnavailable, + dateIsSelected = phrases.dateIsSelected, + dateIsSelectedAsStartDate = phrases.dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate = phrases.dateIsSelectedAsEndDate; + var formattedDate = { + date: day.format(ariaLabelFormat) + }; + + if (modifiers.has('selected-start') && dateIsSelectedAsStartDate) { + return getPhrase(dateIsSelectedAsStartDate, formattedDate); + } + + if (modifiers.has('selected-end') && dateIsSelectedAsEndDate) { + return getPhrase(dateIsSelectedAsEndDate, formattedDate); + } + + if (isSelected(modifiers) && dateIsSelected) { + return getPhrase(dateIsSelected, formattedDate); + } + + if (modifiers.has(BLOCKED_MODIFIER)) { + return getPhrase(dateIsUnavailable, formattedDate); + } + + return getPhrase(chooseAvailableDate, formattedDate); +} + +export default function getCalendarDaySettings(day, ariaLabelFormat, daySize, modifiers, phrases) { + return { + ariaLabel: getAriaLabel(phrases, modifiers, day, ariaLabelFormat), + hoveredSpan: isHoveredSpan(modifiers), + isOutsideRange: modifiers.has('blocked-out-of-range'), + selected: isSelected(modifiers), + useDefaultCursor: shouldUseDefaultCursor(modifiers), + daySizeStyles: { + width: daySize, + height: daySize - 1 + } + }; +} \ No newline at end of file diff --git a/esm/utils/getCalendarMonthWeeks.js b/esm/utils/getCalendarMonthWeeks.js new file mode 100644 index 000000000..717eff7d9 --- /dev/null +++ b/esm/utils/getCalendarMonthWeeks.js @@ -0,0 +1,43 @@ +import moment from 'moment'; +import { WEEKDAYS } from '../constants'; +export default function getCalendarMonthWeeks(month, enableOutsideDays) { + var firstDayOfWeek = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : moment.localeData().firstDayOfWeek(); + + if (!moment.isMoment(month) || !month.isValid()) { + throw new TypeError('`month` must be a valid moment object'); + } + + if (WEEKDAYS.indexOf(firstDayOfWeek) === -1) { + throw new TypeError('`firstDayOfWeek` must be an integer between 0 and 6'); + } // set utc offset to get correct dates in future (when timezone changes) + + + var firstOfMonth = month.clone().startOf('month').hour(12); + var lastOfMonth = month.clone().endOf('month').hour(12); // calculate the exact first and last days to fill the entire matrix + // (considering days outside month) + + var prevDays = (firstOfMonth.day() + 7 - firstDayOfWeek) % 7; + var nextDays = (firstDayOfWeek + 6 - lastOfMonth.day()) % 7; + var firstDay = firstOfMonth.clone().subtract(prevDays, 'day'); + var lastDay = lastOfMonth.clone().add(nextDays, 'day'); + var totalDays = lastDay.diff(firstDay, 'days') + 1; + var currentDay = firstDay.clone(); + var weeksInMonth = []; + + for (var i = 0; i < totalDays; i += 1) { + if (i % 7 === 0) { + weeksInMonth.push([]); + } + + var day = null; + + if (i >= prevDays && i < totalDays - nextDays || enableOutsideDays) { + day = currentDay.clone(); + } + + weeksInMonth[weeksInMonth.length - 1].push(day); + currentDay.add(1, 'day'); + } + + return weeksInMonth; +} \ No newline at end of file diff --git a/esm/utils/getCalendarMonthWidth.js b/esm/utils/getCalendarMonthWidth.js new file mode 100644 index 000000000..f1a9edfbd --- /dev/null +++ b/esm/utils/getCalendarMonthWidth.js @@ -0,0 +1,4 @@ +export default function getCalendarMonthWidth(daySize) { + var calendarMonthPadding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return 7 * daySize + 2 * calendarMonthPadding + 1; +} \ No newline at end of file diff --git a/esm/utils/getDetachedContainerStyles.js b/esm/utils/getDetachedContainerStyles.js new file mode 100644 index 000000000..ceae77072 --- /dev/null +++ b/esm/utils/getDetachedContainerStyles.js @@ -0,0 +1,39 @@ +import { OPEN_UP, ANCHOR_RIGHT } from '../constants'; +/** + * Calculate and return a CSS transform style to position a detached element + * next to a reference element. The open and anchor direction indicate wether + * it should be positioned above/below and/or to the left/right of the + * reference element. + * + * Assuming r(0,0), r(1,1), d(0,0), d(1,1) for the bottom-left and top-right + * corners of the reference and detached elements, respectively: + * - openDirection = DOWN, anchorDirection = LEFT => d(0,1) == r(0,1) + * - openDirection = UP, anchorDirection = LEFT => d(0,0) == r(0,0) + * - openDirection = DOWN, anchorDirection = RIGHT => d(1,1) == r(1,1) + * - openDirection = UP, anchorDirection = RIGHT => d(1,0) == r(1,0) + * + * By using a CSS transform, we allow to further position it using + * top/bottom CSS properties for the anchor gutter. + * + * @param {string} openDirection The vertical positioning of the popup + * @param {string} anchorDirection The horizontal position of the popup + * @param {HTMLElement} referenceEl The reference element + */ + +export default function getDetachedContainerStyles(openDirection, anchorDirection, referenceEl) { + var referenceRect = referenceEl.getBoundingClientRect(); + var offsetX = referenceRect.left; + var offsetY = referenceRect.top; + + if (openDirection === OPEN_UP) { + offsetY = -(window.innerHeight - referenceRect.bottom); + } + + if (anchorDirection === ANCHOR_RIGHT) { + offsetX = -(window.innerWidth - referenceRect.right); + } + + return { + transform: "translate3d(".concat(Math.round(offsetX), "px, ").concat(Math.round(offsetY), "px, 0)") + }; +} \ No newline at end of file diff --git a/esm/utils/getInputHeight.js b/esm/utils/getInputHeight.js new file mode 100644 index 000000000..8825e0d08 --- /dev/null +++ b/esm/utils/getInputHeight.js @@ -0,0 +1,49 @@ +/* eslint-disable camelcase */ +function getPadding(vertical, top, bottom) { + var isTopDefined = typeof top === 'number'; + var isBottomDefined = typeof bottom === 'number'; + var isVerticalDefined = typeof vertical === 'number'; + + if (isTopDefined && isBottomDefined) { + return top + bottom; + } + + if (isTopDefined && isVerticalDefined) { + return top + vertical; + } + + if (isTopDefined) { + return top; + } + + if (isBottomDefined && isVerticalDefined) { + return bottom + vertical; + } + + if (isBottomDefined) { + return bottom; + } + + if (isVerticalDefined) { + return 2 * vertical; + } + + return 0; +} + +export default function getInputHeight(_ref, small) { + var _ref$font$input = _ref.font.input, + lineHeight = _ref$font$input.lineHeight, + lineHeight_small = _ref$font$input.lineHeight_small, + _ref$spacing = _ref.spacing, + inputPadding = _ref$spacing.inputPadding, + displayTextPaddingVertical = _ref$spacing.displayTextPaddingVertical, + displayTextPaddingTop = _ref$spacing.displayTextPaddingTop, + displayTextPaddingBottom = _ref$spacing.displayTextPaddingBottom, + displayTextPaddingVertical_small = _ref$spacing.displayTextPaddingVertical_small, + displayTextPaddingTop_small = _ref$spacing.displayTextPaddingTop_small, + displayTextPaddingBottom_small = _ref$spacing.displayTextPaddingBottom_small; + var calcLineHeight = small ? lineHeight_small : lineHeight; + var padding = small ? getPadding(displayTextPaddingVertical_small, displayTextPaddingTop_small, displayTextPaddingBottom_small) : getPadding(displayTextPaddingVertical, displayTextPaddingTop, displayTextPaddingBottom); + return parseInt(calcLineHeight, 10) + 2 * inputPadding + padding; +} \ No newline at end of file diff --git a/esm/utils/getNumberOfCalendarMonthWeeks.js b/esm/utils/getNumberOfCalendarMonthWeeks.js new file mode 100644 index 000000000..d389e3ffa --- /dev/null +++ b/esm/utils/getNumberOfCalendarMonthWeeks.js @@ -0,0 +1,13 @@ +import moment from 'moment'; + +function getBlankDaysBeforeFirstDay(firstDayOfMonth, firstDayOfWeek) { + var weekDayDiff = firstDayOfMonth.day() - firstDayOfWeek; + return (weekDayDiff + 7) % 7; +} + +export default function getNumberOfCalendarMonthWeeks(month) { + var firstDayOfWeek = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : moment.localeData().firstDayOfWeek(); + var firstDayOfMonth = month.clone().startOf('month').hour(12); + var numBlankDays = getBlankDaysBeforeFirstDay(firstDayOfMonth, firstDayOfWeek); + return Math.ceil((numBlankDays + month.daysInMonth()) / 7); +} \ No newline at end of file diff --git a/esm/utils/getPhrase.js b/esm/utils/getPhrase.js new file mode 100644 index 000000000..0701ca2c5 --- /dev/null +++ b/esm/utils/getPhrase.js @@ -0,0 +1,9 @@ +export default function getPhrase(phrase, args) { + if (typeof phrase === 'string') return phrase; + + if (typeof phrase === 'function') { + return phrase(args); + } + + return ''; +} \ No newline at end of file diff --git a/esm/utils/getPhrasePropTypes.js b/esm/utils/getPhrasePropTypes.js new file mode 100644 index 000000000..ccc617652 --- /dev/null +++ b/esm/utils/getPhrasePropTypes.js @@ -0,0 +1,12 @@ +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import PropTypes from 'prop-types'; +export default function getPhrasePropTypes(defaultPhrases) { + return Object.keys(defaultPhrases).reduce(function (phrases, key) { + return _objectSpread(_objectSpread({}, phrases), {}, _defineProperty({}, key, PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.node]))); + }, {}); +} \ No newline at end of file diff --git a/esm/utils/getPooledMoment.js b/esm/utils/getPooledMoment.js new file mode 100644 index 000000000..2aff3b21c --- /dev/null +++ b/esm/utils/getPooledMoment.js @@ -0,0 +1,9 @@ +import moment from 'moment'; +var momentPool = new Map(); +export default function getPooledMoment(dayString) { + if (!momentPool.has(dayString)) { + momentPool.set(dayString, moment(dayString)); + } + + return momentPool.get(dayString); +} \ No newline at end of file diff --git a/esm/utils/getPreviousMonthMemoLast.js b/esm/utils/getPreviousMonthMemoLast.js new file mode 100644 index 000000000..8d3331318 --- /dev/null +++ b/esm/utils/getPreviousMonthMemoLast.js @@ -0,0 +1,10 @@ +var getPreviousMonthMemoKey; +var getPreviousMonthMemoValue; +export default function getPreviousMonthMemoLast(month) { + if (month !== getPreviousMonthMemoKey) { + getPreviousMonthMemoKey = month; + getPreviousMonthMemoValue = month.clone().subtract(1, 'month'); + } + + return getPreviousMonthMemoValue; +} \ No newline at end of file diff --git a/esm/utils/getResponsiveContainerStyles.js b/esm/utils/getResponsiveContainerStyles.js new file mode 100644 index 000000000..ff89d774d --- /dev/null +++ b/esm/utils/getResponsiveContainerStyles.js @@ -0,0 +1,8 @@ +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; +import { ANCHOR_LEFT } from '../constants'; +export default function getResponsiveContainerStyles(anchorDirection, currentOffset, containerEdge, margin) { + var windowWidth = typeof window !== 'undefined' ? window.innerWidth : 0; + var calculatedOffset = anchorDirection === ANCHOR_LEFT ? windowWidth - containerEdge : containerEdge; + var calculatedMargin = margin || 0; + return _defineProperty({}, anchorDirection, Math.min(currentOffset + calculatedOffset - calculatedMargin, 0)); +} \ No newline at end of file diff --git a/esm/utils/getSelectedDateOffset.js b/esm/utils/getSelectedDateOffset.js new file mode 100644 index 000000000..e4ee5e795 --- /dev/null +++ b/esm/utils/getSelectedDateOffset.js @@ -0,0 +1,9 @@ +var defaultModifier = function defaultModifier(day) { + return day; +}; + +export default function getSelectedDateOffset(fn, day) { + var modifier = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultModifier; + if (!fn) return day; + return modifier(fn(day.clone())); +} \ No newline at end of file diff --git a/esm/utils/getTransformStyles.js b/esm/utils/getTransformStyles.js new file mode 100644 index 000000000..7b6961d07 --- /dev/null +++ b/esm/utils/getTransformStyles.js @@ -0,0 +1,8 @@ +export default function getTransformStyles(transformValue) { + return { + transform: transformValue, + msTransform: transformValue, + MozTransform: transformValue, + WebkitTransform: transformValue + }; +} \ No newline at end of file diff --git a/esm/utils/getVisibleDays.js b/esm/utils/getVisibleDays.js new file mode 100644 index 000000000..f6e273b9c --- /dev/null +++ b/esm/utils/getVisibleDays.js @@ -0,0 +1,45 @@ +import moment from 'moment'; +import toISOMonthString from './toISOMonthString'; +export default function getVisibleDays(month, numberOfMonths, enableOutsideDays, withoutTransitionMonths) { + if (!moment.isMoment(month)) return {}; + var visibleDaysByMonth = {}; + var currentMonth = withoutTransitionMonths ? month.clone() : month.clone().subtract(1, 'month'); + + for (var i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) { + var visibleDays = []; // set utc offset to get correct dates in future (when timezone changes) + + var baseDate = currentMonth.clone(); + var firstOfMonth = baseDate.clone().startOf('month').hour(12); + var lastOfMonth = baseDate.clone().endOf('month').hour(12); + var currentDay = firstOfMonth.clone(); // days belonging to the previous month + + if (enableOutsideDays) { + for (var j = 0; j < currentDay.weekday(); j += 1) { + var prevDay = currentDay.clone().subtract(j + 1, 'day'); + visibleDays.unshift(prevDay); + } + } + + while (currentDay < lastOfMonth) { + visibleDays.push(currentDay.clone()); + currentDay.add(1, 'day'); + } + + if (enableOutsideDays) { + // weekday() returns the index of the day of the week according to the locale + // this means if the week starts on Monday, weekday() will return 0 for a Monday date, not 1 + if (currentDay.weekday() !== 0) { + // days belonging to the next month + for (var k = currentDay.weekday(), count = 0; k < 7; k += 1, count += 1) { + var nextDay = currentDay.clone().add(count, 'day'); + visibleDays.push(nextDay); + } + } + } + + visibleDaysByMonth[toISOMonthString(currentMonth)] = visibleDays; + currentMonth = currentMonth.clone().add(1, 'month'); + } + + return visibleDaysByMonth; +} \ No newline at end of file diff --git a/esm/utils/isAfterDay.js b/esm/utils/isAfterDay.js new file mode 100644 index 000000000..0922f8c21 --- /dev/null +++ b/esm/utils/isAfterDay.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +import isBeforeDay from './isBeforeDay'; +import isSameDay from './isSameDay'; +export default function isAfterDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + return !isBeforeDay(a, b) && !isSameDay(a, b); +} \ No newline at end of file diff --git a/esm/utils/isBeforeDay.js b/esm/utils/isBeforeDay.js new file mode 100644 index 000000000..ced3d7c5e --- /dev/null +++ b/esm/utils/isBeforeDay.js @@ -0,0 +1,13 @@ +import moment from 'moment'; +export default function isBeforeDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + var aYear = a.year(); + var aMonth = a.month(); + var bYear = b.year(); + var bMonth = b.month(); + var isSameYear = aYear === bYear; + var isSameMonth = aMonth === bMonth; + if (isSameYear && isSameMonth) return a.date() < b.date(); + if (isSameYear) return aMonth < bMonth; + return aYear < bYear; +} \ No newline at end of file diff --git a/esm/utils/isDayVisible.js b/esm/utils/isDayVisible.js new file mode 100644 index 000000000..74e6e6b85 --- /dev/null +++ b/esm/utils/isDayVisible.js @@ -0,0 +1,42 @@ +import moment from 'moment'; +import isBeforeDay from './isBeforeDay'; +import isAfterDay from './isAfterDay'; +import toISOMonthString from './toISOMonthString'; +var startCacheOutsideDays = new Map(); +var endCacheOutsideDays = new Map(); +var startCacheInsideDays = new Map(); +var endCacheInsideDays = new Map(); +export default function isDayVisible(day, month, numberOfMonths, enableOutsideDays) { + if (!moment.isMoment(day)) return false; // Cloning is a little expensive, so we want to do it as little as possible. + + var startKey = toISOMonthString(month); // eslint-disable-next-line prefer-template + + var endKey = startKey + '+' + numberOfMonths; + + if (enableOutsideDays) { + if (!startCacheOutsideDays.has(startKey)) { + startCacheOutsideDays.set(startKey, month.clone().startOf('month').startOf('week').hour(12)); + } + + if (isBeforeDay(day, startCacheOutsideDays.get(startKey))) return false; + + if (!endCacheOutsideDays.has(endKey)) { + endCacheOutsideDays.set(endKey, month.clone().endOf('week').add(numberOfMonths - 1, 'months').endOf('month').endOf('week').hour(12)); + } + + return !isAfterDay(day, endCacheOutsideDays.get(endKey)); + } // !enableOutsideDays + + + if (!startCacheInsideDays.has(startKey)) { + startCacheInsideDays.set(startKey, month.clone().startOf('month').hour(12)); + } + + if (isBeforeDay(day, startCacheInsideDays.get(startKey))) return false; + + if (!endCacheInsideDays.has(endKey)) { + endCacheInsideDays.set(endKey, month.clone().add(numberOfMonths - 1, 'months').endOf('month').hour(12)); + } + + return !isAfterDay(day, endCacheInsideDays.get(endKey)); +} \ No newline at end of file diff --git a/esm/utils/isInclusivelyAfterDay.js b/esm/utils/isInclusivelyAfterDay.js new file mode 100644 index 000000000..abd06ff9b --- /dev/null +++ b/esm/utils/isInclusivelyAfterDay.js @@ -0,0 +1,6 @@ +import moment from 'moment'; +import isBeforeDay from './isBeforeDay'; +export default function isInclusivelyAfterDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + return !isBeforeDay(a, b); +} \ No newline at end of file diff --git a/esm/utils/isInclusivelyBeforeDay.js b/esm/utils/isInclusivelyBeforeDay.js new file mode 100644 index 000000000..6ff15c19a --- /dev/null +++ b/esm/utils/isInclusivelyBeforeDay.js @@ -0,0 +1,6 @@ +import moment from 'moment'; +import isAfterDay from './isAfterDay'; +export default function isInclusivelyBeforeDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + return !isAfterDay(a, b); +} \ No newline at end of file diff --git a/esm/utils/isNextDay.js b/esm/utils/isNextDay.js new file mode 100644 index 000000000..087c44825 --- /dev/null +++ b/esm/utils/isNextDay.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +import isSameDay from './isSameDay'; +export default function isNextDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + var nextDay = moment(a).add(1, 'day'); + return isSameDay(nextDay, b); +} \ No newline at end of file diff --git a/esm/utils/isNextMonth.js b/esm/utils/isNextMonth.js new file mode 100644 index 000000000..ba668eaa4 --- /dev/null +++ b/esm/utils/isNextMonth.js @@ -0,0 +1,6 @@ +import moment from 'moment'; +import isSameMonth from './isSameMonth'; +export default function isNextMonth(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + return isSameMonth(a.clone().add(1, 'month'), b); +} \ No newline at end of file diff --git a/esm/utils/isPrevMonth.js b/esm/utils/isPrevMonth.js new file mode 100644 index 000000000..f3666e611 --- /dev/null +++ b/esm/utils/isPrevMonth.js @@ -0,0 +1,6 @@ +import moment from 'moment'; +import isSameMonth from './isSameMonth'; +export default function isPrevMonth(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + return isSameMonth(a.clone().subtract(1, 'month'), b); +} \ No newline at end of file diff --git a/esm/utils/isPreviousDay.js b/esm/utils/isPreviousDay.js new file mode 100644 index 000000000..c19f038ac --- /dev/null +++ b/esm/utils/isPreviousDay.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +import isSameDay from './isSameDay'; +export default function isPreviousDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; + var dayBefore = moment(a).subtract(1, 'day'); + return isSameDay(dayBefore, b); +} \ No newline at end of file diff --git a/esm/utils/isSameDay.js b/esm/utils/isSameDay.js new file mode 100644 index 000000000..211f591da --- /dev/null +++ b/esm/utils/isSameDay.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +export default function isSameDay(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; // Compare least significant, most likely to change units first + // Moment's isSame clones moment inputs and is a tad slow + + return a.date() === b.date() && a.month() === b.month() && a.year() === b.year(); +} \ No newline at end of file diff --git a/esm/utils/isSameMonth.js b/esm/utils/isSameMonth.js new file mode 100644 index 000000000..dac685788 --- /dev/null +++ b/esm/utils/isSameMonth.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +export default function isSameMonth(a, b) { + if (!moment.isMoment(a) || !moment.isMoment(b)) return false; // Compare least significant, most likely to change units first + // Moment's isSame clones moment inputs and is a tad slow + + return a.month() === b.month() && a.year() === b.year(); +} \ No newline at end of file diff --git a/esm/utils/isTransitionEndSupported.js b/esm/utils/isTransitionEndSupported.js new file mode 100644 index 000000000..68a222ef9 --- /dev/null +++ b/esm/utils/isTransitionEndSupported.js @@ -0,0 +1,3 @@ +export default function isTransitionEndSupported() { + return !!(typeof window !== 'undefined' && 'TransitionEvent' in window); +} \ No newline at end of file diff --git a/esm/utils/modifiers.js b/esm/utils/modifiers.js new file mode 100644 index 000000000..f3531894c --- /dev/null +++ b/esm/utils/modifiers.js @@ -0,0 +1,115 @@ +import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +import isDayVisible from './isDayVisible'; +import toISODateString from './toISODateString'; +import toISOMonthString from './toISOMonthString'; +import getPreviousMonthMemoLast from './getPreviousMonthMemoLast'; +import { VERTICAL_SCROLLABLE } from '../constants'; +export function addModifier(updatedDays, day, modifier, props, state) { + var numberOfVisibleMonths = props.numberOfMonths, + enableOutsideDays = props.enableOutsideDays, + orientation = props.orientation; + var firstVisibleMonth = state.currentMonth, + visibleDays = state.visibleDays; + var currentMonth = firstVisibleMonth; + var numberOfMonths = numberOfVisibleMonths; + + if (orientation === VERTICAL_SCROLLABLE) { + numberOfMonths = Object.keys(visibleDays).length; + } else { + currentMonth = getPreviousMonthMemoLast(currentMonth); + numberOfMonths += 2; + } + + if (!day || !isDayVisible(day, currentMonth, numberOfMonths, enableOutsideDays)) { + return updatedDays; + } + + var iso = toISODateString(day); + + var updatedDaysAfterAddition = _objectSpread({}, updatedDays); + + if (enableOutsideDays) { + var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { + return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; + }); + updatedDaysAfterAddition = monthsToUpdate.reduce(function (acc, monthIso) { + var month = updatedDays[monthIso] || visibleDays[monthIso]; + + if (!month[iso] || !month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers.add(modifier); + acc[monthIso] = _objectSpread(_objectSpread({}, month), {}, _defineProperty({}, iso, modifiers)); + } + + return acc; + }, updatedDaysAfterAddition); + } else { + var monthIso = toISOMonthString(day); + var month = updatedDays[monthIso] || visibleDays[monthIso] || {}; + + if (!month[iso] || !month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers.add(modifier); + updatedDaysAfterAddition[monthIso] = _objectSpread(_objectSpread({}, month), {}, _defineProperty({}, iso, modifiers)); + } + } + + return updatedDaysAfterAddition; +} +export function deleteModifier(updatedDays, day, modifier, props, state) { + var numberOfVisibleMonths = props.numberOfMonths, + enableOutsideDays = props.enableOutsideDays, + orientation = props.orientation; + var firstVisibleMonth = state.currentMonth, + visibleDays = state.visibleDays; + var currentMonth = firstVisibleMonth; + var numberOfMonths = numberOfVisibleMonths; + + if (orientation === VERTICAL_SCROLLABLE) { + numberOfMonths = Object.keys(visibleDays).length; + } else { + currentMonth = getPreviousMonthMemoLast(currentMonth); + numberOfMonths += 2; + } + + if (!day || !isDayVisible(day, currentMonth, numberOfMonths, enableOutsideDays)) { + return updatedDays; + } + + var iso = toISODateString(day); + + var updatedDaysAfterDeletion = _objectSpread({}, updatedDays); + + if (enableOutsideDays) { + var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { + return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; + }); + updatedDaysAfterDeletion = monthsToUpdate.reduce(function (acc, monthIso) { + var month = updatedDays[monthIso] || visibleDays[monthIso]; + + if (month[iso] && month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers["delete"](modifier); + acc[monthIso] = _objectSpread(_objectSpread({}, month), {}, _defineProperty({}, iso, modifiers)); + } + + return acc; + }, updatedDaysAfterDeletion); + } else { + var monthIso = toISOMonthString(day); + var month = updatedDays[monthIso] || visibleDays[monthIso] || {}; + + if (month[iso] && month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers["delete"](modifier); + updatedDaysAfterDeletion[monthIso] = _objectSpread(_objectSpread({}, month), {}, _defineProperty({}, iso, modifiers)); + } + } + + return updatedDaysAfterDeletion; +} \ No newline at end of file diff --git a/esm/utils/noflip.js b/esm/utils/noflip.js new file mode 100644 index 000000000..8d4258379 --- /dev/null +++ b/esm/utils/noflip.js @@ -0,0 +1,9 @@ +var NOFLIP = '/* @noflip */'; // Appends a noflip comment to a style rule in order to prevent it from being automatically +// flipped in RTL contexts. This should be used only in situations where the style must remain +// unflipped regardless of direction context. See: https://github.com/kentcdodds/rtl-css-js#usage + +export default function noflip(value) { + if (typeof value === 'number') return "".concat(value, "px ").concat(NOFLIP); + if (typeof value === 'string') return "".concat(value, " ").concat(NOFLIP); + throw new TypeError('noflip expects a string or a number'); +} \ No newline at end of file diff --git a/esm/utils/registerCSSInterfaceWithDefaultTheme.js b/esm/utils/registerCSSInterfaceWithDefaultTheme.js new file mode 100644 index 000000000..53542f170 --- /dev/null +++ b/esm/utils/registerCSSInterfaceWithDefaultTheme.js @@ -0,0 +1,5 @@ +import CSSInterface from 'react-with-styles-interface-css'; +import registerInterfaceWithDefaultTheme from './registerInterfaceWithDefaultTheme'; +export default function registerCSSInterfaceWithDefaultTheme() { + registerInterfaceWithDefaultTheme(CSSInterface); +} \ No newline at end of file diff --git a/esm/utils/registerInterfaceWithDefaultTheme.js b/esm/utils/registerInterfaceWithDefaultTheme.js new file mode 100644 index 000000000..777704c5d --- /dev/null +++ b/esm/utils/registerInterfaceWithDefaultTheme.js @@ -0,0 +1,6 @@ +import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet'; +import DefaultTheme from '../theme/DefaultTheme'; +export default function registerInterfaceWithDefaultTheme(reactWithStylesInterface) { + ThemedStyleSheet.registerInterface(reactWithStylesInterface); + ThemedStyleSheet.registerTheme(DefaultTheme); +} \ No newline at end of file diff --git a/esm/utils/toISODateString.js b/esm/utils/toISODateString.js new file mode 100644 index 000000000..703bbcf19 --- /dev/null +++ b/esm/utils/toISODateString.js @@ -0,0 +1,11 @@ +import moment from 'moment'; +import toMomentObject from './toMomentObject'; +export default function toISODateString(date, currentFormat) { + var dateObj = moment.isMoment(date) ? date : toMomentObject(date, currentFormat); + if (!dateObj) return null; // Template strings compiled in strict mode uses concat, which is slow. Since + // this code is in a hot path and we want it to be as fast as possible, we + // want to use old-fashioned +. + // eslint-disable-next-line prefer-template + + return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0') + '-' + String(dateObj.date()).padStart(2, '0'); +} \ No newline at end of file diff --git a/esm/utils/toISOMonthString.js b/esm/utils/toISOMonthString.js new file mode 100644 index 000000000..b085c9395 --- /dev/null +++ b/esm/utils/toISOMonthString.js @@ -0,0 +1,11 @@ +import moment from 'moment'; +import toMomentObject from './toMomentObject'; +export default function toISOMonthString(date, currentFormat) { + var dateObj = moment.isMoment(date) ? date : toMomentObject(date, currentFormat); + if (!dateObj) return null; // Template strings compiled in strict mode uses concat, which is slow. Since + // this code is in a hot path and we want it to be as fast as possible, we + // want to use old-fashioned +. + // eslint-disable-next-line prefer-template + + return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0'); +} \ No newline at end of file diff --git a/esm/utils/toLocalizedDateString.js b/esm/utils/toLocalizedDateString.js new file mode 100644 index 000000000..75c96f611 --- /dev/null +++ b/esm/utils/toLocalizedDateString.js @@ -0,0 +1,8 @@ +import moment from 'moment'; +import toMomentObject from './toMomentObject'; +import { DISPLAY_FORMAT } from '../constants'; +export default function toLocalizedDateString(date, currentFormat) { + var dateObj = moment.isMoment(date) ? date : toMomentObject(date, currentFormat); + if (!dateObj) return null; + return dateObj.format(DISPLAY_FORMAT); +} \ No newline at end of file diff --git a/esm/utils/toMomentObject.js b/esm/utils/toMomentObject.js new file mode 100644 index 000000000..8ffc36954 --- /dev/null +++ b/esm/utils/toMomentObject.js @@ -0,0 +1,7 @@ +import moment from 'moment'; +import { DISPLAY_FORMAT, ISO_FORMAT } from '../constants'; +export default function toMomentObject(dateString, customFormat) { + var dateFormats = customFormat ? [customFormat, DISPLAY_FORMAT, ISO_FORMAT] : [DISPLAY_FORMAT, ISO_FORMAT]; + var date = moment(dateString, dateFormats, true); + return date.isValid() ? date.hour(12) : null; +} \ No newline at end of file diff --git a/lib/components/CalendarDay.js b/lib/components/CalendarDay.js new file mode 100644 index 000000000..de03e8df1 --- /dev/null +++ b/lib/components/CalendarDay.js @@ -0,0 +1,369 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.PureCalendarDay = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _moment = _interopRequireDefault(require("moment")); + +var _raf = _interopRequireDefault(require("raf")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _getCalendarDaySettings = _interopRequireDefault(require("../utils/getCalendarDaySettings")); + +var _ModifiersShape = _interopRequireDefault(require("../shapes/ModifiersShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + day: _reactMomentProptypes["default"].momentObj, + daySize: _airbnbPropTypes.nonNegativeInteger, + isOutsideDay: _propTypes["default"].bool, + modifiers: _ModifiersShape["default"], + isFocused: _propTypes["default"].bool, + tabIndex: _propTypes["default"].oneOf([0, -1]), + onDayClick: _propTypes["default"].func, + onDayMouseEnter: _propTypes["default"].func, + onDayMouseLeave: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + ariaLabelFormat: _propTypes["default"].string, + // internationalization + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.CalendarDayPhrases)) +})) : {}; +var defaultProps = { + day: (0, _moment["default"])(), + daySize: _constants.DAY_SIZE, + isOutsideDay: false, + modifiers: new Set(), + isFocused: false, + tabIndex: -1, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + renderDayContents: null, + ariaLabelFormat: 'dddd, LL', + // internationalization + phrases: _defaultPhrases.CalendarDayPhrases +}; + +var CalendarDay = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(CalendarDay, _ref2); + var _proto = CalendarDay.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function CalendarDay() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + _this.setButtonRef = _this.setButtonRef.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this2 = this; + + var _this$props = this.props, + isFocused = _this$props.isFocused, + tabIndex = _this$props.tabIndex; + + if (tabIndex === 0) { + if (isFocused || tabIndex !== prevProps.tabIndex) { + (0, _raf["default"])(function () { + if (_this2.buttonRef) { + _this2.buttonRef.focus(); + } + }); + } + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var onDayClick = this.props.onDayClick; + onDayClick(day, e); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day, e) { + var onDayMouseEnter = this.props.onDayMouseEnter; + onDayMouseEnter(day, e); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day, e) { + var onDayMouseLeave = this.props.onDayMouseLeave; + onDayMouseLeave(day, e); + }; + + _proto.onKeyDown = function onKeyDown(day, e) { + var onDayClick = this.props.onDayClick; + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onDayClick(day, e); + } + }; + + _proto.setButtonRef = function setButtonRef(ref) { + this.buttonRef = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props2 = this.props, + day = _this$props2.day, + ariaLabelFormat = _this$props2.ariaLabelFormat, + daySize = _this$props2.daySize, + isOutsideDay = _this$props2.isOutsideDay, + modifiers = _this$props2.modifiers, + renderDayContents = _this$props2.renderDayContents, + tabIndex = _this$props2.tabIndex, + css = _this$props2.css, + styles = _this$props2.styles, + phrases = _this$props2.phrases; + if (!day) return /*#__PURE__*/_react["default"].createElement("td", null); + + var _getCalendarDaySettin = (0, _getCalendarDaySettings["default"])(day, ariaLabelFormat, daySize, modifiers, phrases), + daySizeStyles = _getCalendarDaySettin.daySizeStyles, + useDefaultCursor = _getCalendarDaySettin.useDefaultCursor, + selected = _getCalendarDaySettin.selected, + hoveredSpan = _getCalendarDaySettin.hoveredSpan, + isOutsideRange = _getCalendarDaySettin.isOutsideRange, + ariaLabel = _getCalendarDaySettin.ariaLabel; + + return /*#__PURE__*/_react["default"].createElement("td", (0, _extends2["default"])({}, css(styles.CalendarDay, useDefaultCursor && styles.CalendarDay__defaultCursor, styles.CalendarDay__default, isOutsideDay && styles.CalendarDay__outside, modifiers.has('today') && styles.CalendarDay__today, modifiers.has('first-day-of-week') && styles.CalendarDay__firstDayOfWeek, modifiers.has('last-day-of-week') && styles.CalendarDay__lastDayOfWeek, modifiers.has('hovered-offset') && styles.CalendarDay__hovered_offset, modifiers.has('hovered-start-first-possible-end') && styles.CalendarDay__hovered_start_first_possible_end, modifiers.has('hovered-start-blocked-minimum-nights') && styles.CalendarDay__hovered_start_blocked_min_nights, modifiers.has('highlighted-calendar') && styles.CalendarDay__highlighted_calendar, modifiers.has('blocked-minimum-nights') && styles.CalendarDay__blocked_minimum_nights, modifiers.has('blocked-calendar') && styles.CalendarDay__blocked_calendar, hoveredSpan && styles.CalendarDay__hovered_span, modifiers.has('after-hovered-start') && styles.CalendarDay__after_hovered_start, modifiers.has('selected-span') && styles.CalendarDay__selected_span, modifiers.has('selected-start') && styles.CalendarDay__selected_start, modifiers.has('selected-end') && styles.CalendarDay__selected_end, selected && !modifiers.has('selected-span') && styles.CalendarDay__selected, modifiers.has('before-hovered-end') && styles.CalendarDay__before_hovered_end, modifiers.has('no-selected-start-before-selected-end') && styles.CalendarDay__no_selected_start_before_selected_end, modifiers.has('selected-start-in-hovered-span') && styles.CalendarDay__selected_start_in_hovered_span, modifiers.has('selected-end-in-hovered-span') && styles.CalendarDay__selected_end_in_hovered_span, modifiers.has('selected-start-no-selected-end') && styles.CalendarDay__selected_start_no_selected_end, modifiers.has('selected-end-no-selected-start') && styles.CalendarDay__selected_end_no_selected_start, isOutsideRange && styles.CalendarDay__blocked_out_of_range, daySizeStyles), { + role: "button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role + , + ref: this.setButtonRef, + "aria-disabled": modifiers.has('blocked') + }, modifiers.has('today') ? { + 'aria-current': 'date' + } : {}, { + "aria-label": ariaLabel, + onMouseEnter: function onMouseEnter(e) { + _this3.onDayMouseEnter(day, e); + }, + onMouseLeave: function onMouseLeave(e) { + _this3.onDayMouseLeave(day, e); + }, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + }, + onClick: function onClick(e) { + _this3.onDayClick(day, e); + }, + onKeyDown: function onKeyDown(e) { + _this3.onKeyDown(day, e); + }, + tabIndex: tabIndex + }), renderDayContents ? renderDayContents(day, modifiers) : day.format('D')); + }; + + return CalendarDay; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports.PureCalendarDay = CalendarDay; +CalendarDay.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarDay.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + font = _ref3$reactDates.font; + return { + CalendarDay: { + boxSizing: 'border-box', + cursor: 'pointer', + fontSize: font.size, + textAlign: 'center', + ':active': { + outline: 0 + } + }, + CalendarDay__defaultCursor: { + cursor: 'default' + }, + CalendarDay__default: { + border: "1px solid ".concat(color.core.borderLight), + color: color.text, + background: color.background, + ':hover': { + background: color.core.borderLight, + border: "1px solid ".concat(color.core.borderLight), + color: 'inherit' + } + }, + CalendarDay__hovered_offset: { + background: color.core.borderBright, + border: "1px double ".concat(color.core.borderLight), + color: 'inherit' + }, + CalendarDay__outside: { + border: 0, + background: color.outside.backgroundColor, + color: color.outside.color, + ':hover': { + border: 0 + } + }, + CalendarDay__blocked_minimum_nights: { + background: color.minimumNights.backgroundColor, + border: "1px solid ".concat(color.minimumNights.borderColor), + color: color.minimumNights.color, + ':hover': { + background: color.minimumNights.backgroundColor_hover, + color: color.minimumNights.color_active + }, + ':active': { + background: color.minimumNights.backgroundColor_active, + color: color.minimumNights.color_active + } + }, + CalendarDay__highlighted_calendar: { + background: color.highlighted.backgroundColor, + color: color.highlighted.color, + ':hover': { + background: color.highlighted.backgroundColor_hover, + color: color.highlighted.color_active + }, + ':active': { + background: color.highlighted.backgroundColor_active, + color: color.highlighted.color_active + } + }, + CalendarDay__selected_span: { + background: color.selectedSpan.backgroundColor, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color, + ':hover': { + background: color.selectedSpan.backgroundColor_hover, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + }, + ':active': { + background: color.selectedSpan.backgroundColor_active, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + } + }, + CalendarDay__selected: { + background: color.selected.backgroundColor, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color, + ':hover': { + background: color.selected.backgroundColor_hover, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + }, + ':active': { + background: color.selected.backgroundColor_active, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + } + }, + CalendarDay__hovered_span: { + background: color.hoveredSpan.backgroundColor, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color, + ':hover': { + background: color.hoveredSpan.backgroundColor_hover, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + }, + ':active': { + background: color.hoveredSpan.backgroundColor_active, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + } + }, + CalendarDay__blocked_calendar: { + background: color.blocked_calendar.backgroundColor, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color, + ':hover': { + background: color.blocked_calendar.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + }, + ':active': { + background: color.blocked_calendar.backgroundColor_active, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + } + }, + CalendarDay__blocked_out_of_range: { + background: color.blocked_out_of_range.backgroundColor, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color, + ':hover': { + background: color.blocked_out_of_range.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + }, + ':active': { + background: color.blocked_out_of_range.backgroundColor_active, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + } + }, + CalendarDay__hovered_start_first_possible_end: { + background: color.core.borderLighter, + border: "1px double ".concat(color.core.borderLighter) + }, + CalendarDay__hovered_start_blocked_min_nights: { + background: color.core.borderLighter, + border: "1px double ".concat(color.core.borderLight) + }, + CalendarDay__selected_start: {}, + CalendarDay__selected_end: {}, + CalendarDay__today: {}, + CalendarDay__firstDayOfWeek: {}, + CalendarDay__lastDayOfWeek: {}, + CalendarDay__after_hovered_start: {}, + CalendarDay__before_hovered_end: {}, + CalendarDay__no_selected_start_before_selected_end: {}, + CalendarDay__selected_start_in_hovered_span: {}, + CalendarDay__selected_end_in_hovered_span: {}, + CalendarDay__selected_start_no_selected_end: {}, + CalendarDay__selected_end_no_selected_start: {} + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(CalendarDay); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CalendarIcon.js b/lib/components/CalendarIcon.js new file mode 100644 index 000000000..13c9cf9f5 --- /dev/null +++ b/lib/components/CalendarIcon.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var CalendarIcon = function CalendarIcon(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + d: "m107 1393h241v-241h-241zm295 0h268v-241h-268zm-295-295h241v-268h-241zm295 0h268v-268h-268zm-295-321h241v-241h-241zm616 616h268v-241h-268zm-321-616h268v-241h-268zm643 616h241v-241h-241zm-322-295h268v-268h-268zm-294-723v-241c0-7-3-14-8-19-6-5-12-8-19-8h-54c-7 0-13 3-19 8-5 5-8 12-8 19v241c0 7 3 14 8 19 6 5 12 8 19 8h54c7 0 13-3 19-8 5-5 8-12 8-19zm616 723h241v-268h-241zm-322-321h268v-241h-268zm322 0h241v-241h-241zm27-402v-241c0-7-3-14-8-19-6-5-12-8-19-8h-54c-7 0-13 3-19 8-5 5-8 12-8 19v241c0 7 3 14 8 19 6 5 12 8 19 8h54c7 0 13-3 19-8 5-5 8-12 8-19zm321-54v1072c0 29-11 54-32 75s-46 32-75 32h-1179c-29 0-54-11-75-32s-32-46-32-75v-1072c0-29 11-54 32-75s46-32 75-32h107v-80c0-37 13-68 40-95s57-39 94-39h54c37 0 68 13 95 39 26 26 39 58 39 95v80h321v-80c0-37 13-69 40-95 26-26 57-39 94-39h54c37 0 68 13 94 39s40 58 40 95v80h107c29 0 54 11 75 32s32 46 32 75z" + })); +}; + +CalendarIcon.defaultProps = { + focusable: "false", + viewBox: "0 0 1393.1 1500" +}; +var _default = CalendarIcon; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CalendarMonth.js b/lib/components/CalendarMonth.js new file mode 100644 index 000000000..361a12421 --- /dev/null +++ b/lib/components/CalendarMonth.js @@ -0,0 +1,299 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _moment = _interopRequireDefault(require("moment")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _CalendarWeek = _interopRequireDefault(require("./CalendarWeek")); + +var _CalendarDay = _interopRequireDefault(require("./CalendarDay")); + +var _calculateDimension = _interopRequireDefault(require("../utils/calculateDimension")); + +var _getCalendarMonthWeeks = _interopRequireDefault(require("../utils/getCalendarMonthWeeks")); + +var _isSameDay = _interopRequireDefault(require("../utils/isSameDay")); + +var _toISODateString = _interopRequireDefault(require("../utils/toISODateString")); + +var _ModifiersShape = _interopRequireDefault(require("../shapes/ModifiersShape")); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + month: _reactMomentProptypes["default"].momentObj, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + isVisible: _propTypes["default"].bool, + enableOutsideDays: _propTypes["default"].bool, + modifiers: _propTypes["default"].objectOf(_ModifiersShape["default"]), + orientation: _ScrollableOrientationShape["default"], + daySize: _airbnbPropTypes.nonNegativeInteger, + onDayClick: _propTypes["default"].func, + onDayMouseEnter: _propTypes["default"].func, + onDayMouseLeave: _propTypes["default"].func, + onMonthSelect: _propTypes["default"].func, + onYearSelect: _propTypes["default"].func, + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + firstDayOfWeek: _DayOfWeekShape["default"], + setMonthTitleHeight: _propTypes["default"].func, + verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, + focusedDate: _reactMomentProptypes["default"].momentObj, + // indicates focusable day + isFocused: _propTypes["default"].bool, + // indicates whether or not to move focus to focusable day + // i18n + monthFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.CalendarDayPhrases)), + dayAriaLabelFormat: _propTypes["default"].string +})) : {}; +var defaultProps = { + month: (0, _moment["default"])(), + horizontalMonthPadding: 13, + isVisible: true, + enableOutsideDays: false, + modifiers: {}, + orientation: _constants.HORIZONTAL_ORIENTATION, + daySize: _constants.DAY_SIZE, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + onMonthSelect: function onMonthSelect() {}, + onYearSelect: function onYearSelect() {}, + renderMonthText: null, + renderCalendarDay: function renderCalendarDay(props) { + return /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], props); + }, + renderDayContents: null, + renderMonthElement: null, + firstDayOfWeek: null, + setMonthTitleHeight: null, + focusedDate: null, + isFocused: false, + // i18n + monthFormat: 'MMMM YYYY', + // english locale + phrases: _defaultPhrases.CalendarDayPhrases, + dayAriaLabelFormat: undefined, + verticalBorderSpacing: undefined +}; + +var CalendarMonth = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(CalendarMonth, _ref2); + var _proto = CalendarMonth.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function CalendarMonth(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + weeks: (0, _getCalendarMonthWeeks["default"])(props.month, props.enableOutsideDays, props.firstDayOfWeek == null ? _moment["default"].localeData().firstDayOfWeek() : props.firstDayOfWeek) + }; + _this.setCaptionRef = _this.setCaptionRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setMonthTitleHeight = _this.setMonthTitleHeight.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.queueSetMonthTitleHeight(); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var month = nextProps.month, + enableOutsideDays = nextProps.enableOutsideDays, + firstDayOfWeek = nextProps.firstDayOfWeek; + var _this$props = this.props, + prevMonth = _this$props.month, + prevEnableOutsideDays = _this$props.enableOutsideDays, + prevFirstDayOfWeek = _this$props.firstDayOfWeek; + + if (!month.isSame(prevMonth) || enableOutsideDays !== prevEnableOutsideDays || firstDayOfWeek !== prevFirstDayOfWeek) { + this.setState({ + weeks: (0, _getCalendarMonthWeeks["default"])(month, enableOutsideDays, firstDayOfWeek == null ? _moment["default"].localeData().firstDayOfWeek() : firstDayOfWeek) + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var setMonthTitleHeight = this.props.setMonthTitleHeight; + + if (prevProps.setMonthTitleHeight === null && setMonthTitleHeight !== null) { + this.queueSetMonthTitleHeight(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.setMonthTitleHeightTimeout) { + clearTimeout(this.setMonthTitleHeightTimeout); + } + }; + + _proto.setMonthTitleHeight = function setMonthTitleHeight() { + var setMonthTitleHeight = this.props.setMonthTitleHeight; + + if (setMonthTitleHeight) { + var captionHeight = (0, _calculateDimension["default"])(this.captionRef, 'height', true, true); + setMonthTitleHeight(captionHeight); + } + }; + + _proto.setCaptionRef = function setCaptionRef(ref) { + this.captionRef = ref; + }; + + _proto.queueSetMonthTitleHeight = function queueSetMonthTitleHeight() { + this.setMonthTitleHeightTimeout = window.setTimeout(this.setMonthTitleHeight, 0); + }; + + _proto.render = function render() { + var _this$props2 = this.props, + dayAriaLabelFormat = _this$props2.dayAriaLabelFormat, + daySize = _this$props2.daySize, + focusedDate = _this$props2.focusedDate, + horizontalMonthPadding = _this$props2.horizontalMonthPadding, + isFocused = _this$props2.isFocused, + isVisible = _this$props2.isVisible, + modifiers = _this$props2.modifiers, + month = _this$props2.month, + monthFormat = _this$props2.monthFormat, + onDayClick = _this$props2.onDayClick, + onDayMouseEnter = _this$props2.onDayMouseEnter, + onDayMouseLeave = _this$props2.onDayMouseLeave, + onMonthSelect = _this$props2.onMonthSelect, + onYearSelect = _this$props2.onYearSelect, + orientation = _this$props2.orientation, + phrases = _this$props2.phrases, + renderCalendarDay = _this$props2.renderCalendarDay, + renderDayContents = _this$props2.renderDayContents, + renderMonthElement = _this$props2.renderMonthElement, + renderMonthText = _this$props2.renderMonthText, + css = _this$props2.css, + styles = _this$props2.styles, + verticalBorderSpacing = _this$props2.verticalBorderSpacing; + var weeks = this.state.weeks; + var monthTitle = renderMonthText ? renderMonthText(month) : month.format(monthFormat); + var verticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE; + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.CalendarMonth, { + padding: "0 ".concat(horizontalMonthPadding, "px") + }), { + "data-visible": isVisible + }), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + ref: this.setCaptionRef + }, css(styles.CalendarMonth_caption, verticalScrollable && styles.CalendarMonth_caption__verticalScrollable)), renderMonthElement ? renderMonthElement({ + month: month, + onMonthSelect: onMonthSelect, + onYearSelect: onYearSelect, + isVisible: isVisible + }) : /*#__PURE__*/_react["default"].createElement("strong", null, monthTitle)), /*#__PURE__*/_react["default"].createElement("table", (0, _extends2["default"])({}, css(!verticalBorderSpacing && styles.CalendarMonth_table, verticalBorderSpacing && styles.CalendarMonth_verticalSpacing, verticalBorderSpacing && { + borderSpacing: "0px ".concat(verticalBorderSpacing, "px") + }), { + role: "presentation" + }), /*#__PURE__*/_react["default"].createElement("tbody", null, weeks.map(function (week, i) { + return /*#__PURE__*/_react["default"].createElement(_CalendarWeek["default"], { + key: i + }, week.map(function (day, dayOfWeek) { + return renderCalendarDay({ + key: dayOfWeek, + day: day, + daySize: daySize, + isOutsideDay: !day || day.month() !== month.month(), + tabIndex: isVisible && (0, _isSameDay["default"])(day, focusedDate) ? 0 : -1, + isFocused: isFocused, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onDayClick: onDayClick, + renderDayContents: renderDayContents, + phrases: phrases, + modifiers: modifiers[(0, _toISODateString["default"])(day)], + ariaLabelFormat: dayAriaLabelFormat + }); + })); + })))); + }; + + return CalendarMonth; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +CalendarMonth.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarMonth.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + font = _ref3$reactDates.font, + spacing = _ref3$reactDates.spacing; + return { + CalendarMonth: { + background: color.background, + textAlign: 'center', + verticalAlign: 'top', + userSelect: 'none' + }, + CalendarMonth_table: { + borderCollapse: 'collapse', + borderSpacing: 0 + }, + CalendarMonth_verticalSpacing: { + borderCollapse: 'separate' + }, + CalendarMonth_caption: { + color: color.text, + fontSize: font.captionSize, + textAlign: 'center', + paddingTop: spacing.captionPaddingTop, + paddingBottom: spacing.captionPaddingBottom, + captionSide: 'initial' + }, + CalendarMonth_caption__verticalScrollable: { + paddingTop: 12, + paddingBottom: 7 + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(CalendarMonth); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CalendarMonthGrid.js b/lib/components/CalendarMonthGrid.js new file mode 100644 index 000000000..1686d2607 --- /dev/null +++ b/lib/components/CalendarMonthGrid.js @@ -0,0 +1,429 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _moment = _interopRequireDefault(require("moment")); + +var _consolidatedEvents = require("consolidated-events"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _CalendarMonth = _interopRequireDefault(require("./CalendarMonth")); + +var _isTransitionEndSupported = _interopRequireDefault(require("../utils/isTransitionEndSupported")); + +var _getTransformStyles = _interopRequireDefault(require("../utils/getTransformStyles")); + +var _getCalendarMonthWidth = _interopRequireDefault(require("../utils/getCalendarMonthWidth")); + +var _toISOMonthString = _interopRequireDefault(require("../utils/toISOMonthString")); + +var _isPrevMonth = _interopRequireDefault(require("../utils/isPrevMonth")); + +var _isNextMonth = _interopRequireDefault(require("../utils/isNextMonth")); + +var _ModifiersShape = _interopRequireDefault(require("../shapes/ModifiersShape")); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + enableOutsideDays: _propTypes["default"].bool, + firstVisibleMonthIndex: _propTypes["default"].number, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + initialMonth: _reactMomentProptypes["default"].momentObj, + isAnimating: _propTypes["default"].bool, + numberOfMonths: _propTypes["default"].number, + modifiers: _propTypes["default"].objectOf(_propTypes["default"].objectOf(_ModifiersShape["default"])), + orientation: _ScrollableOrientationShape["default"], + onDayClick: _propTypes["default"].func, + onDayMouseEnter: _propTypes["default"].func, + onDayMouseLeave: _propTypes["default"].func, + onMonthTransitionEnd: _propTypes["default"].func, + onMonthChange: _propTypes["default"].func, + onYearChange: _propTypes["default"].func, + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + translationValue: _propTypes["default"].number, + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + daySize: _airbnbPropTypes.nonNegativeInteger, + focusedDate: _reactMomentProptypes["default"].momentObj, + // indicates focusable day + isFocused: _propTypes["default"].bool, + // indicates whether or not to move focus to focusable day + firstDayOfWeek: _DayOfWeekShape["default"], + setMonthTitleHeight: _propTypes["default"].func, + isRTL: _propTypes["default"].bool, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, + // i18n + monthFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.CalendarDayPhrases)), + dayAriaLabelFormat: _propTypes["default"].string +})) : {}; +var defaultProps = { + enableOutsideDays: false, + firstVisibleMonthIndex: 0, + horizontalMonthPadding: 13, + initialMonth: (0, _moment["default"])(), + isAnimating: false, + numberOfMonths: 1, + modifiers: {}, + orientation: _constants.HORIZONTAL_ORIENTATION, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + onMonthChange: function onMonthChange() {}, + onYearChange: function onYearChange() {}, + onMonthTransitionEnd: function onMonthTransitionEnd() {}, + renderMonthText: null, + renderCalendarDay: undefined, + renderDayContents: null, + translationValue: null, + renderMonthElement: null, + daySize: _constants.DAY_SIZE, + focusedDate: null, + isFocused: false, + firstDayOfWeek: null, + setMonthTitleHeight: null, + isRTL: false, + transitionDuration: 200, + verticalBorderSpacing: undefined, + // i18n + monthFormat: 'MMMM YYYY', + // english locale + phrases: _defaultPhrases.CalendarDayPhrases, + dayAriaLabelFormat: undefined +}; + +function getMonths(initialMonth, numberOfMonths, withoutTransitionMonths) { + var month = initialMonth.clone(); + if (!withoutTransitionMonths) month = month.subtract(1, 'month'); + var months = []; + + for (var i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) { + months.push(month); + month = month.clone().add(1, 'month'); + } + + return months; +} + +var CalendarMonthGrid = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(CalendarMonthGrid, _ref2); + var _proto = CalendarMonthGrid.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function CalendarMonthGrid(props) { + var _this; + + _this = _ref2.call(this, props) || this; + var withoutTransitionMonths = props.orientation === _constants.VERTICAL_SCROLLABLE; + _this.state = { + months: getMonths(props.initialMonth, props.numberOfMonths, withoutTransitionMonths) + }; + _this.isTransitionEndSupported = (0, _isTransitionEndSupported["default"])(); + _this.onTransitionEnd = _this.onTransitionEnd.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setContainerRef = _this.setContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.locale = _moment["default"].locale(); + _this.onMonthSelect = _this.onMonthSelect.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onYearSelect = _this.onYearSelect.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.removeEventListener = (0, _consolidatedEvents.addEventListener)(this.container, 'transitionend', this.onTransitionEnd); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var initialMonth = nextProps.initialMonth, + numberOfMonths = nextProps.numberOfMonths, + orientation = nextProps.orientation; + var months = this.state.months; + var _this$props = this.props, + prevInitialMonth = _this$props.initialMonth, + prevNumberOfMonths = _this$props.numberOfMonths; + var hasMonthChanged = !prevInitialMonth.isSame(initialMonth, 'month'); + var hasNumberOfMonthsChanged = prevNumberOfMonths !== numberOfMonths; + var newMonths = months; + + if (hasMonthChanged || hasNumberOfMonthsChanged) { + if (hasMonthChanged && !hasNumberOfMonthsChanged) { + if ((0, _isNextMonth["default"])(prevInitialMonth, initialMonth)) { + newMonths = months.slice(1); + newMonths.push(months[months.length - 1].clone().add(1, 'month')); + } else if ((0, _isPrevMonth["default"])(prevInitialMonth, initialMonth)) { + newMonths = months.slice(0, months.length - 1); + newMonths.unshift(months[0].clone().subtract(1, 'month')); + } else { + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + newMonths = getMonths(initialMonth, numberOfMonths, withoutTransitionMonths); + } + } + + if (hasNumberOfMonthsChanged) { + var _withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + + newMonths = getMonths(initialMonth, numberOfMonths, _withoutTransitionMonths); + } + + var momentLocale = _moment["default"].locale(); + + if (this.locale !== momentLocale) { + this.locale = momentLocale; + newMonths = newMonths.map(function (m) { + return m.locale(_this2.locale); + }); + } + + this.setState({ + months: newMonths + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate() { + var _this$props2 = this.props, + isAnimating = _this$props2.isAnimating, + transitionDuration = _this$props2.transitionDuration, + onMonthTransitionEnd = _this$props2.onMonthTransitionEnd; // For IE9, immediately call onMonthTransitionEnd instead of + // waiting for the animation to complete. Similarly, if transitionDuration + // is set to 0, also immediately invoke the onMonthTransitionEnd callback + + if ((!this.isTransitionEndSupported || !transitionDuration) && isAnimating) { + onMonthTransitionEnd(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.removeEventListener) this.removeEventListener(); + }; + + _proto.onTransitionEnd = function onTransitionEnd() { + var onMonthTransitionEnd = this.props.onMonthTransitionEnd; + onMonthTransitionEnd(); + }; + + _proto.onMonthSelect = function onMonthSelect(currentMonth, newMonthVal) { + var newMonth = currentMonth.clone(); + var _this$props3 = this.props, + onMonthChange = _this$props3.onMonthChange, + orientation = _this$props3.orientation; + var months = this.state.months; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var initialMonthSubtraction = months.indexOf(currentMonth); + + if (!withoutTransitionMonths) { + initialMonthSubtraction -= 1; + } + + newMonth.set('month', newMonthVal).subtract(initialMonthSubtraction, 'months'); + onMonthChange(newMonth); + }; + + _proto.onYearSelect = function onYearSelect(currentMonth, newYearVal) { + var newMonth = currentMonth.clone(); + var _this$props4 = this.props, + onYearChange = _this$props4.onYearChange, + orientation = _this$props4.orientation; + var months = this.state.months; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var initialMonthSubtraction = months.indexOf(currentMonth); + + if (!withoutTransitionMonths) { + initialMonthSubtraction -= 1; + } + + newMonth.set('year', newYearVal).subtract(initialMonthSubtraction, 'months'); + onYearChange(newMonth); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props5 = this.props, + enableOutsideDays = _this$props5.enableOutsideDays, + firstVisibleMonthIndex = _this$props5.firstVisibleMonthIndex, + horizontalMonthPadding = _this$props5.horizontalMonthPadding, + isAnimating = _this$props5.isAnimating, + modifiers = _this$props5.modifiers, + numberOfMonths = _this$props5.numberOfMonths, + monthFormat = _this$props5.monthFormat, + orientation = _this$props5.orientation, + translationValue = _this$props5.translationValue, + daySize = _this$props5.daySize, + onDayMouseEnter = _this$props5.onDayMouseEnter, + onDayMouseLeave = _this$props5.onDayMouseLeave, + onDayClick = _this$props5.onDayClick, + renderMonthText = _this$props5.renderMonthText, + renderCalendarDay = _this$props5.renderCalendarDay, + renderDayContents = _this$props5.renderDayContents, + renderMonthElement = _this$props5.renderMonthElement, + onMonthTransitionEnd = _this$props5.onMonthTransitionEnd, + firstDayOfWeek = _this$props5.firstDayOfWeek, + focusedDate = _this$props5.focusedDate, + isFocused = _this$props5.isFocused, + isRTL = _this$props5.isRTL, + css = _this$props5.css, + styles = _this$props5.styles, + phrases = _this$props5.phrases, + dayAriaLabelFormat = _this$props5.dayAriaLabelFormat, + transitionDuration = _this$props5.transitionDuration, + verticalBorderSpacing = _this$props5.verticalBorderSpacing, + setMonthTitleHeight = _this$props5.setMonthTitleHeight; + var months = this.state.months; + var isVertical = orientation === _constants.VERTICAL_ORIENTATION; + var isVerticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE; + var isHorizontal = orientation === _constants.HORIZONTAL_ORIENTATION; + var calendarMonthWidth = (0, _getCalendarMonthWidth["default"])(daySize, horizontalMonthPadding); + var width = isVertical || isVerticalScrollable ? calendarMonthWidth : (numberOfMonths + 2) * calendarMonthWidth; + var transformType = isVertical || isVerticalScrollable ? 'translateY' : 'translateX'; + var transformValue = "".concat(transformType, "(").concat(translationValue, "px)"); + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.CalendarMonthGrid, isHorizontal && styles.CalendarMonthGrid__horizontal, isVertical && styles.CalendarMonthGrid__vertical, isVerticalScrollable && styles.CalendarMonthGrid__vertical_scrollable, isAnimating && styles.CalendarMonthGrid__animating, isAnimating && transitionDuration && { + transition: "transform ".concat(transitionDuration, "ms ease-in-out 0.1s") + }, _objectSpread(_objectSpread({}, (0, _getTransformStyles["default"])(transformValue)), {}, { + width: width + })), { + ref: this.setContainerRef, + onTransitionEnd: onMonthTransitionEnd + }), months.map(function (month, i) { + var isVisible = i >= firstVisibleMonthIndex && i < firstVisibleMonthIndex + numberOfMonths; + var hideForAnimation = i === 0 && !isVisible; + var showForAnimation = i === 0 && isAnimating && isVisible; + var monthString = (0, _toISOMonthString["default"])(month); + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + key: monthString + }, css(isHorizontal && styles.CalendarMonthGrid_month__horizontal, hideForAnimation && styles.CalendarMonthGrid_month__hideForAnimation, showForAnimation && !isVertical && !isRTL && { + position: 'absolute', + left: -calendarMonthWidth + }, showForAnimation && !isVertical && isRTL && { + position: 'absolute', + right: 0 + }, showForAnimation && isVertical && { + position: 'absolute', + top: -translationValue + }, !isVisible && !isAnimating && styles.CalendarMonthGrid_month__hidden)), /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + month: month, + isVisible: isVisible, + enableOutsideDays: enableOutsideDays, + modifiers: modifiers[monthString], + monthFormat: monthFormat, + orientation: orientation, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onDayClick: onDayClick, + onMonthSelect: _this3.onMonthSelect, + onYearSelect: _this3.onYearSelect, + renderMonthText: renderMonthText, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderMonthElement: renderMonthElement, + firstDayOfWeek: firstDayOfWeek, + daySize: daySize, + focusedDate: isVisible ? focusedDate : null, + isFocused: isFocused, + phrases: phrases, + setMonthTitleHeight: setMonthTitleHeight, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + })); + })); + }; + + return CalendarMonthGrid; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +CalendarMonthGrid.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CalendarMonthGrid.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + spacing = _ref3$reactDates.spacing, + zIndex = _ref3$reactDates.zIndex; + return { + CalendarMonthGrid: { + background: color.background, + textAlign: (0, _noflip["default"])('left'), + zIndex: zIndex + }, + CalendarMonthGrid__animating: { + zIndex: zIndex + 1 + }, + CalendarMonthGrid__horizontal: { + position: 'absolute', + left: (0, _noflip["default"])(spacing.dayPickerHorizontalPadding) + }, + CalendarMonthGrid__vertical: { + margin: '0 auto' + }, + CalendarMonthGrid__vertical_scrollable: { + margin: '0 auto' + }, + CalendarMonthGrid_month__horizontal: { + display: 'inline-block', + verticalAlign: 'top', + minHeight: '100%' + }, + CalendarMonthGrid_month__hideForAnimation: { + position: 'absolute', + zIndex: zIndex - 1, + opacity: 0, + pointerEvents: 'none' + }, + CalendarMonthGrid_month__hidden: { + visibility: 'hidden' + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(CalendarMonthGrid); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CalendarWeek.js b/lib/components/CalendarWeek.js new file mode 100644 index 000000000..83c4cde2d --- /dev/null +++ b/lib/components/CalendarWeek.js @@ -0,0 +1,25 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = CalendarWeek; + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({ + children: _propTypes["default"].node.isRequired +}) : {}; + +function CalendarWeek(_ref) { + var children = _ref.children; + return /*#__PURE__*/_react["default"].createElement("tr", null, children); +} + +CalendarWeek.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; \ No newline at end of file diff --git a/lib/components/ChevronDown.js b/lib/components/ChevronDown.js new file mode 100644 index 000000000..3f75dda1b --- /dev/null +++ b/lib/components/ChevronDown.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var ChevronDown = function ChevronDown(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + d: "M968 289L514 741c-11 11-21 11-32 0L29 289c-4-5-6-11-6-16 0-13 10-23 23-23 6 0 11 2 15 7l437 436 438-436c4-5 9-7 16-7 6 0 11 2 16 7 9 10 9 21 0 32z" + })); +}; + +ChevronDown.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +var _default = ChevronDown; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/ChevronUp.js b/lib/components/ChevronUp.js new file mode 100644 index 000000000..3285f4a55 --- /dev/null +++ b/lib/components/ChevronUp.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var ChevronUp = function ChevronUp(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + d: "M32 713l453-453c11-11 21-11 32 0l453 453c5 5 7 10 7 16 0 13-10 23-22 23-7 0-12-2-16-7L501 309 64 745c-4 5-9 7-15 7-7 0-12-2-17-7-9-11-9-21 0-32z" + })); +}; + +ChevronUp.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +var _default = ChevronUp; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CloseButton.js b/lib/components/CloseButton.js new file mode 100644 index 000000000..4a2de10a4 --- /dev/null +++ b/lib/components/CloseButton.js @@ -0,0 +1,24 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var CloseButton = function CloseButton(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + fillRule: "evenodd", + d: "M11.53.47a.75.75 0 0 0-1.061 0l-4.47 4.47L1.529.47A.75.75 0 1 0 .468 1.531l4.47 4.47-4.47 4.47a.75.75 0 1 0 1.061 1.061l4.47-4.47 4.47 4.47a.75.75 0 1 0 1.061-1.061l-4.47-4.47 4.47-4.47a.75.75 0 0 0 0-1.061z" + })); +}; + +CloseButton.defaultProps = { + focusable: "false", + viewBox: "0 0 12 12" +}; +var _default = CloseButton; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/CustomizableCalendarDay.js b/lib/components/CustomizableCalendarDay.js new file mode 100644 index 000000000..9c3777675 --- /dev/null +++ b/lib/components/CustomizableCalendarDay.js @@ -0,0 +1,403 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.selectedStyles = exports.selectedSpanStyles = exports.outsideStyles = exports.lastInRangeStyles = exports.hoveredSpanStyles = exports.highlightedCalendarStyles = exports.defaultStyles = exports["default"] = exports.blockedOutOfRangeStyles = exports.blockedMinNightsStyles = exports.blockedCalendarStyles = exports.PureCustomizableCalendarDay = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _moment = _interopRequireDefault(require("moment")); + +var _raf = _interopRequireDefault(require("raf")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _getCalendarDaySettings = _interopRequireDefault(require("../utils/getCalendarDaySettings")); + +var _constants = require("../constants"); + +var _DefaultTheme = _interopRequireDefault(require("../theme/DefaultTheme")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var color = _DefaultTheme["default"].reactDates.color; + +function getStyles(stylesObj, isHovered) { + if (!stylesObj) return null; + var hover = stylesObj.hover; + + if (isHovered && hover) { + return hover; + } + + return stylesObj; +} + +var DayStyleShape = process.env.NODE_ENV !== "production" ? _propTypes["default"].shape({ + background: _propTypes["default"].string, + border: (0, _airbnbPropTypes.or)([_propTypes["default"].string, _propTypes["default"].number]), + color: _propTypes["default"].string, + hover: _propTypes["default"].shape({ + background: _propTypes["default"].string, + border: (0, _airbnbPropTypes.or)([_propTypes["default"].string, _propTypes["default"].number]), + color: _propTypes["default"].string + }) +}) : {}; +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + day: _reactMomentProptypes["default"].momentObj, + daySize: _airbnbPropTypes.nonNegativeInteger, + isOutsideDay: _propTypes["default"].bool, + modifiers: _propTypes["default"].instanceOf(Set), + isFocused: _propTypes["default"].bool, + tabIndex: _propTypes["default"].oneOf([0, -1]), + onDayClick: _propTypes["default"].func, + onDayMouseEnter: _propTypes["default"].func, + onDayMouseLeave: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + ariaLabelFormat: _propTypes["default"].string, + // style overrides + defaultStyles: DayStyleShape, + outsideStyles: DayStyleShape, + todayStyles: DayStyleShape, + firstDayOfWeekStyles: DayStyleShape, + lastDayOfWeekStyles: DayStyleShape, + highlightedCalendarStyles: DayStyleShape, + blockedMinNightsStyles: DayStyleShape, + blockedCalendarStyles: DayStyleShape, + blockedOutOfRangeStyles: DayStyleShape, + hoveredSpanStyles: DayStyleShape, + selectedSpanStyles: DayStyleShape, + lastInRangeStyles: DayStyleShape, + selectedStyles: DayStyleShape, + selectedStartStyles: DayStyleShape, + selectedEndStyles: DayStyleShape, + afterHoveredStartStyles: DayStyleShape, + hoveredStartFirstPossibleEndStyles: DayStyleShape, + hoveredStartBlockedMinNightsStyles: DayStyleShape, + // internationalization + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.CalendarDayPhrases)) +})) : {}; +var defaultStyles = { + border: "1px solid ".concat(color.core.borderLight), + color: color.text, + background: color.background, + hover: { + background: color.core.borderLight, + border: "1px solid ".concat(color.core.borderLight), + color: 'inherit' + } +}; +exports.defaultStyles = defaultStyles; +var outsideStyles = { + background: color.outside.backgroundColor, + border: 0, + color: color.outside.color +}; +exports.outsideStyles = outsideStyles; +var highlightedCalendarStyles = { + background: color.highlighted.backgroundColor, + color: color.highlighted.color, + hover: { + background: color.highlighted.backgroundColor_hover, + color: color.highlighted.color_active + } +}; +exports.highlightedCalendarStyles = highlightedCalendarStyles; +var blockedMinNightsStyles = { + background: color.minimumNights.backgroundColor, + border: "1px solid ".concat(color.minimumNights.borderColor), + color: color.minimumNights.color, + hover: { + background: color.minimumNights.backgroundColor_hover, + color: color.minimumNights.color_active + } +}; +exports.blockedMinNightsStyles = blockedMinNightsStyles; +var blockedCalendarStyles = { + background: color.blocked_calendar.backgroundColor, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color, + hover: { + background: color.blocked_calendar.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_calendar.borderColor), + color: color.blocked_calendar.color_active + } +}; +exports.blockedCalendarStyles = blockedCalendarStyles; +var blockedOutOfRangeStyles = { + background: color.blocked_out_of_range.backgroundColor, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color, + hover: { + background: color.blocked_out_of_range.backgroundColor_hover, + border: "1px solid ".concat(color.blocked_out_of_range.borderColor), + color: color.blocked_out_of_range.color_active + } +}; +exports.blockedOutOfRangeStyles = blockedOutOfRangeStyles; +var hoveredSpanStyles = { + background: color.hoveredSpan.backgroundColor, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color, + hover: { + background: color.hoveredSpan.backgroundColor_hover, + border: "1px double ".concat(color.hoveredSpan.borderColor), + color: color.hoveredSpan.color_active + } +}; +exports.hoveredSpanStyles = hoveredSpanStyles; +var selectedSpanStyles = { + background: color.selectedSpan.backgroundColor, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color, + hover: { + background: color.selectedSpan.backgroundColor_hover, + border: "1px double ".concat(color.selectedSpan.borderColor), + color: color.selectedSpan.color_active + } +}; +exports.selectedSpanStyles = selectedSpanStyles; +var lastInRangeStyles = {}; +exports.lastInRangeStyles = lastInRangeStyles; +var selectedStyles = { + background: color.selected.backgroundColor, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color, + hover: { + background: color.selected.backgroundColor_hover, + border: "1px double ".concat(color.selected.borderColor), + color: color.selected.color_active + } +}; +exports.selectedStyles = selectedStyles; +var defaultProps = { + day: (0, _moment["default"])(), + daySize: _constants.DAY_SIZE, + isOutsideDay: false, + modifiers: new Set(), + isFocused: false, + tabIndex: -1, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + renderDayContents: null, + ariaLabelFormat: 'dddd, LL', + // style defaults + defaultStyles: defaultStyles, + outsideStyles: outsideStyles, + todayStyles: {}, + highlightedCalendarStyles: highlightedCalendarStyles, + blockedMinNightsStyles: blockedMinNightsStyles, + blockedCalendarStyles: blockedCalendarStyles, + blockedOutOfRangeStyles: blockedOutOfRangeStyles, + hoveredSpanStyles: hoveredSpanStyles, + selectedSpanStyles: selectedSpanStyles, + lastInRangeStyles: lastInRangeStyles, + selectedStyles: selectedStyles, + selectedStartStyles: {}, + selectedEndStyles: {}, + afterHoveredStartStyles: {}, + firstDayOfWeekStyles: {}, + lastDayOfWeekStyles: {}, + hoveredStartFirstPossibleEndStyles: {}, + hoveredStartBlockedMinNightsStyles: {}, + // internationalization + phrases: _defaultPhrases.CalendarDayPhrases +}; + +var CustomizableCalendarDay = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(CustomizableCalendarDay, _ref2); + var _proto = CustomizableCalendarDay.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function CustomizableCalendarDay() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + _this.state = { + isHovered: false + }; + _this.setButtonRef = _this.setButtonRef.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this2 = this; + + var _this$props = this.props, + isFocused = _this$props.isFocused, + tabIndex = _this$props.tabIndex; + + if (tabIndex === 0) { + if (isFocused || tabIndex !== prevProps.tabIndex) { + (0, _raf["default"])(function () { + if (_this2.buttonRef) { + _this2.buttonRef.focus(); + } + }); + } + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var onDayClick = this.props.onDayClick; + onDayClick(day, e); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day, e) { + var onDayMouseEnter = this.props.onDayMouseEnter; + this.setState({ + isHovered: true + }); + onDayMouseEnter(day, e); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day, e) { + var onDayMouseLeave = this.props.onDayMouseLeave; + this.setState({ + isHovered: false + }); + onDayMouseLeave(day, e); + }; + + _proto.onKeyDown = function onKeyDown(day, e) { + var onDayClick = this.props.onDayClick; + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onDayClick(day, e); + } + }; + + _proto.setButtonRef = function setButtonRef(ref) { + this.buttonRef = ref; + }; + + _proto.render = function render() { + var _this3 = this; + + var _this$props2 = this.props, + day = _this$props2.day, + ariaLabelFormat = _this$props2.ariaLabelFormat, + daySize = _this$props2.daySize, + isOutsideDay = _this$props2.isOutsideDay, + modifiers = _this$props2.modifiers, + tabIndex = _this$props2.tabIndex, + renderDayContents = _this$props2.renderDayContents, + css = _this$props2.css, + styles = _this$props2.styles, + phrases = _this$props2.phrases, + defaultStylesWithHover = _this$props2.defaultStyles, + outsideStylesWithHover = _this$props2.outsideStyles, + todayStylesWithHover = _this$props2.todayStyles, + firstDayOfWeekStylesWithHover = _this$props2.firstDayOfWeekStyles, + lastDayOfWeekStylesWithHover = _this$props2.lastDayOfWeekStyles, + highlightedCalendarStylesWithHover = _this$props2.highlightedCalendarStyles, + blockedMinNightsStylesWithHover = _this$props2.blockedMinNightsStyles, + blockedCalendarStylesWithHover = _this$props2.blockedCalendarStyles, + blockedOutOfRangeStylesWithHover = _this$props2.blockedOutOfRangeStyles, + hoveredSpanStylesWithHover = _this$props2.hoveredSpanStyles, + selectedSpanStylesWithHover = _this$props2.selectedSpanStyles, + lastInRangeStylesWithHover = _this$props2.lastInRangeStyles, + selectedStylesWithHover = _this$props2.selectedStyles, + selectedStartStylesWithHover = _this$props2.selectedStartStyles, + selectedEndStylesWithHover = _this$props2.selectedEndStyles, + afterHoveredStartStylesWithHover = _this$props2.afterHoveredStartStyles, + hoveredStartFirstPossibleEndStylesWithHover = _this$props2.hoveredStartFirstPossibleEndStyles, + hoveredStartBlockedMinNightsStylesWithHover = _this$props2.hoveredStartBlockedMinNightsStyles; + var isHovered = this.state.isHovered; + if (!day) return /*#__PURE__*/_react["default"].createElement("td", null); + + var _getCalendarDaySettin = (0, _getCalendarDaySettings["default"])(day, ariaLabelFormat, daySize, modifiers, phrases), + daySizeStyles = _getCalendarDaySettin.daySizeStyles, + useDefaultCursor = _getCalendarDaySettin.useDefaultCursor, + selected = _getCalendarDaySettin.selected, + hoveredSpan = _getCalendarDaySettin.hoveredSpan, + isOutsideRange = _getCalendarDaySettin.isOutsideRange, + ariaLabel = _getCalendarDaySettin.ariaLabel; + + return /*#__PURE__*/_react["default"].createElement("td", (0, _extends2["default"])({}, css(styles.CalendarDay, useDefaultCursor && styles.CalendarDay__defaultCursor, daySizeStyles, getStyles(defaultStylesWithHover, isHovered), isOutsideDay && getStyles(outsideStylesWithHover, isHovered), modifiers.has('today') && getStyles(todayStylesWithHover, isHovered), modifiers.has('first-day-of-week') && getStyles(firstDayOfWeekStylesWithHover, isHovered), modifiers.has('last-day-of-week') && getStyles(lastDayOfWeekStylesWithHover, isHovered), modifiers.has('hovered-start-first-possible-end') && getStyles(hoveredStartFirstPossibleEndStylesWithHover, isHovered), modifiers.has('hovered-start-blocked-minimum-nights') && getStyles(hoveredStartBlockedMinNightsStylesWithHover, isHovered), modifiers.has('highlighted-calendar') && getStyles(highlightedCalendarStylesWithHover, isHovered), modifiers.has('blocked-minimum-nights') && getStyles(blockedMinNightsStylesWithHover, isHovered), modifiers.has('blocked-calendar') && getStyles(blockedCalendarStylesWithHover, isHovered), hoveredSpan && getStyles(hoveredSpanStylesWithHover, isHovered), modifiers.has('after-hovered-start') && getStyles(afterHoveredStartStylesWithHover, isHovered), modifiers.has('selected-span') && getStyles(selectedSpanStylesWithHover, isHovered), modifiers.has('last-in-range') && getStyles(lastInRangeStylesWithHover, isHovered), selected && getStyles(selectedStylesWithHover, isHovered), modifiers.has('selected-start') && getStyles(selectedStartStylesWithHover, isHovered), modifiers.has('selected-end') && getStyles(selectedEndStylesWithHover, isHovered), isOutsideRange && getStyles(blockedOutOfRangeStylesWithHover, isHovered)), { + role: "button" // eslint-disable-line jsx-a11y/no-noninteractive-element-to-interactive-role + , + ref: this.setButtonRef, + "aria-disabled": modifiers.has('blocked'), + "aria-label": ariaLabel, + onMouseEnter: function onMouseEnter(e) { + _this3.onDayMouseEnter(day, e); + }, + onMouseLeave: function onMouseLeave(e) { + _this3.onDayMouseLeave(day, e); + }, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + }, + onClick: function onClick(e) { + _this3.onDayClick(day, e); + }, + onKeyDown: function onKeyDown(e) { + _this3.onKeyDown(day, e); + }, + tabIndex: tabIndex + }), renderDayContents ? renderDayContents(day, modifiers) : day.format('D')); + }; + + return CustomizableCalendarDay; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports.PureCustomizableCalendarDay = CustomizableCalendarDay; +CustomizableCalendarDay.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +CustomizableCalendarDay.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var font = _ref3.reactDates.font; + return { + CalendarDay: { + boxSizing: 'border-box', + cursor: 'pointer', + fontSize: font.size, + textAlign: 'center', + ':active': { + outline: 0 + } + }, + CalendarDay__defaultCursor: { + cursor: 'default' + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(CustomizableCalendarDay); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DateInput.js b/lib/components/DateInput.js new file mode 100644 index 000000000..aa3f5ae12 --- /dev/null +++ b/lib/components/DateInput.js @@ -0,0 +1,383 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _throttle = _interopRequireDefault(require("lodash/throttle")); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _getInputHeight = _interopRequireDefault(require("../utils/getInputHeight")); + +var _OpenDirectionShape = _interopRequireDefault(require("../shapes/OpenDirectionShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var FANG_PATH_TOP = "M0,".concat(_constants.FANG_HEIGHT_PX, " ").concat(_constants.FANG_WIDTH_PX, ",").concat(_constants.FANG_HEIGHT_PX, " ").concat(_constants.FANG_WIDTH_PX / 2, ",0z"); +var FANG_STROKE_TOP = "M0,".concat(_constants.FANG_HEIGHT_PX, " ").concat(_constants.FANG_WIDTH_PX / 2, ",0 ").concat(_constants.FANG_WIDTH_PX, ",").concat(_constants.FANG_HEIGHT_PX); +var FANG_PATH_BOTTOM = "M0,0 ".concat(_constants.FANG_WIDTH_PX, ",0 ").concat(_constants.FANG_WIDTH_PX / 2, ",").concat(_constants.FANG_HEIGHT_PX, "z"); +var FANG_STROKE_BOTTOM = "M0,0 ".concat(_constants.FANG_WIDTH_PX / 2, ",").concat(_constants.FANG_HEIGHT_PX, " ").concat(_constants.FANG_WIDTH_PX, ",0"); +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + id: _propTypes["default"].string.isRequired, + placeholder: _propTypes["default"].string, + displayValue: _propTypes["default"].string, + ariaLabel: _propTypes["default"].string, + autoComplete: _propTypes["default"].string, + titleText: _propTypes["default"].string, + screenReaderMessage: _propTypes["default"].string, + focused: _propTypes["default"].bool, + disabled: _propTypes["default"].bool, + required: _propTypes["default"].bool, + readOnly: _propTypes["default"].bool, + openDirection: _OpenDirectionShape["default"], + showCaret: _propTypes["default"].bool, + verticalSpacing: _airbnbPropTypes.nonNegativeInteger, + small: _propTypes["default"].bool, + block: _propTypes["default"].bool, + regular: _propTypes["default"].bool, + onChange: _propTypes["default"].func, + onFocus: _propTypes["default"].func, + onKeyDownShiftTab: _propTypes["default"].func, + onKeyDownTab: _propTypes["default"].func, + onKeyDownArrowDown: _propTypes["default"].func, + onKeyDownQuestionMark: _propTypes["default"].func, + // accessibility + isFocused: _propTypes["default"].bool // describes actual DOM focus + +})) : {}; +var defaultProps = { + placeholder: 'Select Date', + displayValue: '', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + screenReaderMessage: '', + focused: false, + disabled: false, + required: false, + readOnly: null, + openDirection: _constants.OPEN_DOWN, + showCaret: false, + verticalSpacing: _constants.DEFAULT_VERTICAL_SPACING, + small: false, + block: false, + regular: false, + onChange: function onChange() {}, + onFocus: function onFocus() {}, + onKeyDownShiftTab: function onKeyDownShiftTab() {}, + onKeyDownTab: function onKeyDownTab() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + // accessibility + isFocused: false +}; + +var DateInput = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DateInput, _ref2); + var _proto = DateInput.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DateInput(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + dateString: '', + isTouchDevice: false + }; + _this.onChange = _this.onChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onKeyDown = _this.onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setInputRef = _this.setInputRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.throttledKeyDown = (0, _throttle["default"])(_this.onFinalKeyDown, 300, { + trailing: false + }); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.setState({ + isTouchDevice: (0, _isTouchDevice["default"])() + }); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var dateString = this.state.dateString; + + if (dateString && nextProps.displayValue) { + this.setState({ + dateString: '' + }); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var _this$props = this.props, + focused = _this$props.focused, + isFocused = _this$props.isFocused; + if (prevProps.focused === focused && prevProps.isFocused === isFocused) return; + + if (focused && isFocused) { + this.inputRef.focus(); + } + }; + + _proto.onChange = function onChange(e) { + var _this$props2 = this.props, + onChange = _this$props2.onChange, + onKeyDownQuestionMark = _this$props2.onKeyDownQuestionMark; + var dateString = e.target.value; // In Safari, onKeyDown does not consistently fire ahead of onChange. As a result, we need to + // special case the `?` key so that it always triggers the appropriate callback, instead of + // modifying the input value + + if (dateString[dateString.length - 1] === '?') { + onKeyDownQuestionMark(e); + } else { + this.setState({ + dateString: dateString + }, function () { + return onChange(dateString); + }); + } + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + + if (!_constants.MODIFIER_KEY_NAMES.has(e.key)) { + this.throttledKeyDown(e); + } + }; + + _proto.onFinalKeyDown = function onFinalKeyDown(e) { + var _this$props3 = this.props, + onKeyDownShiftTab = _this$props3.onKeyDownShiftTab, + onKeyDownTab = _this$props3.onKeyDownTab, + onKeyDownArrowDown = _this$props3.onKeyDownArrowDown, + onKeyDownQuestionMark = _this$props3.onKeyDownQuestionMark; + var key = e.key; + + if (key === 'Tab') { + if (e.shiftKey) { + onKeyDownShiftTab(e); + } else { + onKeyDownTab(e); + } + } else if (key === 'ArrowDown') { + onKeyDownArrowDown(e); + } else if (key === '?') { + e.preventDefault(); + onKeyDownQuestionMark(e); + } + }; + + _proto.setInputRef = function setInputRef(ref) { + this.inputRef = ref; + }; + + _proto.render = function render() { + var _this$state = this.state, + dateString = _this$state.dateString, + isTouch = _this$state.isTouchDevice; + var _this$props4 = this.props, + id = _this$props4.id, + placeholder = _this$props4.placeholder, + ariaLabel = _this$props4.ariaLabel, + autoComplete = _this$props4.autoComplete, + titleText = _this$props4.titleText, + displayValue = _this$props4.displayValue, + screenReaderMessage = _this$props4.screenReaderMessage, + focused = _this$props4.focused, + showCaret = _this$props4.showCaret, + onFocus = _this$props4.onFocus, + disabled = _this$props4.disabled, + required = _this$props4.required, + readOnly = _this$props4.readOnly, + openDirection = _this$props4.openDirection, + verticalSpacing = _this$props4.verticalSpacing, + small = _this$props4.small, + regular = _this$props4.regular, + block = _this$props4.block, + css = _this$props4.css, + styles = _this$props4.styles, + reactDates = _this$props4.theme.reactDates; + var value = dateString || displayValue || ''; + var screenReaderMessageId = "DateInput__screen-reader-message-".concat(id); + var withFang = showCaret && focused; + var inputHeight = (0, _getInputHeight["default"])(reactDates, small); + return /*#__PURE__*/_react["default"].createElement("div", css(styles.DateInput, small && styles.DateInput__small, block && styles.DateInput__block, withFang && styles.DateInput__withFang, disabled && styles.DateInput__disabled, withFang && openDirection === _constants.OPEN_DOWN && styles.DateInput__openDown, withFang && openDirection === _constants.OPEN_UP && styles.DateInput__openUp), /*#__PURE__*/_react["default"].createElement("input", (0, _extends2["default"])({}, css(styles.DateInput_input, small && styles.DateInput_input__small, regular && styles.DateInput_input__regular, readOnly && styles.DateInput_input__readOnly, focused && styles.DateInput_input__focused, disabled && styles.DateInput_input__disabled), { + "aria-label": ariaLabel === undefined ? placeholder : ariaLabel, + title: titleText, + type: "text", + id: id, + name: id, + ref: this.setInputRef, + value: value, + onChange: this.onChange, + onKeyDown: this.onKeyDown, + onFocus: onFocus, + placeholder: placeholder, + autoComplete: autoComplete, + disabled: disabled, + readOnly: typeof readOnly === 'boolean' ? readOnly : isTouch, + required: required, + "aria-describedby": screenReaderMessage && screenReaderMessageId + })), withFang && /*#__PURE__*/_react["default"].createElement("svg", (0, _extends2["default"])({ + role: "presentation", + focusable: "false" + }, css(styles.DateInput_fang, openDirection === _constants.OPEN_DOWN && { + top: inputHeight + verticalSpacing - _constants.FANG_HEIGHT_PX - 1 + }, openDirection === _constants.OPEN_UP && { + bottom: inputHeight + verticalSpacing - _constants.FANG_HEIGHT_PX - 1 + })), /*#__PURE__*/_react["default"].createElement("path", (0, _extends2["default"])({}, css(styles.DateInput_fangShape), { + d: openDirection === _constants.OPEN_DOWN ? FANG_PATH_TOP : FANG_PATH_BOTTOM + })), /*#__PURE__*/_react["default"].createElement("path", (0, _extends2["default"])({}, css(styles.DateInput_fangStroke), { + d: openDirection === _constants.OPEN_DOWN ? FANG_STROKE_TOP : FANG_STROKE_BOTTOM + }))), screenReaderMessage && /*#__PURE__*/_react["default"].createElement("p", (0, _extends2["default"])({}, css(styles.DateInput_screenReaderMessage), { + id: screenReaderMessageId + }), screenReaderMessage)); + }; + + return DateInput; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +DateInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateInput.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + border = _ref3$reactDates.border, + color = _ref3$reactDates.color, + sizing = _ref3$reactDates.sizing, + spacing = _ref3$reactDates.spacing, + font = _ref3$reactDates.font, + zIndex = _ref3$reactDates.zIndex; + return { + DateInput: { + margin: 0, + padding: spacing.inputPadding, + background: color.background, + position: 'relative', + display: 'inline-block', + width: sizing.inputWidth, + verticalAlign: 'middle' + }, + DateInput__small: { + width: sizing.inputWidth_small + }, + DateInput__block: { + width: '100%' + }, + DateInput__disabled: { + background: color.disabled, + color: color.textDisabled + }, + DateInput_input: { + fontWeight: font.input.weight, + fontSize: font.input.size, + lineHeight: font.input.lineHeight, + color: color.text, + backgroundColor: color.background, + width: '100%', + padding: "".concat(spacing.displayTextPaddingVertical, "px ").concat(spacing.displayTextPaddingHorizontal, "px"), + paddingTop: spacing.displayTextPaddingTop, + paddingBottom: spacing.displayTextPaddingBottom, + paddingLeft: (0, _noflip["default"])(spacing.displayTextPaddingLeft), + paddingRight: (0, _noflip["default"])(spacing.displayTextPaddingRight), + border: border.input.border, + borderTop: border.input.borderTop, + borderRight: (0, _noflip["default"])(border.input.borderRight), + borderBottom: border.input.borderBottom, + borderLeft: (0, _noflip["default"])(border.input.borderLeft), + borderRadius: border.input.borderRadius + }, + DateInput_input__small: { + fontSize: font.input.size_small, + lineHeight: font.input.lineHeight_small, + letterSpacing: font.input.letterSpacing_small, + padding: "".concat(spacing.displayTextPaddingVertical_small, "px ").concat(spacing.displayTextPaddingHorizontal_small, "px"), + paddingTop: spacing.displayTextPaddingTop_small, + paddingBottom: spacing.displayTextPaddingBottom_small, + paddingLeft: (0, _noflip["default"])(spacing.displayTextPaddingLeft_small), + paddingRight: (0, _noflip["default"])(spacing.displayTextPaddingRight_small) + }, + DateInput_input__regular: { + fontWeight: 'inherit' + }, + DateInput_input__readOnly: { + userSelect: 'none' + }, + DateInput_input__focused: { + outline: border.input.outlineFocused, + background: color.backgroundFocused, + border: border.input.borderFocused, + borderTop: border.input.borderTopFocused, + borderRight: (0, _noflip["default"])(border.input.borderRightFocused), + borderBottom: border.input.borderBottomFocused, + borderLeft: (0, _noflip["default"])(border.input.borderLeftFocused) + }, + DateInput_input__disabled: { + background: color.disabled, + fontStyle: font.input.styleDisabled + }, + DateInput_screenReaderMessage: { + border: 0, + clip: 'rect(0, 0, 0, 0)', + height: 1, + margin: -1, + overflow: 'hidden', + padding: 0, + position: 'absolute', + width: 1 + }, + DateInput_fang: { + position: 'absolute', + width: _constants.FANG_WIDTH_PX, + height: _constants.FANG_HEIGHT_PX, + left: 22, + // TODO: should be noflip wrapped and handled by an isRTL prop + zIndex: zIndex + 2 + }, + DateInput_fangShape: { + fill: color.background + }, + DateInput_fangStroke: { + stroke: color.core.border, + fill: 'transparent' + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DateInput); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DateRangePicker.js b/lib/components/DateRangePicker.js new file mode 100644 index 000000000..d422e43cd --- /dev/null +++ b/lib/components/DateRangePicker.js @@ -0,0 +1,732 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.PureDateRangePicker = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _moment = _interopRequireDefault(require("moment")); + +var _reactWithStyles = require("react-with-styles"); + +var _reactPortal = require("react-portal"); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _consolidatedEvents = require("consolidated-events"); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _reactOutsideClickHandler = _interopRequireDefault(require("react-outside-click-handler")); + +var _color2k = require("color2k"); + +var _DateRangePickerShape = _interopRequireDefault(require("../shapes/DateRangePickerShape")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getResponsiveContainerStyles = _interopRequireDefault(require("../utils/getResponsiveContainerStyles")); + +var _getDetachedContainerStyles = _interopRequireDefault(require("../utils/getDetachedContainerStyles")); + +var _getInputHeight = _interopRequireDefault(require("../utils/getInputHeight")); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("../utils/isInclusivelyAfterDay")); + +var _disableScroll2 = _interopRequireDefault(require("../utils/disableScroll")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _DateRangePickerInputController = _interopRequireDefault(require("./DateRangePickerInputController")); + +var _DayPickerRangeController = _interopRequireDefault(require("./DayPickerRangeController")); + +var _CloseButton = _interopRequireDefault(require("./CloseButton")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), _DateRangePickerShape["default"])) : {}; +var defaultProps = { + // required props for a functional interactive DateRangePicker + startDate: null, + endDate: null, + focusedInput: null, + // input related props + startDatePlaceholderText: 'Start Date', + endDatePlaceholderText: 'End Date', + startDateAriaLabel: undefined, + endDateAriaLabel: undefined, + startDateTitleText: undefined, + endDateTitleText: undefined, + startDateOffset: undefined, + endDateOffset: undefined, + disabled: false, + required: false, + readOnly: false, + screenReaderInputMessage: '', + showClearDates: false, + showDefaultInputIcon: false, + inputIconPosition: _constants.ICON_BEFORE_POSITION, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + keepFocusOnInput: false, + // calendar presentation and interaction related props + renderMonthText: null, + renderWeekHeaderElement: null, + orientation: _constants.HORIZONTAL_ORIENTATION, + anchorDirection: _constants.ANCHOR_LEFT, + openDirection: _constants.OPEN_DOWN, + horizontalMargin: 0, + withPortal: false, + withFullScreenPortal: false, + appendToBody: false, + disableScroll: false, + initialVisibleMonth: null, + numberOfMonths: 2, + keepOpenOnDateSelect: false, + reopenPickerOnClearDates: false, + renderCalendarInfo: null, + calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: _constants.DAY_SIZE, + isRTL: false, + firstDayOfWeek: null, + verticalHeight: null, + transitionDuration: undefined, + verticalSpacing: _constants.DEFAULT_VERTICAL_SPACING, + autoComplete: 'off', + horizontalMonthPadding: undefined, + // navigation related props + dayPickerNavigationInlineStyles: null, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onClose: function onClose() {}, + // day presentation and interaction related props + renderCalendarDay: undefined, + renderDayContents: null, + renderMonthElement: null, + minimumNights: 1, + enableOutsideDays: false, + isDayBlocked: function isDayBlocked() { + return false; + }, + isOutsideRange: function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, (0, _moment["default"])()); + }, + isDayHighlighted: function isDayHighlighted() { + return false; + }, + minDate: undefined, + maxDate: undefined, + // internationalization + displayFormat: function displayFormat() { + return _moment["default"].localeData().longDateFormat('L'); + }, + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: _defaultPhrases.DateRangePickerPhrases, + dayAriaLabelFormat: undefined +}; + +var DateRangePicker = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DateRangePicker, _ref2); + var _proto = DateRangePicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DateRangePicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.state = { + dayPickerContainerStyles: {}, + isDateRangePickerInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }; + _this.isTouchDevice = false; + _this.onOutsideClick = _this.onOutsideClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDateRangePickerInputFocus = _this.onDateRangePickerInputFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayPickerFocus = _this.onDayPickerFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayPickerFocusOut = _this.onDayPickerFocusOut.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayPickerBlur = _this.onDayPickerBlur.bind((0, _assertThisInitialized2["default"])(_this)); + _this.showKeyboardShortcutsPanel = _this.showKeyboardShortcutsPanel.bind((0, _assertThisInitialized2["default"])(_this)); + _this.responsivizePickerPosition = _this.responsivizePickerPosition.bind((0, _assertThisInitialized2["default"])(_this)); + _this.disableScroll = _this.disableScroll.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setDayPickerContainerRef = _this.setDayPickerContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setContainerRef = _this.setContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.removeEventListener = (0, _consolidatedEvents.addEventListener)(window, 'resize', this.responsivizePickerPosition, { + passive: true + }); + this.responsivizePickerPosition(); + this.disableScroll(); + var focusedInput = this.props.focusedInput; + + if (focusedInput) { + this.setState({ + isDateRangePickerInputFocused: true + }); + } + + this.isTouchDevice = (0, _isTouchDevice["default"])(); + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var focusedInput = this.props.focusedInput; + + if (!prevProps.focusedInput && focusedInput && this.isOpened()) { + // The date picker just changed from being closed to being open. + this.responsivizePickerPosition(); + this.disableScroll(); + } else if (prevProps.focusedInput && !focusedInput && !this.isOpened()) { + // The date picker just changed from being open to being closed. + if (this.enableScroll) this.enableScroll(); + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + this.removeDayPickerEventListeners(); + if (this.removeEventListener) this.removeEventListener(); + if (this.enableScroll) this.enableScroll(); + }; + + _proto.onOutsideClick = function onOutsideClick(event) { + var _this$props = this.props, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose, + startDate = _this$props.startDate, + endDate = _this$props.endDate, + appendToBody = _this$props.appendToBody; + if (!this.isOpened()) return; + if (appendToBody && this.dayPickerContainer.contains(event.target)) return; + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + }; + + _proto.onDateRangePickerInputFocus = function onDateRangePickerInputFocus(focusedInput) { + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + readOnly = _this$props2.readOnly, + withPortal = _this$props2.withPortal, + withFullScreenPortal = _this$props2.withFullScreenPortal, + keepFocusOnInput = _this$props2.keepFocusOnInput; + + if (focusedInput) { + var withAnyPortal = withPortal || withFullScreenPortal; + var moveFocusToDayPicker = withAnyPortal || readOnly && !keepFocusOnInput || this.isTouchDevice && !keepFocusOnInput; + + if (moveFocusToDayPicker) { + this.onDayPickerFocus(); + } else { + this.onDayPickerBlur(); + } + } + + onFocusChange(focusedInput); + }; + + _proto.onDayPickerFocus = function onDayPickerFocus() { + var _this$props3 = this.props, + focusedInput = _this$props3.focusedInput, + onFocusChange = _this$props3.onFocusChange; + if (!focusedInput) onFocusChange(_constants.START_DATE); + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: false + }); + }; + + _proto.onDayPickerFocusOut = function onDayPickerFocusOut(event) { + // In cases where **relatedTarget** is not null, it points to the right + // element here. However, in cases where it is null (such as clicking on a + // specific day) or it is **document.body** (IE11), the appropriate value is **event.target**. + // + // We handle both situations here by using the ` || ` operator to fallback + // to *event.target** when **relatedTarget** is not provided. + var relatedTarget = event.relatedTarget === document.body ? event.target : event.relatedTarget || event.target; + if (this.dayPickerContainer.contains(relatedTarget)) return; + this.onOutsideClick(event); + }; + + _proto.onDayPickerBlur = function onDayPickerBlur() { + this.setState({ + isDateRangePickerInputFocused: true, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + }; + + _proto.setDayPickerContainerRef = function setDayPickerContainerRef(ref) { + if (ref === this.dayPickerContainer) return; + if (this.dayPickerContainer) this.removeDayPickerEventListeners(); + this.dayPickerContainer = ref; + if (!ref) return; + this.addDayPickerEventListeners(); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.addDayPickerEventListeners = function addDayPickerEventListeners() { + // NOTE: We are using a manual event listener here, because React doesn't + // provide FocusOut, while blur and keydown don't provide the information + // needed in order to know whether we have left focus or not. + // + // For reference, this issue is further described here: + // - https://github.com/facebook/react/issues/6410 + this.removeDayPickerFocusOut = (0, _consolidatedEvents.addEventListener)(this.dayPickerContainer, 'focusout', this.onDayPickerFocusOut); + }; + + _proto.removeDayPickerEventListeners = function removeDayPickerEventListeners() { + if (this.removeDayPickerFocusOut) this.removeDayPickerFocusOut(); + }; + + _proto.isOpened = function isOpened() { + var focusedInput = this.props.focusedInput; + return focusedInput === _constants.START_DATE || focusedInput === _constants.END_DATE; + }; + + _proto.disableScroll = function disableScroll() { + var _this$props4 = this.props, + appendToBody = _this$props4.appendToBody, + propDisableScroll = _this$props4.disableScroll; + if (!appendToBody && !propDisableScroll) return; + if (!this.isOpened()) return; // Disable scroll for every ancestor of this DateRangePicker up to the + // document level. This ensures the input and the picker never move. Other + // sibling elements or the picker itself can scroll. + + this.enableScroll = (0, _disableScroll2["default"])(this.container); + }; + + _proto.responsivizePickerPosition = function responsivizePickerPosition() { + // It's possible the portal props have been changed in response to window resizes + // So let's ensure we reset this back to the base state each time + var dayPickerContainerStyles = this.state.dayPickerContainerStyles; + + if (Object.keys(dayPickerContainerStyles).length > 0) { + this.setState({ + dayPickerContainerStyles: {} + }); + } + + if (!this.isOpened()) { + return; + } + + var _this$props5 = this.props, + openDirection = _this$props5.openDirection, + anchorDirection = _this$props5.anchorDirection, + horizontalMargin = _this$props5.horizontalMargin, + withPortal = _this$props5.withPortal, + withFullScreenPortal = _this$props5.withFullScreenPortal, + appendToBody = _this$props5.appendToBody; + var isAnchoredLeft = anchorDirection === _constants.ANCHOR_LEFT; + + if (!withPortal && !withFullScreenPortal) { + var containerRect = this.dayPickerContainer.getBoundingClientRect(); + var currentOffset = dayPickerContainerStyles[anchorDirection] || 0; + var containerEdge = isAnchoredLeft ? containerRect[_constants.ANCHOR_RIGHT] : containerRect[_constants.ANCHOR_LEFT]; + this.setState({ + dayPickerContainerStyles: _objectSpread(_objectSpread({}, (0, _getResponsiveContainerStyles["default"])(anchorDirection, currentOffset, containerEdge, horizontalMargin)), appendToBody && (0, _getDetachedContainerStyles["default"])(openDirection, anchorDirection, this.container)) + }); + } + }; + + _proto.showKeyboardShortcutsPanel = function showKeyboardShortcutsPanel() { + this.setState({ + isDateRangePickerInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: true + }); + }; + + _proto.maybeRenderDayPickerWithPortal = function maybeRenderDayPickerWithPortal() { + var _this$props6 = this.props, + withPortal = _this$props6.withPortal, + withFullScreenPortal = _this$props6.withFullScreenPortal, + appendToBody = _this$props6.appendToBody; + + if (!this.isOpened()) { + return null; + } + + if (withPortal || withFullScreenPortal || appendToBody) { + return /*#__PURE__*/_react["default"].createElement(_reactPortal.Portal, null, this.renderDayPicker()); + } + + return this.renderDayPicker(); + }; + + _proto.renderDayPicker = function renderDayPicker() { + var _this$props7 = this.props, + anchorDirection = _this$props7.anchorDirection, + openDirection = _this$props7.openDirection, + isDayBlocked = _this$props7.isDayBlocked, + isDayHighlighted = _this$props7.isDayHighlighted, + isOutsideRange = _this$props7.isOutsideRange, + numberOfMonths = _this$props7.numberOfMonths, + orientation = _this$props7.orientation, + monthFormat = _this$props7.monthFormat, + renderMonthText = _this$props7.renderMonthText, + renderWeekHeaderElement = _this$props7.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props7.dayPickerNavigationInlineStyles, + navPosition = _this$props7.navPosition, + navPrev = _this$props7.navPrev, + navNext = _this$props7.navNext, + renderNavPrevButton = _this$props7.renderNavPrevButton, + renderNavNextButton = _this$props7.renderNavNextButton, + onPrevMonthClick = _this$props7.onPrevMonthClick, + onNextMonthClick = _this$props7.onNextMonthClick, + onDatesChange = _this$props7.onDatesChange, + onFocusChange = _this$props7.onFocusChange, + withPortal = _this$props7.withPortal, + withFullScreenPortal = _this$props7.withFullScreenPortal, + daySize = _this$props7.daySize, + enableOutsideDays = _this$props7.enableOutsideDays, + focusedInput = _this$props7.focusedInput, + startDate = _this$props7.startDate, + startDateOffset = _this$props7.startDateOffset, + endDate = _this$props7.endDate, + endDateOffset = _this$props7.endDateOffset, + minDate = _this$props7.minDate, + maxDate = _this$props7.maxDate, + minimumNights = _this$props7.minimumNights, + keepOpenOnDateSelect = _this$props7.keepOpenOnDateSelect, + renderCalendarDay = _this$props7.renderCalendarDay, + renderDayContents = _this$props7.renderDayContents, + renderCalendarInfo = _this$props7.renderCalendarInfo, + renderMonthElement = _this$props7.renderMonthElement, + calendarInfoPosition = _this$props7.calendarInfoPosition, + firstDayOfWeek = _this$props7.firstDayOfWeek, + initialVisibleMonth = _this$props7.initialVisibleMonth, + hideKeyboardShortcutsPanel = _this$props7.hideKeyboardShortcutsPanel, + customCloseIcon = _this$props7.customCloseIcon, + onClose = _this$props7.onClose, + phrases = _this$props7.phrases, + dayAriaLabelFormat = _this$props7.dayAriaLabelFormat, + isRTL = _this$props7.isRTL, + weekDayFormat = _this$props7.weekDayFormat, + css = _this$props7.css, + styles = _this$props7.styles, + verticalHeight = _this$props7.verticalHeight, + noBorder = _this$props7.noBorder, + transitionDuration = _this$props7.transitionDuration, + verticalSpacing = _this$props7.verticalSpacing, + horizontalMonthPadding = _this$props7.horizontalMonthPadding, + small = _this$props7.small, + disabled = _this$props7.disabled, + reactDates = _this$props7.theme.reactDates; + var _this$state = this.state, + dayPickerContainerStyles = _this$state.dayPickerContainerStyles, + isDayPickerFocused = _this$state.isDayPickerFocused, + showKeyboardShortcuts = _this$state.showKeyboardShortcuts; + var onOutsideClick = !withFullScreenPortal && withPortal ? this.onOutsideClick : undefined; + + var initialVisibleMonthThunk = initialVisibleMonth || function () { + return startDate || endDate || (0, _moment["default"])(); + }; + + var closeIcon = customCloseIcon || /*#__PURE__*/_react["default"].createElement(_CloseButton["default"], css(styles.DateRangePicker_closeButton_svg)); + + var inputHeight = (0, _getInputHeight["default"])(reactDates, small); + var withAnyPortal = withPortal || withFullScreenPortal; + /* eslint-disable jsx-a11y/no-static-element-interactions */ + + /* eslint-disable jsx-a11y/click-events-have-key-events */ + + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + key: "day-picker", + ref: this.setDayPickerContainerRef + }, css(styles.DateRangePicker_picker, anchorDirection === _constants.ANCHOR_LEFT && styles.DateRangePicker_picker__directionLeft, anchorDirection === _constants.ANCHOR_RIGHT && styles.DateRangePicker_picker__directionRight, orientation === _constants.HORIZONTAL_ORIENTATION && styles.DateRangePicker_picker__horizontal, orientation === _constants.VERTICAL_ORIENTATION && styles.DateRangePicker_picker__vertical, !withAnyPortal && openDirection === _constants.OPEN_DOWN && { + top: inputHeight + verticalSpacing + }, !withAnyPortal && openDirection === _constants.OPEN_UP && { + bottom: inputHeight + verticalSpacing + }, withAnyPortal && styles.DateRangePicker_picker__portal, withFullScreenPortal && styles.DateRangePicker_picker__fullScreenPortal, isRTL && styles.DateRangePicker_picker__rtl, dayPickerContainerStyles), { + onClick: onOutsideClick + }), /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + numberOfMonths: numberOfMonths, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + onDatesChange: onDatesChange, + onFocusChange: onFocusChange, + onClose: onClose, + focusedInput: focusedInput, + startDate: startDate, + startDateOffset: startDateOffset, + endDate: endDate, + endDateOffset: endDateOffset, + minDate: minDate, + maxDate: maxDate, + monthFormat: monthFormat, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + withPortal: withAnyPortal, + daySize: daySize, + initialVisibleMonth: initialVisibleMonthThunk, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + minimumNights: minimumNights, + isOutsideRange: isOutsideRange, + isDayHighlighted: isDayHighlighted, + isDayBlocked: isDayBlocked, + keepOpenOnDateSelect: keepOpenOnDateSelect, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isDayPickerFocused, + showKeyboardShortcuts: showKeyboardShortcuts, + onBlur: this.onDayPickerBlur, + phrases: phrases, + dayAriaLabelFormat: dayAriaLabelFormat, + isRTL: isRTL, + firstDayOfWeek: firstDayOfWeek, + weekDayFormat: weekDayFormat, + verticalHeight: verticalHeight, + noBorder: noBorder, + transitionDuration: transitionDuration, + disabled: disabled, + horizontalMonthPadding: horizontalMonthPadding + }), withFullScreenPortal && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({}, css(styles.DateRangePicker_closeButton), { + type: "button", + onClick: this.onOutsideClick, + "aria-label": phrases.closeDatePicker, + tabIndex: "-1" + }), closeIcon)); + /* eslint-enable jsx-a11y/no-static-element-interactions */ + + /* eslint-enable jsx-a11y/click-events-have-key-events */ + }; + + _proto.render = function render() { + var _this$props8 = this.props, + startDate = _this$props8.startDate, + startDateId = _this$props8.startDateId, + startDatePlaceholderText = _this$props8.startDatePlaceholderText, + startDateAriaLabel = _this$props8.startDateAriaLabel, + startDateTitleText = _this$props8.startDateTitleText, + endDate = _this$props8.endDate, + endDateId = _this$props8.endDateId, + endDatePlaceholderText = _this$props8.endDatePlaceholderText, + endDateAriaLabel = _this$props8.endDateAriaLabel, + endDateTitleText = _this$props8.endDateTitleText, + focusedInput = _this$props8.focusedInput, + screenReaderInputMessage = _this$props8.screenReaderInputMessage, + showClearDates = _this$props8.showClearDates, + showDefaultInputIcon = _this$props8.showDefaultInputIcon, + inputIconPosition = _this$props8.inputIconPosition, + customInputIcon = _this$props8.customInputIcon, + customArrowIcon = _this$props8.customArrowIcon, + customCloseIcon = _this$props8.customCloseIcon, + disabled = _this$props8.disabled, + required = _this$props8.required, + readOnly = _this$props8.readOnly, + autoComplete = _this$props8.autoComplete, + openDirection = _this$props8.openDirection, + phrases = _this$props8.phrases, + isOutsideRange = _this$props8.isOutsideRange, + isDayBlocked = _this$props8.isDayBlocked, + minimumNights = _this$props8.minimumNights, + withPortal = _this$props8.withPortal, + withFullScreenPortal = _this$props8.withFullScreenPortal, + displayFormat = _this$props8.displayFormat, + reopenPickerOnClearDates = _this$props8.reopenPickerOnClearDates, + keepOpenOnDateSelect = _this$props8.keepOpenOnDateSelect, + onDatesChange = _this$props8.onDatesChange, + onClose = _this$props8.onClose, + isRTL = _this$props8.isRTL, + noBorder = _this$props8.noBorder, + block = _this$props8.block, + verticalSpacing = _this$props8.verticalSpacing, + small = _this$props8.small, + regular = _this$props8.regular, + css = _this$props8.css, + styles = _this$props8.styles; + var isDateRangePickerInputFocused = this.state.isDateRangePickerInputFocused; + var enableOutsideClick = !withPortal && !withFullScreenPortal; + var hideFang = verticalSpacing < _constants.FANG_HEIGHT_PX; + + var input = /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + startDate: startDate, + startDateId: startDateId, + startDatePlaceholderText: startDatePlaceholderText, + isStartDateFocused: focusedInput === _constants.START_DATE, + startDateAriaLabel: startDateAriaLabel, + startDateTitleText: startDateTitleText, + endDate: endDate, + endDateId: endDateId, + endDatePlaceholderText: endDatePlaceholderText, + isEndDateFocused: focusedInput === _constants.END_DATE, + endDateAriaLabel: endDateAriaLabel, + endDateTitleText: endDateTitleText, + displayFormat: displayFormat, + showClearDates: showClearDates, + showCaret: !withPortal && !withFullScreenPortal && !hideFang, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + customInputIcon: customInputIcon, + customArrowIcon: customArrowIcon, + customCloseIcon: customCloseIcon, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + reopenPickerOnClearDates: reopenPickerOnClearDates, + keepOpenOnDateSelect: keepOpenOnDateSelect, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + minimumNights: minimumNights, + withFullScreenPortal: withFullScreenPortal, + onDatesChange: onDatesChange, + onFocusChange: this.onDateRangePickerInputFocus, + onKeyDownArrowDown: this.onDayPickerFocus, + onKeyDownQuestionMark: this.showKeyboardShortcutsPanel, + onClose: onClose, + phrases: phrases, + screenReaderMessage: screenReaderInputMessage, + isFocused: isDateRangePickerInputFocused, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + autoComplete: autoComplete + }, this.maybeRenderDayPickerWithPortal()); + + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + ref: this.setContainerRef + }, css(styles.DateRangePicker, block && styles.DateRangePicker__block)), enableOutsideClick && /*#__PURE__*/_react["default"].createElement(_reactOutsideClickHandler["default"], { + onOutsideClick: this.onOutsideClick + }, input), enableOutsideClick || input); + }; + + return DateRangePicker; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports.PureDateRangePicker = DateRangePicker; +DateRangePicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePicker.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + zIndex = _ref3$reactDates.zIndex; + return { + DateRangePicker: { + position: 'relative', + display: 'inline-block' + }, + DateRangePicker__block: { + display: 'block' + }, + DateRangePicker_picker: { + zIndex: zIndex + 1, + backgroundColor: color.background, + position: 'absolute' + }, + DateRangePicker_picker__rtl: { + direction: (0, _noflip["default"])('rtl') + }, + DateRangePicker_picker__directionLeft: { + left: (0, _noflip["default"])(0) + }, + DateRangePicker_picker__directionRight: { + right: (0, _noflip["default"])(0) + }, + DateRangePicker_picker__portal: { + backgroundColor: 'rgba(0, 0, 0, 0.3)', + position: 'fixed', + top: 0, + left: (0, _noflip["default"])(0), + height: '100%', + width: '100%' + }, + DateRangePicker_picker__fullScreenPortal: { + backgroundColor: color.background + }, + DateRangePicker_closeButton: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + position: 'absolute', + top: 0, + right: (0, _noflip["default"])(0), + padding: 15, + zIndex: zIndex + 2, + ':hover': { + color: (0, _color2k.darken)(color.core.grayLighter, 0.1), + textDecoration: 'none' + }, + ':focus': { + color: (0, _color2k.darken)(color.core.grayLighter, 0.1), + textDecoration: 'none' + } + }, + DateRangePicker_closeButton_svg: { + height: 15, + width: 15, + fill: color.core.grayLighter + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DateRangePicker); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DateRangePickerInput.js b/lib/components/DateRangePickerInput.js new file mode 100644 index 000000000..40aee9fc4 --- /dev/null +++ b/lib/components/DateRangePickerInput.js @@ -0,0 +1,383 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _OpenDirectionShape = _interopRequireDefault(require("../shapes/OpenDirectionShape")); + +var _DateInput = _interopRequireDefault(require("./DateInput")); + +var _IconPositionShape = _interopRequireDefault(require("../shapes/IconPositionShape")); + +var _DisabledShape = _interopRequireDefault(require("../shapes/DisabledShape")); + +var _RightArrow = _interopRequireDefault(require("./RightArrow")); + +var _LeftArrow = _interopRequireDefault(require("./LeftArrow")); + +var _CloseButton = _interopRequireDefault(require("./CloseButton")); + +var _CalendarIcon = _interopRequireDefault(require("./CalendarIcon")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + children: _propTypes["default"].node, + startDateId: _propTypes["default"].string, + startDatePlaceholderText: _propTypes["default"].string, + startDateAriaLabel: _propTypes["default"].string, + startDateTitleText: _propTypes["default"].string, + screenReaderMessage: _propTypes["default"].string, + endDateId: _propTypes["default"].string, + endDatePlaceholderText: _propTypes["default"].string, + endDateAriaLabel: _propTypes["default"].string, + endDateTitleText: _propTypes["default"].string, + onStartDateFocus: _propTypes["default"].func, + onEndDateFocus: _propTypes["default"].func, + onStartDateChange: _propTypes["default"].func, + onEndDateChange: _propTypes["default"].func, + onStartDateShiftTab: _propTypes["default"].func, + onEndDateTab: _propTypes["default"].func, + onClearDates: _propTypes["default"].func, + onKeyDownArrowDown: _propTypes["default"].func, + onKeyDownQuestionMark: _propTypes["default"].func, + startDate: _propTypes["default"].string, + endDate: _propTypes["default"].string, + isStartDateFocused: _propTypes["default"].bool, + isEndDateFocused: _propTypes["default"].bool, + showClearDates: _propTypes["default"].bool, + disabled: _DisabledShape["default"], + required: _propTypes["default"].bool, + readOnly: _propTypes["default"].bool, + openDirection: _OpenDirectionShape["default"], + showCaret: _propTypes["default"].bool, + showDefaultInputIcon: _propTypes["default"].bool, + inputIconPosition: _IconPositionShape["default"], + customInputIcon: _propTypes["default"].node, + customArrowIcon: _propTypes["default"].node, + customCloseIcon: _propTypes["default"].node, + noBorder: _propTypes["default"].bool, + block: _propTypes["default"].bool, + small: _propTypes["default"].bool, + regular: _propTypes["default"].bool, + verticalSpacing: _airbnbPropTypes.nonNegativeInteger, + autoComplete: _propTypes["default"].string, + // accessibility + isFocused: _propTypes["default"].bool, + // describes actual DOM focus + // i18n + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DateRangePickerInputPhrases)), + isRTL: _propTypes["default"].bool +})) : {}; +var defaultProps = { + children: null, + startDateId: _constants.START_DATE, + endDateId: _constants.END_DATE, + startDatePlaceholderText: 'Start Date', + endDatePlaceholderText: 'End Date', + startDateAriaLabel: undefined, + endDateAriaLabel: undefined, + startDateTitleText: undefined, + endDateTitleText: undefined, + screenReaderMessage: '', + autoComplete: 'off', + onStartDateFocus: function onStartDateFocus() {}, + onEndDateFocus: function onEndDateFocus() {}, + onStartDateChange: function onStartDateChange() {}, + onEndDateChange: function onEndDateChange() {}, + onStartDateShiftTab: function onStartDateShiftTab() {}, + onEndDateTab: function onEndDateTab() {}, + onClearDates: function onClearDates() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + startDate: '', + endDate: '', + isStartDateFocused: false, + isEndDateFocused: false, + showClearDates: false, + disabled: false, + required: false, + readOnly: false, + openDirection: _constants.OPEN_DOWN, + showCaret: false, + showDefaultInputIcon: false, + inputIconPosition: _constants.ICON_BEFORE_POSITION, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + // accessibility + isFocused: false, + // i18n + phrases: _defaultPhrases.DateRangePickerInputPhrases, + isRTL: false +}; + +function DateRangePickerInput(_ref) { + var children = _ref.children, + startDate = _ref.startDate, + startDateId = _ref.startDateId, + startDatePlaceholderText = _ref.startDatePlaceholderText, + screenReaderMessage = _ref.screenReaderMessage, + isStartDateFocused = _ref.isStartDateFocused, + onStartDateChange = _ref.onStartDateChange, + onStartDateFocus = _ref.onStartDateFocus, + onStartDateShiftTab = _ref.onStartDateShiftTab, + startDateAriaLabel = _ref.startDateAriaLabel, + startDateTitleText = _ref.startDateTitleText, + endDate = _ref.endDate, + endDateId = _ref.endDateId, + endDatePlaceholderText = _ref.endDatePlaceholderText, + isEndDateFocused = _ref.isEndDateFocused, + onEndDateChange = _ref.onEndDateChange, + onEndDateFocus = _ref.onEndDateFocus, + onEndDateTab = _ref.onEndDateTab, + endDateAriaLabel = _ref.endDateAriaLabel, + endDateTitleText = _ref.endDateTitleText, + onKeyDownArrowDown = _ref.onKeyDownArrowDown, + onKeyDownQuestionMark = _ref.onKeyDownQuestionMark, + onClearDates = _ref.onClearDates, + showClearDates = _ref.showClearDates, + disabled = _ref.disabled, + required = _ref.required, + readOnly = _ref.readOnly, + autoComplete = _ref.autoComplete, + showCaret = _ref.showCaret, + openDirection = _ref.openDirection, + showDefaultInputIcon = _ref.showDefaultInputIcon, + inputIconPosition = _ref.inputIconPosition, + customInputIcon = _ref.customInputIcon, + customArrowIcon = _ref.customArrowIcon, + customCloseIcon = _ref.customCloseIcon, + isFocused = _ref.isFocused, + phrases = _ref.phrases, + isRTL = _ref.isRTL, + noBorder = _ref.noBorder, + block = _ref.block, + verticalSpacing = _ref.verticalSpacing, + small = _ref.small, + regular = _ref.regular, + css = _ref.css, + styles = _ref.styles; + + var calendarIcon = customInputIcon || /*#__PURE__*/_react["default"].createElement(_CalendarIcon["default"], css(styles.DateRangePickerInput_calendarIcon_svg)); + + var arrowIcon = /*#__PURE__*/_react["default"].createElement(_RightArrow["default"], css(styles.DateRangePickerInput_arrow_svg)); + + if (isRTL) arrowIcon = /*#__PURE__*/_react["default"].createElement(_LeftArrow["default"], css(styles.DateRangePickerInput_arrow_svg)); + if (small) arrowIcon = '-'; + if (customArrowIcon) arrowIcon = customArrowIcon; + + var closeIcon = customCloseIcon || /*#__PURE__*/_react["default"].createElement(_CloseButton["default"], css(styles.DateRangePickerInput_clearDates_svg, small && styles.DateRangePickerInput_clearDates_svg__small)); + + var screenReaderStartDateText = screenReaderMessage || phrases.keyboardForwardNavigationInstructions; + var screenReaderEndDateText = screenReaderMessage || phrases.keyboardBackwardNavigationInstructions; + + var inputIcon = (showDefaultInputIcon || customInputIcon !== null) && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({}, css(styles.DateRangePickerInput_calendarIcon), { + type: "button", + disabled: disabled, + "aria-label": phrases.focusStartDate, + onClick: onKeyDownArrowDown + }), calendarIcon); + + var startDateDisabled = disabled === _constants.START_DATE || disabled === true; + var endDateDisabled = disabled === _constants.END_DATE || disabled === true; + return /*#__PURE__*/_react["default"].createElement("div", css(styles.DateRangePickerInput, disabled && styles.DateRangePickerInput__disabled, isRTL && styles.DateRangePickerInput__rtl, !noBorder && styles.DateRangePickerInput__withBorder, block && styles.DateRangePickerInput__block, showClearDates && styles.DateRangePickerInput__showClearDates), inputIconPosition === _constants.ICON_BEFORE_POSITION && inputIcon, /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: startDateId, + placeholder: startDatePlaceholderText, + ariaLabel: startDateAriaLabel, + autoComplete: autoComplete, + titleText: startDateTitleText, + displayValue: startDate, + screenReaderMessage: screenReaderStartDateText, + focused: isStartDateFocused, + isFocused: isFocused, + disabled: startDateDisabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + openDirection: openDirection, + onChange: onStartDateChange, + onFocus: onStartDateFocus, + onKeyDownShiftTab: onStartDateShiftTab, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + verticalSpacing: verticalSpacing, + small: small, + regular: regular + }), !isEndDateFocused && children, /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DateRangePickerInput_arrow), { + "aria-hidden": "true", + role: "presentation" + }), arrowIcon), /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: endDateId, + placeholder: endDatePlaceholderText, + ariaLabel: endDateAriaLabel, + autoComplete: autoComplete, + titleText: endDateTitleText, + displayValue: endDate, + screenReaderMessage: screenReaderEndDateText, + focused: isEndDateFocused, + isFocused: isFocused, + disabled: endDateDisabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + openDirection: openDirection, + onChange: onEndDateChange, + onFocus: onEndDateFocus, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + onKeyDownTab: onEndDateTab, + verticalSpacing: verticalSpacing, + small: small, + regular: regular + }), isEndDateFocused && children, showClearDates && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({ + type: "button", + "aria-label": phrases.clearDates + }, css(styles.DateRangePickerInput_clearDates, small && styles.DateRangePickerInput_clearDates__small, !customCloseIcon && styles.DateRangePickerInput_clearDates_default, !(startDate || endDate) && styles.DateRangePickerInput_clearDates__hide), { + onClick: onClearDates, + disabled: disabled + }), closeIcon), inputIconPosition === _constants.ICON_AFTER_POSITION && inputIcon); +} + +DateRangePickerInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePickerInput.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref2) { + var _ref2$reactDates = _ref2.reactDates, + border = _ref2$reactDates.border, + color = _ref2$reactDates.color, + sizing = _ref2$reactDates.sizing; + return { + DateRangePickerInput: { + backgroundColor: color.background, + display: 'inline-block' + }, + DateRangePickerInput__disabled: { + background: color.disabled + }, + DateRangePickerInput__withBorder: { + borderColor: color.border, + borderWidth: border.pickerInput.borderWidth, + borderStyle: border.pickerInput.borderStyle, + borderRadius: border.pickerInput.borderRadius + }, + DateRangePickerInput__rtl: { + direction: (0, _noflip["default"])('rtl') + }, + DateRangePickerInput__block: { + display: 'block' + }, + DateRangePickerInput__showClearDates: { + paddingRight: 30 // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + DateRangePickerInput_arrow: { + display: 'inline-block', + verticalAlign: 'middle', + color: color.text + }, + DateRangePickerInput_arrow_svg: { + verticalAlign: 'middle', + fill: color.text, + height: sizing.arrowWidth, + width: sizing.arrowWidth + }, + DateRangePickerInput_clearDates: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + padding: 10, + margin: '0 10px 0 5px', + // TODO: should be noflip wrapped and handled by an isRTL prop + position: 'absolute', + right: 0, + // TODO: should be noflip wrapped and handled by an isRTL prop + top: '50%', + transform: 'translateY(-50%)' + }, + DateRangePickerInput_clearDates__small: { + padding: 6 + }, + DateRangePickerInput_clearDates_default: { + ':focus': { + background: color.core.border, + borderRadius: '50%' + }, + ':hover': { + background: color.core.border, + borderRadius: '50%' + } + }, + DateRangePickerInput_clearDates__hide: { + visibility: 'hidden' + }, + DateRangePickerInput_clearDates_svg: { + fill: color.core.grayLight, + height: 12, + width: 15, + verticalAlign: 'middle' + }, + DateRangePickerInput_clearDates_svg__small: { + height: 9 + }, + DateRangePickerInput_calendarIcon: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + display: 'inline-block', + verticalAlign: 'middle', + padding: 10, + margin: '0 5px 0 10px' // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + DateRangePickerInput_calendarIcon_svg: { + fill: color.core.grayLight, + height: 15, + width: 14, + verticalAlign: 'middle' + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DateRangePickerInput); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DateRangePickerInputController.js b/lib/components/DateRangePickerInputController.js new file mode 100644 index 000000000..d11b12e52 --- /dev/null +++ b/lib/components/DateRangePickerInputController.js @@ -0,0 +1,401 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +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"); + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({ + children: _propTypes["default"].node, + startDate: _reactMomentProptypes["default"].momentObj, + startDateId: _propTypes["default"].string, + startDatePlaceholderText: _propTypes["default"].string, + isStartDateFocused: _propTypes["default"].bool, + startDateAriaLabel: _propTypes["default"].string, + startDateTitleText: _propTypes["default"].string, + endDate: _reactMomentProptypes["default"].momentObj, + endDateId: _propTypes["default"].string, + endDatePlaceholderText: _propTypes["default"].string, + isEndDateFocused: _propTypes["default"].bool, + endDateAriaLabel: _propTypes["default"].string, + endDateTitleText: _propTypes["default"].string, + 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, + autoComplete: _propTypes["default"].string, + keepOpenOnDateSelect: _propTypes["default"].bool, + reopenPickerOnClearDates: _propTypes["default"].bool, + withFullScreenPortal: _propTypes["default"].bool, + minimumNights: _airbnbPropTypes.nonNegativeInteger, + isOutsideRange: _propTypes["default"].func, + isDayBlocked: _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 = { + children: null, + startDate: null, + startDateId: _constants.START_DATE, + startDatePlaceholderText: 'Start Date', + isStartDateFocused: false, + startDateAriaLabel: undefined, + startDateTitleText: undefined, + endDate: null, + endDateId: _constants.END_DATE, + endDatePlaceholderText: 'End Date', + isEndDateFocused: false, + endDateAriaLabel: undefined, + endDateTitleText: undefined, + 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, + autoComplete: 'off', + keepOpenOnDateSelect: false, + reopenPickerOnClearDates: false, + withFullScreenPortal: false, + minimumNights: 1, + isOutsideRange: function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, (0, _moment["default"])()); + }, + isDayBlocked: function isDayBlocked() { + return false; + }, + displayFormat: function displayFormat() { + return _moment["default"].localeData().longDateFormat('L'); + }, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + onDatesChange: function onDatesChange() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + customInputIcon: null, + customArrowIcon: null, + customCloseIcon: null, + // accessibility + isFocused: false, + // i18n + phrases: _defaultPhrases.DateRangePickerInputPhrases, + isRTL: false +}; + +var DateRangePickerInputController = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DateRangePickerInputController, _ref2); + var _proto = DateRangePickerInputController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DateRangePickerInputController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.onClearFocus = _this.onClearFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onStartDateChange = _this.onStartDateChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onStartDateFocus = _this.onStartDateFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onEndDateChange = _this.onEndDateChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onEndDateFocus = _this.onEndDateFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.clearDates = _this.clearDates.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.onClearFocus = 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 + }); + }; + + _proto.onEndDateChange = function onEndDateChange(endDateString) { + var _this$props2 = this.props, + startDate = _this$props2.startDate, + isOutsideRange = _this$props2.isOutsideRange, + isDayBlocked = _this$props2.isDayBlocked, + minimumNights = _this$props2.minimumNights, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + onDatesChange = _this$props2.onDatesChange, + onClose = _this$props2.onClose, + onFocusChange = _this$props2.onFocusChange; + var endDate = (0, _toMomentObject["default"])(endDateString, this.getDisplayFormat()); + var isEndDateValid = endDate && !isOutsideRange(endDate) && !isDayBlocked(endDate) && !(startDate && (0, _isBeforeDay["default"])(endDate, startDate.clone().add(minimumNights, 'days'))); + + if (isEndDateValid) { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (!keepOpenOnDateSelect) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } + } else { + onDatesChange({ + startDate: startDate, + endDate: null + }); + } + }; + + _proto.onEndDateFocus = 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); + } + }; + + _proto.onStartDateChange = function onStartDateChange(startDateString) { + var endDate = this.props.endDate; + var _this$props4 = this.props, + isOutsideRange = _this$props4.isOutsideRange, + isDayBlocked = _this$props4.isDayBlocked, + 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) && !isDayBlocked(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 + }); + } + }; + + _proto.onStartDateFocus = 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); + } + }; + + _proto.getDisplayFormat = function getDisplayFormat() { + var displayFormat = this.props.displayFormat; + return typeof displayFormat === 'string' ? displayFormat : displayFormat(); + }; + + _proto.getDateString = function getDateString(date) { + var displayFormat = this.getDisplayFormat(); + + if (date && displayFormat) { + return date && date.format(displayFormat); + } + + return (0, _toLocalizedDateString["default"])(date); + }; + + _proto.clearDates = 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); + } + }; + + _proto.render = function render() { + var _this$props7 = this.props, + children = _this$props7.children, + startDate = _this$props7.startDate, + startDateId = _this$props7.startDateId, + startDatePlaceholderText = _this$props7.startDatePlaceholderText, + isStartDateFocused = _this$props7.isStartDateFocused, + startDateAriaLabel = _this$props7.startDateAriaLabel, + startDateTitleText = _this$props7.startDateTitleText, + endDate = _this$props7.endDate, + endDateId = _this$props7.endDateId, + endDatePlaceholderText = _this$props7.endDatePlaceholderText, + endDateAriaLabel = _this$props7.endDateAriaLabel, + endDateTitleText = _this$props7.endDateTitleText, + 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, + autoComplete = _this$props7.autoComplete; + var startDateString = this.getDateString(startDate); + var endDateString = this.getDateString(endDate); + return /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + startDate: startDateString, + startDateId: startDateId, + startDatePlaceholderText: startDatePlaceholderText, + isStartDateFocused: isStartDateFocused, + startDateAriaLabel: startDateAriaLabel, + startDateTitleText: startDateTitleText, + endDate: endDateString, + endDateId: endDateId, + endDatePlaceholderText: endDatePlaceholderText, + isEndDateFocused: isEndDateFocused, + endDateAriaLabel: endDateAriaLabel, + endDateTitleText: endDateTitleText, + 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, + showClearDates: showClearDates, + onClearDates: this.clearDates, + screenReaderMessage: screenReaderMessage, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + autoComplete: autoComplete + }, children); + }; + + return DateRangePickerInputController; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports["default"] = DateRangePickerInputController; +DateRangePickerInputController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DateRangePickerInputController.defaultProps = defaultProps; \ No newline at end of file diff --git a/lib/components/DayPicker.js b/lib/components/DayPicker.js new file mode 100644 index 000000000..ca2d71f17 --- /dev/null +++ b/lib/components/DayPicker.js @@ -0,0 +1,1351 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.defaultProps = exports["default"] = exports.PureDayPicker = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _moment = _interopRequireDefault(require("moment")); + +var _throttle = _interopRequireDefault(require("lodash/throttle")); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _reactOutsideClickHandler = _interopRequireDefault(require("react-outside-click-handler")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _CalendarMonthGrid = _interopRequireDefault(require("./CalendarMonthGrid")); + +var _DayPickerNavigation = _interopRequireDefault(require("./DayPickerNavigation")); + +var _DayPickerKeyboardShortcuts = _interopRequireWildcard(require("./DayPickerKeyboardShortcuts")); + +var _getNumberOfCalendarMonthWeeks = _interopRequireDefault(require("../utils/getNumberOfCalendarMonthWeeks")); + +var _getCalendarMonthWidth = _interopRequireDefault(require("../utils/getCalendarMonthWidth")); + +var _calculateDimension = _interopRequireDefault(require("../utils/calculateDimension")); + +var _getActiveElement = _interopRequireDefault(require("../utils/getActiveElement")); + +var _isDayVisible = _interopRequireDefault(require("../utils/isDayVisible")); + +var _isSameMonth = _interopRequireDefault(require("../utils/isSameMonth")); + +var _ModifiersShape = _interopRequireDefault(require("../shapes/ModifiersShape")); + +var _NavPositionShape = _interopRequireDefault(require("../shapes/NavPositionShape")); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape")); + +var _CalendarInfoPositionShape = _interopRequireDefault(require("../shapes/CalendarInfoPositionShape")); + +var _constants = require("../constants"); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var MONTH_PADDING = 23; +var PREV_TRANSITION = 'prev'; +var NEXT_TRANSITION = 'next'; +var MONTH_SELECTION_TRANSITION = 'month_selection'; +var YEAR_SELECTION_TRANSITION = 'year_selection'; +var PREV_NAV = 'prev_nav'; +var NEXT_NAV = 'next_nav'; +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + // calendar presentation props + enableOutsideDays: _propTypes["default"].bool, + numberOfMonths: _propTypes["default"].number, + orientation: _ScrollableOrientationShape["default"], + withPortal: _propTypes["default"].bool, + onOutsideClick: _propTypes["default"].func, + hidden: _propTypes["default"].bool, + initialVisibleMonth: _propTypes["default"].func, + firstDayOfWeek: _DayOfWeekShape["default"], + renderCalendarInfo: _propTypes["default"].func, + calendarInfoPosition: _CalendarInfoPositionShape["default"], + hideKeyboardShortcutsPanel: _propTypes["default"].bool, + daySize: _airbnbPropTypes.nonNegativeInteger, + isRTL: _propTypes["default"].bool, + verticalHeight: _airbnbPropTypes.nonNegativeInteger, + noBorder: _propTypes["default"].bool, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + renderKeyboardShortcutsButton: _propTypes["default"].func, + renderKeyboardShortcutsPanel: _propTypes["default"].func, + // navigation props + dayPickerNavigationInlineStyles: _propTypes["default"].object, + disablePrev: _propTypes["default"].bool, + disableNext: _propTypes["default"].bool, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + noNavButtons: _propTypes["default"].bool, + noNavNextButton: _propTypes["default"].bool, + noNavPrevButton: _propTypes["default"].bool, + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + onMonthChange: _propTypes["default"].func, + onYearChange: _propTypes["default"].func, + onGetNextScrollableMonths: _propTypes["default"].func, + // VERTICAL_SCROLLABLE daypickers only + onGetPrevScrollableMonths: _propTypes["default"].func, + // VERTICAL_SCROLLABLE daypickers only + // month props + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: _propTypes["default"].func, + // day props + modifiers: _propTypes["default"].objectOf(_propTypes["default"].objectOf(_ModifiersShape["default"])), + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + onDayClick: _propTypes["default"].func, + onDayMouseEnter: _propTypes["default"].func, + onDayMouseLeave: _propTypes["default"].func, + // accessibility props + isFocused: _propTypes["default"].bool, + getFirstFocusableDay: _propTypes["default"].func, + onBlur: _propTypes["default"].func, + showKeyboardShortcuts: _propTypes["default"].bool, + onTab: _propTypes["default"].func, + onShiftTab: _propTypes["default"].func, + // internationalization + monthFormat: _propTypes["default"].string, + weekDayFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DayPickerPhrases)), + dayAriaLabelFormat: _propTypes["default"].string +})) : {}; +var defaultProps = { + // calendar presentation props + enableOutsideDays: false, + numberOfMonths: 2, + orientation: _constants.HORIZONTAL_ORIENTATION, + withPortal: false, + onOutsideClick: function onOutsideClick() {}, + hidden: false, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + }, + firstDayOfWeek: null, + renderCalendarInfo: null, + calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: _constants.DAY_SIZE, + isRTL: false, + verticalHeight: null, + noBorder: false, + transitionDuration: undefined, + verticalBorderSpacing: undefined, + horizontalMonthPadding: 13, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined, + // navigation props + dayPickerNavigationInlineStyles: null, + disablePrev: false, + disableNext: false, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onMonthChange: function onMonthChange() {}, + onYearChange: function onYearChange() {}, + onGetNextScrollableMonths: function onGetNextScrollableMonths() {}, + onGetPrevScrollableMonths: function onGetPrevScrollableMonths() {}, + // month props + renderMonthText: null, + renderMonthElement: null, + renderWeekHeaderElement: null, + // day props + modifiers: {}, + renderCalendarDay: undefined, + renderDayContents: null, + onDayClick: function onDayClick() {}, + onDayMouseEnter: function onDayMouseEnter() {}, + onDayMouseLeave: function onDayMouseLeave() {}, + // accessibility props + isFocused: false, + getFirstFocusableDay: null, + onBlur: function onBlur() {}, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // internationalization + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: _defaultPhrases.DayPickerPhrases, + dayAriaLabelFormat: undefined +}; +exports.defaultProps = defaultProps; + +var DayPicker = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DayPicker, _ref2); + var _proto = DayPicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DayPicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + var currentMonth = props.hidden ? (0, _moment["default"])() : props.initialVisibleMonth(); + var focusedDate = currentMonth.clone().startOf('month').hour(12); + + if (props.getFirstFocusableDay) { + focusedDate = props.getFirstFocusableDay(currentMonth); + } + + var horizontalMonthPadding = props.horizontalMonthPadding; + var translationValue = props.isRTL && _this.isHorizontal() ? -(0, _getCalendarMonthWidth["default"])(props.daySize, horizontalMonthPadding) : 0; + _this.hasSetInitialVisibleMonth = !props.hidden; + _this.state = { + currentMonthScrollTop: null, + currentMonth: currentMonth, + monthTransition: null, + translationValue: translationValue, + scrollableMonthMultiple: 1, + calendarMonthWidth: (0, _getCalendarMonthWidth["default"])(props.daySize, horizontalMonthPadding), + focusedDate: !props.hidden || props.isFocused ? focusedDate : null, + nextFocusedDate: null, + showKeyboardShortcuts: props.showKeyboardShortcuts, + onKeyboardShortcutsPanelClose: function onKeyboardShortcutsPanelClose() {}, + isTouchDevice: (0, _isTouchDevice["default"])(), + withMouseInteractions: true, + calendarInfoWidth: 0, + monthTitleHeight: null, + hasSetHeight: false + }; + + _this.setCalendarMonthWeeks(currentMonth); + + _this.calendarMonthGridHeight = 0; + _this.setCalendarInfoWidthTimeout = null; + _this.setCalendarMonthGridHeightTimeout = null; + _this.onKeyDown = _this.onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)); + _this.throttledKeyDown = (0, _throttle["default"])(_this.onFinalKeyDown, 200, { + trailing: false + }); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onPrevMonthTransition = _this.onPrevMonthTransition.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onNextMonthTransition = _this.onNextMonthTransition.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onMonthChange = _this.onMonthChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onYearChange = _this.onYearChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.getNextScrollableMonths = _this.getNextScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.getPrevScrollableMonths = _this.getPrevScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.updateStateAfterMonthTransition = _this.updateStateAfterMonthTransition.bind((0, _assertThisInitialized2["default"])(_this)); + _this.openKeyboardShortcutsPanel = _this.openKeyboardShortcutsPanel.bind((0, _assertThisInitialized2["default"])(_this)); + _this.closeKeyboardShortcutsPanel = _this.closeKeyboardShortcutsPanel.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setCalendarInfoRef = _this.setCalendarInfoRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setContainerRef = _this.setContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setTransitionContainerRef = _this.setTransitionContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setMonthTitleHeight = _this.setMonthTitleHeight.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + var orientation = this.props.orientation; + var currentMonth = this.state.currentMonth; + var calendarInfoWidth = this.calendarInfo ? (0, _calculateDimension["default"])(this.calendarInfo, 'width', true, true) : 0; + var currentMonthScrollTop = this.transitionContainer && orientation === _constants.VERTICAL_SCROLLABLE ? this.transitionContainer.scrollHeight - this.transitionContainer.scrollTop : null; + this.setState({ + isTouchDevice: (0, _isTouchDevice["default"])(), + calendarInfoWidth: calendarInfoWidth, + currentMonthScrollTop: currentMonthScrollTop + }); + this.setCalendarMonthWeeks(currentMonth); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps, nextState) { + var hidden = nextProps.hidden, + isFocused = nextProps.isFocused, + showKeyboardShortcuts = nextProps.showKeyboardShortcuts, + onBlur = nextProps.onBlur, + orientation = nextProps.orientation, + renderMonthText = nextProps.renderMonthText, + horizontalMonthPadding = nextProps.horizontalMonthPadding; + var currentMonth = this.state.currentMonth; + var nextCurrentMonth = nextState.currentMonth; + + if (!hidden) { + if (!this.hasSetInitialVisibleMonth) { + this.hasSetInitialVisibleMonth = true; + this.setState({ + currentMonth: nextProps.initialVisibleMonth() + }); + } else { + var numberOfMonths = this.props.numberOfMonths; + var newDate = nextProps.initialVisibleMonth(); + + if (!(0, _isDayVisible["default"])(newDate, currentMonth, numberOfMonths)) { + this.onMonthChange(newDate); + } + } + } + + var _this$props = this.props, + daySize = _this$props.daySize, + prevIsFocused = _this$props.isFocused, + prevRenderMonthText = _this$props.renderMonthText; + + if (nextProps.daySize !== daySize) { + this.setState({ + calendarMonthWidth: (0, _getCalendarMonthWidth["default"])(nextProps.daySize, horizontalMonthPadding) + }); + } + + if (isFocused !== prevIsFocused) { + if (isFocused) { + var focusedDate = this.getFocusedDay(currentMonth); + var onKeyboardShortcutsPanelClose = this.state.onKeyboardShortcutsPanelClose; + + if (nextProps.showKeyboardShortcuts) { + // the ? shortcut came from the input and we should return input there once it is close + onKeyboardShortcutsPanelClose = onBlur; + } + + this.setState({ + showKeyboardShortcuts: showKeyboardShortcuts, + onKeyboardShortcutsPanelClose: onKeyboardShortcutsPanelClose, + focusedDate: focusedDate, + withMouseInteractions: false + }); + } else { + this.setState({ + focusedDate: null + }); + } + } + + if (renderMonthText !== null && prevRenderMonthText !== null && renderMonthText(currentMonth) !== prevRenderMonthText(currentMonth)) { + this.setState({ + monthTitleHeight: null + }); + } // Capture the scroll position so when previous months are rendered above the current month + // we can adjust scroll after the component has updated and the previous current month + // stays in view. + + + if (orientation === _constants.VERTICAL_SCROLLABLE && this.transitionContainer && !(0, _isSameMonth["default"])(currentMonth, nextCurrentMonth)) { + this.setState({ + currentMonthScrollTop: this.transitionContainer.scrollHeight - this.transitionContainer.scrollTop + }); + } + }; + + _proto.componentWillUpdate = function componentWillUpdate() { + var _this2 = this; + + var transitionDuration = this.props.transitionDuration; // Calculating the dimensions trigger a DOM repaint which + // breaks the CSS transition. + // The setTimeout will wait until the transition ends. + + if (this.calendarInfo) { + this.setCalendarInfoWidthTimeout = setTimeout(function () { + var calendarInfoWidth = _this2.state.calendarInfoWidth; + var calendarInfoPanelWidth = (0, _calculateDimension["default"])(_this2.calendarInfo, 'width', true, true); + + if (calendarInfoWidth !== calendarInfoPanelWidth) { + _this2.setState({ + calendarInfoWidth: calendarInfoPanelWidth + }); + } + }, transitionDuration); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { + var _this$props2 = this.props, + orientation = _this$props2.orientation, + daySize = _this$props2.daySize, + isFocused = _this$props2.isFocused, + numberOfMonths = _this$props2.numberOfMonths; + var _this$state = this.state, + currentMonth = _this$state.currentMonth, + currentMonthScrollTop = _this$state.currentMonthScrollTop, + focusedDate = _this$state.focusedDate, + monthTitleHeight = _this$state.monthTitleHeight; + var shouldAdjustHeight = false; + + if (numberOfMonths !== prevProps.numberOfMonths) { + this.setCalendarMonthWeeks(currentMonth); + shouldAdjustHeight = true; + } + + if (this.isHorizontal() && (orientation !== prevProps.orientation || daySize !== prevProps.daySize)) { + shouldAdjustHeight = true; + } + + if (shouldAdjustHeight) { + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1); + var calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat((0, _toConsumableArray2["default"])(visibleCalendarWeeks))) * (daySize - 1); + var newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + if (!prevProps.isFocused && isFocused && !focusedDate) { + this.container.focus(); + } // If orientation is VERTICAL_SCROLLABLE and currentMonth has changed adjust scrollTop so the + // new months rendered above the current month don't push the current month out of view. + + + if (orientation === _constants.VERTICAL_SCROLLABLE && !(0, _isSameMonth["default"])(prevState.currentMonth, currentMonth) && currentMonthScrollTop && this.transitionContainer) { + this.transitionContainer.scrollTop = this.transitionContainer.scrollHeight - currentMonthScrollTop; + } + }; + + _proto.componentWillUnmount = function componentWillUnmount() { + clearTimeout(this.setCalendarInfoWidthTimeout); + clearTimeout(this.setCalendarMonthGridHeightTimeout); + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + + if (!_constants.MODIFIER_KEY_NAMES.has(e.key)) { + this.throttledKeyDown(e); + } + }; + + _proto.onFinalKeyDown = function onFinalKeyDown(e) { + this.setState({ + withMouseInteractions: false + }); + var _this$props3 = this.props, + onBlur = _this$props3.onBlur, + onTab = _this$props3.onTab, + onShiftTab = _this$props3.onShiftTab, + isRTL = _this$props3.isRTL; + var _this$state2 = this.state, + focusedDate = _this$state2.focusedDate, + showKeyboardShortcuts = _this$state2.showKeyboardShortcuts; + if (!focusedDate) return; + var newFocusedDate = focusedDate.clone(); + var didTransitionMonth = false; // focus might be anywhere when the keyboard shortcuts panel is opened so we want to + // return it to wherever it was before when the panel was opened + + var activeElement = (0, _getActiveElement["default"])(); + + var onKeyboardShortcutsPanelClose = function onKeyboardShortcutsPanelClose() { + if (activeElement) activeElement.focus(); + }; + + switch (e.key) { + case 'ArrowUp': + e.preventDefault(); + newFocusedDate.subtract(1, 'week'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'ArrowLeft': + e.preventDefault(); + + if (isRTL) { + newFocusedDate.add(1, 'day'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + } else { + newFocusedDate.subtract(1, 'day'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + } + + break; + + case 'Home': + e.preventDefault(); + newFocusedDate.startOf('week').hour(12); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'PageUp': + e.preventDefault(); + newFocusedDate.subtract(1, 'month'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + break; + + case 'ArrowDown': + e.preventDefault(); + newFocusedDate.add(1, 'week'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case 'ArrowRight': + e.preventDefault(); + + if (isRTL) { + newFocusedDate.subtract(1, 'day'); + didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate); + } else { + newFocusedDate.add(1, 'day'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + } + + break; + + case 'End': + e.preventDefault(); + newFocusedDate.endOf('week'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case 'PageDown': + e.preventDefault(); + newFocusedDate.add(1, 'month'); + didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate); + break; + + case '?': + this.openKeyboardShortcutsPanel(onKeyboardShortcutsPanelClose); + break; + + case 'Escape': + if (showKeyboardShortcuts) { + this.closeKeyboardShortcutsPanel(); + } else { + onBlur(e); + } + + break; + + case 'Tab': + if (e.shiftKey) { + onShiftTab(); + } else { + onTab(e); + } + + break; + + default: + break; + } // If there was a month transition, do not update the focused date until the transition has + // completed. Otherwise, attempting to focus on a DOM node may interrupt the CSS animation. If + // didTransitionMonth is true, the focusedDate gets updated in #updateStateAfterMonthTransition + + + if (!didTransitionMonth) { + this.setState({ + focusedDate: newFocusedDate + }); + } + }; + + _proto.onPrevMonthClick = function onPrevMonthClick(e) { + if (e) e.preventDefault(); + this.onPrevMonthTransition(); + }; + + _proto.onPrevMonthTransition = function onPrevMonthTransition(nextFocusedDate) { + var _this$props4 = this.props, + daySize = _this$props4.daySize, + isRTL = _this$props4.isRTL, + numberOfMonths = _this$props4.numberOfMonths; + var _this$state3 = this.state, + calendarMonthWidth = _this$state3.calendarMonthWidth, + monthTitleHeight = _this$state3.monthTitleHeight; + var translationValue; + + if (this.isVertical()) { + var calendarMonthWeeksHeight = this.calendarMonthWeeks[0] * (daySize - 1); + translationValue = monthTitleHeight + calendarMonthWeeksHeight + 1; + } else if (this.isHorizontal()) { + translationValue = calendarMonthWidth; + + if (isRTL) { + translationValue = -2 * calendarMonthWidth; + } + + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(0, numberOfMonths); + + var _calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat((0, _toConsumableArray2["default"])(visibleCalendarWeeks))) * (daySize - 1); + + var newMonthHeight = monthTitleHeight + _calendarMonthWeeksHeight + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + this.setState({ + monthTransition: PREV_TRANSITION, + translationValue: translationValue, + focusedDate: null, + nextFocusedDate: nextFocusedDate + }); + }; + + _proto.onMonthChange = function onMonthChange(currentMonth) { + this.setCalendarMonthWeeks(currentMonth); + this.calculateAndSetDayPickerHeight(); // Translation value is a hack to force an invisible transition that + // properly rerenders the CalendarMonthGrid + + this.setState({ + monthTransition: MONTH_SELECTION_TRANSITION, + translationValue: 0.00001, + focusedDate: null, + nextFocusedDate: currentMonth, + currentMonth: currentMonth + }); + }; + + _proto.onYearChange = function onYearChange(currentMonth) { + this.setCalendarMonthWeeks(currentMonth); + this.calculateAndSetDayPickerHeight(); // Translation value is a hack to force an invisible transition that + // properly rerenders the CalendarMonthGrid + + this.setState({ + monthTransition: YEAR_SELECTION_TRANSITION, + translationValue: 0.0001, + focusedDate: null, + nextFocusedDate: currentMonth, + currentMonth: currentMonth + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick(e) { + if (e) e.preventDefault(); + this.onNextMonthTransition(); + }; + + _proto.onNextMonthTransition = function onNextMonthTransition(nextFocusedDate) { + var _this$props5 = this.props, + isRTL = _this$props5.isRTL, + numberOfMonths = _this$props5.numberOfMonths, + daySize = _this$props5.daySize; + var _this$state4 = this.state, + calendarMonthWidth = _this$state4.calendarMonthWidth, + monthTitleHeight = _this$state4.monthTitleHeight; + var translationValue; + + if (this.isVertical()) { + var firstVisibleMonthWeeks = this.calendarMonthWeeks[1]; + var calendarMonthWeeksHeight = firstVisibleMonthWeeks * (daySize - 1); + translationValue = -(monthTitleHeight + calendarMonthWeeksHeight + 1); + } + + if (this.isHorizontal()) { + translationValue = -calendarMonthWidth; + + if (isRTL) { + translationValue = 0; + } + + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(2, numberOfMonths + 2); + + var _calendarMonthWeeksHeight2 = Math.max.apply(Math, [0].concat((0, _toConsumableArray2["default"])(visibleCalendarWeeks))) * (daySize - 1); + + var newMonthHeight = monthTitleHeight + _calendarMonthWeeksHeight2 + 1; + this.adjustDayPickerHeight(newMonthHeight); + } + + this.setState({ + monthTransition: NEXT_TRANSITION, + translationValue: translationValue, + focusedDate: null, + nextFocusedDate: nextFocusedDate + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return _moment["default"].localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getWeekHeaders = function getWeekHeaders() { + var weekDayFormat = this.props.weekDayFormat; + var currentMonth = this.state.currentMonth; + var firstDayOfWeek = this.getFirstDayOfWeek(); + var weekHeaders = []; + + for (var i = 0; i < 7; i += 1) { + weekHeaders.push(currentMonth.clone().day((i + firstDayOfWeek) % 7).format(weekDayFormat)); + } + + return weekHeaders; + }; + + _proto.getFirstVisibleIndex = function getFirstVisibleIndex() { + var orientation = this.props.orientation; + var monthTransition = this.state.monthTransition; + if (orientation === _constants.VERTICAL_SCROLLABLE) return 0; + var firstVisibleMonthIndex = 1; + + if (monthTransition === PREV_TRANSITION) { + firstVisibleMonthIndex -= 1; + } else if (monthTransition === NEXT_TRANSITION) { + firstVisibleMonthIndex += 1; + } + + return firstVisibleMonthIndex; + }; + + _proto.getFocusedDay = function getFocusedDay(newMonth) { + var _this$props6 = this.props, + getFirstFocusableDay = _this$props6.getFirstFocusableDay, + numberOfMonths = _this$props6.numberOfMonths; + var focusedDate; + + if (getFirstFocusableDay) { + focusedDate = getFirstFocusableDay(newMonth); + } + + if (newMonth && (!focusedDate || !(0, _isDayVisible["default"])(focusedDate, newMonth, numberOfMonths))) { + focusedDate = newMonth.clone().startOf('month').hour(12); + } + + return focusedDate; + }; + + _proto.setMonthTitleHeight = function setMonthTitleHeight(monthTitleHeight) { + var _this3 = this; + + this.setState({ + monthTitleHeight: monthTitleHeight + }, function () { + _this3.calculateAndSetDayPickerHeight(); + }); + }; + + _proto.setCalendarMonthWeeks = function setCalendarMonthWeeks(currentMonth) { + var numberOfMonths = this.props.numberOfMonths; + this.calendarMonthWeeks = []; + var month = currentMonth.clone().subtract(1, 'months'); + var firstDayOfWeek = this.getFirstDayOfWeek(); + + for (var i = 0; i < numberOfMonths + 2; i += 1) { + var numberOfWeeks = (0, _getNumberOfCalendarMonthWeeks["default"])(month, firstDayOfWeek); + this.calendarMonthWeeks.push(numberOfWeeks); + month = month.add(1, 'months'); + } + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.setCalendarInfoRef = function setCalendarInfoRef(ref) { + this.calendarInfo = ref; + }; + + _proto.setTransitionContainerRef = function setTransitionContainerRef(ref) { + this.transitionContainer = ref; + }; + + _proto.getNextScrollableMonths = function getNextScrollableMonths(e) { + var onGetNextScrollableMonths = this.props.onGetNextScrollableMonths; + if (e) e.preventDefault(); + if (onGetNextScrollableMonths) onGetNextScrollableMonths(e); + this.setState(function (_ref3) { + var scrollableMonthMultiple = _ref3.scrollableMonthMultiple; + return { + scrollableMonthMultiple: scrollableMonthMultiple + 1 + }; + }); + }; + + _proto.getPrevScrollableMonths = function getPrevScrollableMonths(e) { + var _this$props7 = this.props, + numberOfMonths = _this$props7.numberOfMonths, + onGetPrevScrollableMonths = _this$props7.onGetPrevScrollableMonths; + if (e) e.preventDefault(); + if (onGetPrevScrollableMonths) onGetPrevScrollableMonths(e); + this.setState(function (_ref4) { + var currentMonth = _ref4.currentMonth, + scrollableMonthMultiple = _ref4.scrollableMonthMultiple; + return { + currentMonth: currentMonth.clone().subtract(numberOfMonths, 'month'), + scrollableMonthMultiple: scrollableMonthMultiple + 1 + }; + }); + }; + + _proto.maybeTransitionNextMonth = function maybeTransitionNextMonth(newFocusedDate) { + var numberOfMonths = this.props.numberOfMonths; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + focusedDate = _this$state5.focusedDate; + var newFocusedDateMonth = newFocusedDate.month(); + var focusedDateMonth = focusedDate.month(); + var isNewFocusedDateVisible = (0, _isDayVisible["default"])(newFocusedDate, currentMonth, numberOfMonths); + + if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) { + this.onNextMonthTransition(newFocusedDate); + return true; + } + + return false; + }; + + _proto.maybeTransitionPrevMonth = function maybeTransitionPrevMonth(newFocusedDate) { + var numberOfMonths = this.props.numberOfMonths; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + focusedDate = _this$state6.focusedDate; + var newFocusedDateMonth = newFocusedDate.month(); + var focusedDateMonth = focusedDate.month(); + var isNewFocusedDateVisible = (0, _isDayVisible["default"])(newFocusedDate, currentMonth, numberOfMonths); + + if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) { + this.onPrevMonthTransition(newFocusedDate); + return true; + } + + return false; + }; + + _proto.isHorizontal = function isHorizontal() { + var orientation = this.props.orientation; + return orientation === _constants.HORIZONTAL_ORIENTATION; + }; + + _proto.isVertical = function isVertical() { + var orientation = this.props.orientation; + return orientation === _constants.VERTICAL_ORIENTATION || orientation === _constants.VERTICAL_SCROLLABLE; + }; + + _proto.updateStateAfterMonthTransition = function updateStateAfterMonthTransition() { + var _this4 = this; + + var _this$props8 = this.props, + onPrevMonthClick = _this$props8.onPrevMonthClick, + onNextMonthClick = _this$props8.onNextMonthClick, + numberOfMonths = _this$props8.numberOfMonths, + onMonthChange = _this$props8.onMonthChange, + onYearChange = _this$props8.onYearChange, + isRTL = _this$props8.isRTL; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + monthTransition = _this$state7.monthTransition, + focusedDate = _this$state7.focusedDate, + nextFocusedDate = _this$state7.nextFocusedDate, + withMouseInteractions = _this$state7.withMouseInteractions, + calendarMonthWidth = _this$state7.calendarMonthWidth; + if (!monthTransition) return; + var newMonth = currentMonth.clone(); + var firstDayOfWeek = this.getFirstDayOfWeek(); + + if (monthTransition === PREV_TRANSITION) { + newMonth.subtract(1, 'month'); + if (onPrevMonthClick) onPrevMonthClick(newMonth); + var newInvisibleMonth = newMonth.clone().subtract(1, 'month'); + var numberOfWeeks = (0, _getNumberOfCalendarMonthWeeks["default"])(newInvisibleMonth, firstDayOfWeek); + this.calendarMonthWeeks = [numberOfWeeks].concat((0, _toConsumableArray2["default"])(this.calendarMonthWeeks.slice(0, -1))); + } else if (monthTransition === NEXT_TRANSITION) { + newMonth.add(1, 'month'); + if (onNextMonthClick) onNextMonthClick(newMonth); + + var _newInvisibleMonth = newMonth.clone().add(numberOfMonths, 'month'); + + var _numberOfWeeks = (0, _getNumberOfCalendarMonthWeeks["default"])(_newInvisibleMonth, firstDayOfWeek); + + this.calendarMonthWeeks = [].concat((0, _toConsumableArray2["default"])(this.calendarMonthWeeks.slice(1)), [_numberOfWeeks]); + } else if (monthTransition === MONTH_SELECTION_TRANSITION) { + if (onMonthChange) onMonthChange(newMonth); + } else if (monthTransition === YEAR_SELECTION_TRANSITION) { + if (onYearChange) onYearChange(newMonth); + } + + var newFocusedDate = null; + + if (nextFocusedDate) { + newFocusedDate = nextFocusedDate; + } else if (!focusedDate && !withMouseInteractions) { + newFocusedDate = this.getFocusedDay(newMonth); + } + + this.setState({ + currentMonth: newMonth, + monthTransition: null, + translationValue: isRTL && this.isHorizontal() ? -calendarMonthWidth : 0, + nextFocusedDate: null, + focusedDate: newFocusedDate + }, function () { + // we don't want to focus on the relevant calendar day after a month transition + // if the user is navigating around using a mouse + if (withMouseInteractions) { + var activeElement = (0, _getActiveElement["default"])(); + + if (activeElement && activeElement !== document.body && _this4.container.contains(activeElement) && activeElement.blur) { + activeElement.blur(); + } + } + }); + }; + + _proto.adjustDayPickerHeight = function adjustDayPickerHeight(newMonthHeight) { + var _this5 = this; + + var monthHeight = newMonthHeight + MONTH_PADDING; + + if (monthHeight !== this.calendarMonthGridHeight) { + this.transitionContainer.style.height = "".concat(monthHeight, "px"); + + if (!this.calendarMonthGridHeight) { + this.setCalendarMonthGridHeightTimeout = setTimeout(function () { + _this5.setState({ + hasSetHeight: true + }); + }, 0); + } + + this.calendarMonthGridHeight = monthHeight; + } + }; + + _proto.calculateAndSetDayPickerHeight = function calculateAndSetDayPickerHeight() { + var _this$props9 = this.props, + daySize = _this$props9.daySize, + numberOfMonths = _this$props9.numberOfMonths; + var monthTitleHeight = this.state.monthTitleHeight; + var visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1); + var calendarMonthWeeksHeight = Math.max.apply(Math, [0].concat((0, _toConsumableArray2["default"])(visibleCalendarWeeks))) * (daySize - 1); + var newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1; + + if (this.isHorizontal()) { + this.adjustDayPickerHeight(newMonthHeight); + } + }; + + _proto.openKeyboardShortcutsPanel = function openKeyboardShortcutsPanel(onCloseCallBack) { + this.setState({ + showKeyboardShortcuts: true, + onKeyboardShortcutsPanelClose: onCloseCallBack + }); + }; + + _proto.closeKeyboardShortcutsPanel = function closeKeyboardShortcutsPanel() { + var onKeyboardShortcutsPanelClose = this.state.onKeyboardShortcutsPanelClose; + + if (onKeyboardShortcutsPanelClose) { + onKeyboardShortcutsPanelClose(); + } + + this.setState({ + onKeyboardShortcutsPanelClose: null, + showKeyboardShortcuts: false + }); + }; + + _proto.renderNavigation = function renderNavigation(navDirection) { + var _this$props10 = this.props, + dayPickerNavigationInlineStyles = _this$props10.dayPickerNavigationInlineStyles, + disablePrev = _this$props10.disablePrev, + disableNext = _this$props10.disableNext, + navPosition = _this$props10.navPosition, + navPrev = _this$props10.navPrev, + navNext = _this$props10.navNext, + noNavButtons = _this$props10.noNavButtons, + noNavNextButton = _this$props10.noNavNextButton, + noNavPrevButton = _this$props10.noNavPrevButton, + orientation = _this$props10.orientation, + phrases = _this$props10.phrases, + renderNavPrevButton = _this$props10.renderNavPrevButton, + renderNavNextButton = _this$props10.renderNavNextButton, + isRTL = _this$props10.isRTL; + + if (noNavButtons) { + return null; + } + + var onPrevMonthClick = orientation === _constants.VERTICAL_SCROLLABLE ? this.getPrevScrollableMonths : this.onPrevMonthClick; + var onNextMonthClick = orientation === _constants.VERTICAL_SCROLLABLE ? this.getNextScrollableMonths : this.onNextMonthClick; + return /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + disablePrev: disablePrev, + disableNext: disableNext, + inlineStyles: dayPickerNavigationInlineStyles, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + orientation: orientation, + phrases: phrases, + isRTL: isRTL, + showNavNextButton: !(noNavNextButton || orientation === _constants.VERTICAL_SCROLLABLE && navDirection === PREV_NAV), + showNavPrevButton: !(noNavPrevButton || orientation === _constants.VERTICAL_SCROLLABLE && navDirection === NEXT_NAV) + }); + }; + + _proto.renderWeekHeader = function renderWeekHeader(index) { + var _this$props11 = this.props, + daySize = _this$props11.daySize, + horizontalMonthPadding = _this$props11.horizontalMonthPadding, + orientation = _this$props11.orientation, + renderWeekHeaderElement = _this$props11.renderWeekHeaderElement, + css = _this$props11.css, + styles = _this$props11.styles; + var calendarMonthWidth = this.state.calendarMonthWidth; + var verticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE; + var horizontalStyle = { + left: index * calendarMonthWidth + }; + var verticalStyle = { + marginLeft: -calendarMonthWidth / 2 + }; + var weekHeaderStyle = {}; // no styles applied to the vertical-scrollable orientation + + if (this.isHorizontal()) { + weekHeaderStyle = horizontalStyle; + } else if (this.isVertical() && !verticalScrollable) { + weekHeaderStyle = verticalStyle; + } + + var weekHeaders = this.getWeekHeaders(); + var header = weekHeaders.map(function (day) { + return /*#__PURE__*/_react["default"].createElement("li", (0, _extends2["default"])({ + key: day + }, css(styles.DayPicker_weekHeader_li, { + width: daySize + })), renderWeekHeaderElement ? renderWeekHeaderElement(day) : /*#__PURE__*/_react["default"].createElement("small", null, day)); + }); + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPicker_weekHeader, this.isVertical() && styles.DayPicker_weekHeader__vertical, verticalScrollable && styles.DayPicker_weekHeader__verticalScrollable, weekHeaderStyle, { + padding: "0 ".concat(horizontalMonthPadding, "px") + }), { + key: "week-".concat(index) + }), /*#__PURE__*/_react["default"].createElement("ul", css(styles.DayPicker_weekHeader_ul), header)); + }; + + _proto.render = function render() { + var _this6 = this; + + var _this$state8 = this.state, + calendarMonthWidth = _this$state8.calendarMonthWidth, + currentMonth = _this$state8.currentMonth, + monthTransition = _this$state8.monthTransition, + translationValue = _this$state8.translationValue, + scrollableMonthMultiple = _this$state8.scrollableMonthMultiple, + focusedDate = _this$state8.focusedDate, + showKeyboardShortcuts = _this$state8.showKeyboardShortcuts, + isTouch = _this$state8.isTouchDevice, + hasSetHeight = _this$state8.hasSetHeight, + calendarInfoWidth = _this$state8.calendarInfoWidth, + monthTitleHeight = _this$state8.monthTitleHeight; + var _this$props12 = this.props, + enableOutsideDays = _this$props12.enableOutsideDays, + numberOfMonths = _this$props12.numberOfMonths, + orientation = _this$props12.orientation, + modifiers = _this$props12.modifiers, + withPortal = _this$props12.withPortal, + onDayClick = _this$props12.onDayClick, + onDayMouseEnter = _this$props12.onDayMouseEnter, + onDayMouseLeave = _this$props12.onDayMouseLeave, + firstDayOfWeek = _this$props12.firstDayOfWeek, + renderMonthText = _this$props12.renderMonthText, + renderCalendarDay = _this$props12.renderCalendarDay, + renderDayContents = _this$props12.renderDayContents, + renderCalendarInfo = _this$props12.renderCalendarInfo, + renderMonthElement = _this$props12.renderMonthElement, + renderKeyboardShortcutsButton = _this$props12.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props12.renderKeyboardShortcutsPanel, + calendarInfoPosition = _this$props12.calendarInfoPosition, + hideKeyboardShortcutsPanel = _this$props12.hideKeyboardShortcutsPanel, + onOutsideClick = _this$props12.onOutsideClick, + monthFormat = _this$props12.monthFormat, + daySize = _this$props12.daySize, + isFocused = _this$props12.isFocused, + isRTL = _this$props12.isRTL, + css = _this$props12.css, + styles = _this$props12.styles, + theme = _this$props12.theme, + phrases = _this$props12.phrases, + verticalHeight = _this$props12.verticalHeight, + dayAriaLabelFormat = _this$props12.dayAriaLabelFormat, + noBorder = _this$props12.noBorder, + transitionDuration = _this$props12.transitionDuration, + verticalBorderSpacing = _this$props12.verticalBorderSpacing, + horizontalMonthPadding = _this$props12.horizontalMonthPadding, + navPosition = _this$props12.navPosition; + var dayPickerHorizontalPadding = theme.reactDates.spacing.dayPickerHorizontalPadding; + var isHorizontal = this.isHorizontal(); + var numOfWeekHeaders = this.isVertical() ? 1 : numberOfMonths; + var weekHeaders = []; + + for (var i = 0; i < numOfWeekHeaders; i += 1) { + weekHeaders.push(this.renderWeekHeader(i)); + } + + var verticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE; + var height; + + if (isHorizontal) { + height = this.calendarMonthGridHeight; + } else if (this.isVertical() && !verticalScrollable && !withPortal) { + // If the user doesn't set a desired height, + // we default back to this kind of made-up value that generally looks good + height = verticalHeight || 1.75 * calendarMonthWidth; + } + + var isCalendarMonthGridAnimating = monthTransition !== null; + var shouldFocusDate = !isCalendarMonthGridAnimating && isFocused; + var keyboardShortcutButtonLocation = _DayPickerKeyboardShortcuts.BOTTOM_RIGHT; + + if (this.isVertical()) { + keyboardShortcutButtonLocation = withPortal ? _DayPickerKeyboardShortcuts.TOP_LEFT : _DayPickerKeyboardShortcuts.TOP_RIGHT; + } + + var shouldAnimateHeight = isHorizontal && hasSetHeight; + var calendarInfoPositionTop = calendarInfoPosition === _constants.INFO_POSITION_TOP; + var calendarInfoPositionBottom = calendarInfoPosition === _constants.INFO_POSITION_BOTTOM; + var calendarInfoPositionBefore = calendarInfoPosition === _constants.INFO_POSITION_BEFORE; + var calendarInfoPositionAfter = calendarInfoPosition === _constants.INFO_POSITION_AFTER; + var calendarInfoIsInline = calendarInfoPositionBefore || calendarInfoPositionAfter; + + var calendarInfo = renderCalendarInfo && /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + ref: this.setCalendarInfoRef + }, css(calendarInfoIsInline && styles.DayPicker_calendarInfo__horizontal)), renderCalendarInfo()); + + var calendarInfoPanelWidth = renderCalendarInfo && calendarInfoIsInline ? calendarInfoWidth : 0; + var firstVisibleMonthIndex = this.getFirstVisibleIndex(); + var wrapperHorizontalWidth = calendarMonthWidth * numberOfMonths + 2 * dayPickerHorizontalPadding; // Adding `1px` because of whitespace between 2 inline-block + + var fullHorizontalWidth = wrapperHorizontalWidth + calendarInfoPanelWidth + 1; + var transitionContainerStyle = { + width: isHorizontal && wrapperHorizontalWidth, + height: height + }; + var dayPickerWrapperStyle = { + width: isHorizontal && wrapperHorizontalWidth + }; + var dayPickerStyle = { + width: isHorizontal && fullHorizontalWidth, + // These values are to center the datepicker (approximately) on the page + marginLeft: isHorizontal && withPortal ? -fullHorizontalWidth / 2 : null, + marginTop: isHorizontal && withPortal ? -calendarMonthWidth / 2 : null + }; + return /*#__PURE__*/_react["default"].createElement("div", css(styles.DayPicker, isHorizontal && styles.DayPicker__horizontal, verticalScrollable && styles.DayPicker__verticalScrollable, isHorizontal && withPortal && styles.DayPicker_portal__horizontal, this.isVertical() && withPortal && styles.DayPicker_portal__vertical, dayPickerStyle, !monthTitleHeight && styles.DayPicker__hidden, !noBorder && styles.DayPicker__withBorder), /*#__PURE__*/_react["default"].createElement(_reactOutsideClickHandler["default"], { + onOutsideClick: onOutsideClick + }, (calendarInfoPositionTop || calendarInfoPositionBefore) && calendarInfo, /*#__PURE__*/_react["default"].createElement("div", css(dayPickerWrapperStyle, calendarInfoIsInline && isHorizontal && styles.DayPicker_wrapper__horizontal), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPicker_weekHeaders, isHorizontal && styles.DayPicker_weekHeaders__horizontal), { + "aria-hidden": "true", + role: "presentation" + }), weekHeaders), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPicker_focusRegion), { + ref: this.setContainerRef, + onClick: function onClick(e) { + e.stopPropagation(); + }, + onKeyDown: this.onKeyDown, + onMouseUp: function onMouseUp() { + _this6.setState({ + withMouseInteractions: true + }); + }, + tabIndex: -1, + role: "application", + "aria-roledescription": phrases.roleDescription, + "aria-label": phrases.calendarLabel + }), !verticalScrollable && navPosition === _constants.NAV_POSITION_TOP && this.renderNavigation(), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPicker_transitionContainer, shouldAnimateHeight && styles.DayPicker_transitionContainer__horizontal, this.isVertical() && styles.DayPicker_transitionContainer__vertical, verticalScrollable && styles.DayPicker_transitionContainer__verticalScrollable, transitionContainerStyle), { + ref: this.setTransitionContainerRef + }), verticalScrollable && this.renderNavigation(PREV_NAV), /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + setMonthTitleHeight: !monthTitleHeight ? this.setMonthTitleHeight : undefined, + translationValue: translationValue, + enableOutsideDays: enableOutsideDays, + firstVisibleMonthIndex: firstVisibleMonthIndex, + initialMonth: currentMonth, + isAnimating: isCalendarMonthGridAnimating, + modifiers: modifiers, + orientation: orientation, + numberOfMonths: numberOfMonths * scrollableMonthMultiple, + onDayClick: onDayClick, + onDayMouseEnter: onDayMouseEnter, + onDayMouseLeave: onDayMouseLeave, + onMonthChange: this.onMonthChange, + onYearChange: this.onYearChange, + renderMonthText: renderMonthText, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderMonthElement: renderMonthElement, + onMonthTransitionEnd: this.updateStateAfterMonthTransition, + monthFormat: monthFormat, + daySize: daySize, + firstDayOfWeek: firstDayOfWeek, + isFocused: shouldFocusDate, + focusedDate: focusedDate, + phrases: phrases, + isRTL: isRTL, + dayAriaLabelFormat: dayAriaLabelFormat, + transitionDuration: transitionDuration, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + }), verticalScrollable && this.renderNavigation(NEXT_NAV)), !verticalScrollable && navPosition === _constants.NAV_POSITION_BOTTOM && this.renderNavigation(), !isTouch && !hideKeyboardShortcutsPanel && /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + block: this.isVertical() && !withPortal, + buttonLocation: keyboardShortcutButtonLocation, + showKeyboardShortcutsPanel: showKeyboardShortcuts, + openKeyboardShortcutsPanel: this.openKeyboardShortcutsPanel, + closeKeyboardShortcutsPanel: this.closeKeyboardShortcutsPanel, + phrases: phrases, + renderKeyboardShortcutsButton: renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel: renderKeyboardShortcutsPanel + }))), (calendarInfoPositionBottom || calendarInfoPositionAfter) && calendarInfo)); + }; + + return DayPicker; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports.PureDayPicker = DayPicker; +DayPicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPicker.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref5) { + var _ref5$reactDates = _ref5.reactDates, + color = _ref5$reactDates.color, + font = _ref5$reactDates.font, + noScrollBarOnVerticalScrollable = _ref5$reactDates.noScrollBarOnVerticalScrollable, + spacing = _ref5$reactDates.spacing, + zIndex = _ref5$reactDates.zIndex; + return { + DayPicker: { + background: color.background, + position: 'relative', + textAlign: (0, _noflip["default"])('left') + }, + DayPicker__horizontal: { + background: color.background + }, + DayPicker__verticalScrollable: { + height: '100%' + }, + DayPicker__hidden: { + visibility: 'hidden' + }, + DayPicker__withBorder: { + boxShadow: (0, _noflip["default"])('0 2px 6px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.07)'), + borderRadius: 3 + }, + DayPicker_portal__horizontal: { + boxShadow: 'none', + position: 'absolute', + left: (0, _noflip["default"])('50%'), + top: '50%' + }, + DayPicker_portal__vertical: { + position: 'initial' + }, + DayPicker_focusRegion: { + outline: 'none' + }, + DayPicker_calendarInfo__horizontal: { + display: 'inline-block', + verticalAlign: 'top' + }, + DayPicker_wrapper__horizontal: { + display: 'inline-block', + verticalAlign: 'top' + }, + DayPicker_weekHeaders: { + position: 'relative' + }, + DayPicker_weekHeaders__horizontal: { + marginLeft: (0, _noflip["default"])(spacing.dayPickerHorizontalPadding) + }, + DayPicker_weekHeader: { + color: color.placeholderText, + position: 'absolute', + top: 62, + zIndex: zIndex + 2, + textAlign: (0, _noflip["default"])('left') + }, + DayPicker_weekHeader__vertical: { + left: (0, _noflip["default"])('50%') + }, + DayPicker_weekHeader__verticalScrollable: { + top: 0, + display: 'table-row', + borderBottom: "1px solid ".concat(color.core.border), + background: color.background, + marginLeft: (0, _noflip["default"])(0), + left: (0, _noflip["default"])(0), + width: '100%', + textAlign: 'center' + }, + DayPicker_weekHeader_ul: { + listStyle: 'none', + margin: '1px 0', + paddingLeft: (0, _noflip["default"])(0), + paddingRight: (0, _noflip["default"])(0), + fontSize: font.size + }, + DayPicker_weekHeader_li: { + display: 'inline-block', + textAlign: 'center' + }, + DayPicker_transitionContainer: { + position: 'relative', + overflow: 'hidden', + borderRadius: 3 + }, + DayPicker_transitionContainer__horizontal: { + transition: 'height 0.2s ease-in-out' + }, + DayPicker_transitionContainer__vertical: { + width: '100%' + }, + DayPicker_transitionContainer__verticalScrollable: _objectSpread({ + paddingTop: 20, + height: '100%', + position: 'absolute', + top: 0, + bottom: 0, + right: (0, _noflip["default"])(0), + left: (0, _noflip["default"])(0), + overflowY: 'scroll' + }, noScrollBarOnVerticalScrollable && { + '-webkitOverflowScrolling': 'touch', + '::-webkit-scrollbar': { + '-webkit-appearance': 'none', + display: 'none' + } + }) + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DayPicker); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DayPickerKeyboardShortcuts.js b/lib/components/DayPickerKeyboardShortcuts.js new file mode 100644 index 000000000..c4002c40c --- /dev/null +++ b/lib/components/DayPickerKeyboardShortcuts.js @@ -0,0 +1,407 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.TOP_RIGHT = exports.TOP_LEFT = exports.BOTTOM_RIGHT = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _KeyboardShortcutRow = _interopRequireDefault(require("./KeyboardShortcutRow")); + +var _CloseButton = _interopRequireDefault(require("./CloseButton")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var TOP_LEFT = 'top-left'; +exports.TOP_LEFT = TOP_LEFT; +var TOP_RIGHT = 'top-right'; +exports.TOP_RIGHT = TOP_RIGHT; +var BOTTOM_RIGHT = 'bottom-right'; +exports.BOTTOM_RIGHT = BOTTOM_RIGHT; +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + block: _propTypes["default"].bool, + // TODO: rename button location to be direction-agnostic + buttonLocation: _propTypes["default"].oneOf([TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT]), + showKeyboardShortcutsPanel: _propTypes["default"].bool, + openKeyboardShortcutsPanel: _propTypes["default"].func, + closeKeyboardShortcutsPanel: _propTypes["default"].func, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DayPickerKeyboardShortcutsPhrases)), + renderKeyboardShortcutsButton: _propTypes["default"].func, + renderKeyboardShortcutsPanel: _propTypes["default"].func +})) : {}; +var defaultProps = { + block: false, + buttonLocation: BOTTOM_RIGHT, + showKeyboardShortcutsPanel: false, + openKeyboardShortcutsPanel: function openKeyboardShortcutsPanel() {}, + closeKeyboardShortcutsPanel: function closeKeyboardShortcutsPanel() {}, + phrases: _defaultPhrases.DayPickerKeyboardShortcutsPhrases, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined +}; + +function getKeyboardShortcuts(phrases) { + return [{ + unicode: '↵', + label: phrases.enterKey, + action: phrases.selectFocusedDate + }, { + unicode: '←/→', + label: phrases.leftArrowRightArrow, + action: phrases.moveFocusByOneDay + }, { + unicode: '↑/↓', + label: phrases.upArrowDownArrow, + action: phrases.moveFocusByOneWeek + }, { + unicode: 'PgUp/PgDn', + label: phrases.pageUpPageDown, + action: phrases.moveFocusByOneMonth + }, { + unicode: 'Home/End', + label: phrases.homeEnd, + action: phrases.moveFocustoStartAndEndOfWeek + }, { + unicode: 'Esc', + label: phrases.escape, + action: phrases.returnFocusToInput + }, { + unicode: '?', + label: phrases.questionMark, + action: phrases.openThisPanel + }]; +} + +var DayPickerKeyboardShortcuts = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DayPickerKeyboardShortcuts, _ref2); + var _proto = DayPickerKeyboardShortcuts.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DayPickerKeyboardShortcuts() { + var _this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + _this = _ref2.call.apply(_ref2, [this].concat(args)) || this; + var phrases = _this.props.phrases; + _this.keyboardShortcuts = getKeyboardShortcuts(phrases); + _this.onShowKeyboardShortcutsButtonClick = _this.onShowKeyboardShortcutsButtonClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setShowKeyboardShortcutsButtonRef = _this.setShowKeyboardShortcutsButtonRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setHideKeyboardShortcutsButtonRef = _this.setHideKeyboardShortcutsButtonRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.handleFocus = _this.handleFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onKeyDown = _this.onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var phrases = this.props.phrases; + + if (nextProps.phrases !== phrases) { + this.keyboardShortcuts = getKeyboardShortcuts(nextProps.phrases); + } + }; + + _proto.componentDidUpdate = function componentDidUpdate() { + this.handleFocus(); + }; + + _proto.handleFocus = function handleFocus() { + if (this.hideKeyboardShortcutsButton) { + // automatically move focus into the dialog by moving + // to the only interactive element, the hide button + this.hideKeyboardShortcutsButton.focus(); + } + }; + + _proto.onKeyDown = function onKeyDown(e) { + e.stopPropagation(); + var closeKeyboardShortcutsPanel = this.props.closeKeyboardShortcutsPanel; // Because the close button is the only focusable element inside of the panel, this + // amounts to a very basic focus trap. The user can exit the panel by "pressing" the + // close button or hitting escape + + switch (e.key) { + case 'Escape': + closeKeyboardShortcutsPanel(); + break; + // do nothing - this allows the up and down arrows continue their + // default behavior of scrolling the content of the Keyboard Shortcuts Panel + // which is needed when only a single month is shown for instance. + + case 'ArrowUp': + case 'ArrowDown': + break; + // completely block the rest of the keys that have functionality outside of this panel + + case 'Tab': + case 'Home': + case 'End': + case 'PageUp': + case 'PageDown': + case 'ArrowLeft': + case 'ArrowRight': + e.preventDefault(); + break; + + default: + break; + } + }; + + _proto.onShowKeyboardShortcutsButtonClick = function onShowKeyboardShortcutsButtonClick() { + var _this2 = this; + + var openKeyboardShortcutsPanel = this.props.openKeyboardShortcutsPanel; // we want to return focus to this button after closing the keyboard shortcuts panel + + openKeyboardShortcutsPanel(function () { + _this2.showKeyboardShortcutsButton.focus(); + }); + }; + + _proto.setShowKeyboardShortcutsButtonRef = function setShowKeyboardShortcutsButtonRef(ref) { + this.showKeyboardShortcutsButton = ref; + }; + + _proto.setHideKeyboardShortcutsButtonRef = function setHideKeyboardShortcutsButtonRef(ref) { + this.hideKeyboardShortcutsButton = ref; + }; + + _proto.render = function render() { + var _this$props = this.props, + block = _this$props.block, + buttonLocation = _this$props.buttonLocation, + showKeyboardShortcutsPanel = _this$props.showKeyboardShortcutsPanel, + closeKeyboardShortcutsPanel = _this$props.closeKeyboardShortcutsPanel, + css = _this$props.css, + styles = _this$props.styles, + phrases = _this$props.phrases, + renderKeyboardShortcutsButton = _this$props.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props.renderKeyboardShortcutsPanel; + var toggleButtonText = showKeyboardShortcutsPanel ? phrases.hideKeyboardShortcutsPanel : phrases.showKeyboardShortcutsPanel; + var bottomRight = buttonLocation === BOTTOM_RIGHT; + var topRight = buttonLocation === TOP_RIGHT; + var topLeft = buttonLocation === TOP_LEFT; + return /*#__PURE__*/_react["default"].createElement("div", null, renderKeyboardShortcutsButton && renderKeyboardShortcutsButton({ + // passing in context-specific props + ref: this.setShowKeyboardShortcutsButtonRef, + onClick: this.onShowKeyboardShortcutsButtonClick, + ariaLabel: toggleButtonText + }), !renderKeyboardShortcutsButton && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({ + ref: this.setShowKeyboardShortcutsButtonRef + }, css(styles.DayPickerKeyboardShortcuts_buttonReset, styles.DayPickerKeyboardShortcuts_show, bottomRight && styles.DayPickerKeyboardShortcuts_show__bottomRight, topRight && styles.DayPickerKeyboardShortcuts_show__topRight, topLeft && styles.DayPickerKeyboardShortcuts_show__topLeft), { + type: "button", + "aria-label": toggleButtonText, + onClick: this.onShowKeyboardShortcutsButtonClick, + onMouseUp: function onMouseUp(e) { + e.currentTarget.blur(); + } + }), /*#__PURE__*/_react["default"].createElement("span", css(styles.DayPickerKeyboardShortcuts_showSpan, bottomRight && styles.DayPickerKeyboardShortcuts_showSpan__bottomRight, topRight && styles.DayPickerKeyboardShortcuts_showSpan__topRight, topLeft && styles.DayPickerKeyboardShortcuts_showSpan__topLeft), "?")), showKeyboardShortcutsPanel && (renderKeyboardShortcutsPanel ? renderKeyboardShortcutsPanel({ + closeButtonAriaLabel: phrases.hideKeyboardShortcutsPanel, + keyboardShortcuts: this.keyboardShortcuts, + onCloseButtonClick: closeKeyboardShortcutsPanel, + onKeyDown: this.onKeyDown, + title: phrases.keyboardShortcuts + }) : /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPickerKeyboardShortcuts_panel), { + role: "dialog", + "aria-labelledby": "DayPickerKeyboardShortcuts_title", + "aria-describedby": "DayPickerKeyboardShortcuts_description" + }), /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({}, css(styles.DayPickerKeyboardShortcuts_title), { + id: "DayPickerKeyboardShortcuts_title" + }), phrases.keyboardShortcuts), /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({ + ref: this.setHideKeyboardShortcutsButtonRef + }, css(styles.DayPickerKeyboardShortcuts_buttonReset, styles.DayPickerKeyboardShortcuts_close), { + type: "button", + tabIndex: "0", + "aria-label": phrases.hideKeyboardShortcutsPanel, + onClick: closeKeyboardShortcutsPanel, + onKeyDown: this.onKeyDown + }), /*#__PURE__*/_react["default"].createElement(_CloseButton["default"], css(styles.DayPickerKeyboardShortcuts_closeSvg))), /*#__PURE__*/_react["default"].createElement("ul", (0, _extends2["default"])({}, css(styles.DayPickerKeyboardShortcuts_list), { + id: "DayPickerKeyboardShortcuts_description" + }), this.keyboardShortcuts.map(function (_ref3) { + var unicode = _ref3.unicode, + label = _ref3.label, + action = _ref3.action; + return /*#__PURE__*/_react["default"].createElement(_KeyboardShortcutRow["default"], { + key: label, + unicode: unicode, + label: label, + action: action, + block: block + }); + }))))); + }; + + return DayPickerKeyboardShortcuts; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +DayPickerKeyboardShortcuts.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerKeyboardShortcuts.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref4) { + var _ref4$reactDates = _ref4.reactDates, + color = _ref4$reactDates.color, + font = _ref4$reactDates.font, + zIndex = _ref4$reactDates.zIndex; + return { + DayPickerKeyboardShortcuts_buttonReset: { + background: 'none', + border: 0, + borderRadius: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + padding: 0, + cursor: 'pointer', + fontSize: font.size, + ':active': { + outline: 'none' + } + }, + DayPickerKeyboardShortcuts_show: { + width: 33, + height: 26, + position: 'absolute', + zIndex: zIndex + 2, + '::before': { + content: '""', + display: 'block', + position: 'absolute' + } + }, + DayPickerKeyboardShortcuts_show__bottomRight: { + bottom: 0, + right: 0, + '::before': { + borderTop: '26px solid transparent', + borderRight: "33px solid ".concat(color.core.primary), + bottom: 0, + right: 0 + }, + ':hover::before': { + borderRight: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_show__topRight: { + top: 0, + right: 0, + '::before': { + borderBottom: '26px solid transparent', + borderRight: "33px solid ".concat(color.core.primary), + top: 0, + right: 0 + }, + ':hover::before': { + borderRight: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_show__topLeft: { + top: 0, + left: 0, + '::before': { + borderBottom: '26px solid transparent', + borderLeft: "33px solid ".concat(color.core.primary), + top: 0, + left: 0 + }, + ':hover::before': { + borderLeft: "33px solid ".concat(color.core.primary_dark) + } + }, + DayPickerKeyboardShortcuts_showSpan: { + color: color.core.white, + position: 'absolute' + }, + DayPickerKeyboardShortcuts_showSpan__bottomRight: { + bottom: 0, + right: 5 + }, + DayPickerKeyboardShortcuts_showSpan__topRight: { + top: 1, + right: 5 + }, + DayPickerKeyboardShortcuts_showSpan__topLeft: { + top: 1, + left: 5 + }, + DayPickerKeyboardShortcuts_panel: { + overflow: 'auto', + background: color.background, + border: "1px solid ".concat(color.core.border), + borderRadius: 2, + position: 'absolute', + top: 0, + bottom: 0, + right: 0, + left: 0, + zIndex: zIndex + 2, + padding: 22, + margin: 33, + textAlign: 'left' // TODO: investigate use of text-align throughout the library + + }, + DayPickerKeyboardShortcuts_title: { + fontSize: 16, + fontWeight: 'bold', + margin: 0 + }, + DayPickerKeyboardShortcuts_list: { + listStyle: 'none', + padding: 0, + fontSize: font.size + }, + DayPickerKeyboardShortcuts_close: { + position: 'absolute', + right: 22, + top: 22, + zIndex: zIndex + 2, + ':active': { + outline: 'none' + } + }, + DayPickerKeyboardShortcuts_closeSvg: { + height: 15, + width: 15, + fill: color.core.grayLighter, + ':hover': { + fill: color.core.grayLight + }, + ':focus': { + fill: color.core.grayLight + } + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DayPickerKeyboardShortcuts); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DayPickerNavigation.js b/lib/components/DayPickerNavigation.js new file mode 100644 index 000000000..f2ddbaa08 --- /dev/null +++ b/lib/components/DayPickerNavigation.js @@ -0,0 +1,369 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _LeftArrow = _interopRequireDefault(require("./LeftArrow")); + +var _RightArrow = _interopRequireDefault(require("./RightArrow")); + +var _ChevronUp = _interopRequireDefault(require("./ChevronUp")); + +var _ChevronDown = _interopRequireDefault(require("./ChevronDown")); + +var _NavPositionShape = _interopRequireDefault(require("../shapes/NavPositionShape")); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + disablePrev: _propTypes["default"].bool, + disableNext: _propTypes["default"].bool, + inlineStyles: _propTypes["default"].object, + isRTL: _propTypes["default"].bool, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + orientation: _ScrollableOrientationShape["default"], + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + // internationalization + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DayPickerNavigationPhrases)), + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + showNavPrevButton: _propTypes["default"].bool, + showNavNextButton: _propTypes["default"].bool +})) : {}; +var defaultProps = { + disablePrev: false, + disableNext: false, + inlineStyles: null, + isRTL: false, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + orientation: _constants.HORIZONTAL_ORIENTATION, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + // internationalization + phrases: _defaultPhrases.DayPickerNavigationPhrases, + renderNavPrevButton: null, + renderNavNextButton: null, + showNavPrevButton: true, + showNavNextButton: true +}; + +var DayPickerNavigation = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DayPickerNavigation, _ref2); + + function DayPickerNavigation() { + return _ref2.apply(this, arguments) || this; + } + + var _proto = DayPickerNavigation.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + _proto.render = function render() { + var _this$props = this.props, + inlineStyles = _this$props.inlineStyles, + isRTL = _this$props.isRTL, + disablePrev = _this$props.disablePrev, + disableNext = _this$props.disableNext, + navPosition = _this$props.navPosition, + navPrev = _this$props.navPrev, + navNext = _this$props.navNext, + onPrevMonthClick = _this$props.onPrevMonthClick, + onNextMonthClick = _this$props.onNextMonthClick, + orientation = _this$props.orientation, + phrases = _this$props.phrases, + renderNavPrevButton = _this$props.renderNavPrevButton, + renderNavNextButton = _this$props.renderNavNextButton, + showNavPrevButton = _this$props.showNavPrevButton, + showNavNextButton = _this$props.showNavNextButton, + css = _this$props.css, + styles = _this$props.styles; + + if (!showNavNextButton && !showNavPrevButton) { + return null; + } + + var isHorizontal = orientation === _constants.HORIZONTAL_ORIENTATION; + var isVertical = orientation !== _constants.HORIZONTAL_ORIENTATION; + var isVerticalScrollable = orientation === _constants.VERTICAL_SCROLLABLE; + var isBottomNavPosition = navPosition === _constants.NAV_POSITION_BOTTOM; + var hasInlineStyles = !!inlineStyles; + var navPrevIcon = navPrev; + var navNextIcon = navNext; + var isDefaultNavPrev = false; + var isDefaultNavNext = false; + var navPrevTabIndex = {}; + var navNextTabIndex = {}; + + if (!navPrevIcon && !renderNavPrevButton && showNavPrevButton) { + navPrevTabIndex = { + tabIndex: '0' + }; + isDefaultNavPrev = true; + var Icon = isVertical ? _ChevronUp["default"] : _LeftArrow["default"]; + + if (isRTL && !isVertical) { + Icon = _RightArrow["default"]; + } + + navPrevIcon = /*#__PURE__*/_react["default"].createElement(Icon, css(isHorizontal && styles.DayPickerNavigation_svg__horizontal, isVertical && styles.DayPickerNavigation_svg__vertical, disablePrev && styles.DayPickerNavigation_svg__disabled)); + } + + if (!navNextIcon && !renderNavNextButton && showNavNextButton) { + navNextTabIndex = { + tabIndex: '0' + }; + isDefaultNavNext = true; + + var _Icon = isVertical ? _ChevronDown["default"] : _RightArrow["default"]; + + if (isRTL && !isVertical) { + _Icon = _LeftArrow["default"]; + } + + navNextIcon = /*#__PURE__*/_react["default"].createElement(_Icon, css(isHorizontal && styles.DayPickerNavigation_svg__horizontal, isVertical && styles.DayPickerNavigation_svg__vertical, disableNext && styles.DayPickerNavigation_svg__disabled)); + } + + var isDefaultNav = isDefaultNavNext || isDefaultNavPrev; + return /*#__PURE__*/_react["default"].createElement("div", css.apply(void 0, [styles.DayPickerNavigation, isHorizontal && styles.DayPickerNavigation__horizontal].concat((0, _toConsumableArray2["default"])(isVertical ? [styles.DayPickerNavigation__vertical, isDefaultNav && styles.DayPickerNavigation__verticalDefault] : []), (0, _toConsumableArray2["default"])(isVerticalScrollable ? [styles.DayPickerNavigation__verticalScrollable, isDefaultNav && styles.DayPickerNavigation__verticalScrollableDefault, showNavPrevButton && styles.DayPickerNavigation__verticalScrollable_prevNav] : []), (0, _toConsumableArray2["default"])(isBottomNavPosition ? [styles.DayPickerNavigation__bottom, isDefaultNav && styles.DayPickerNavigation__bottomDefault] : []), [hasInlineStyles && inlineStyles])), showNavPrevButton && (renderNavPrevButton ? renderNavPrevButton({ + ariaLabel: phrases.jumpToPrevMonth, + disabled: disablePrev, + onClick: disablePrev ? undefined : onPrevMonthClick, + onKeyUp: disablePrev ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onPrevMonthClick(e); + } + }, + onMouseUp: disablePrev ? undefined : function (e) { + e.currentTarget.blur(); + } + }) : /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + // eslint-disable-line jsx-a11y/interactive-supports-focus + role: "button" + }, navPrevTabIndex, css.apply(void 0, [styles.DayPickerNavigation_button, isDefaultNavPrev && styles.DayPickerNavigation_button__default, disablePrev && styles.DayPickerNavigation_button__disabled].concat((0, _toConsumableArray2["default"])(isHorizontal ? [styles.DayPickerNavigation_button__horizontal].concat((0, _toConsumableArray2["default"])(isDefaultNavPrev ? [styles.DayPickerNavigation_button__horizontalDefault, isBottomNavPosition && styles.DayPickerNavigation_bottomButton__horizontalDefault, !isRTL && styles.DayPickerNavigation_leftButton__horizontalDefault, isRTL && styles.DayPickerNavigation_rightButton__horizontalDefault] : [])) : []), (0, _toConsumableArray2["default"])(isVertical ? [styles.DayPickerNavigation_button__vertical].concat((0, _toConsumableArray2["default"])(isDefaultNavPrev ? [styles.DayPickerNavigation_button__verticalDefault, styles.DayPickerNavigation_prevButton__verticalDefault, isVerticalScrollable && styles.DayPickerNavigation_prevButton__verticalScrollableDefault] : [])) : []))), { + "aria-disabled": disablePrev ? true : undefined, + "aria-label": phrases.jumpToPrevMonth, + onClick: disablePrev ? undefined : onPrevMonthClick, + onKeyUp: disablePrev ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onPrevMonthClick(e); + } + }, + onMouseUp: disablePrev ? undefined : function (e) { + e.currentTarget.blur(); + } + }), navPrevIcon)), showNavNextButton && (renderNavNextButton ? renderNavNextButton({ + ariaLabel: phrases.jumpToNextMonth, + disabled: disableNext, + onClick: disableNext ? undefined : onNextMonthClick, + onKeyUp: disableNext ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onNextMonthClick(e); + } + }, + onMouseUp: disableNext ? undefined : function (e) { + e.currentTarget.blur(); + } + }) : /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + // eslint-disable-line jsx-a11y/interactive-supports-focus + role: "button" + }, navNextTabIndex, css.apply(void 0, [styles.DayPickerNavigation_button, isDefaultNavNext && styles.DayPickerNavigation_button__default, disableNext && styles.DayPickerNavigation_button__disabled].concat((0, _toConsumableArray2["default"])(isHorizontal ? [styles.DayPickerNavigation_button__horizontal].concat((0, _toConsumableArray2["default"])(isDefaultNavNext ? [styles.DayPickerNavigation_button__horizontalDefault, isBottomNavPosition && styles.DayPickerNavigation_bottomButton__horizontalDefault, isRTL && styles.DayPickerNavigation_leftButton__horizontalDefault, !isRTL && styles.DayPickerNavigation_rightButton__horizontalDefault] : [])) : []), (0, _toConsumableArray2["default"])(isVertical ? [styles.DayPickerNavigation_button__vertical].concat((0, _toConsumableArray2["default"])(isDefaultNavNext ? [styles.DayPickerNavigation_button__verticalDefault, styles.DayPickerNavigation_nextButton__verticalDefault, isVerticalScrollable && styles.DayPickerNavigation_nextButton__verticalScrollableDefault] : [])) : []))), { + "aria-disabled": disableNext ? true : undefined, + "aria-label": phrases.jumpToNextMonth, + onClick: disableNext ? undefined : onNextMonthClick, + onKeyUp: disableNext ? undefined : function (e) { + var key = e.key; + + if (key === 'Enter' || key === ' ') { + onNextMonthClick(e); + } + }, + onMouseUp: disableNext ? undefined : function (e) { + e.currentTarget.blur(); + } + }), navNextIcon))); + }; + + return DayPickerNavigation; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +DayPickerNavigation.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerNavigation.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref3) { + var _ref3$reactDates = _ref3.reactDates, + color = _ref3$reactDates.color, + zIndex = _ref3$reactDates.zIndex; + return { + DayPickerNavigation: { + position: 'relative', + zIndex: zIndex + 2 + }, + DayPickerNavigation__horizontal: { + height: 0 + }, + DayPickerNavigation__vertical: {}, + DayPickerNavigation__verticalScrollable: {}, + DayPickerNavigation__verticalScrollable_prevNav: { + zIndex: zIndex + 1 // zIndex + 2 causes the button to show on top of the day of week headers + + }, + DayPickerNavigation__verticalDefault: { + position: 'absolute', + width: '100%', + height: 52, + bottom: 0, + left: (0, _noflip["default"])(0) + }, + DayPickerNavigation__verticalScrollableDefault: { + position: 'relative' + }, + DayPickerNavigation__bottom: { + height: 'auto' + }, + DayPickerNavigation__bottomDefault: { + display: 'flex', + justifyContent: 'space-between' + }, + DayPickerNavigation_button: { + cursor: 'pointer', + userSelect: 'none', + border: 0, + padding: 0, + margin: 0 + }, + DayPickerNavigation_button__default: { + border: "1px solid ".concat(color.core.borderLight), + backgroundColor: color.background, + color: color.placeholderText, + ':focus': { + border: "1px solid ".concat(color.core.borderMedium) + }, + ':hover': { + border: "1px solid ".concat(color.core.borderMedium) + }, + ':active': { + background: color.backgroundDark + } + }, + DayPickerNavigation_button__disabled: { + cursor: 'default', + border: "1px solid ".concat(color.disabled), + ':focus': { + border: "1px solid ".concat(color.disabled) + }, + ':hover': { + border: "1px solid ".concat(color.disabled) + }, + ':active': { + background: 'none' + } + }, + DayPickerNavigation_button__horizontal: {}, + DayPickerNavigation_button__horizontalDefault: { + position: 'absolute', + top: 18, + lineHeight: 0.78, + borderRadius: 3, + padding: '6px 9px' + }, + DayPickerNavigation_bottomButton__horizontalDefault: { + position: 'static', + marginLeft: 22, + marginRight: 22, + marginBottom: 30, + marginTop: -10 + }, + DayPickerNavigation_leftButton__horizontalDefault: { + left: (0, _noflip["default"])(22) + }, + DayPickerNavigation_rightButton__horizontalDefault: { + right: (0, _noflip["default"])(22) + }, + DayPickerNavigation_button__vertical: {}, + DayPickerNavigation_button__verticalDefault: { + padding: 5, + background: color.background, + boxShadow: (0, _noflip["default"])('0 0 5px 2px rgba(0, 0, 0, 0.1)'), + position: 'relative', + display: 'inline-block', + textAlign: 'center', + height: '100%', + width: '50%' + }, + DayPickerNavigation_prevButton__verticalDefault: {}, + DayPickerNavigation_nextButton__verticalDefault: { + borderLeft: (0, _noflip["default"])(0) + }, + DayPickerNavigation_nextButton__verticalScrollableDefault: { + width: '100%' + }, + DayPickerNavigation_prevButton__verticalScrollableDefault: { + width: '100%' + }, + DayPickerNavigation_svg__horizontal: { + height: 19, + width: 19, + fill: color.core.grayLight, + display: 'block' + }, + DayPickerNavigation_svg__vertical: { + height: 42, + width: 42, + fill: color.text + }, + DayPickerNavigation_svg__disabled: { + fill: color.disabled + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(DayPickerNavigation); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/DayPickerRangeController.js b/lib/components/DayPickerRangeController.js new file mode 100644 index 000000000..a2b758183 --- /dev/null +++ b/lib/components/DayPickerRangeController.js @@ -0,0 +1,1457 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _moment = _interopRequireDefault(require("moment")); + +var _object = _interopRequireDefault(require("object.values")); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("../utils/isInclusivelyAfterDay")); + +var _isNextDay = _interopRequireDefault(require("../utils/isNextDay")); + +var _isSameDay = _interopRequireDefault(require("../utils/isSameDay")); + +var _isAfterDay = _interopRequireDefault(require("../utils/isAfterDay")); + +var _isBeforeDay = _interopRequireDefault(require("../utils/isBeforeDay")); + +var _isPreviousDay = _interopRequireDefault(require("../utils/isPreviousDay")); + +var _getVisibleDays = _interopRequireDefault(require("../utils/getVisibleDays")); + +var _isDayVisible = _interopRequireDefault(require("../utils/isDayVisible")); + +var _getSelectedDateOffset = _interopRequireDefault(require("../utils/getSelectedDateOffset")); + +var _enumrateDatesBetween = _interopRequireDefault(require("../utils/enumrateDatesBetween")); + +var _toISODateString = _interopRequireDefault(require("../utils/toISODateString")); + +var _modifiers = require("../utils/modifiers"); + +var _DisabledShape = _interopRequireDefault(require("../shapes/DisabledShape")); + +var _FocusedInputShape = _interopRequireDefault(require("../shapes/FocusedInputShape")); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape")); + +var _CalendarInfoPositionShape = _interopRequireDefault(require("../shapes/CalendarInfoPositionShape")); + +var _NavPositionShape = _interopRequireDefault(require("../shapes/NavPositionShape")); + +var _constants = require("../constants"); + +var _DayPicker = _interopRequireDefault(require("./DayPicker")); + +var _getPooledMoment = _interopRequireDefault(require("../utils/getPooledMoment")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({ + startDate: _reactMomentProptypes["default"].momentObj, + endDate: _reactMomentProptypes["default"].momentObj, + onDatesChange: _propTypes["default"].func, + startDateOffset: _propTypes["default"].func, + endDateOffset: _propTypes["default"].func, + minDate: _reactMomentProptypes["default"].momentObj, + maxDate: _reactMomentProptypes["default"].momentObj, + focusedInput: _FocusedInputShape["default"], + onFocusChange: _propTypes["default"].func, + onClose: _propTypes["default"].func, + keepOpenOnDateSelect: _propTypes["default"].bool, + minimumNights: _propTypes["default"].number, + disabled: _DisabledShape["default"], + isOutsideRange: _propTypes["default"].func, + isDayBlocked: _propTypes["default"].func, + isDayHighlighted: _propTypes["default"].func, + getMinNightsForHoverDate: _propTypes["default"].func, + daysViolatingMinNightsCanBeClicked: _propTypes["default"].bool, + moveOffsetForDisabledDates: _propTypes["default"].bool, + // DayPicker props + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: _propTypes["default"].func, + enableOutsideDays: _propTypes["default"].bool, + numberOfMonths: _propTypes["default"].number, + orientation: _ScrollableOrientationShape["default"], + withPortal: _propTypes["default"].bool, + initialVisibleMonth: _propTypes["default"].func, + hideKeyboardShortcutsPanel: _propTypes["default"].bool, + daySize: _airbnbPropTypes.nonNegativeInteger, + noBorder: _propTypes["default"].bool, + verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + dayPickerNavigationInlineStyles: _propTypes["default"].object, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + noNavButtons: _propTypes["default"].bool, + noNavNextButton: _propTypes["default"].bool, + noNavPrevButton: _propTypes["default"].bool, + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + onOutsideClick: _propTypes["default"].func, + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + renderCalendarInfo: _propTypes["default"].func, + renderKeyboardShortcutsButton: _propTypes["default"].func, + renderKeyboardShortcutsPanel: _propTypes["default"].func, + calendarInfoPosition: _CalendarInfoPositionShape["default"], + firstDayOfWeek: _DayOfWeekShape["default"], + verticalHeight: _airbnbPropTypes.nonNegativeInteger, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + // accessibility + onBlur: _propTypes["default"].func, + isFocused: _propTypes["default"].bool, + showKeyboardShortcuts: _propTypes["default"].bool, + onTab: _propTypes["default"].func, + onShiftTab: _propTypes["default"].func, + // i18n + monthFormat: _propTypes["default"].string, + weekDayFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DayPickerPhrases)), + dayAriaLabelFormat: _propTypes["default"].string, + isRTL: _propTypes["default"].bool +}) : {}; +var defaultProps = { + startDate: undefined, + // TODO: use null + endDate: undefined, + // TODO: use null + minDate: null, + maxDate: null, + onDatesChange: function onDatesChange() {}, + startDateOffset: undefined, + endDateOffset: undefined, + focusedInput: null, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + keepOpenOnDateSelect: false, + minimumNights: 1, + disabled: false, + isOutsideRange: function isOutsideRange() {}, + isDayBlocked: function isDayBlocked() {}, + isDayHighlighted: function isDayHighlighted() {}, + getMinNightsForHoverDate: function getMinNightsForHoverDate() {}, + daysViolatingMinNightsCanBeClicked: false, + moveOffsetForDisabledDates: false, + // DayPicker props + renderMonthText: null, + renderWeekHeaderElement: null, + enableOutsideDays: false, + numberOfMonths: 1, + orientation: _constants.HORIZONTAL_ORIENTATION, + withPortal: false, + hideKeyboardShortcutsPanel: false, + initialVisibleMonth: null, + daySize: _constants.DAY_SIZE, + dayPickerNavigationInlineStyles: null, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onOutsideClick: function onOutsideClick() {}, + renderCalendarDay: undefined, + renderDayContents: null, + renderCalendarInfo: null, + renderMonthElement: null, + renderKeyboardShortcutsButton: undefined, + renderKeyboardShortcutsPanel: undefined, + calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, + firstDayOfWeek: null, + verticalHeight: null, + noBorder: false, + transitionDuration: undefined, + verticalBorderSpacing: undefined, + horizontalMonthPadding: 13, + // accessibility + onBlur: function onBlur() {}, + isFocused: false, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // 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; + } + + if (focusedInput === _constants.END_DATE) { + return phrases.chooseAvailableEndDate; + } + + return phrases.chooseAvailableDate; +}; + +var DayPickerRangeController = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DayPickerRangeController, _ref2); + var _proto = DayPickerRangeController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DayPickerRangeController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = (0, _isTouchDevice["default"])(); + _this.today = (0, _moment["default"])(); + _this.modifiers = { + today: function today(day) { + return _this.isToday(day); + }, + blocked: function blocked(day) { + return _this.isBlocked(day); + }, + 'blocked-calendar': function blockedCalendar(day) { + return props.isDayBlocked(day); + }, + 'blocked-out-of-range': function blockedOutOfRange(day) { + return props.isOutsideRange(day); + }, + 'highlighted-calendar': function highlightedCalendar(day) { + return props.isDayHighlighted(day); + }, + valid: function valid(day) { + return !_this.isBlocked(day); + }, + 'selected-start': function selectedStart(day) { + return _this.isStartDate(day); + }, + 'selected-end': function selectedEnd(day) { + return _this.isEndDate(day); + }, + 'blocked-minimum-nights': function blockedMinimumNights(day) { + return _this.doesNotMeetMinimumNights(day); + }, + 'selected-span': function selectedSpan(day) { + return _this.isInSelectedSpan(day); + }, + 'last-in-range': function lastInRange(day) { + return _this.isLastInRange(day); + }, + hovered: function hovered(day) { + return _this.isHovered(day); + }, + 'hovered-span': function hoveredSpan(day) { + return _this.isInHoveredSpan(day); + }, + 'hovered-offset': function hoveredOffset(day) { + return _this.isInHoveredSpan(day); + }, + 'after-hovered-start': function afterHoveredStart(day) { + return _this.isDayAfterHoveredStartDate(day); + }, + 'first-day-of-week': function firstDayOfWeek(day) { + return _this.isFirstDayOfWeek(day); + }, + 'last-day-of-week': function lastDayOfWeek(day) { + return _this.isLastDayOfWeek(day); + }, + 'hovered-start-first-possible-end': function hoveredStartFirstPossibleEnd(day, hoverDate) { + return _this.isFirstPossibleEndDateForHoveredStartDate(day, hoverDate); + }, + 'hovered-start-blocked-minimum-nights': function hoveredStartBlockedMinimumNights(day, hoverDate) { + return _this.doesNotMeetMinNightsForHoveredStartDate(day, hoverDate); + }, + 'before-hovered-end': function beforeHoveredEnd(day) { + return _this.isDayBeforeHoveredEndDate(day); + }, + 'no-selected-start-before-selected-end': function noSelectedStartBeforeSelectedEnd(day) { + return _this.beforeSelectedEnd(day) && !props.startDate; + }, + 'selected-start-in-hovered-span': function selectedStartInHoveredSpan(day, hoverDate) { + return _this.isStartDate(day) && (0, _isAfterDay["default"])(hoverDate, day); + }, + 'selected-start-no-selected-end': function selectedStartNoSelectedEnd(day) { + return _this.isStartDate(day) && !props.endDate; + }, + 'selected-end-no-selected-start': function selectedEndNoSelectedStart(day) { + return _this.isEndDate(day) && !props.startDate; + } + }; + + 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: _objectSpread(_objectSpread({}, props.phrases), {}, { + chooseAvailableDate: chooseAvailableDate + }), + visibleDays: visibleDays, + disablePrev: _this.shouldDisableMonthNavigation(props.minDate, currentMonth), + disableNext: _this.shouldDisableMonthNavigation(props.maxDate, currentMonth) + }; + _this.onDayClick = _this.onDayClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayMouseEnter = _this.onDayMouseEnter.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayMouseLeave = _this.onDayMouseLeave.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onMonthChange = _this.onMonthChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onYearChange = _this.onYearChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onGetNextScrollableMonths = _this.onGetNextScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onGetPrevScrollableMonths = _this.onGetPrevScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.getFirstFocusableDay = _this.getFirstFocusableDay.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var startDate = nextProps.startDate, + endDate = nextProps.endDate, + focusedInput = nextProps.focusedInput, + getMinNightsForHoverDate = nextProps.getMinNightsForHoverDate, + 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 _this$props = this.props, + prevStartDate = _this$props.startDate, + prevEndDate = _this$props.endDate, + prevFocusedInput = _this$props.focusedInput, + prevMinimumNights = _this$props.minimumNights, + prevIsOutsideRange = _this$props.isOutsideRange, + prevIsDayBlocked = _this$props.isDayBlocked, + prevIsDayHighlighted = _this$props.isDayHighlighted, + prevPhrases = _this$props.phrases, + prevInitialVisibleMonth = _this$props.initialVisibleMonth, + prevNumberOfMonths = _this$props.numberOfMonths, + prevEnableOutsideDays = _this$props.enableOutsideDays; + var hoverDate = this.state.hoverDate; + 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 (!endDate || !prevEndDate) { + modifiers = this.deleteModifier(modifiers, prevStartDate, 'selected-start-no-selected-end'); + } + } + + if (!prevStartDate && endDate && startDate) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-no-selected-start'); + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + (0, _object["default"])(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = (0, _moment["default"])(day); + modifiers = _this2.deleteModifier(modifiers, momentObj, 'no-selected-start-before-selected-end'); + }); + }); + } + } + + if (didEndDateChange) { + modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end'); + modifiers = this.addModifier(modifiers, endDate, 'selected-end'); + + if (prevEndDate && (!startDate || !prevStartDate)) { + modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end-no-selected-start'); + } + } + + 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 (startDate && !endDate) { + modifiers = this.addModifier(modifiers, startDate, 'selected-start-no-selected-end'); + } + + if (endDate && !startDate) { + modifiers = this.addModifier(modifiers, endDate, 'selected-end-no-selected-start'); + } + + if (!startDate && endDate) { + (0, _object["default"])(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = (0, _moment["default"])(day); + + if ((0, _isBeforeDay["default"])(momentObj, endDate)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'no-selected-start-before-selected-end'); + } + }); + }); + } + } + + 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 (!this.isTouchDevice && didEndDateChange && !startDate && endDate) { + var _startSpan2 = endDate.clone().subtract(minimumNights, 'days'); + + var _endSpan2 = endDate.clone(); + + modifiers = this.addModifierToRange(modifiers, _startSpan2, _endSpan2, 'before-hovered-end'); + } + + if (prevMinimumNights > 0) { + if (didFocusChange || didStartDateChange || minimumNights !== prevMinimumNights) { + var _startSpan3 = prevStartDate || this.today; + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan3, _startSpan3.clone().add(prevMinimumNights, 'days'), 'blocked-minimum-nights'); + modifiers = this.deleteModifierFromRange(modifiers, _startSpan3, _startSpan3.clone().add(prevMinimumNights, 'days'), 'blocked'); + } + } + + if (didFocusChange || recomputePropModifiers) { + (0, _object["default"])(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = (0, _getPooledMoment["default"])(day); + var isBlocked = false; + + if (didFocusChange || recomputeOutsideRange) { + if (isOutsideRange(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-out-of-range'); + isBlocked = true; + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-out-of-range'); + } + } + + if (didFocusChange || recomputeDayBlocked) { + if (isDayBlocked(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked-calendar'); + isBlocked = true; + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked-calendar'); + } + } + + if (isBlocked) { + modifiers = _this2.addModifier(modifiers, momentObj, 'blocked'); + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'blocked'); + } + + if (didFocusChange || recomputeDayHighlighted) { + if (isDayHighlighted(momentObj)) { + modifiers = _this2.addModifier(modifiers, momentObj, 'highlighted-calendar'); + } else { + modifiers = _this2.deleteModifier(modifiers, momentObj, 'highlighted-calendar'); + } + } + }); + }); + } + + if (!this.isTouchDevice && didFocusChange && hoverDate && !this.isBlocked(hoverDate)) { + var minNightsForHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForHoverDate > 0 && focusedInput === _constants.END_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + + if (minNightsForHoverDate > 0 && focusedInput === _constants.START_DATE) { + modifiers = this.addModifierToRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.addModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + if (minimumNights > 0 && startDate && focusedInput === _constants.END_DATE) { + modifiers = this.addModifierToRange(modifiers, startDate, startDate.clone().add(minimumNights, 'days'), 'blocked-minimum-nights'); + modifiers = this.addModifierToRange(modifiers, startDate, startDate.clone().add(minimumNights, 'days'), 'blocked'); + } + + var today = (0, _moment["default"])(); + + if (!(0, _isSameDay["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: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + + if (didFocusChange || phrases !== prevPhrases) { + // set the appropriate CalendarDay phrase based on focusedInput + var chooseAvailableDate = getChooseAvailableDatePhrase(phrases, focusedInput); + this.setState({ + phrases: _objectSpread(_objectSpread({}, phrases), {}, { + chooseAvailableDate: chooseAvailableDate + }) + }); + } + }; + + _proto.onDayClick = function onDayClick(day, e) { + var _this$props2 = this.props, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + minimumNights = _this$props2.minimumNights, + onBlur = _this$props2.onBlur, + focusedInput = _this$props2.focusedInput, + onFocusChange = _this$props2.onFocusChange, + onClose = _this$props2.onClose, + onDatesChange = _this$props2.onDatesChange, + startDateOffset = _this$props2.startDateOffset, + endDateOffset = _this$props2.endDateOffset, + disabled = _this$props2.disabled, + daysViolatingMinNightsCanBeClicked = _this$props2.daysViolatingMinNightsCanBeClicked, + moveOffsetForDisabledDates = _this$props2.moveOffsetForDisabledDates; + if (e) e.preventDefault(); + if (this.isBlocked(day, !daysViolatingMinNightsCanBeClicked)) return; + var _this$props3 = this.props, + startDate = _this$props3.startDate, + endDate = _this$props3.endDate; + + if (startDateOffset || endDateOffset) { + startDate = (0, _getSelectedDateOffset["default"])(startDateOffset, day); + + if (moveOffsetForDisabledDates) { + endDate = this.getDisabledEndDateOffset(startDate, (0, _getSelectedDateOffset["default"])(endDateOffset, day)); + } else { + endDate = (0, _getSelectedDateOffset["default"])(endDateOffset, day); + } + + if (this.isBlocked(startDate) || this.isBlocked(endDate)) { + return; + } + + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + 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, _isBeforeDay["default"])(lastAllowedStartDate, day) || (0, _isAfterDay["default"])(startDate, endDate); + var isEndDateDisabled = disabled === _constants.END_DATE; + + if (!isEndDateDisabled || !isStartDateAfterEndDate) { + startDate = day; + + if (isStartDateAfterEndDate) { + endDate = null; + } + } + + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + 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; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + onFocusChange(_constants.START_DATE); + } else if ((0, _isInclusivelyAfterDay["default"])(day, firstAllowedEndDate)) { + endDate = day; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + + if (!keepOpenOnDateSelect) { + onFocusChange(null); + onClose({ + startDate: startDate, + endDate: endDate + }); + } + } else if (daysViolatingMinNightsCanBeClicked && this.doesNotMeetMinimumNights(day)) { + endDate = day; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } else if (disabled !== _constants.START_DATE) { + startDate = day; + endDate = null; + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } else { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } + } else { + onDatesChange({ + startDate: startDate, + endDate: endDate + }); + } + + onBlur(); + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day) { + /* eslint react/destructuring-assignment: 1 */ + if (this.isTouchDevice) return; + var _this$props4 = this.props, + startDate = _this$props4.startDate, + endDate = _this$props4.endDate, + focusedInput = _this$props4.focusedInput, + getMinNightsForHoverDate = _this$props4.getMinNightsForHoverDate, + minimumNights = _this$props4.minimumNights, + startDateOffset = _this$props4.startDateOffset, + endDateOffset = _this$props4.endDateOffset, + moveOffsetForDisabledDates = _this$props4.moveOffsetForDisabledDates; + var _this$state = this.state, + hoverDate = _this$state.hoverDate, + visibleDays = _this$state.visibleDays, + dateOffset = _this$state.dateOffset; + var nextDateOffset = null; + + if (focusedInput) { + var hasOffset = startDateOffset || endDateOffset; + var modifiers = {}; + + if (hasOffset) { + var start = (0, _getSelectedDateOffset["default"])(startDateOffset, day); + var end = null; + + if (moveOffsetForDisabledDates) { + end = this.getDisabledEndDateOffset(start, (0, _getSelectedDateOffset["default"])(endDateOffset, day, function (rangeDay) { + return rangeDay.add(1, 'day'); + })); + } else { + end = (0, _getSelectedDateOffset["default"])(endDateOffset, day, function (rangeDay) { + return rangeDay.add(1, 'day'); + }); + } + + nextDateOffset = { + start: start, + end: end + }; // eslint-disable-next-line react/destructuring-assignment + + if (dateOffset && dateOffset.start && dateOffset.end) { + modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, 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, _isAfterDay["default"])(hoverDate, startDate)) { + var endSpan = hoverDate.clone().add(1, 'day'); + modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); + } + + if ((0, _isBeforeDay["default"])(day, startDate) || (0, _isSameDay["default"])(day, startDate)) { + modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + + if (!this.isBlocked(day) && (0, _isAfterDay["default"])(day, startDate)) { + var _endSpan3 = day.clone().add(1, 'day'); + + modifiers = this.addModifierToRange(modifiers, startDate, _endSpan3, 'hovered-span'); + modifiers = this.addModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + } + + if (!startDate && endDate && focusedInput === _constants.START_DATE) { + if ((0, _isBeforeDay["default"])(hoverDate, endDate)) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); + } + + if ((0, _isAfterDay["default"])(day, endDate) || (0, _isSameDay["default"])(day, endDate)) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + + if (!this.isBlocked(day) && (0, _isBeforeDay["default"])(day, endDate)) { + modifiers = this.addModifierToRange(modifiers, day, endDate, 'hovered-span'); + modifiers = this.addModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + } + + if (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'); + + if ((0, _isSameDay["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'); + } + } + + if (endDate) { + var _startSpan4 = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan4, endDate, 'before-hovered-end'); + + if ((0, _isSameDay["default"])(day, endDate)) { + var _newStartSpan = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.addModifierToRange(modifiers, _newStartSpan, endDate, 'before-hovered-end'); + } + } + + if (hoverDate && !this.isBlocked(hoverDate)) { + var minNightsForPrevHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForPrevHoverDate > 0 && focusedInput === _constants.START_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForPrevHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForPrevHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + if (!this.isBlocked(day)) { + var minNightsForHoverDate = getMinNightsForHoverDate(day); + + if (minNightsForHoverDate > 0 && focusedInput === _constants.START_DATE) { + modifiers = this.addModifierToRange(modifiers, day.clone().add(1, 'days'), day.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.addModifier(modifiers, day.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + } + + this.setState({ + hoverDate: day, + dateOffset: nextDateOffset, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + }; + + _proto.onDayMouseLeave = function onDayMouseLeave(day) { + var _this$props5 = this.props, + startDate = _this$props5.startDate, + endDate = _this$props5.endDate, + focusedInput = _this$props5.focusedInput, + getMinNightsForHoverDate = _this$props5.getMinNightsForHoverDate, + minimumNights = _this$props5.minimumNights; + var _this$state2 = this.state, + hoverDate = _this$state2.hoverDate, + visibleDays = _this$state2.visibleDays, + dateOffset = _this$state2.dateOffset; + if (this.isTouchDevice || !hoverDate) return; + var modifiers = {}; + modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered'); + + if (dateOffset) { + modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, dateOffset.end, 'hovered-offset'); + } + + if (startDate && !endDate) { + if ((0, _isAfterDay["default"])(hoverDate, startDate)) { + var endSpan = hoverDate.clone().add(1, 'day'); + modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span'); + } + + if ((0, _isAfterDay["default"])(day, startDate)) { + modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span'); + } + } + + if (!startDate && endDate) { + if ((0, _isAfterDay["default"])(endDate, hoverDate)) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span'); + } + + if ((0, _isBeforeDay["default"])(day, endDate)) { + modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span'); + } + } + + if (startDate && (0, _isSameDay["default"])(day, startDate)) { + var startSpan = startDate.clone().add(1, 'day'); + + var _endSpan5 = startDate.clone().add(minimumNights + 1, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, startSpan, _endSpan5, 'after-hovered-start'); + } + + if (endDate && (0, _isSameDay["default"])(day, endDate)) { + var _startSpan5 = endDate.clone().subtract(minimumNights, 'days'); + + modifiers = this.deleteModifierFromRange(modifiers, _startSpan5, endDate, 'before-hovered-end'); + } + + if (!this.isBlocked(hoverDate)) { + var minNightsForHoverDate = getMinNightsForHoverDate(hoverDate); + + if (minNightsForHoverDate > 0 && focusedInput === _constants.START_DATE) { + modifiers = this.deleteModifierFromRange(modifiers, hoverDate.clone().add(1, 'days'), hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-blocked-minimum-nights'); + modifiers = this.deleteModifier(modifiers, hoverDate.clone().add(minNightsForHoverDate, 'days'), 'hovered-start-first-possible-end'); + } + } + + this.setState({ + hoverDate: null, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onPrevMonthClick = function onPrevMonthClick() { + var _this$props6 = this.props, + enableOutsideDays = _this$props6.enableOutsideDays, + maxDate = _this$props6.maxDate, + minDate = _this$props6.minDate, + numberOfMonths = _this$props6.numberOfMonths, + onPrevMonthClick = _this$props6.onPrevMonthClick; + var _this$state3 = this.state, + currentMonth = _this$state3.currentMonth, + visibleDays = _this$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, _getVisibleDays["default"])(prevMonth, 1, enableOutsideDays, true); + var newCurrentMonth = currentMonth.clone().subtract(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(prevMonthVisibleDays)) + }, function () { + onPrevMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick() { + var _this$props7 = this.props, + enableOutsideDays = _this$props7.enableOutsideDays, + maxDate = _this$props7.maxDate, + minDate = _this$props7.minDate, + numberOfMonths = _this$props7.numberOfMonths, + onNextMonthClick = _this$props7.onNextMonthClick; + var _this$state4 = this.state, + currentMonth = _this$state4.currentMonth, + visibleDays = _this$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, _getVisibleDays["default"])(nextMonth, 1, enableOutsideDays, true); + var newCurrentMonth = currentMonth.clone().add(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(nextMonthVisibleDays)) + }, function () { + onNextMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onMonthChange = function onMonthChange(newMonth) { + var _this$props8 = this.props, + numberOfMonths = _this$props8.numberOfMonths, + enableOutsideDays = _this$props8.enableOutsideDays, + orientation = _this$props8.orientation; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var newVisibleDays = (0, _getVisibleDays["default"])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onYearChange = function onYearChange(newMonth) { + var _this$props9 = this.props, + numberOfMonths = _this$props9.numberOfMonths, + enableOutsideDays = _this$props9.enableOutsideDays, + orientation = _this$props9.orientation; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var newVisibleDays = (0, _getVisibleDays["default"])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onGetNextScrollableMonths = function onGetNextScrollableMonths() { + var _this$props10 = this.props, + numberOfMonths = _this$props10.numberOfMonths, + enableOutsideDays = _this$props10.enableOutsideDays; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + visibleDays = _this$state5.visibleDays; + var numberOfVisibleMonths = Object.keys(visibleDays).length; + var nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month'); + var newVisibleDays = (0, _getVisibleDays["default"])(nextMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.onGetPrevScrollableMonths = function onGetPrevScrollableMonths() { + var _this$props11 = this.props, + numberOfMonths = _this$props11.numberOfMonths, + enableOutsideDays = _this$props11.enableOutsideDays; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + visibleDays = _this$state6.visibleDays; + var firstPreviousMonth = currentMonth.clone().subtract(numberOfMonths, 'month'); + var newVisibleDays = (0, _getVisibleDays["default"])(firstPreviousMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + currentMonth: firstPreviousMonth.clone(), + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return _moment["default"].localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getFirstFocusableDay = function getFirstFocusableDay(newMonth) { + var _this3 = this; + + var _this$props12 = this.props, + startDate = _this$props12.startDate, + endDate = _this$props12.endDate, + focusedInput = _this$props12.focusedInput, + minimumNights = _this$props12.minimumNights, + numberOfMonths = _this$props12.numberOfMonths; + var focusedDate = newMonth.clone().startOf('month').hour(12); + + 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, _isAfterDay["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 = (0, _slicedToArray2["default"])(viableDays, 1); + + focusedDate = _viableDays[0]; + } + } + + return focusedDate; + }; + + _proto.getModifiers = function getModifiers(visibleDays) { + var _this4 = this; + + var modifiers = {}; + Object.keys(visibleDays).forEach(function (month) { + modifiers[month] = {}; + visibleDays[month].forEach(function (day) { + modifiers[month][(0, _toISODateString["default"])(day)] = _this4.getModifiersForDay(day); + }); + }); + return modifiers; + }; + + _proto.getModifiersForDay = function getModifiersForDay(day) { + var _this5 = this; + + return new Set(Object.keys(this.modifiers).filter(function (modifier) { + return _this5.modifiers[modifier](day); + })); + }; + + _proto.getStateForNewMonth = 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, _getVisibleDays["default"])(currentMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths)); + return { + currentMonth: currentMonth, + visibleDays: visibleDays + }; + }; + + _proto.shouldDisableMonthNavigation = function shouldDisableMonthNavigation(date, visibleMonth) { + if (!date) return false; + var _this$props13 = this.props, + numberOfMonths = _this$props13.numberOfMonths, + enableOutsideDays = _this$props13.enableOutsideDays; + return (0, _isDayVisible["default"])(date, visibleMonth, numberOfMonths, enableOutsideDays); + }; + + _proto.addModifier = function addModifier(updatedDays, day, modifier) { + return (0, _modifiers.addModifier)(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.addModifierToRange = function addModifierToRange(updatedDays, start, end, modifier) { + var days = updatedDays; + var spanStart = start.clone(); + + while ((0, _isBeforeDay["default"])(spanStart, end)) { + days = this.addModifier(days, spanStart, modifier); + spanStart = spanStart.clone().add(1, 'day'); + } + + return days; + }; + + _proto.deleteModifier = function deleteModifier(updatedDays, day, modifier) { + return (0, _modifiers.deleteModifier)(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.deleteModifierFromRange = function deleteModifierFromRange(updatedDays, start, end, modifier) { + var days = updatedDays; + var spanStart = start.clone(); + + while ((0, _isBeforeDay["default"])(spanStart, end)) { + days = this.deleteModifier(days, spanStart, modifier); + spanStart = spanStart.clone().add(1, 'day'); + } + + return days; + }; + + _proto.doesNotMeetMinimumNights = function doesNotMeetMinimumNights(day) { + var _this$props14 = this.props, + startDate = _this$props14.startDate, + isOutsideRange = _this$props14.isOutsideRange, + focusedInput = _this$props14.focusedInput, + minimumNights = _this$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, _moment["default"])(day).subtract(minimumNights, 'days')); + }; + + _proto.doesNotMeetMinNightsForHoveredStartDate = function doesNotMeetMinNightsForHoveredStartDate(day, hoverDate) { + var _this$props15 = this.props, + focusedInput = _this$props15.focusedInput, + getMinNightsForHoverDate = _this$props15.getMinNightsForHoverDate; + if (focusedInput !== _constants.END_DATE) return false; + + if (hoverDate && !this.isBlocked(hoverDate)) { + var minNights = getMinNightsForHoverDate(hoverDate); + var dayDiff = day.diff(hoverDate.clone().startOf('day').hour(12), 'days'); + return dayDiff < minNights && dayDiff >= 0; + } + + return false; + }; + + _proto.getDisabledEndDateOffset = function getDisabledEndDateOffset(start, end) { + var _this7 = this; + + var isSaturday = this.isSaturday(end); + var dates = (0, _enumrateDatesBetween["default"])(start, end); + var daysToAdd = 0; + dates.map(function (d) { + if (_this7.isBlocked((0, _moment["default"])(d))) { + daysToAdd++; + } + }); + var newEndDate = end.add(isSaturday ? 2 : daysToAdd, 'day'); + return newEndDate; + }; + + _proto.isDayAfterHoveredStartDate = function isDayAfterHoveredStartDate(day) { + var _this$props16 = this.props, + startDate = _this$props16.startDate, + endDate = _this$props16.endDate, + minimumNights = _this$props16.minimumNights; + + var _ref3 = this.state || {}, + hoverDate = _ref3.hoverDate; + + return !!startDate && !endDate && !this.isBlocked(day) && (0, _isNextDay["default"])(hoverDate, day) && minimumNights > 0 && (0, _isSameDay["default"])(hoverDate, startDate); + }; + + _proto.isEndDate = function isEndDate(day) { + var endDate = this.props.endDate; + return (0, _isSameDay["default"])(day, endDate); + }; + + _proto.isHovered = function isHovered(day) { + var _ref4 = this.state || {}, + hoverDate = _ref4.hoverDate; + + var focusedInput = this.props.focusedInput; + return !!focusedInput && (0, _isSameDay["default"])(day, hoverDate); + }; + + _proto.isInHoveredSpan = function isInHoveredSpan(day) { + var _this$props17 = this.props, + startDate = _this$props17.startDate, + endDate = _this$props17.endDate; + + var _ref5 = this.state || {}, + hoverDate = _ref5.hoverDate; + + var isForwardRange = !!startDate && !endDate && (day.isBetween(startDate, hoverDate) || (0, _isSameDay["default"])(hoverDate, day)); + var isBackwardRange = !!endDate && !startDate && (day.isBetween(hoverDate, endDate) || (0, _isSameDay["default"])(hoverDate, day)); + var isValidDayHovered = hoverDate && !this.isBlocked(hoverDate); + return (isForwardRange || isBackwardRange) && isValidDayHovered; + }; + + _proto.isInSelectedSpan = function isInSelectedSpan(day) { + var _this$props18 = this.props, + startDate = _this$props18.startDate, + endDate = _this$props18.endDate; + return day.isBetween(startDate, endDate, 'days'); + }; + + _proto.isLastInRange = function isLastInRange(day) { + var endDate = this.props.endDate; + return this.isInSelectedSpan(day) && (0, _isNextDay["default"])(day, endDate); + }; + + _proto.isStartDate = function isStartDate(day) { + var startDate = this.props.startDate; + return (0, _isSameDay["default"])(day, startDate); + }; + + _proto.isBlocked = function isBlocked(day) { + var blockDaysViolatingMinNights = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _this$props19 = this.props, + isDayBlocked = _this$props19.isDayBlocked, + isOutsideRange = _this$props19.isOutsideRange; + return isDayBlocked(day) || isOutsideRange(day) || blockDaysViolatingMinNights && this.doesNotMeetMinimumNights(day); + }; + + _proto.isSunday = function isSunday(day) { + var dateDay = day.day(); + return dateDay === 0; + }; + + _proto.isSaturday = function isSaturday(day) { + var dateDay = day.day(); + return dateDay === 6; + }; + + _proto.isToday = function isToday(day) { + return (0, _isSameDay["default"])(day, this.today); + }; + + _proto.isFirstDayOfWeek = function isFirstDayOfWeek(day) { + return day.day() === this.getFirstDayOfWeek(); + }; + + _proto.isLastDayOfWeek = function isLastDayOfWeek(day) { + return day.day() === (this.getFirstDayOfWeek() + 6) % 7; + }; + + _proto.isFirstPossibleEndDateForHoveredStartDate = function isFirstPossibleEndDateForHoveredStartDate(day, hoverDate) { + var _this$props20 = this.props, + focusedInput = _this$props20.focusedInput, + getMinNightsForHoverDate = _this$props20.getMinNightsForHoverDate; + if (focusedInput !== _constants.END_DATE || !hoverDate || this.isBlocked(hoverDate)) return false; + var minNights = getMinNightsForHoverDate(hoverDate); + var firstAvailableEndDate = hoverDate.clone().add(minNights, 'days'); + return (0, _isSameDay["default"])(day, firstAvailableEndDate); + }; + + _proto.beforeSelectedEnd = function beforeSelectedEnd(day) { + var endDate = this.props.endDate; + return (0, _isBeforeDay["default"])(day, endDate); + }; + + _proto.isDayBeforeHoveredEndDate = function isDayBeforeHoveredEndDate(day) { + var _this$props21 = this.props, + startDate = _this$props21.startDate, + endDate = _this$props21.endDate, + minimumNights = _this$props21.minimumNights; + + var _ref6 = this.state || {}, + hoverDate = _ref6.hoverDate; + + return !!endDate && !startDate && !this.isBlocked(day) && (0, _isPreviousDay["default"])(hoverDate, day) && minimumNights > 0 && (0, _isSameDay["default"])(hoverDate, endDate); + }; + + _proto.render = function render() { + var _this$props22 = this.props, + numberOfMonths = _this$props22.numberOfMonths, + orientation = _this$props22.orientation, + monthFormat = _this$props22.monthFormat, + renderMonthText = _this$props22.renderMonthText, + renderWeekHeaderElement = _this$props22.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props22.dayPickerNavigationInlineStyles, + navPosition = _this$props22.navPosition, + navPrev = _this$props22.navPrev, + navNext = _this$props22.navNext, + renderNavPrevButton = _this$props22.renderNavPrevButton, + renderNavNextButton = _this$props22.renderNavNextButton, + noNavButtons = _this$props22.noNavButtons, + noNavNextButton = _this$props22.noNavNextButton, + noNavPrevButton = _this$props22.noNavPrevButton, + onOutsideClick = _this$props22.onOutsideClick, + withPortal = _this$props22.withPortal, + enableOutsideDays = _this$props22.enableOutsideDays, + firstDayOfWeek = _this$props22.firstDayOfWeek, + renderKeyboardShortcutsButton = _this$props22.renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel = _this$props22.renderKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel = _this$props22.hideKeyboardShortcutsPanel, + daySize = _this$props22.daySize, + focusedInput = _this$props22.focusedInput, + renderCalendarDay = _this$props22.renderCalendarDay, + renderDayContents = _this$props22.renderDayContents, + renderCalendarInfo = _this$props22.renderCalendarInfo, + renderMonthElement = _this$props22.renderMonthElement, + calendarInfoPosition = _this$props22.calendarInfoPosition, + onBlur = _this$props22.onBlur, + onShiftTab = _this$props22.onShiftTab, + onTab = _this$props22.onTab, + isFocused = _this$props22.isFocused, + showKeyboardShortcuts = _this$props22.showKeyboardShortcuts, + isRTL = _this$props22.isRTL, + weekDayFormat = _this$props22.weekDayFormat, + dayAriaLabelFormat = _this$props22.dayAriaLabelFormat, + verticalHeight = _this$props22.verticalHeight, + noBorder = _this$props22.noBorder, + transitionDuration = _this$props22.transitionDuration, + verticalBorderSpacing = _this$props22.verticalBorderSpacing, + horizontalMonthPadding = _this$props22.horizontalMonthPadding; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + phrases = _this$state7.phrases, + visibleDays = _this$state7.visibleDays, + disablePrev = _this$state7.disablePrev, + disableNext = _this$state7.disableNext; + return /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + modifiers: visibleDays, + numberOfMonths: numberOfMonths, + onDayClick: this.onDayClick, + onDayMouseEnter: this.onDayMouseEnter, + onDayMouseLeave: this.onDayMouseLeave, + onPrevMonthClick: this.onPrevMonthClick, + onNextMonthClick: this.onNextMonthClick, + onMonthChange: this.onMonthChange, + onTab: onTab, + onShiftTab: onShiftTab, + onYearChange: this.onYearChange, + onGetNextScrollableMonths: this.onGetNextScrollableMonths, + onGetPrevScrollableMonths: this.onGetPrevScrollableMonths, + monthFormat: monthFormat, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + withPortal: withPortal, + hidden: !focusedInput, + initialVisibleMonth: function initialVisibleMonth() { + return currentMonth; + }, + daySize: daySize, + onOutsideClick: onOutsideClick, + disablePrev: disablePrev, + disableNext: disableNext, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + noNavButtons: noNavButtons, + noNavPrevButton: noNavPrevButton, + noNavNextButton: noNavNextButton, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + renderKeyboardShortcutsButton: renderKeyboardShortcutsButton, + renderKeyboardShortcutsPanel: renderKeyboardShortcutsPanel, + calendarInfoPosition: calendarInfoPosition, + firstDayOfWeek: firstDayOfWeek, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + isFocused: isFocused, + getFirstFocusableDay: this.getFirstFocusableDay, + onBlur: onBlur, + showKeyboardShortcuts: showKeyboardShortcuts, + phrases: phrases, + isRTL: isRTL, + weekDayFormat: weekDayFormat, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalHeight: verticalHeight, + verticalBorderSpacing: verticalBorderSpacing, + noBorder: noBorder, + transitionDuration: transitionDuration, + horizontalMonthPadding: horizontalMonthPadding + }); + }; + + return DayPickerRangeController; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports["default"] = DayPickerRangeController; +DayPickerRangeController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerRangeController.defaultProps = defaultProps; \ No newline at end of file diff --git a/lib/components/DayPickerSingleDateController.js b/lib/components/DayPickerSingleDateController.js new file mode 100644 index 000000000..338e62303 --- /dev/null +++ b/lib/components/DayPickerSingleDateController.js @@ -0,0 +1,799 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _moment = _interopRequireDefault(require("moment")); + +var _object = _interopRequireDefault(require("object.values")); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _isSameDay = _interopRequireDefault(require("../utils/isSameDay")); + +var _isAfterDay = _interopRequireDefault(require("../utils/isAfterDay")); + +var _isDayVisible = _interopRequireDefault(require("../utils/isDayVisible")); + +var _getVisibleDays = _interopRequireDefault(require("../utils/getVisibleDays")); + +var _toISODateString = _interopRequireDefault(require("../utils/toISODateString")); + +var _modifiers = require("../utils/modifiers"); + +var _ScrollableOrientationShape = _interopRequireDefault(require("../shapes/ScrollableOrientationShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("../shapes/DayOfWeekShape")); + +var _CalendarInfoPositionShape = _interopRequireDefault(require("../shapes/CalendarInfoPositionShape")); + +var _NavPositionShape = _interopRequireDefault(require("../shapes/NavPositionShape")); + +var _constants = require("../constants"); + +var _DayPicker = _interopRequireDefault(require("./DayPicker")); + +var _getPooledMoment = _interopRequireDefault(require("../utils/getPooledMoment")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +// Default value of the date property. Represents the state +// when there is no date selected. +// TODO: use null +var DATE_UNSET_VALUE = undefined; +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({ + date: _reactMomentProptypes["default"].momentObj, + minDate: _reactMomentProptypes["default"].momentObj, + maxDate: _reactMomentProptypes["default"].momentObj, + onDateChange: _propTypes["default"].func, + allowUnselect: _propTypes["default"].bool, + focused: _propTypes["default"].bool, + onFocusChange: _propTypes["default"].func, + onClose: _propTypes["default"].func, + keepOpenOnDateSelect: _propTypes["default"].bool, + isOutsideRange: _propTypes["default"].func, + isDayBlocked: _propTypes["default"].func, + isDayHighlighted: _propTypes["default"].func, + // DayPicker props + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: _propTypes["default"].func, + enableOutsideDays: _propTypes["default"].bool, + numberOfMonths: _propTypes["default"].number, + orientation: _ScrollableOrientationShape["default"], + withPortal: _propTypes["default"].bool, + initialVisibleMonth: _propTypes["default"].func, + firstDayOfWeek: _DayOfWeekShape["default"], + hideKeyboardShortcutsPanel: _propTypes["default"].bool, + daySize: _airbnbPropTypes.nonNegativeInteger, + verticalHeight: _airbnbPropTypes.nonNegativeInteger, + noBorder: _propTypes["default"].bool, + verticalBorderSpacing: _airbnbPropTypes.nonNegativeInteger, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + dayPickerNavigationInlineStyles: _propTypes["default"].object, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + noNavButtons: _propTypes["default"].bool, + noNavNextButton: _propTypes["default"].bool, + noNavPrevButton: _propTypes["default"].bool, + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + onOutsideClick: _propTypes["default"].func, + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + renderCalendarInfo: _propTypes["default"].func, + calendarInfoPosition: _CalendarInfoPositionShape["default"], + // accessibility + onBlur: _propTypes["default"].func, + isFocused: _propTypes["default"].bool, + showKeyboardShortcuts: _propTypes["default"].bool, + onTab: _propTypes["default"].func, + onShiftTab: _propTypes["default"].func, + // i18n + monthFormat: _propTypes["default"].string, + weekDayFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DayPickerPhrases)), + dayAriaLabelFormat: _propTypes["default"].string, + isRTL: _propTypes["default"].bool +}) : {}; +var defaultProps = { + date: DATE_UNSET_VALUE, + minDate: null, + maxDate: null, + onDateChange: function onDateChange() {}, + allowUnselect: false, + focused: false, + onFocusChange: function onFocusChange() {}, + onClose: function onClose() {}, + keepOpenOnDateSelect: false, + isOutsideRange: function isOutsideRange() {}, + isDayBlocked: function isDayBlocked() {}, + isDayHighlighted: function isDayHighlighted() {}, + // DayPicker props + renderMonthText: null, + renderWeekHeaderElement: null, + enableOutsideDays: false, + numberOfMonths: 1, + orientation: _constants.HORIZONTAL_ORIENTATION, + withPortal: false, + hideKeyboardShortcutsPanel: false, + initialVisibleMonth: null, + firstDayOfWeek: null, + daySize: _constants.DAY_SIZE, + verticalHeight: null, + noBorder: false, + verticalBorderSpacing: undefined, + transitionDuration: undefined, + horizontalMonthPadding: 13, + dayPickerNavigationInlineStyles: null, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + noNavButtons: false, + noNavNextButton: false, + noNavPrevButton: false, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onOutsideClick: function onOutsideClick() {}, + renderCalendarDay: undefined, + renderDayContents: null, + renderCalendarInfo: null, + renderMonthElement: null, + calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, + // accessibility + onBlur: function onBlur() {}, + isFocused: false, + showKeyboardShortcuts: false, + onTab: function onTab() {}, + onShiftTab: function onShiftTab() {}, + // i18n + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: _defaultPhrases.DayPickerPhrases, + dayAriaLabelFormat: undefined, + isRTL: false +}; + +var DayPickerSingleDateController = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(DayPickerSingleDateController, _ref2); + var _proto = DayPickerSingleDateController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function DayPickerSingleDateController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = false; + _this.today = (0, _moment["default"])(); + _this.modifiers = { + today: function today(day) { + return _this.isToday(day); + }, + blocked: function blocked(day) { + return _this.isBlocked(day); + }, + 'blocked-calendar': function blockedCalendar(day) { + return props.isDayBlocked(day); + }, + 'blocked-out-of-range': function blockedOutOfRange(day) { + return props.isOutsideRange(day); + }, + 'highlighted-calendar': function highlightedCalendar(day) { + return props.isDayHighlighted(day); + }, + valid: function valid(day) { + return !_this.isBlocked(day); + }, + hovered: function hovered(day) { + return _this.isHovered(day); + }, + selected: function selected(day) { + return _this.isSelected(day); + }, + 'first-day-of-week': function firstDayOfWeek(day) { + return _this.isFirstDayOfWeek(day); + }, + 'last-day-of-week': function lastDayOfWeek(day) { + return _this.isLastDayOfWeek(day); + } + }; + + var _this$getStateForNewM = _this.getStateForNewMonth(props), + currentMonth = _this$getStateForNewM.currentMonth, + visibleDays = _this$getStateForNewM.visibleDays; + + _this.state = { + hoverDate: null, + currentMonth: currentMonth, + visibleDays: visibleDays, + disablePrev: _this.shouldDisableMonthNavigation(props.minDate, currentMonth), + disableNext: _this.shouldDisableMonthNavigation(props.maxDate, currentMonth) + }; + _this.onDayMouseEnter = _this.onDayMouseEnter.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayMouseLeave = _this.onDayMouseLeave.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayClick = _this.onDayClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onPrevMonthClick = _this.onPrevMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onNextMonthClick = _this.onNextMonthClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onMonthChange = _this.onMonthChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onYearChange = _this.onYearChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onGetNextScrollableMonths = _this.onGetNextScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onGetPrevScrollableMonths = _this.onGetPrevScrollableMonths.bind((0, _assertThisInitialized2["default"])(_this)); + _this.getFirstFocusableDay = _this.getFirstFocusableDay.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.componentDidMount = function componentDidMount() { + this.isTouchDevice = (0, _isTouchDevice["default"])(); + }; + + _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + var _this2 = this; + + var date = nextProps.date, + focused = nextProps.focused, + isOutsideRange = nextProps.isOutsideRange, + isDayBlocked = nextProps.isDayBlocked, + isDayHighlighted = nextProps.isDayHighlighted, + initialVisibleMonth = nextProps.initialVisibleMonth, + numberOfMonths = nextProps.numberOfMonths, + enableOutsideDays = nextProps.enableOutsideDays; + var _this$props = this.props, + prevIsOutsideRange = _this$props.isOutsideRange, + prevIsDayBlocked = _this$props.isDayBlocked, + prevIsDayHighlighted = _this$props.isDayHighlighted, + prevNumberOfMonths = _this$props.numberOfMonths, + prevEnableOutsideDays = _this$props.enableOutsideDays, + prevInitialVisibleMonth = _this$props.initialVisibleMonth, + prevFocused = _this$props.focused, + prevDate = _this$props.date; + 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 prevCurrentMonth = this.state.currentMonth; + + if (numberOfMonths !== prevNumberOfMonths || enableOutsideDays !== prevEnableOutsideDays || initialVisibleMonth !== prevInitialVisibleMonth && !prevFocused && focused || prevDate && prevDate.diff(date) && !(0, _isDayVisible["default"])(date, prevCurrentMonth, numberOfMonths)) { + var newMonthState = this.getStateForNewMonth(nextProps); + var currentMonth = newMonthState.currentMonth; + visibleDays = newMonthState.visibleDays; + this.setState({ + currentMonth: currentMonth, + visibleDays: visibleDays + }); + } + + var didDateChange = date !== prevDate; + var didFocusChange = focused !== prevFocused; + var modifiers = {}; + + if (didDateChange) { + modifiers = this.deleteModifier(modifiers, prevDate, 'selected'); + modifiers = this.addModifier(modifiers, date, 'selected'); + } + + if (didFocusChange || recomputePropModifiers) { + (0, _object["default"])(visibleDays).forEach(function (days) { + Object.keys(days).forEach(function (day) { + var momentObj = (0, _getPooledMoment["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, _moment["default"])(); + + if (!(0, _isSameDay["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: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + } + }; + + _proto.componentWillUpdate = function componentWillUpdate() { + this.today = (0, _moment["default"])(); + }; + + _proto.onDayClick = function onDayClick(day, e) { + if (e) e.preventDefault(); + if (this.isBlocked(day)) return; + var _this$props2 = this.props, + allowUnselect = _this$props2.allowUnselect, + onDateChange = _this$props2.onDateChange, + keepOpenOnDateSelect = _this$props2.keepOpenOnDateSelect, + onFocusChange = _this$props2.onFocusChange, + onClose = _this$props2.onClose; + var clickedDay = allowUnselect && this.isSelected(day) ? DATE_UNSET_VALUE : day; + onDateChange(clickedDay); + + if (!keepOpenOnDateSelect) { + onFocusChange({ + focused: false + }); + onClose({ + date: clickedDay + }); + } + }; + + _proto.onDayMouseEnter = function onDayMouseEnter(day) { + if (this.isTouchDevice) return; + var _this$state = this.state, + hoverDate = _this$state.hoverDate, + visibleDays = _this$state.visibleDays; + var modifiers = this.deleteModifier({}, hoverDate, 'hovered'); + modifiers = this.addModifier(modifiers, day, 'hovered'); + this.setState({ + hoverDate: day, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onDayMouseLeave = function onDayMouseLeave() { + var _this$state2 = this.state, + hoverDate = _this$state2.hoverDate, + visibleDays = _this$state2.visibleDays; + if (this.isTouchDevice || !hoverDate) return; + var modifiers = this.deleteModifier({}, hoverDate, 'hovered'); + this.setState({ + hoverDate: null, + visibleDays: _objectSpread(_objectSpread({}, visibleDays), modifiers) + }); + }; + + _proto.onPrevMonthClick = function onPrevMonthClick() { + var _this$props3 = this.props, + enableOutsideDays = _this$props3.enableOutsideDays, + maxDate = _this$props3.maxDate, + minDate = _this$props3.minDate, + numberOfMonths = _this$props3.numberOfMonths, + onPrevMonthClick = _this$props3.onPrevMonthClick; + var _this$state3 = this.state, + currentMonth = _this$state3.currentMonth, + visibleDays = _this$state3.visibleDays; + var newVisibleDays = {}; + Object.keys(visibleDays).sort().slice(0, numberOfMonths + 1).forEach(function (month) { + newVisibleDays[month] = visibleDays[month]; + }); + var prevMonth = currentMonth.clone().subtract(1, 'month'); + var prevMonthVisibleDays = (0, _getVisibleDays["default"])(prevMonth, 1, enableOutsideDays); + var newCurrentMonth = currentMonth.clone().subtract(1, 'month'); + this.setState({ + currentMonth: prevMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(prevMonthVisibleDays)) + }, function () { + onPrevMonthClick(prevMonth.clone()); + }); + }; + + _proto.onNextMonthClick = function onNextMonthClick() { + var _this$props4 = this.props, + enableOutsideDays = _this$props4.enableOutsideDays, + maxDate = _this$props4.maxDate, + minDate = _this$props4.minDate, + numberOfMonths = _this$props4.numberOfMonths, + onNextMonthClick = _this$props4.onNextMonthClick; + var _this$state4 = this.state, + currentMonth = _this$state4.currentMonth, + visibleDays = _this$state4.visibleDays; + var newVisibleDays = {}; + Object.keys(visibleDays).sort().slice(1).forEach(function (month) { + newVisibleDays[month] = visibleDays[month]; + }); + var nextMonth = currentMonth.clone().add(numberOfMonths, 'month'); + var nextMonthVisibleDays = (0, _getVisibleDays["default"])(nextMonth, 1, enableOutsideDays); + var newCurrentMonth = currentMonth.clone().add(1, 'month'); + this.setState({ + currentMonth: newCurrentMonth, + disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth), + disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth), + visibleDays: _objectSpread(_objectSpread({}, newVisibleDays), this.getModifiers(nextMonthVisibleDays)) + }, function () { + onNextMonthClick(newCurrentMonth.clone()); + }); + }; + + _proto.onMonthChange = function onMonthChange(newMonth) { + var _this$props5 = this.props, + numberOfMonths = _this$props5.numberOfMonths, + enableOutsideDays = _this$props5.enableOutsideDays, + orientation = _this$props5.orientation; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var newVisibleDays = (0, _getVisibleDays["default"])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onYearChange = function onYearChange(newMonth) { + var _this$props6 = this.props, + numberOfMonths = _this$props6.numberOfMonths, + enableOutsideDays = _this$props6.enableOutsideDays, + orientation = _this$props6.orientation; + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var newVisibleDays = (0, _getVisibleDays["default"])(newMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths); + this.setState({ + currentMonth: newMonth.clone(), + visibleDays: this.getModifiers(newVisibleDays) + }); + }; + + _proto.onGetNextScrollableMonths = function onGetNextScrollableMonths() { + var _this$props7 = this.props, + numberOfMonths = _this$props7.numberOfMonths, + enableOutsideDays = _this$props7.enableOutsideDays; + var _this$state5 = this.state, + currentMonth = _this$state5.currentMonth, + visibleDays = _this$state5.visibleDays; + var numberOfVisibleMonths = Object.keys(visibleDays).length; + var nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month'); + var newVisibleDays = (0, _getVisibleDays["default"])(nextMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.onGetPrevScrollableMonths = function onGetPrevScrollableMonths() { + var _this$props8 = this.props, + numberOfMonths = _this$props8.numberOfMonths, + enableOutsideDays = _this$props8.enableOutsideDays; + var _this$state6 = this.state, + currentMonth = _this$state6.currentMonth, + visibleDays = _this$state6.visibleDays; + var firstPreviousMonth = currentMonth.clone().subtract(numberOfMonths, 'month'); + var newVisibleDays = (0, _getVisibleDays["default"])(firstPreviousMonth, numberOfMonths, enableOutsideDays, true); + this.setState({ + currentMonth: firstPreviousMonth.clone(), + visibleDays: _objectSpread(_objectSpread({}, visibleDays), this.getModifiers(newVisibleDays)) + }); + }; + + _proto.getFirstDayOfWeek = function getFirstDayOfWeek() { + var firstDayOfWeek = this.props.firstDayOfWeek; + + if (firstDayOfWeek == null) { + return _moment["default"].localeData().firstDayOfWeek(); + } + + return firstDayOfWeek; + }; + + _proto.getFirstFocusableDay = function getFirstFocusableDay(newMonth) { + var _this3 = this; + + var _this$props9 = this.props, + date = _this$props9.date, + numberOfMonths = _this$props9.numberOfMonths; + var focusedDate = newMonth.clone().startOf('month').hour(12); + + if (date) { + focusedDate = date.clone(); + } + + if (this.isBlocked(focusedDate)) { + var days = []; + var lastVisibleDay = newMonth.clone().add(numberOfMonths - 1, 'months').endOf('month'); + var currentDay = focusedDate.clone(); + + while (!(0, _isAfterDay["default"])(currentDay, lastVisibleDay)) { + currentDay = currentDay.clone().add(1, 'day'); + days.push(currentDay); + } + + var viableDays = days.filter(function (day) { + return !_this3.isBlocked(day) && (0, _isAfterDay["default"])(day, focusedDate); + }); + + if (viableDays.length > 0) { + var _viableDays = (0, _slicedToArray2["default"])(viableDays, 1); + + focusedDate = _viableDays[0]; + } + } + + return focusedDate; + }; + + _proto.getModifiers = function getModifiers(visibleDays) { + var _this4 = this; + + var modifiers = {}; + Object.keys(visibleDays).forEach(function (month) { + modifiers[month] = {}; + visibleDays[month].forEach(function (day) { + modifiers[month][(0, _toISODateString["default"])(day)] = _this4.getModifiersForDay(day); + }); + }); + return modifiers; + }; + + _proto.getModifiersForDay = function getModifiersForDay(day) { + var _this5 = this; + + return new Set(Object.keys(this.modifiers).filter(function (modifier) { + return _this5.modifiers[modifier](day); + })); + }; + + _proto.getStateForNewMonth = function getStateForNewMonth(nextProps) { + var _this6 = this; + + var initialVisibleMonth = nextProps.initialVisibleMonth, + date = nextProps.date, + numberOfMonths = nextProps.numberOfMonths, + orientation = nextProps.orientation, + enableOutsideDays = nextProps.enableOutsideDays; + var initialVisibleMonthThunk = initialVisibleMonth || (date ? function () { + return date; + } : function () { + return _this6.today; + }); + var currentMonth = initialVisibleMonthThunk(); + var withoutTransitionMonths = orientation === _constants.VERTICAL_SCROLLABLE; + var visibleDays = this.getModifiers((0, _getVisibleDays["default"])(currentMonth, numberOfMonths, enableOutsideDays, withoutTransitionMonths)); + return { + currentMonth: currentMonth, + visibleDays: visibleDays + }; + }; + + _proto.shouldDisableMonthNavigation = function shouldDisableMonthNavigation(date, visibleMonth) { + if (!date) return false; + var _this$props10 = this.props, + numberOfMonths = _this$props10.numberOfMonths, + enableOutsideDays = _this$props10.enableOutsideDays; + return (0, _isDayVisible["default"])(date, visibleMonth, numberOfMonths, enableOutsideDays); + }; + + _proto.addModifier = function addModifier(updatedDays, day, modifier) { + return (0, _modifiers.addModifier)(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.deleteModifier = function deleteModifier(updatedDays, day, modifier) { + return (0, _modifiers.deleteModifier)(updatedDays, day, modifier, this.props, this.state); + }; + + _proto.isBlocked = function isBlocked(day) { + var _this$props11 = this.props, + isDayBlocked = _this$props11.isDayBlocked, + isOutsideRange = _this$props11.isOutsideRange; + return isDayBlocked(day) || isOutsideRange(day); + }; + + _proto.isHovered = function isHovered(day) { + var _ref3 = this.state || {}, + hoverDate = _ref3.hoverDate; + + return (0, _isSameDay["default"])(day, hoverDate); + }; + + _proto.isSelected = function isSelected(day) { + var date = this.props.date; + return (0, _isSameDay["default"])(day, date); + }; + + _proto.isToday = function isToday(day) { + return (0, _isSameDay["default"])(day, this.today); + }; + + _proto.isFirstDayOfWeek = function isFirstDayOfWeek(day) { + return day.day() === this.getFirstDayOfWeek(); + }; + + _proto.isLastDayOfWeek = function isLastDayOfWeek(day) { + return day.day() === (this.getFirstDayOfWeek() + 6) % 7; + }; + + _proto.render = function render() { + var _this$props12 = this.props, + numberOfMonths = _this$props12.numberOfMonths, + orientation = _this$props12.orientation, + monthFormat = _this$props12.monthFormat, + renderMonthText = _this$props12.renderMonthText, + renderWeekHeaderElement = _this$props12.renderWeekHeaderElement, + dayPickerNavigationInlineStyles = _this$props12.dayPickerNavigationInlineStyles, + navPosition = _this$props12.navPosition, + navPrev = _this$props12.navPrev, + navNext = _this$props12.navNext, + renderNavPrevButton = _this$props12.renderNavPrevButton, + renderNavNextButton = _this$props12.renderNavNextButton, + noNavButtons = _this$props12.noNavButtons, + noNavPrevButton = _this$props12.noNavPrevButton, + noNavNextButton = _this$props12.noNavNextButton, + onOutsideClick = _this$props12.onOutsideClick, + onShiftTab = _this$props12.onShiftTab, + onTab = _this$props12.onTab, + withPortal = _this$props12.withPortal, + focused = _this$props12.focused, + enableOutsideDays = _this$props12.enableOutsideDays, + hideKeyboardShortcutsPanel = _this$props12.hideKeyboardShortcutsPanel, + daySize = _this$props12.daySize, + firstDayOfWeek = _this$props12.firstDayOfWeek, + renderCalendarDay = _this$props12.renderCalendarDay, + renderDayContents = _this$props12.renderDayContents, + renderCalendarInfo = _this$props12.renderCalendarInfo, + renderMonthElement = _this$props12.renderMonthElement, + calendarInfoPosition = _this$props12.calendarInfoPosition, + isFocused = _this$props12.isFocused, + isRTL = _this$props12.isRTL, + phrases = _this$props12.phrases, + dayAriaLabelFormat = _this$props12.dayAriaLabelFormat, + onBlur = _this$props12.onBlur, + showKeyboardShortcuts = _this$props12.showKeyboardShortcuts, + weekDayFormat = _this$props12.weekDayFormat, + verticalHeight = _this$props12.verticalHeight, + noBorder = _this$props12.noBorder, + transitionDuration = _this$props12.transitionDuration, + verticalBorderSpacing = _this$props12.verticalBorderSpacing, + horizontalMonthPadding = _this$props12.horizontalMonthPadding; + var _this$state7 = this.state, + currentMonth = _this$state7.currentMonth, + disableNext = _this$state7.disableNext, + disablePrev = _this$state7.disablePrev, + visibleDays = _this$state7.visibleDays; + return /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: orientation, + enableOutsideDays: enableOutsideDays, + modifiers: visibleDays, + numberOfMonths: numberOfMonths, + onDayClick: this.onDayClick, + onDayMouseEnter: this.onDayMouseEnter, + onDayMouseLeave: this.onDayMouseLeave, + onPrevMonthClick: this.onPrevMonthClick, + onNextMonthClick: this.onNextMonthClick, + onMonthChange: this.onMonthChange, + onYearChange: this.onYearChange, + onGetNextScrollableMonths: this.onGetNextScrollableMonths, + onGetPrevScrollableMonths: this.onGetPrevScrollableMonths, + monthFormat: monthFormat, + withPortal: withPortal, + hidden: !focused, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + initialVisibleMonth: function initialVisibleMonth() { + return currentMonth; + }, + firstDayOfWeek: firstDayOfWeek, + onOutsideClick: onOutsideClick, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + disablePrev: disablePrev, + disableNext: disableNext, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + noNavButtons: noNavButtons, + noNavNextButton: noNavNextButton, + noNavPrevButton: noNavPrevButton, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isFocused, + getFirstFocusableDay: this.getFirstFocusableDay, + onBlur: onBlur, + onTab: onTab, + onShiftTab: onShiftTab, + phrases: phrases, + daySize: daySize, + isRTL: isRTL, + showKeyboardShortcuts: showKeyboardShortcuts, + weekDayFormat: weekDayFormat, + dayAriaLabelFormat: dayAriaLabelFormat, + verticalHeight: verticalHeight, + noBorder: noBorder, + transitionDuration: transitionDuration, + verticalBorderSpacing: verticalBorderSpacing, + horizontalMonthPadding: horizontalMonthPadding + }); + }; + + return DayPickerSingleDateController; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports["default"] = DayPickerSingleDateController; +DayPickerSingleDateController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +DayPickerSingleDateController.defaultProps = defaultProps; \ No newline at end of file diff --git a/lib/components/KeyboardShortcutRow.js b/lib/components/KeyboardShortcutRow.js new file mode 100644 index 000000000..c0955d8e7 --- /dev/null +++ b/lib/components/KeyboardShortcutRow.js @@ -0,0 +1,94 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + unicode: _propTypes["default"].string.isRequired, + label: _propTypes["default"].string.isRequired, + action: _propTypes["default"].string.isRequired, + block: _propTypes["default"].bool +})) : {}; +var defaultProps = { + block: false +}; + +function KeyboardShortcutRow(_ref) { + var unicode = _ref.unicode, + label = _ref.label, + action = _ref.action, + block = _ref.block, + css = _ref.css, + styles = _ref.styles; + return /*#__PURE__*/_react["default"].createElement("li", css(styles.KeyboardShortcutRow, block && styles.KeyboardShortcutRow__block), /*#__PURE__*/_react["default"].createElement("div", css(styles.KeyboardShortcutRow_keyContainer, block && styles.KeyboardShortcutRow_keyContainer__block), /*#__PURE__*/_react["default"].createElement("span", (0, _extends2["default"])({}, css(styles.KeyboardShortcutRow_key), { + role: "img", + "aria-label": "".concat(label, ",") // add comma so screen readers will pause before reading action + + }), unicode)), /*#__PURE__*/_react["default"].createElement("div", css(styles.KeyboardShortcutRow_action), action)); +} + +KeyboardShortcutRow.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +KeyboardShortcutRow.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref2) { + var color = _ref2.reactDates.color; + return { + KeyboardShortcutRow: { + listStyle: 'none', + margin: '6px 0' + }, + KeyboardShortcutRow__block: { + marginBottom: 16 + }, + KeyboardShortcutRow_keyContainer: { + display: 'inline-block', + whiteSpace: 'nowrap', + textAlign: 'right', + // is not handled by isRTL + marginRight: 6 // is not handled by isRTL + + }, + KeyboardShortcutRow_keyContainer__block: { + textAlign: 'left', + // is not handled by isRTL + display: 'inline' + }, + KeyboardShortcutRow_key: { + fontFamily: 'monospace', + fontSize: 12, + textTransform: 'uppercase', + background: color.core.grayLightest, + padding: '2px 6px' + }, + KeyboardShortcutRow_action: { + display: 'inline', + wordBreak: 'break-word', + marginLeft: 8 // is not handled by isRTL + + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(KeyboardShortcutRow); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/LeftArrow.js b/lib/components/LeftArrow.js new file mode 100644 index 000000000..f70c16445 --- /dev/null +++ b/lib/components/LeftArrow.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var LeftArrow = function LeftArrow(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + d: "M336 275L126 485h806c13 0 23 10 23 23s-10 23-23 23H126l210 210c11 11 11 21 0 32-5 5-10 7-16 7s-11-2-16-7L55 524c-11-11-11-21 0-32l249-249c21-22 53 10 32 32z" + })); +}; + +LeftArrow.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +var _default = LeftArrow; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/RightArrow.js b/lib/components/RightArrow.js new file mode 100644 index 000000000..18f1520a0 --- /dev/null +++ b/lib/components/RightArrow.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _react = _interopRequireDefault(require("react")); + +var RightArrow = function RightArrow(props) { + return /*#__PURE__*/_react["default"].createElement("svg", props, /*#__PURE__*/_react["default"].createElement("path", { + d: "M694 242l249 250c12 11 12 21 1 32L694 773c-5 5-10 7-16 7s-11-2-16-7c-11-11-11-21 0-32l210-210H68c-13 0-23-10-23-23s10-23 23-23h806L662 275c-21-22 11-54 32-33z" + })); +}; + +RightArrow.defaultProps = { + focusable: "false", + viewBox: "0 0 1000 1000" +}; +var _default = RightArrow; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/SingleDatePicker.js b/lib/components/SingleDatePicker.js new file mode 100644 index 000000000..0a1ed2e72 --- /dev/null +++ b/lib/components/SingleDatePicker.js @@ -0,0 +1,687 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.PureSingleDatePicker = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _moment = _interopRequireDefault(require("moment")); + +var _reactWithStyles = require("react-with-styles"); + +var _reactPortal = require("react-portal"); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _consolidatedEvents = require("consolidated-events"); + +var _isTouchDevice = _interopRequireDefault(require("is-touch-device")); + +var _reactOutsideClickHandler = _interopRequireDefault(require("react-outside-click-handler")); + +var _color2k = require("color2k"); + +var _SingleDatePickerShape = _interopRequireDefault(require("../shapes/SingleDatePickerShape")); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getResponsiveContainerStyles = _interopRequireDefault(require("../utils/getResponsiveContainerStyles")); + +var _getDetachedContainerStyles = _interopRequireDefault(require("../utils/getDetachedContainerStyles")); + +var _getInputHeight = _interopRequireDefault(require("../utils/getInputHeight")); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("../utils/isInclusivelyAfterDay")); + +var _disableScroll2 = _interopRequireDefault(require("../utils/disableScroll")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _SingleDatePickerInputController = _interopRequireDefault(require("./SingleDatePickerInputController")); + +var _DayPickerSingleDateController = _interopRequireDefault(require("./DayPickerSingleDateController")); + +var _CloseButton = _interopRequireDefault(require("./CloseButton")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), _SingleDatePickerShape["default"])) : {}; +var defaultProps = { + // required props for a functional interactive SingleDatePicker + date: null, + focused: false, + minDate: null, + maxDate: null, + // input related props + id: 'date', + placeholder: 'Date', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + disabled: false, + required: false, + readOnly: false, + screenReaderInputMessage: '', + showClearDate: false, + showDefaultInputIcon: false, + inputIconPosition: _constants.ICON_BEFORE_POSITION, + customInputIcon: null, + customCloseIcon: null, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: _constants.DEFAULT_VERTICAL_SPACING, + keepFocusOnInput: false, + // calendar presentation and interaction related props + orientation: _constants.HORIZONTAL_ORIENTATION, + anchorDirection: _constants.ANCHOR_LEFT, + openDirection: _constants.OPEN_DOWN, + horizontalMargin: 0, + withPortal: false, + withFullScreenPortal: false, + appendToBody: false, + disableScroll: false, + initialVisibleMonth: null, + firstDayOfWeek: null, + numberOfMonths: 2, + keepOpenOnDateSelect: false, + reopenPickerOnClearDate: false, + renderCalendarInfo: null, + calendarInfoPosition: _constants.INFO_POSITION_BOTTOM, + hideKeyboardShortcutsPanel: false, + daySize: _constants.DAY_SIZE, + isRTL: false, + verticalHeight: null, + transitionDuration: undefined, + horizontalMonthPadding: 13, + // navigation related props + dayPickerNavigationInlineStyles: null, + navPosition: _constants.NAV_POSITION_TOP, + navPrev: null, + navNext: null, + renderNavPrevButton: null, + renderNavNextButton: null, + onPrevMonthClick: function onPrevMonthClick() {}, + onNextMonthClick: function onNextMonthClick() {}, + onClose: function onClose() {}, + // month presentation and interaction related props + renderMonthText: null, + renderWeekHeaderElement: null, + // day presentation and interaction related props + renderCalendarDay: undefined, + renderDayContents: null, + renderMonthElement: null, + enableOutsideDays: false, + isDayBlocked: function isDayBlocked() { + return false; + }, + isOutsideRange: function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, (0, _moment["default"])()); + }, + isDayHighlighted: function isDayHighlighted() {}, + // internationalization props + displayFormat: function displayFormat() { + return _moment["default"].localeData().longDateFormat('L'); + }, + monthFormat: 'MMMM YYYY', + weekDayFormat: 'dd', + phrases: _defaultPhrases.SingleDatePickerPhrases, + dayAriaLabelFormat: undefined +}; + +var SingleDatePicker = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(SingleDatePicker, _ref2); + var _proto = SingleDatePicker.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function SingleDatePicker(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.isTouchDevice = false; + _this.state = { + dayPickerContainerStyles: {}, + isDayPickerFocused: false, + isInputFocused: false, + showKeyboardShortcuts: false + }; + _this.onFocusOut = _this.onFocusOut.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onOutsideClick = _this.onOutsideClick.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onInputFocus = _this.onInputFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayPickerFocus = _this.onDayPickerFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onDayPickerBlur = _this.onDayPickerBlur.bind((0, _assertThisInitialized2["default"])(_this)); + _this.showKeyboardShortcutsPanel = _this.showKeyboardShortcutsPanel.bind((0, _assertThisInitialized2["default"])(_this)); + _this.responsivizePickerPosition = _this.responsivizePickerPosition.bind((0, _assertThisInitialized2["default"])(_this)); + _this.disableScroll = _this.disableScroll.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setDayPickerContainerRef = _this.setDayPickerContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + _this.setContainerRef = _this.setContainerRef.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + /* istanbul ignore next */ + + + _proto.componentDidMount = function componentDidMount() { + this.removeResizeEventListener = (0, _consolidatedEvents.addEventListener)(window, 'resize', this.responsivizePickerPosition, { + passive: true + }); + this.responsivizePickerPosition(); + this.disableScroll(); + var focused = this.props.focused; + + if (focused) { + this.setState({ + isInputFocused: true + }); + } + + this.isTouchDevice = (0, _isTouchDevice["default"])(); + }; + + _proto.componentDidUpdate = function componentDidUpdate(prevProps) { + var focused = this.props.focused; + + if (!prevProps.focused && focused) { + this.responsivizePickerPosition(); + this.disableScroll(); + } else if (prevProps.focused && !focused) { + if (this.enableScroll) this.enableScroll(); + } + } + /* istanbul ignore next */ + ; + + _proto.componentWillUnmount = function componentWillUnmount() { + if (this.removeResizeEventListener) this.removeResizeEventListener(); + if (this.removeFocusOutEventListener) this.removeFocusOutEventListener(); + if (this.enableScroll) this.enableScroll(); + }; + + _proto.onOutsideClick = function onOutsideClick(event) { + var _this$props = this.props, + focused = _this$props.focused, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose, + date = _this$props.date, + appendToBody = _this$props.appendToBody; + if (!focused) return; + if (appendToBody && this.dayPickerContainer.contains(event.target)) return; + this.setState({ + isInputFocused: false, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + onFocusChange({ + focused: false + }); + onClose({ + date: date + }); + }; + + _proto.onInputFocus = function onInputFocus(_ref3) { + var focused = _ref3.focused; + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + readOnly = _this$props2.readOnly, + withPortal = _this$props2.withPortal, + withFullScreenPortal = _this$props2.withFullScreenPortal, + keepFocusOnInput = _this$props2.keepFocusOnInput; + + if (focused) { + var withAnyPortal = withPortal || withFullScreenPortal; + var moveFocusToDayPicker = withAnyPortal || readOnly && !keepFocusOnInput || this.isTouchDevice && !keepFocusOnInput; + + if (moveFocusToDayPicker) { + this.onDayPickerFocus(); + } else { + this.onDayPickerBlur(); + } + } + + onFocusChange({ + focused: focused + }); + }; + + _proto.onDayPickerFocus = function onDayPickerFocus() { + this.setState({ + isInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: false + }); + }; + + _proto.onDayPickerBlur = function onDayPickerBlur() { + this.setState({ + isInputFocused: true, + isDayPickerFocused: false, + showKeyboardShortcuts: false + }); + }; + + _proto.onFocusOut = function onFocusOut(e) { + var onFocusChange = this.props.onFocusChange; // In cases where **relatedTarget** is not null, it points to the right + // element here. However, in cases where it is null (such as clicking on a + // specific day) or it is **document.body** (IE11), the appropriate value is **event.target**. + // + // We handle both situations here by using the ` || ` operator to fallback + // to *event.target** when **relatedTarget** is not provided. + + var relatedTarget = e.relatedTarget === document.body ? e.target : e.relatedTarget || e.target; + if (this.dayPickerContainer.contains(relatedTarget)) return; + onFocusChange({ + focused: false + }); + }; + + _proto.setDayPickerContainerRef = function setDayPickerContainerRef(ref) { + if (ref === this.dayPickerContainer) return; + this.removeEventListeners(); + this.dayPickerContainer = ref; + if (!ref) return; + this.addEventListeners(); + }; + + _proto.setContainerRef = function setContainerRef(ref) { + this.container = ref; + }; + + _proto.addEventListeners = function addEventListeners() { + // We manually set event because React has not implemented onFocusIn/onFocusOut. + // Keep an eye on https://github.com/facebook/react/issues/6410 for updates + // We use "blur w/ useCapture param" vs "onfocusout" for FF browser support + this.removeFocusOutEventListener = (0, _consolidatedEvents.addEventListener)(this.dayPickerContainer, 'focusout', this.onFocusOut); + }; + + _proto.removeEventListeners = function removeEventListeners() { + if (this.removeFocusOutEventListener) this.removeFocusOutEventListener(); + }; + + _proto.disableScroll = function disableScroll() { + var _this$props3 = this.props, + appendToBody = _this$props3.appendToBody, + propDisableScroll = _this$props3.disableScroll, + focused = _this$props3.focused; + if (!appendToBody && !propDisableScroll) return; + if (!focused) return; // Disable scroll for every ancestor of this up to the + // document level. This ensures the input and the picker never move. Other + // sibling elements or the picker itself can scroll. + + this.enableScroll = (0, _disableScroll2["default"])(this.container); + } + /* istanbul ignore next */ + ; + + _proto.responsivizePickerPosition = function responsivizePickerPosition() { + // It's possible the portal props have been changed in response to window resizes + // So let's ensure we reset this back to the base state each time + this.setState({ + dayPickerContainerStyles: {} + }); + var _this$props4 = this.props, + openDirection = _this$props4.openDirection, + anchorDirection = _this$props4.anchorDirection, + horizontalMargin = _this$props4.horizontalMargin, + withPortal = _this$props4.withPortal, + withFullScreenPortal = _this$props4.withFullScreenPortal, + appendToBody = _this$props4.appendToBody, + focused = _this$props4.focused; + var dayPickerContainerStyles = this.state.dayPickerContainerStyles; + + if (!focused) { + return; + } + + var isAnchoredLeft = anchorDirection === _constants.ANCHOR_LEFT; + + if (!withPortal && !withFullScreenPortal) { + var containerRect = this.dayPickerContainer.getBoundingClientRect(); + var currentOffset = dayPickerContainerStyles[anchorDirection] || 0; + var containerEdge = isAnchoredLeft ? containerRect[_constants.ANCHOR_RIGHT] : containerRect[_constants.ANCHOR_LEFT]; + this.setState({ + dayPickerContainerStyles: _objectSpread(_objectSpread({}, (0, _getResponsiveContainerStyles["default"])(anchorDirection, currentOffset, containerEdge, horizontalMargin)), appendToBody && (0, _getDetachedContainerStyles["default"])(openDirection, anchorDirection, this.container)) + }); + } + }; + + _proto.showKeyboardShortcutsPanel = function showKeyboardShortcutsPanel() { + this.setState({ + isInputFocused: false, + isDayPickerFocused: true, + showKeyboardShortcuts: true + }); + }; + + _proto.maybeRenderDayPickerWithPortal = function maybeRenderDayPickerWithPortal() { + var _this$props5 = this.props, + focused = _this$props5.focused, + withPortal = _this$props5.withPortal, + withFullScreenPortal = _this$props5.withFullScreenPortal, + appendToBody = _this$props5.appendToBody; + + if (!focused) { + return null; + } + + if (withPortal || withFullScreenPortal || appendToBody) { + return /*#__PURE__*/_react["default"].createElement(_reactPortal.Portal, null, this.renderDayPicker()); + } + + return this.renderDayPicker(); + }; + + _proto.renderDayPicker = function renderDayPicker() { + var _this$props6 = this.props, + anchorDirection = _this$props6.anchorDirection, + openDirection = _this$props6.openDirection, + onDateChange = _this$props6.onDateChange, + date = _this$props6.date, + minDate = _this$props6.minDate, + maxDate = _this$props6.maxDate, + onFocusChange = _this$props6.onFocusChange, + focused = _this$props6.focused, + enableOutsideDays = _this$props6.enableOutsideDays, + numberOfMonths = _this$props6.numberOfMonths, + orientation = _this$props6.orientation, + monthFormat = _this$props6.monthFormat, + dayPickerNavigationInlineStyles = _this$props6.dayPickerNavigationInlineStyles, + navPosition = _this$props6.navPosition, + navPrev = _this$props6.navPrev, + navNext = _this$props6.navNext, + renderNavPrevButton = _this$props6.renderNavPrevButton, + renderNavNextButton = _this$props6.renderNavNextButton, + onPrevMonthClick = _this$props6.onPrevMonthClick, + onNextMonthClick = _this$props6.onNextMonthClick, + onClose = _this$props6.onClose, + withPortal = _this$props6.withPortal, + withFullScreenPortal = _this$props6.withFullScreenPortal, + keepOpenOnDateSelect = _this$props6.keepOpenOnDateSelect, + initialVisibleMonth = _this$props6.initialVisibleMonth, + renderMonthText = _this$props6.renderMonthText, + renderWeekHeaderElement = _this$props6.renderWeekHeaderElement, + renderCalendarDay = _this$props6.renderCalendarDay, + renderDayContents = _this$props6.renderDayContents, + renderCalendarInfo = _this$props6.renderCalendarInfo, + renderMonthElement = _this$props6.renderMonthElement, + calendarInfoPosition = _this$props6.calendarInfoPosition, + hideKeyboardShortcutsPanel = _this$props6.hideKeyboardShortcutsPanel, + firstDayOfWeek = _this$props6.firstDayOfWeek, + customCloseIcon = _this$props6.customCloseIcon, + phrases = _this$props6.phrases, + dayAriaLabelFormat = _this$props6.dayAriaLabelFormat, + daySize = _this$props6.daySize, + isRTL = _this$props6.isRTL, + isOutsideRange = _this$props6.isOutsideRange, + isDayBlocked = _this$props6.isDayBlocked, + isDayHighlighted = _this$props6.isDayHighlighted, + weekDayFormat = _this$props6.weekDayFormat, + css = _this$props6.css, + styles = _this$props6.styles, + verticalHeight = _this$props6.verticalHeight, + transitionDuration = _this$props6.transitionDuration, + verticalSpacing = _this$props6.verticalSpacing, + horizontalMonthPadding = _this$props6.horizontalMonthPadding, + small = _this$props6.small, + reactDates = _this$props6.theme.reactDates; + var _this$state = this.state, + dayPickerContainerStyles = _this$state.dayPickerContainerStyles, + isDayPickerFocused = _this$state.isDayPickerFocused, + showKeyboardShortcuts = _this$state.showKeyboardShortcuts; + var onOutsideClick = !withFullScreenPortal && withPortal ? this.onOutsideClick : undefined; + + var closeIcon = customCloseIcon || /*#__PURE__*/_react["default"].createElement(_CloseButton["default"], null); + + var inputHeight = (0, _getInputHeight["default"])(reactDates, small); + var withAnyPortal = withPortal || withFullScreenPortal; + /* eslint-disable jsx-a11y/no-static-element-interactions */ + + /* eslint-disable jsx-a11y/click-events-have-key-events */ + + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + ref: this.setDayPickerContainerRef + }, css(styles.SingleDatePicker_picker, anchorDirection === _constants.ANCHOR_LEFT && styles.SingleDatePicker_picker__directionLeft, anchorDirection === _constants.ANCHOR_RIGHT && styles.SingleDatePicker_picker__directionRight, openDirection === _constants.OPEN_DOWN && styles.SingleDatePicker_picker__openDown, openDirection === _constants.OPEN_UP && styles.SingleDatePicker_picker__openUp, !withAnyPortal && openDirection === _constants.OPEN_DOWN && { + top: inputHeight + verticalSpacing + }, !withAnyPortal && openDirection === _constants.OPEN_UP && { + bottom: inputHeight + verticalSpacing + }, orientation === _constants.HORIZONTAL_ORIENTATION && styles.SingleDatePicker_picker__horizontal, orientation === _constants.VERTICAL_ORIENTATION && styles.SingleDatePicker_picker__vertical, withAnyPortal && styles.SingleDatePicker_picker__portal, withFullScreenPortal && styles.SingleDatePicker_picker__fullScreenPortal, isRTL && styles.SingleDatePicker_picker__rtl, dayPickerContainerStyles), { + onClick: onOutsideClick + }), /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: date, + minDate: minDate, + maxDate: maxDate, + onDateChange: onDateChange, + onFocusChange: onFocusChange, + orientation: orientation, + enableOutsideDays: enableOutsideDays, + numberOfMonths: numberOfMonths, + monthFormat: monthFormat, + withPortal: withAnyPortal, + focused: focused, + keepOpenOnDateSelect: keepOpenOnDateSelect, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + initialVisibleMonth: initialVisibleMonth, + dayPickerNavigationInlineStyles: dayPickerNavigationInlineStyles, + navPosition: navPosition, + navPrev: navPrev, + navNext: navNext, + renderNavPrevButton: renderNavPrevButton, + renderNavNextButton: renderNavNextButton, + onPrevMonthClick: onPrevMonthClick, + onNextMonthClick: onNextMonthClick, + onClose: onClose, + renderMonthText: renderMonthText, + renderWeekHeaderElement: renderWeekHeaderElement, + renderCalendarDay: renderCalendarDay, + renderDayContents: renderDayContents, + renderCalendarInfo: renderCalendarInfo, + renderMonthElement: renderMonthElement, + calendarInfoPosition: calendarInfoPosition, + isFocused: isDayPickerFocused, + showKeyboardShortcuts: showKeyboardShortcuts, + onBlur: this.onDayPickerBlur, + phrases: phrases, + dayAriaLabelFormat: dayAriaLabelFormat, + daySize: daySize, + isRTL: isRTL, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + isDayHighlighted: isDayHighlighted, + firstDayOfWeek: firstDayOfWeek, + weekDayFormat: weekDayFormat, + verticalHeight: verticalHeight, + transitionDuration: transitionDuration, + horizontalMonthPadding: horizontalMonthPadding + }), withFullScreenPortal && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({}, css(styles.SingleDatePicker_closeButton), { + "aria-label": phrases.closeDatePicker, + type: "button", + onClick: this.onOutsideClick + }), /*#__PURE__*/_react["default"].createElement("div", css(styles.SingleDatePicker_closeButton_svg), closeIcon))); + /* eslint-enable jsx-a11y/no-static-element-interactions */ + + /* eslint-enable jsx-a11y/click-events-have-key-events */ + }; + + _proto.render = function render() { + var _this$props7 = this.props, + id = _this$props7.id, + placeholder = _this$props7.placeholder, + ariaLabel = _this$props7.ariaLabel, + autoComplete = _this$props7.autoComplete, + titleText = _this$props7.titleText, + disabled = _this$props7.disabled, + focused = _this$props7.focused, + required = _this$props7.required, + readOnly = _this$props7.readOnly, + openDirection = _this$props7.openDirection, + showClearDate = _this$props7.showClearDate, + showDefaultInputIcon = _this$props7.showDefaultInputIcon, + inputIconPosition = _this$props7.inputIconPosition, + customCloseIcon = _this$props7.customCloseIcon, + customInputIcon = _this$props7.customInputIcon, + date = _this$props7.date, + onDateChange = _this$props7.onDateChange, + displayFormat = _this$props7.displayFormat, + phrases = _this$props7.phrases, + withPortal = _this$props7.withPortal, + withFullScreenPortal = _this$props7.withFullScreenPortal, + screenReaderInputMessage = _this$props7.screenReaderInputMessage, + isRTL = _this$props7.isRTL, + noBorder = _this$props7.noBorder, + block = _this$props7.block, + small = _this$props7.small, + regular = _this$props7.regular, + verticalSpacing = _this$props7.verticalSpacing, + reopenPickerOnClearDate = _this$props7.reopenPickerOnClearDate, + keepOpenOnDateSelect = _this$props7.keepOpenOnDateSelect, + css = _this$props7.css, + styles = _this$props7.styles, + isOutsideRange = _this$props7.isOutsideRange, + isDayBlocked = _this$props7.isDayBlocked; + var isInputFocused = this.state.isInputFocused; + var enableOutsideClick = !withPortal && !withFullScreenPortal; + var hideFang = verticalSpacing < _constants.FANG_HEIGHT_PX; + + var input = /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + focused: focused, + isFocused: isInputFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + showCaret: !withPortal && !withFullScreenPortal && !hideFang, + showClearDate: showClearDate, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + isOutsideRange: isOutsideRange, + isDayBlocked: isDayBlocked, + customCloseIcon: customCloseIcon, + customInputIcon: customInputIcon, + date: date, + onDateChange: onDateChange, + displayFormat: displayFormat, + onFocusChange: this.onInputFocus, + onKeyDownArrowDown: this.onDayPickerFocus, + onKeyDownQuestionMark: this.showKeyboardShortcutsPanel, + screenReaderMessage: screenReaderInputMessage, + phrases: phrases, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing, + reopenPickerOnClearDate: reopenPickerOnClearDate, + keepOpenOnDateSelect: keepOpenOnDateSelect + }, this.maybeRenderDayPickerWithPortal()); + + return /*#__PURE__*/_react["default"].createElement("div", (0, _extends2["default"])({ + ref: this.setContainerRef + }, css(styles.SingleDatePicker, block && styles.SingleDatePicker__block)), enableOutsideClick && /*#__PURE__*/_react["default"].createElement(_reactOutsideClickHandler["default"], { + onOutsideClick: this.onOutsideClick + }, input), enableOutsideClick || input); + }; + + return SingleDatePicker; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports.PureSingleDatePicker = SingleDatePicker; +SingleDatePicker.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePicker.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref4) { + var _ref4$reactDates = _ref4.reactDates, + color = _ref4$reactDates.color, + zIndex = _ref4$reactDates.zIndex; + return { + SingleDatePicker: { + position: 'relative', + display: 'inline-block' + }, + SingleDatePicker__block: { + display: 'block' + }, + SingleDatePicker_picker: { + zIndex: zIndex + 1, + backgroundColor: color.background, + position: 'absolute' + }, + SingleDatePicker_picker__rtl: { + direction: (0, _noflip["default"])('rtl') + }, + SingleDatePicker_picker__directionLeft: { + left: (0, _noflip["default"])(0) + }, + SingleDatePicker_picker__directionRight: { + right: (0, _noflip["default"])(0) + }, + SingleDatePicker_picker__portal: { + backgroundColor: 'rgba(0, 0, 0, 0.3)', + position: 'fixed', + top: 0, + left: (0, _noflip["default"])(0), + height: '100%', + width: '100%' + }, + SingleDatePicker_picker__fullScreenPortal: { + backgroundColor: color.background + }, + SingleDatePicker_closeButton: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + position: 'absolute', + top: 0, + right: (0, _noflip["default"])(0), + padding: 15, + zIndex: zIndex + 2, + ':hover': { + color: (0, _color2k.darken)(color.core.grayLighter, 0.1), + textDecoration: 'none' + }, + ':focus': { + color: (0, _color2k.darken)(color.core.grayLighter, 0.1), + textDecoration: 'none' + } + }, + SingleDatePicker_closeButton_svg: { + height: 15, + width: 15, + fill: color.core.grayLighter + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(SingleDatePicker); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/SingleDatePickerInput.js b/lib/components/SingleDatePickerInput.js new file mode 100644 index 000000000..9e8a70200 --- /dev/null +++ b/lib/components/SingleDatePickerInput.js @@ -0,0 +1,302 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _reactWithStyles = require("react-with-styles"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _noflip = _interopRequireDefault(require("../utils/noflip")); + +var _DateInput = _interopRequireDefault(require("./DateInput")); + +var _IconPositionShape = _interopRequireDefault(require("../shapes/IconPositionShape")); + +var _CloseButton = _interopRequireDefault(require("./CloseButton")); + +var _CalendarIcon = _interopRequireDefault(require("./CalendarIcon")); + +var _OpenDirectionShape = _interopRequireDefault(require("../shapes/OpenDirectionShape")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)(_objectSpread(_objectSpread({}, _reactWithStyles.withStylesPropTypes), {}, { + id: _propTypes["default"].string.isRequired, + children: _propTypes["default"].node, + placeholder: _propTypes["default"].string, + ariaLabel: _propTypes["default"].string, + autoComplete: _propTypes["default"].string, + titleText: _propTypes["default"].string, + displayValue: _propTypes["default"].string, + screenReaderMessage: _propTypes["default"].string, + focused: _propTypes["default"].bool, + isFocused: _propTypes["default"].bool, + // describes actual DOM focus + disabled: _propTypes["default"].bool, + required: _propTypes["default"].bool, + readOnly: _propTypes["default"].bool, + openDirection: _OpenDirectionShape["default"], + showCaret: _propTypes["default"].bool, + showClearDate: _propTypes["default"].bool, + customCloseIcon: _propTypes["default"].node, + showDefaultInputIcon: _propTypes["default"].bool, + inputIconPosition: _IconPositionShape["default"], + customInputIcon: _propTypes["default"].node, + isRTL: _propTypes["default"].bool, + noBorder: _propTypes["default"].bool, + block: _propTypes["default"].bool, + small: _propTypes["default"].bool, + regular: _propTypes["default"].bool, + verticalSpacing: _airbnbPropTypes.nonNegativeInteger, + onChange: _propTypes["default"].func, + onClearDate: _propTypes["default"].func, + onFocus: _propTypes["default"].func, + onKeyDownShiftTab: _propTypes["default"].func, + onKeyDownTab: _propTypes["default"].func, + onKeyDownArrowDown: _propTypes["default"].func, + onKeyDownQuestionMark: _propTypes["default"].func, + // i18n + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.SingleDatePickerInputPhrases)) +})) : {}; +var defaultProps = { + children: null, + placeholder: 'Select Date', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + displayValue: '', + screenReaderMessage: '', + focused: false, + isFocused: false, + disabled: false, + required: false, + readOnly: false, + openDirection: _constants.OPEN_DOWN, + showCaret: false, + showClearDate: false, + showDefaultInputIcon: false, + inputIconPosition: _constants.ICON_BEFORE_POSITION, + customCloseIcon: null, + customInputIcon: null, + isRTL: false, + noBorder: false, + block: false, + small: false, + regular: false, + verticalSpacing: undefined, + onChange: function onChange() {}, + onClearDate: function onClearDate() {}, + onFocus: function onFocus() {}, + onKeyDownShiftTab: function onKeyDownShiftTab() {}, + onKeyDownTab: function onKeyDownTab() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + // i18n + phrases: _defaultPhrases.SingleDatePickerInputPhrases +}; + +function SingleDatePickerInput(_ref) { + var id = _ref.id, + children = _ref.children, + placeholder = _ref.placeholder, + ariaLabel = _ref.ariaLabel, + autoComplete = _ref.autoComplete, + titleText = _ref.titleText, + displayValue = _ref.displayValue, + focused = _ref.focused, + isFocused = _ref.isFocused, + disabled = _ref.disabled, + required = _ref.required, + readOnly = _ref.readOnly, + showCaret = _ref.showCaret, + showClearDate = _ref.showClearDate, + showDefaultInputIcon = _ref.showDefaultInputIcon, + inputIconPosition = _ref.inputIconPosition, + phrases = _ref.phrases, + onClearDate = _ref.onClearDate, + onChange = _ref.onChange, + onFocus = _ref.onFocus, + onKeyDownShiftTab = _ref.onKeyDownShiftTab, + onKeyDownTab = _ref.onKeyDownTab, + onKeyDownArrowDown = _ref.onKeyDownArrowDown, + onKeyDownQuestionMark = _ref.onKeyDownQuestionMark, + screenReaderMessage = _ref.screenReaderMessage, + customCloseIcon = _ref.customCloseIcon, + customInputIcon = _ref.customInputIcon, + openDirection = _ref.openDirection, + isRTL = _ref.isRTL, + noBorder = _ref.noBorder, + block = _ref.block, + small = _ref.small, + regular = _ref.regular, + verticalSpacing = _ref.verticalSpacing, + css = _ref.css, + styles = _ref.styles; + + var calendarIcon = customInputIcon || /*#__PURE__*/_react["default"].createElement(_CalendarIcon["default"], css(styles.SingleDatePickerInput_calendarIcon_svg)); + + var closeIcon = customCloseIcon || /*#__PURE__*/_react["default"].createElement(_CloseButton["default"], css(styles.SingleDatePickerInput_clearDate_svg, small && styles.SingleDatePickerInput_clearDate_svg__small)); + + var screenReaderText = screenReaderMessage || phrases.keyboardForwardNavigationInstructions; + + var inputIcon = (showDefaultInputIcon || customInputIcon !== null) && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({}, css(styles.SingleDatePickerInput_calendarIcon), { + type: "button", + disabled: disabled, + "aria-label": phrases.focusStartDate, + onClick: onFocus, + tabIndex: "-1" + }), calendarIcon); + + return /*#__PURE__*/_react["default"].createElement("div", css(styles.SingleDatePickerInput, disabled && styles.SingleDatePickerInput__disabled, isRTL && styles.SingleDatePickerInput__rtl, !noBorder && styles.SingleDatePickerInput__withBorder, block && styles.SingleDatePickerInput__block, showClearDate && styles.SingleDatePickerInput__showClearDate), inputIconPosition === _constants.ICON_BEFORE_POSITION && inputIcon, /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + displayValue: displayValue, + screenReaderMessage: screenReaderText, + focused: focused, + isFocused: isFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + showCaret: showCaret, + onChange: onChange, + onFocus: onFocus, + onKeyDownShiftTab: onKeyDownShiftTab, + onKeyDownTab: onKeyDownTab, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + openDirection: openDirection, + verticalSpacing: verticalSpacing, + small: small, + regular: regular, + block: block + }), children, showClearDate && /*#__PURE__*/_react["default"].createElement("button", (0, _extends2["default"])({}, css(styles.SingleDatePickerInput_clearDate, small && styles.SingleDatePickerInput_clearDate__small, !customCloseIcon && styles.SingleDatePickerInput_clearDate__default, !displayValue && styles.SingleDatePickerInput_clearDate__hide), { + type: "button", + "aria-label": phrases.clearDate, + disabled: disabled, + onClick: onClearDate + }), closeIcon), inputIconPosition === _constants.ICON_AFTER_POSITION && inputIcon); +} + +SingleDatePickerInput.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePickerInput.defaultProps = defaultProps; + +var _default = (0, _reactWithStyles.withStyles)(function (_ref2) { + var _ref2$reactDates = _ref2.reactDates, + border = _ref2$reactDates.border, + color = _ref2$reactDates.color; + return { + SingleDatePickerInput: { + display: 'inline-block', + backgroundColor: color.background + }, + SingleDatePickerInput__withBorder: { + borderColor: color.border, + borderWidth: border.pickerInput.borderWidth, + borderStyle: border.pickerInput.borderStyle, + borderRadius: border.pickerInput.borderRadius + }, + SingleDatePickerInput__rtl: { + direction: (0, _noflip["default"])('rtl') + }, + SingleDatePickerInput__disabled: { + backgroundColor: color.disabled + }, + SingleDatePickerInput__block: { + display: 'block' + }, + SingleDatePickerInput__showClearDate: { + paddingRight: 30 // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + SingleDatePickerInput_clearDate: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + padding: 10, + margin: '0 10px 0 5px', + // TODO: should be noflip wrapped and handled by an isRTL prop + position: 'absolute', + right: 0, + // TODO: should be noflip wrapped and handled by an isRTL prop + top: '50%', + transform: 'translateY(-50%)' + }, + SingleDatePickerInput_clearDate__default: { + ':focus': { + background: color.core.border, + borderRadius: '50%' + }, + ':hover': { + background: color.core.border, + borderRadius: '50%' + } + }, + SingleDatePickerInput_clearDate__small: { + padding: 6 + }, + SingleDatePickerInput_clearDate__hide: { + visibility: 'hidden' + }, + SingleDatePickerInput_clearDate_svg: { + fill: color.core.grayLight, + height: 12, + width: 15, + verticalAlign: 'middle' + }, + SingleDatePickerInput_clearDate_svg__small: { + height: 9 + }, + SingleDatePickerInput_calendarIcon: { + background: 'none', + border: 0, + color: 'inherit', + font: 'inherit', + lineHeight: 'normal', + overflow: 'visible', + cursor: 'pointer', + display: 'inline-block', + verticalAlign: 'middle', + padding: 10, + margin: '0 5px 0 10px' // TODO: should be noflip wrapped and handled by an isRTL prop + + }, + SingleDatePickerInput_calendarIcon_svg: { + fill: color.core.grayLight, + height: 15, + width: 14, + verticalAlign: 'middle' + } + }; +}, { + pureComponent: typeof _react["default"].PureComponent !== 'undefined' +})(SingleDatePickerInput); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/components/SingleDatePickerInputController.js b/lib/components/SingleDatePickerInputController.js new file mode 100644 index 000000000..3d10ef9db --- /dev/null +++ b/lib/components/SingleDatePickerInputController.js @@ -0,0 +1,307 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _enzymeShallowEqual = _interopRequireDefault(require("enzyme-shallow-equal")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +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 _SingleDatePickerInput = _interopRequireDefault(require("./SingleDatePickerInput")); + +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 _constants = require("../constants"); + +var propTypes = process.env.NODE_ENV !== "production" ? (0, _airbnbPropTypes.forbidExtraProps)({ + children: _propTypes["default"].node, + date: _reactMomentProptypes["default"].momentObj, + onDateChange: _propTypes["default"].func.isRequired, + focused: _propTypes["default"].bool, + onFocusChange: _propTypes["default"].func.isRequired, + id: _propTypes["default"].string.isRequired, + placeholder: _propTypes["default"].string, + ariaLabel: _propTypes["default"].string, + autoComplete: _propTypes["default"].string, + titleText: _propTypes["default"].string, + screenReaderMessage: _propTypes["default"].string, + showClearDate: _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, + reopenPickerOnClearDate: _propTypes["default"].bool, + isOutsideRange: _propTypes["default"].func, + isDayBlocked: _propTypes["default"].func, + displayFormat: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), + onClose: _propTypes["default"].func, + onKeyDownArrowDown: _propTypes["default"].func, + onKeyDownQuestionMark: _propTypes["default"].func, + customInputIcon: _propTypes["default"].node, + customCloseIcon: _propTypes["default"].node, + // accessibility + isFocused: _propTypes["default"].bool, + // i18n + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.SingleDatePickerInputPhrases)), + isRTL: _propTypes["default"].bool +}) : {}; +var defaultProps = { + children: null, + date: null, + focused: false, + placeholder: '', + ariaLabel: undefined, + autoComplete: 'off', + titleText: undefined, + screenReaderMessage: 'Date', + showClearDate: 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, + reopenPickerOnClearDate: false, + isOutsideRange: function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, (0, _moment["default"])()); + }, + isDayBlocked: function isDayBlocked() { + return false; + }, + displayFormat: function displayFormat() { + return _moment["default"].localeData().longDateFormat('L'); + }, + onClose: function onClose() {}, + onKeyDownArrowDown: function onKeyDownArrowDown() {}, + onKeyDownQuestionMark: function onKeyDownQuestionMark() {}, + customInputIcon: null, + customCloseIcon: null, + // accessibility + isFocused: false, + // i18n + phrases: _defaultPhrases.SingleDatePickerInputPhrases, + isRTL: false +}; + +var SingleDatePickerInputController = /*#__PURE__*/function (_ref2, _ref) { + (0, _inheritsLoose2["default"])(SingleDatePickerInputController, _ref2); + var _proto = SingleDatePickerInputController.prototype; + + _proto[_ref] = function (nextProps, nextState) { + return !(0, _enzymeShallowEqual["default"])(this.props, nextProps) || !(0, _enzymeShallowEqual["default"])(this.state, nextState); + }; + + function SingleDatePickerInputController(props) { + var _this; + + _this = _ref2.call(this, props) || this; + _this.onChange = _this.onChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onFocus = _this.onFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onClearFocus = _this.onClearFocus.bind((0, _assertThisInitialized2["default"])(_this)); + _this.clearDate = _this.clearDate.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + _proto.onChange = function onChange(dateString) { + var _this$props = this.props, + isOutsideRange = _this$props.isOutsideRange, + isDayBlocked = _this$props.isDayBlocked, + keepOpenOnDateSelect = _this$props.keepOpenOnDateSelect, + onDateChange = _this$props.onDateChange, + onFocusChange = _this$props.onFocusChange, + onClose = _this$props.onClose; + var newDate = (0, _toMomentObject["default"])(dateString, this.getDisplayFormat()); + var isValid = newDate && !isOutsideRange(newDate) && !isDayBlocked(newDate); + + if (isValid) { + onDateChange(newDate); + + if (!keepOpenOnDateSelect) { + onFocusChange({ + focused: false + }); + onClose({ + date: newDate + }); + } + } else { + onDateChange(null); + } + }; + + _proto.onFocus = function onFocus() { + var _this$props2 = this.props, + onFocusChange = _this$props2.onFocusChange, + disabled = _this$props2.disabled; + + if (!disabled) { + onFocusChange({ + focused: true + }); + } + }; + + _proto.onClearFocus = function onClearFocus() { + var _this$props3 = this.props, + focused = _this$props3.focused, + onFocusChange = _this$props3.onFocusChange, + onClose = _this$props3.onClose, + date = _this$props3.date; + if (!focused) return; + onFocusChange({ + focused: false + }); + onClose({ + date: date + }); + }; + + _proto.getDisplayFormat = function getDisplayFormat() { + var displayFormat = this.props.displayFormat; + return typeof displayFormat === 'string' ? displayFormat : displayFormat(); + }; + + _proto.getDateString = function getDateString(date) { + var displayFormat = this.getDisplayFormat(); + + if (date && displayFormat) { + return date && date.format(displayFormat); + } + + return (0, _toLocalizedDateString["default"])(date); + }; + + _proto.clearDate = function clearDate() { + var _this$props4 = this.props, + onDateChange = _this$props4.onDateChange, + reopenPickerOnClearDate = _this$props4.reopenPickerOnClearDate, + onFocusChange = _this$props4.onFocusChange; + onDateChange(null); + + if (reopenPickerOnClearDate) { + onFocusChange({ + focused: true + }); + } + }; + + _proto.render = function render() { + var _this$props5 = this.props, + children = _this$props5.children, + id = _this$props5.id, + placeholder = _this$props5.placeholder, + ariaLabel = _this$props5.ariaLabel, + autoComplete = _this$props5.autoComplete, + titleText = _this$props5.titleText, + disabled = _this$props5.disabled, + focused = _this$props5.focused, + isFocused = _this$props5.isFocused, + required = _this$props5.required, + readOnly = _this$props5.readOnly, + openDirection = _this$props5.openDirection, + showClearDate = _this$props5.showClearDate, + showCaret = _this$props5.showCaret, + showDefaultInputIcon = _this$props5.showDefaultInputIcon, + inputIconPosition = _this$props5.inputIconPosition, + customCloseIcon = _this$props5.customCloseIcon, + customInputIcon = _this$props5.customInputIcon, + date = _this$props5.date, + phrases = _this$props5.phrases, + onKeyDownArrowDown = _this$props5.onKeyDownArrowDown, + onKeyDownQuestionMark = _this$props5.onKeyDownQuestionMark, + screenReaderMessage = _this$props5.screenReaderMessage, + isRTL = _this$props5.isRTL, + noBorder = _this$props5.noBorder, + block = _this$props5.block, + small = _this$props5.small, + regular = _this$props5.regular, + verticalSpacing = _this$props5.verticalSpacing; + var displayValue = this.getDateString(date); + return /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: id, + placeholder: placeholder, + ariaLabel: ariaLabel, + autoComplete: autoComplete, + titleText: titleText, + focused: focused, + isFocused: isFocused, + disabled: disabled, + required: required, + readOnly: readOnly, + openDirection: openDirection, + showCaret: showCaret, + onClearDate: this.clearDate, + showClearDate: showClearDate, + showDefaultInputIcon: showDefaultInputIcon, + inputIconPosition: inputIconPosition, + customCloseIcon: customCloseIcon, + customInputIcon: customInputIcon, + displayValue: displayValue, + onChange: this.onChange, + onFocus: this.onFocus, + onKeyDownShiftTab: this.onClearFocus, + onKeyDownArrowDown: onKeyDownArrowDown, + onKeyDownQuestionMark: onKeyDownQuestionMark, + screenReaderMessage: screenReaderMessage, + phrases: phrases, + isRTL: isRTL, + noBorder: noBorder, + block: block, + small: small, + regular: regular, + verticalSpacing: verticalSpacing + }, children); + }; + + return SingleDatePickerInputController; +}(_react["default"].PureComponent || _react["default"].Component, !_react["default"].PureComponent && "shouldComponentUpdate"); + +exports["default"] = SingleDatePickerInputController; +SingleDatePickerInputController.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; +SingleDatePickerInputController.defaultProps = defaultProps; \ No newline at end of file diff --git a/lib/constants.js b/lib/constants.js new file mode 100644 index 000000000..19402edea --- /dev/null +++ b/lib/constants.js @@ -0,0 +1,61 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.WEEKDAYS = exports.VERTICAL_SCROLLABLE = exports.VERTICAL_ORIENTATION = exports.START_DATE = exports.OPEN_UP = exports.OPEN_DOWN = exports.NAV_POSITION_TOP = exports.NAV_POSITION_BOTTOM = exports.MODIFIER_KEY_NAMES = exports.ISO_MONTH_FORMAT = exports.ISO_FORMAT = exports.INFO_POSITION_TOP = exports.INFO_POSITION_BOTTOM = exports.INFO_POSITION_BEFORE = exports.INFO_POSITION_AFTER = exports.ICON_BEFORE_POSITION = exports.ICON_AFTER_POSITION = exports.HORIZONTAL_ORIENTATION = exports.FANG_WIDTH_PX = exports.FANG_HEIGHT_PX = exports.END_DATE = exports.DISPLAY_FORMAT = exports.DEFAULT_VERTICAL_SPACING = exports.DAY_SIZE = exports.BLOCKED_MODIFIER = exports.ANCHOR_RIGHT = exports.ANCHOR_LEFT = void 0; +var DISPLAY_FORMAT = 'L'; +exports.DISPLAY_FORMAT = DISPLAY_FORMAT; +var ISO_FORMAT = 'YYYY-MM-DD'; +exports.ISO_FORMAT = ISO_FORMAT; +var ISO_MONTH_FORMAT = 'YYYY-MM'; // TODO delete this line of dead code on next breaking change + +exports.ISO_MONTH_FORMAT = ISO_MONTH_FORMAT; +var START_DATE = 'startDate'; +exports.START_DATE = START_DATE; +var END_DATE = 'endDate'; +exports.END_DATE = END_DATE; +var HORIZONTAL_ORIENTATION = 'horizontal'; +exports.HORIZONTAL_ORIENTATION = HORIZONTAL_ORIENTATION; +var VERTICAL_ORIENTATION = 'vertical'; +exports.VERTICAL_ORIENTATION = VERTICAL_ORIENTATION; +var VERTICAL_SCROLLABLE = 'verticalScrollable'; +exports.VERTICAL_SCROLLABLE = VERTICAL_SCROLLABLE; +var NAV_POSITION_BOTTOM = 'navPositionBottom'; +exports.NAV_POSITION_BOTTOM = NAV_POSITION_BOTTOM; +var NAV_POSITION_TOP = 'navPositionTop'; +exports.NAV_POSITION_TOP = NAV_POSITION_TOP; +var ICON_BEFORE_POSITION = 'before'; +exports.ICON_BEFORE_POSITION = ICON_BEFORE_POSITION; +var ICON_AFTER_POSITION = 'after'; +exports.ICON_AFTER_POSITION = ICON_AFTER_POSITION; +var INFO_POSITION_TOP = 'top'; +exports.INFO_POSITION_TOP = INFO_POSITION_TOP; +var INFO_POSITION_BOTTOM = 'bottom'; +exports.INFO_POSITION_BOTTOM = INFO_POSITION_BOTTOM; +var INFO_POSITION_BEFORE = 'before'; +exports.INFO_POSITION_BEFORE = INFO_POSITION_BEFORE; +var INFO_POSITION_AFTER = 'after'; +exports.INFO_POSITION_AFTER = INFO_POSITION_AFTER; +var ANCHOR_LEFT = 'left'; +exports.ANCHOR_LEFT = ANCHOR_LEFT; +var ANCHOR_RIGHT = 'right'; +exports.ANCHOR_RIGHT = ANCHOR_RIGHT; +var OPEN_DOWN = 'down'; +exports.OPEN_DOWN = OPEN_DOWN; +var OPEN_UP = 'up'; +exports.OPEN_UP = OPEN_UP; +var DAY_SIZE = 39; +exports.DAY_SIZE = DAY_SIZE; +var BLOCKED_MODIFIER = 'blocked'; +exports.BLOCKED_MODIFIER = BLOCKED_MODIFIER; +var WEEKDAYS = [0, 1, 2, 3, 4, 5, 6]; +exports.WEEKDAYS = WEEKDAYS; +var FANG_WIDTH_PX = 20; +exports.FANG_WIDTH_PX = FANG_WIDTH_PX; +var FANG_HEIGHT_PX = 10; +exports.FANG_HEIGHT_PX = FANG_HEIGHT_PX; +var DEFAULT_VERTICAL_SPACING = 22; +exports.DEFAULT_VERTICAL_SPACING = DEFAULT_VERTICAL_SPACING; +var MODIFIER_KEY_NAMES = new Set(['Shift', 'Control', 'Alt', 'Meta']); +exports.MODIFIER_KEY_NAMES = MODIFIER_KEY_NAMES; \ No newline at end of file diff --git a/lib/css/_datepicker.css b/lib/css/_datepicker.css new file mode 100644 index 000000000..15b5f90e5 --- /dev/null +++ b/lib/css/_datepicker.css @@ -0,0 +1,886 @@ +.PresetDateRangePicker_panel { + padding: 0 22px 11px +} +.PresetDateRangePicker_button { + position: relative; + height: 100%; + text-align: center; + background: 0 0; + border: 2px solid #00a699; + color: #00a699; + padding: 4px 12px; + margin-right: 8px; + font: inherit; + font-weight: 700; + line-height: normal; + overflow: visible; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer +} +.PresetDateRangePicker_button:active { + outline: 0 +} +.PresetDateRangePicker_button__selected { + color: #fff; + background: #00a699 +} +.SingleDatePickerInput { + display: inline-block; + background-color: #fff +} +.SingleDatePickerInput__withBorder { + border-radius: 2px; + border: 1px solid #dbdbdb +} +.SingleDatePickerInput__rtl { + direction: rtl +} +.SingleDatePickerInput__disabled { + background-color: #f2f2f2 +} +.SingleDatePickerInput__block { + display: block +} +.SingleDatePickerInput__showClearDate { + padding-right: 30px +} +.SingleDatePickerInput_clearDate { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + padding: 10px; + margin: 0 10px 0 5px; + position: absolute; + right: 0; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%) +} +.SingleDatePickerInput_clearDate__default:focus, +.SingleDatePickerInput_clearDate__default:hover { + background: #dbdbdb; + border-radius: 50% +} +.SingleDatePickerInput_clearDate__small { + padding: 6px +} +.SingleDatePickerInput_clearDate__hide { + visibility: hidden +} +.SingleDatePickerInput_clearDate_svg { + fill: #82888a; + height: 12px; + width: 15px; + vertical-align: middle +} +.SingleDatePickerInput_clearDate_svg__small { + height: 9px +} +.SingleDatePickerInput_calendarIcon { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + display: inline-block; + vertical-align: middle; + padding: 10px; + margin: 0 5px 0 10px +} +.SingleDatePickerInput_calendarIcon_svg { + fill: #82888a; + height: 15px; + width: 14px; + vertical-align: middle +} +.SingleDatePicker { + position: relative; + display: inline-block +} +.SingleDatePicker__block { + display: block +} +.SingleDatePicker_picker { + z-index: 1; + background-color: #fff; + position: absolute +} +.SingleDatePicker_picker__rtl { + direction: rtl +} +.SingleDatePicker_picker__directionLeft { + left: 0 +} +.SingleDatePicker_picker__directionRight { + right: 0 +} +.SingleDatePicker_picker__portal { + background-color: rgba(0,0,0,.3); + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100% +} +.SingleDatePicker_picker__fullScreenPortal { + background-color: #fff +} +.SingleDatePicker_closeButton { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + position: absolute; + top: 0; + right: 0; + padding: 15px; + z-index: 2 +} +.SingleDatePicker_closeButton:focus, +.SingleDatePicker_closeButton:hover { + color: #b0b3b4; + text-decoration: none +} +.SingleDatePicker_closeButton_svg { + height: 15px; + width: 15px; + fill: #cacccd +} +.DayPickerKeyboardShortcuts_buttonReset { + background: 0 0; + border: 0; + border-radius: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + cursor: pointer; + font-size: 14px +} +.DayPickerKeyboardShortcuts_buttonReset:active { + outline: 0 +} +.DayPickerKeyboardShortcuts_show { + width: 33px; + height: 26px; + position: absolute; + z-index: 2 +} +.DayPickerKeyboardShortcuts_show::before { + content: ""; + display: block; + position: absolute +} +.DayPickerKeyboardShortcuts_show__bottomRight { + bottom: 0; + right: 0 +} +.DayPickerKeyboardShortcuts_show__bottomRight::before { + border-top: 26px solid transparent; + border-right: 33px solid #00a699; + bottom: 0; + right: 0 +} +.DayPickerKeyboardShortcuts_show__bottomRight:hover::before { + border-right: 33px solid #008489 +} +.DayPickerKeyboardShortcuts_show__topRight { + top: 0; + right: 0 +} +.DayPickerKeyboardShortcuts_show__topRight::before { + border-bottom: 26px solid transparent; + border-right: 33px solid #00a699; + top: 0; + right: 0 +} +.DayPickerKeyboardShortcuts_show__topRight:hover::before { + border-right: 33px solid #008489 +} +.DayPickerKeyboardShortcuts_show__topLeft { + top: 0; + left: 0 +} +.DayPickerKeyboardShortcuts_show__topLeft::before { + border-bottom: 26px solid transparent; + border-left: 33px solid #00a699; + top: 0; + left: 0 +} +.DayPickerKeyboardShortcuts_show__topLeft:hover::before { + border-left: 33px solid #008489 +} +.DayPickerKeyboardShortcuts_showSpan { + color: #fff; + position: absolute +} +.DayPickerKeyboardShortcuts_showSpan__bottomRight { + bottom: 0; + right: 5px +} +.DayPickerKeyboardShortcuts_showSpan__topRight { + top: 1px; + right: 5px +} +.DayPickerKeyboardShortcuts_showSpan__topLeft { + top: 1px; + left: 5px +} +.DayPickerKeyboardShortcuts_panel { + overflow: auto; + background: #fff; + border: 1px solid #dbdbdb; + border-radius: 2px; + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + z-index: 2; + padding: 22px; + margin: 33px; + text-align: left +} +.DayPickerKeyboardShortcuts_title { + font-size: 16px; + font-weight: 700; + margin: 0 +} +.DayPickerKeyboardShortcuts_list { + list-style: none; + padding: 0; + font-size: 14px +} +.DayPickerKeyboardShortcuts_close { + position: absolute; + right: 22px; + top: 22px; + z-index: 2 +} +.DayPickerKeyboardShortcuts_close:active { + outline: 0 +} +.DayPickerKeyboardShortcuts_closeSvg { + height: 15px; + width: 15px; + fill: #cacccd +} +.DayPickerKeyboardShortcuts_closeSvg:focus, +.DayPickerKeyboardShortcuts_closeSvg:hover { + fill: #82888a +} +.CalendarDay { + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + font-size: 14px; + text-align: center +} +.CalendarDay:active { + outline: 0 +} +.CalendarDay__defaultCursor { + cursor: default +} +.CalendarDay__default { + border: 1px solid #e4e7e7; + color: #484848; + background: #fff +} +.CalendarDay__default:hover { + background: #e4e7e7; + border: 1px solid #e4e7e7; + color: inherit +} +.CalendarDay__hovered_offset { + background: #f4f5f5; + border: 1px double #e4e7e7; + color: inherit +} +.CalendarDay__outside { + border: 0; + background: #fff; + color: #484848 +} +.CalendarDay__outside:hover { + border: 0 +} +.CalendarDay__blocked_minimum_nights { + background: #fff; + border: 1px solid #eceeee; + color: #cacccd +} +.CalendarDay__blocked_minimum_nights:active, +.CalendarDay__blocked_minimum_nights:hover { + background: #fff; + color: #cacccd +} +.CalendarDay__highlighted_calendar { + background: #ffe8bc; + color: #484848 +} +.CalendarDay__highlighted_calendar:active, +.CalendarDay__highlighted_calendar:hover { + background: #ffce71; + color: #484848 +} +.CalendarDay__selected_span { + background: #66e2da; + border: 1px double #33dacd; + color: #fff +} +.CalendarDay__selected_span:active, +.CalendarDay__selected_span:hover { + background: #33dacd; + border: 1px double #33dacd; + color: #fff +} +.CalendarDay__selected, +.CalendarDay__selected:active, +.CalendarDay__selected:hover { + background: #00a699; + border: 1px double #00a699; + color: #fff +} +.CalendarDay__hovered_span, +.CalendarDay__hovered_span:hover { + background: #b2f1ec; + border: 1px double #80e8e0; + color: #007a87 +} +.CalendarDay__hovered_span:active { + background: #80e8e0; + border: 1px double #80e8e0; + color: #007a87 +} +.CalendarDay__blocked_calendar, +.CalendarDay__blocked_calendar:active, +.CalendarDay__blocked_calendar:hover { + background: #cacccd; + border: 1px solid #cacccd; + color: #82888a +} +.CalendarDay__blocked_out_of_range, +.CalendarDay__blocked_out_of_range:active, +.CalendarDay__blocked_out_of_range:hover { + background: #fff; + border: 1px solid #e4e7e7; + color: #cacccd +} +.CalendarDay__hovered_start_first_possible_end { + background: #eceeee; + border: 1px double #eceeee +} +.CalendarDay__hovered_start_blocked_min_nights { + background: #eceeee; + border: 1px double #e4e7e7 +} +.CalendarMonth { + background: #fff; + text-align: center; + vertical-align: top; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} +.CalendarMonth_table { + border-collapse: collapse; + border-spacing: 0 +} +.CalendarMonth_verticalSpacing { + border-collapse: separate +} +.CalendarMonth_caption { + color: #484848; + font-size: 18px; + text-align: center; + padding-top: 22px; + padding-bottom: 37px; + caption-side: initial +} +.CalendarMonth_caption__verticalScrollable { + padding-top: 12px; + padding-bottom: 7px +} +.CalendarMonthGrid { + background: #fff; + text-align: left; + z-index: 0 +} +.CalendarMonthGrid__animating { + z-index: 1 +} +.CalendarMonthGrid__horizontal { + position: absolute; + left: 9px +} +.CalendarMonthGrid__vertical, +.CalendarMonthGrid__vertical_scrollable { + margin: 0 auto +} +.CalendarMonthGrid_month__horizontal { + display: inline-block; + vertical-align: top; + min-height: 100% +} +.CalendarMonthGrid_month__hideForAnimation { + position: absolute; + z-index: -1; + opacity: 0; + pointer-events: none +} +.CalendarMonthGrid_month__hidden { + visibility: hidden +} +.DayPickerNavigation { + position: relative; + z-index: 2 +} +.DayPickerNavigation__horizontal { + height: 0 +} +.DayPickerNavigation__verticalScrollable_prevNav { + z-index: 1 +} +.DayPickerNavigation__verticalDefault { + position: absolute; + width: 100%; + height: 52px; + bottom: 0; + left: 0 +} +.DayPickerNavigation__verticalScrollableDefault { + position: relative +} +.DayPickerNavigation__bottom { + height: auto +} +.DayPickerNavigation__bottomDefault { + -webkit-box-pack: justify; + -ms-flex-pack: justify; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-justify-content: space-between; + justify-content: space-between +} +.DayPickerNavigation_button { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 0; + padding: 0; + margin: 0 +} +.DayPickerNavigation_button__default { + border: 1px solid #e4e7e7; + background-color: #fff; + color: #757575 +} +.DayPickerNavigation_button__default:focus, +.DayPickerNavigation_button__default:hover { + border: 1px solid #c4c4c4 +} +.DayPickerNavigation_button__default:active { + background: #f2f2f2 +} +.DayPickerNavigation_button__disabled { + cursor: default; + border: 1px solid #f2f2f2 +} +.DayPickerNavigation_button__disabled:focus, +.DayPickerNavigation_button__disabled:hover { + border: 1px solid #f2f2f2 +} +.DayPickerNavigation_button__disabled:active { + background: 0 0 +} +.DayPickerNavigation_button__horizontalDefault { + position: absolute; + top: 18px; + line-height: .78; + border-radius: 3px; + padding: 6px 9px +} +.DayPickerNavigation_bottomButton__horizontalDefault { + position: static; + margin: -10px 22px 30px +} +.DayPickerNavigation_leftButton__horizontalDefault { + left: 22px +} +.DayPickerNavigation_rightButton__horizontalDefault { + right: 22px +} +.DayPickerNavigation_button__verticalDefault { + padding: 5px; + background: #fff; + box-shadow: 0 0 5px 2px rgba(0,0,0,.1); + position: relative; + display: inline-block; + text-align: center; + height: 100%; + width: 50% +} +.DayPickerNavigation_nextButton__verticalDefault { + border-left: 0 +} +.DayPickerNavigation_nextButton__verticalScrollableDefault, +.DayPickerNavigation_prevButton__verticalScrollableDefault { + width: 100% +} +.DayPickerNavigation_svg__horizontal { + height: 19px; + width: 19px; + fill: #82888a; + display: block +} +.DayPickerNavigation_svg__vertical { + height: 42px; + width: 42px; + fill: #484848 +} +.DayPickerNavigation_svg__disabled { + fill: #f2f2f2 +} +.DayPicker { + background: #fff; + position: relative; + text-align: left +} +.DayPicker__horizontal { + background: #fff +} +.DayPicker__verticalScrollable { + height: 100% +} +.DayPicker__hidden { + visibility: hidden +} +.DayPicker__withBorder { + box-shadow: 0 2px 6px rgba(0,0,0,.05),0 0 0 1px rgba(0,0,0,.07); + border-radius: 3px +} +.DayPicker_portal__horizontal { + box-shadow: none; + position: absolute; + left: 50%; + top: 50% +} +.DayPicker_portal__vertical { + position: initial +} +.DayPicker_focusRegion { + outline: 0 +} +.DayPicker_calendarInfo__horizontal, +.DayPicker_wrapper__horizontal { + display: inline-block; + vertical-align: top +} +.DayPicker_weekHeaders { + position: relative +} +.DayPicker_weekHeaders__horizontal { + margin-left: 9px +} +.DayPicker_weekHeader { + color: #757575; + position: absolute; + top: 62px; + z-index: 2; + text-align: left +} +.DayPicker_weekHeader__vertical { + left: 50% +} +.DayPicker_weekHeader__verticalScrollable { + top: 0; + display: table-row; + border-bottom: 1px solid #dbdbdb; + background: #fff; + margin-left: 0; + left: 0; + width: 100%; + text-align: center +} +.DayPicker_weekHeader_ul { + list-style: none; + margin: 1px 0; + padding-left: 0; + padding-right: 0; + font-size: 14px +} +.DayPicker_weekHeader_li { + display: inline-block; + text-align: center +} +.DayPicker_transitionContainer { + position: relative; + overflow: hidden; + border-radius: 3px +} +.DayPicker_transitionContainer__horizontal { + -webkit-transition: height .2s ease-in-out; + -moz-transition: height .2s ease-in-out; + transition: height .2s ease-in-out +} +.DayPicker_transitionContainer__vertical { + width: 100% +} +.DayPicker_transitionContainer__verticalScrollable { + padding-top: 20px; + height: 100%; + position: absolute; + top: 0; + bottom: 0; + right: 0; + left: 0; + overflow-y: scroll +} +.DateInput { + margin: 0; + padding: 0; + background: #fff; + position: relative; + display: inline-block; + width: 130px; + vertical-align: middle +} +.DateInput__small { + width: 97px +} +.DateInput__block { + width: 100% +} +.DateInput__disabled { + background: #f2f2f2; + color: #dbdbdb +} +.DateInput_input { + font-weight: 200; + font-size: 19px; + line-height: 24px; + color: #484848; + background-color: #fff; + width: 100%; + padding: 11px 11px 9px; + border: 0; + border-top: 0; + border-right: 0; + border-bottom: 2px solid transparent; + border-left: 0; + border-radius: 0 +} +.DateInput_input__small { + font-size: 15px; + line-height: 18px; + letter-spacing: .2px; + padding: 7px 7px 5px +} +.DateInput_input__regular { + font-weight: inherit +} +.DateInput_input__readOnly { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none +} +.DateInput_input__focused { + outline: 0; + background: #fff; + border: 0; + border-top: 0; + border-right: 0; + border-bottom: 2px solid #008489; + border-left: 0 +} +.DateInput_input__disabled { + background: #f2f2f2; + font-style: italic +} +.DateInput_screenReaderMessage { + border: 0; + clip: rect(0,0,0,0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px +} +.DateInput_fang { + position: absolute; + width: 20px; + height: 10px; + left: 22px; + z-index: 2 +} +.DateInput_fangShape { + fill: #fff +} +.DateInput_fangStroke { + stroke: #dbdbdb; + fill: transparent +} +.DateRangePickerInput { + background-color: #fff; + display: inline-block +} +.DateRangePickerInput__disabled { + background: #f2f2f2 +} +.DateRangePickerInput__withBorder { + border-radius: 2px; + border: 1px solid #dbdbdb +} +.DateRangePickerInput__rtl { + direction: rtl +} +.DateRangePickerInput__block { + display: block +} +.DateRangePickerInput__showClearDates { + padding-right: 30px +} +.DateRangePickerInput_arrow { + display: inline-block; + vertical-align: middle; + color: #484848 +} +.DateRangePickerInput_arrow_svg { + vertical-align: middle; + fill: #484848; + height: 24px; + width: 24px +} +.DateRangePickerInput_clearDates { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + padding: 10px; + margin: 0 10px 0 5px; + position: absolute; + right: 0; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%) +} +.DateRangePickerInput_clearDates__small { + padding: 6px +} +.DateRangePickerInput_clearDates_default:focus, +.DateRangePickerInput_clearDates_default:hover { + background: #dbdbdb; + border-radius: 50% +} +.DateRangePickerInput_clearDates__hide { + visibility: hidden +} +.DateRangePickerInput_clearDates_svg { + fill: #82888a; + height: 12px; + width: 15px; + vertical-align: middle +} +.DateRangePickerInput_clearDates_svg__small { + height: 9px +} +.DateRangePickerInput_calendarIcon { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + display: inline-block; + vertical-align: middle; + padding: 10px; + margin: 0 5px 0 10px +} +.DateRangePickerInput_calendarIcon_svg { + fill: #82888a; + height: 15px; + width: 14px; + vertical-align: middle +} +.DateRangePicker { + position: relative; + display: inline-block +} +.DateRangePicker__block { + display: block +} +.DateRangePicker_picker { + z-index: 1; + background-color: #fff; + position: absolute +} +.DateRangePicker_picker__rtl { + direction: rtl +} +.DateRangePicker_picker__directionLeft { + left: 0 +} +.DateRangePicker_picker__directionRight { + right: 0 +} +.DateRangePicker_picker__portal { + background-color: rgba(0,0,0,.3); + position: fixed; + top: 0; + left: 0; + height: 100%; + width: 100% +} +.DateRangePicker_picker__fullScreenPortal { + background-color: #fff +} +.DateRangePicker_closeButton { + background: 0 0; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + cursor: pointer; + position: absolute; + top: 0; + right: 0; + padding: 15px; + z-index: 2 +} +.DateRangePicker_closeButton:focus, +.DateRangePicker_closeButton:hover { + color: #b0b3b4; + text-decoration: none +} +.DateRangePicker_closeButton_svg { + height: 15px; + width: 15px; + fill: #cacccd +} \ No newline at end of file diff --git a/lib/defaultPhrases.js b/lib/defaultPhrases.js new file mode 100644 index 000000000..012ed08ee --- /dev/null +++ b/lib/defaultPhrases.js @@ -0,0 +1,248 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.SingleDatePickerPhrases = exports.SingleDatePickerInputPhrases = exports.DayPickerPhrases = exports.DayPickerNavigationPhrases = exports.DayPickerKeyboardShortcutsPhrases = exports.DateRangePickerPhrases = exports.DateRangePickerInputPhrases = exports.CalendarDayPhrases = void 0; +var calendarLabel = 'Calendar'; +var roleDescription = 'datepicker'; +var closeDatePicker = 'Close'; +var focusStartDate = 'Interact with the calendar and add the check-in date for your trip.'; +var clearDate = 'Clear Date'; +var clearDates = 'Clear Dates'; +var jumpToPrevMonth = 'Move backward to switch to the previous month.'; +var jumpToNextMonth = 'Move forward to switch to the next month.'; +var keyboardShortcuts = 'Keyboard Shortcuts'; +var showKeyboardShortcutsPanel = 'Open the keyboard shortcuts panel.'; +var hideKeyboardShortcutsPanel = 'Close the shortcuts panel.'; +var openThisPanel = 'Open this panel.'; +var enterKey = 'Enter key'; +var leftArrowRightArrow = 'Right and left arrow keys'; +var upArrowDownArrow = 'up and down arrow keys'; +var pageUpPageDown = 'page up and page down keys'; +var homeEnd = 'Home and end keys'; +var escape = 'Escape key'; +var questionMark = 'Question mark'; +var selectFocusedDate = 'Select the date in focus.'; +var moveFocusByOneDay = 'Move backward (left) and forward (right) by one day.'; +var moveFocusByOneWeek = 'Move backward (up) and forward (down) by one week.'; +var moveFocusByOneMonth = 'Switch months.'; +var moveFocustoStartAndEndOfWeek = 'Go to the first or last day of a week.'; +var returnFocusToInput = 'Return to the date input field.'; +var keyboardForwardNavigationInstructions = 'Navigate forward to interact with the calendar and select a date. Press the question mark key to get the keyboard shortcuts for changing dates.'; +var keyboardBackwardNavigationInstructions = 'Navigate backward to interact with the calendar and select a date. Press the question mark key to get the keyboard shortcuts for changing dates.'; + +var chooseAvailableStartDate = function chooseAvailableStartDate(_ref) { + var date = _ref.date; + return "Choose ".concat(date, " as your check-in date. It\u2019s available."); +}; + +var chooseAvailableEndDate = function chooseAvailableEndDate(_ref2) { + var date = _ref2.date; + return "Choose ".concat(date, " as your check-out date. It\u2019s available."); +}; + +var chooseAvailableDate = function chooseAvailableDate(_ref3) { + var date = _ref3.date; + return date; +}; + +var dateIsUnavailable = function dateIsUnavailable(_ref4) { + var date = _ref4.date; + return "Not available. ".concat(date); +}; + +var dateIsSelected = function dateIsSelected(_ref5) { + var date = _ref5.date; + return "Selected. ".concat(date); +}; + +var dateIsSelectedAsStartDate = function dateIsSelectedAsStartDate(_ref6) { + var date = _ref6.date; + return "Selected as start date. ".concat(date); +}; + +var dateIsSelectedAsEndDate = function dateIsSelectedAsEndDate(_ref7) { + var date = _ref7.date; + return "Selected as end date. ".concat(date); +}; + +var _default = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + focusStartDate: focusStartDate, + clearDate: clearDate, + clearDates: clearDates, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +exports["default"] = _default; +var DateRangePickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + clearDates: clearDates, + focusStartDate: focusStartDate, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +exports.DateRangePickerPhrases = DateRangePickerPhrases; +var DateRangePickerInputPhrases = { + focusStartDate: focusStartDate, + clearDates: clearDates, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions +}; +exports.DateRangePickerInputPhrases = DateRangePickerInputPhrases; +var SingleDatePickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + closeDatePicker: closeDatePicker, + clearDate: clearDate, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions, + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected +}; +exports.SingleDatePickerPhrases = SingleDatePickerPhrases; +var SingleDatePickerInputPhrases = { + clearDate: clearDate, + keyboardForwardNavigationInstructions: keyboardForwardNavigationInstructions, + keyboardBackwardNavigationInstructions: keyboardBackwardNavigationInstructions +}; +exports.SingleDatePickerInputPhrases = SingleDatePickerInputPhrases; +var DayPickerPhrases = { + calendarLabel: calendarLabel, + roleDescription: roleDescription, + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth, + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput, + chooseAvailableStartDate: chooseAvailableStartDate, + chooseAvailableEndDate: chooseAvailableEndDate, + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +exports.DayPickerPhrases = DayPickerPhrases; +var DayPickerKeyboardShortcutsPhrases = { + keyboardShortcuts: keyboardShortcuts, + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel, + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel, + openThisPanel: openThisPanel, + enterKey: enterKey, + leftArrowRightArrow: leftArrowRightArrow, + upArrowDownArrow: upArrowDownArrow, + pageUpPageDown: pageUpPageDown, + homeEnd: homeEnd, + escape: escape, + questionMark: questionMark, + selectFocusedDate: selectFocusedDate, + moveFocusByOneDay: moveFocusByOneDay, + moveFocusByOneWeek: moveFocusByOneWeek, + moveFocusByOneMonth: moveFocusByOneMonth, + moveFocustoStartAndEndOfWeek: moveFocustoStartAndEndOfWeek, + returnFocusToInput: returnFocusToInput +}; +exports.DayPickerKeyboardShortcutsPhrases = DayPickerKeyboardShortcutsPhrases; +var DayPickerNavigationPhrases = { + jumpToPrevMonth: jumpToPrevMonth, + jumpToNextMonth: jumpToNextMonth +}; +exports.DayPickerNavigationPhrases = DayPickerNavigationPhrases; +var CalendarDayPhrases = { + chooseAvailableDate: chooseAvailableDate, + dateIsUnavailable: dateIsUnavailable, + dateIsSelected: dateIsSelected, + dateIsSelectedAsStartDate: dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate: dateIsSelectedAsEndDate +}; +exports.CalendarDayPhrases = CalendarDayPhrases; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 000000000..e1036ab9c --- /dev/null +++ b/lib/index.js @@ -0,0 +1,167 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "CalendarDay", { + enumerable: true, + get: function get() { + return _CalendarDay["default"]; + } +}); +Object.defineProperty(exports, "CalendarMonth", { + enumerable: true, + get: function get() { + return _CalendarMonth["default"]; + } +}); +Object.defineProperty(exports, "CalendarMonthGrid", { + enumerable: true, + get: function get() { + return _CalendarMonthGrid["default"]; + } +}); +Object.defineProperty(exports, "DateRangePicker", { + enumerable: true, + get: function get() { + return _DateRangePicker["default"]; + } +}); +Object.defineProperty(exports, "DateRangePickerInput", { + enumerable: true, + get: function get() { + return _DateRangePickerInput["default"]; + } +}); +Object.defineProperty(exports, "DateRangePickerInputController", { + enumerable: true, + get: function get() { + return _DateRangePickerInputController["default"]; + } +}); +Object.defineProperty(exports, "DateRangePickerShape", { + enumerable: true, + get: function get() { + return _DateRangePickerShape["default"]; + } +}); +Object.defineProperty(exports, "DayPicker", { + enumerable: true, + get: function get() { + return _DayPicker["default"]; + } +}); +Object.defineProperty(exports, "DayPickerRangeController", { + enumerable: true, + get: function get() { + return _DayPickerRangeController["default"]; + } +}); +Object.defineProperty(exports, "DayPickerSingleDateController", { + enumerable: true, + get: function get() { + return _DayPickerSingleDateController["default"]; + } +}); +Object.defineProperty(exports, "SingleDatePicker", { + enumerable: true, + get: function get() { + return _SingleDatePicker["default"]; + } +}); +Object.defineProperty(exports, "SingleDatePickerInput", { + enumerable: true, + get: function get() { + return _SingleDatePickerInput["default"]; + } +}); +Object.defineProperty(exports, "SingleDatePickerShape", { + enumerable: true, + get: function get() { + return _SingleDatePickerShape["default"]; + } +}); +Object.defineProperty(exports, "isInclusivelyAfterDay", { + enumerable: true, + get: function get() { + return _isInclusivelyAfterDay["default"]; + } +}); +Object.defineProperty(exports, "isInclusivelyBeforeDay", { + enumerable: true, + get: function get() { + return _isInclusivelyBeforeDay["default"]; + } +}); +Object.defineProperty(exports, "isNextDay", { + enumerable: true, + get: function get() { + return _isNextDay["default"]; + } +}); +Object.defineProperty(exports, "isSameDay", { + enumerable: true, + get: function get() { + return _isSameDay["default"]; + } +}); +Object.defineProperty(exports, "toISODateString", { + enumerable: true, + get: function get() { + return _toISODateString["default"]; + } +}); +Object.defineProperty(exports, "toLocalizedDateString", { + enumerable: true, + get: function get() { + return _toLocalizedDateString["default"]; + } +}); +Object.defineProperty(exports, "toMomentObject", { + enumerable: true, + get: function get() { + return _toMomentObject["default"]; + } +}); + +var _CalendarDay = _interopRequireDefault(require("./components/CalendarDay")); + +var _CalendarMonth = _interopRequireDefault(require("./components/CalendarMonth")); + +var _CalendarMonthGrid = _interopRequireDefault(require("./components/CalendarMonthGrid")); + +var _DateRangePicker = _interopRequireDefault(require("./components/DateRangePicker")); + +var _DateRangePickerInput = _interopRequireDefault(require("./components/DateRangePickerInput")); + +var _DateRangePickerInputController = _interopRequireDefault(require("./components/DateRangePickerInputController")); + +var _DateRangePickerShape = _interopRequireDefault(require("./shapes/DateRangePickerShape")); + +var _DayPicker = _interopRequireDefault(require("./components/DayPicker")); + +var _DayPickerRangeController = _interopRequireDefault(require("./components/DayPickerRangeController")); + +var _DayPickerSingleDateController = _interopRequireDefault(require("./components/DayPickerSingleDateController")); + +var _SingleDatePicker = _interopRequireDefault(require("./components/SingleDatePicker")); + +var _SingleDatePickerInput = _interopRequireDefault(require("./components/SingleDatePickerInput")); + +var _SingleDatePickerShape = _interopRequireDefault(require("./shapes/SingleDatePickerShape")); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("./utils/isInclusivelyAfterDay")); + +var _isInclusivelyBeforeDay = _interopRequireDefault(require("./utils/isInclusivelyBeforeDay")); + +var _isNextDay = _interopRequireDefault(require("./utils/isNextDay")); + +var _isSameDay = _interopRequireDefault(require("./utils/isSameDay")); + +var _toISODateString = _interopRequireDefault(require("./utils/toISODateString")); + +var _toLocalizedDateString = _interopRequireDefault(require("./utils/toLocalizedDateString")); + +var _toMomentObject = _interopRequireDefault(require("./utils/toMomentObject")); \ No newline at end of file diff --git a/lib/initialize.js b/lib/initialize.js new file mode 100644 index 000000000..23bd2e65a --- /dev/null +++ b/lib/initialize.js @@ -0,0 +1,7 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _registerCSSInterfaceWithDefaultTheme = _interopRequireDefault(require("./utils/registerCSSInterfaceWithDefaultTheme")); + +(0, _registerCSSInterfaceWithDefaultTheme["default"])(); \ No newline at end of file diff --git a/lib/shapes/AnchorDirectionShape.js b/lib/shapes/AnchorDirectionShape.js new file mode 100644 index 000000000..c925aa2fc --- /dev/null +++ b/lib/shapes/AnchorDirectionShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.ANCHOR_LEFT, _constants.ANCHOR_RIGHT]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/CalendarInfoPositionShape.js b/lib/shapes/CalendarInfoPositionShape.js new file mode 100644 index 000000000..57d7629ca --- /dev/null +++ b/lib/shapes/CalendarInfoPositionShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.INFO_POSITION_TOP, _constants.INFO_POSITION_BOTTOM, _constants.INFO_POSITION_BEFORE, _constants.INFO_POSITION_AFTER]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/DateRangePickerShape.js b/lib/shapes/DateRangePickerShape.js new file mode 100644 index 000000000..346bf71f2 --- /dev/null +++ b/lib/shapes/DateRangePickerShape.js @@ -0,0 +1,125 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _FocusedInputShape = _interopRequireDefault(require("./FocusedInputShape")); + +var _IconPositionShape = _interopRequireDefault(require("./IconPositionShape")); + +var _OrientationShape = _interopRequireDefault(require("./OrientationShape")); + +var _DisabledShape = _interopRequireDefault(require("./DisabledShape")); + +var _AnchorDirectionShape = _interopRequireDefault(require("./AnchorDirectionShape")); + +var _OpenDirectionShape = _interopRequireDefault(require("./OpenDirectionShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("./DayOfWeekShape")); + +var _CalendarInfoPositionShape = _interopRequireDefault(require("./CalendarInfoPositionShape")); + +var _NavPositionShape = _interopRequireDefault(require("./NavPositionShape")); + +var _default = { + // required props for a functional interactive DateRangePicker + startDate: _reactMomentProptypes["default"].momentObj, + endDate: _reactMomentProptypes["default"].momentObj, + onDatesChange: _propTypes["default"].func.isRequired, + focusedInput: _FocusedInputShape["default"], + onFocusChange: _propTypes["default"].func.isRequired, + onClose: _propTypes["default"].func, + // input related props + startDateId: _propTypes["default"].string.isRequired, + startDatePlaceholderText: _propTypes["default"].string, + startDateOffset: _propTypes["default"].func, + endDateOffset: _propTypes["default"].func, + endDateId: _propTypes["default"].string.isRequired, + endDatePlaceholderText: _propTypes["default"].string, + startDateAriaLabel: _propTypes["default"].string, + endDateAriaLabel: _propTypes["default"].string, + startDateTitleText: _propTypes["default"].string, + endDateTitleText: _propTypes["default"].string, + disabled: _DisabledShape["default"], + required: _propTypes["default"].bool, + readOnly: _propTypes["default"].bool, + screenReaderInputMessage: _propTypes["default"].string, + showClearDates: _propTypes["default"].bool, + showDefaultInputIcon: _propTypes["default"].bool, + inputIconPosition: _IconPositionShape["default"], + customInputIcon: _propTypes["default"].node, + customArrowIcon: _propTypes["default"].node, + customCloseIcon: _propTypes["default"].node, + noBorder: _propTypes["default"].bool, + block: _propTypes["default"].bool, + small: _propTypes["default"].bool, + regular: _propTypes["default"].bool, + keepFocusOnInput: _propTypes["default"].bool, + autoComplete: _propTypes["default"].string, + // calendar presentation and interaction related props + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: _propTypes["default"].func, + orientation: _OrientationShape["default"], + anchorDirection: _AnchorDirectionShape["default"], + openDirection: _OpenDirectionShape["default"], + horizontalMargin: _propTypes["default"].number, + withPortal: _propTypes["default"].bool, + withFullScreenPortal: _propTypes["default"].bool, + appendToBody: _propTypes["default"].bool, + disableScroll: _propTypes["default"].bool, + daySize: _airbnbPropTypes.nonNegativeInteger, + isRTL: _propTypes["default"].bool, + firstDayOfWeek: _DayOfWeekShape["default"], + initialVisibleMonth: _propTypes["default"].func, + numberOfMonths: _propTypes["default"].number, + keepOpenOnDateSelect: _propTypes["default"].bool, + reopenPickerOnClearDates: _propTypes["default"].bool, + renderCalendarInfo: _propTypes["default"].func, + calendarInfoPosition: _CalendarInfoPositionShape["default"], + hideKeyboardShortcutsPanel: _propTypes["default"].bool, + verticalHeight: _airbnbPropTypes.nonNegativeInteger, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + verticalSpacing: _airbnbPropTypes.nonNegativeInteger, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + // navigation related props + dayPickerNavigationInlineStyles: _propTypes["default"].object, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + // day presentation and interaction related props + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + minimumNights: _propTypes["default"].number, + minDate: _reactMomentProptypes["default"].momentObj, + maxDate: _reactMomentProptypes["default"].momentObj, + enableOutsideDays: _propTypes["default"].bool, + isDayBlocked: _propTypes["default"].func, + isOutsideRange: _propTypes["default"].func, + isDayHighlighted: _propTypes["default"].func, + // internationalization props + displayFormat: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), + monthFormat: _propTypes["default"].string, + weekDayFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.DateRangePickerPhrases)), + dayAriaLabelFormat: _propTypes["default"].string +}; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/DayOfWeekShape.js b/lib/shapes/DayOfWeekShape.js new file mode 100644 index 000000000..1016d178b --- /dev/null +++ b/lib/shapes/DayOfWeekShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf(_constants.WEEKDAYS); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/DisabledShape.js b/lib/shapes/DisabledShape.js new file mode 100644 index 000000000..56a2bedce --- /dev/null +++ b/lib/shapes/DisabledShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOfType([_propTypes["default"].bool, _propTypes["default"].oneOf([_constants.START_DATE, _constants.END_DATE])]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/FocusedInputShape.js b/lib/shapes/FocusedInputShape.js new file mode 100644 index 000000000..16456c81d --- /dev/null +++ b/lib/shapes/FocusedInputShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.START_DATE, _constants.END_DATE]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/IconPositionShape.js b/lib/shapes/IconPositionShape.js new file mode 100644 index 000000000..02a76a136 --- /dev/null +++ b/lib/shapes/IconPositionShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.ICON_BEFORE_POSITION, _constants.ICON_AFTER_POSITION]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/ModifiersShape.js b/lib/shapes/ModifiersShape.js new file mode 100644 index 000000000..e81968cdb --- /dev/null +++ b/lib/shapes/ModifiersShape.js @@ -0,0 +1,35 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _default = (0, _airbnbPropTypes.and)([_propTypes["default"].instanceOf(Set), function modifiers(props, propName) { + for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + rest[_key - 2] = arguments[_key]; + } + + var propValue = props[propName]; + var firstError; + (0, _toConsumableArray2["default"])(propValue).some(function (v, i) { + var _PropTypes$string; + + var fakePropName = "".concat(propName, ": index ").concat(i); + firstError = (_PropTypes$string = _propTypes["default"].string).isRequired.apply(_PropTypes$string, [(0, _defineProperty2["default"])({}, fakePropName, v), fakePropName].concat(rest)); + return firstError != null; + }); + return firstError == null ? null : firstError; +}], 'Modifiers (Set of Strings)'); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/NavPositionShape.js b/lib/shapes/NavPositionShape.js new file mode 100644 index 000000000..d9fcb4b09 --- /dev/null +++ b/lib/shapes/NavPositionShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.NAV_POSITION_BOTTOM, _constants.NAV_POSITION_TOP]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/OpenDirectionShape.js b/lib/shapes/OpenDirectionShape.js new file mode 100644 index 000000000..3942eb8fa --- /dev/null +++ b/lib/shapes/OpenDirectionShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.OPEN_DOWN, _constants.OPEN_UP]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/OrientationShape.js b/lib/shapes/OrientationShape.js new file mode 100644 index 000000000..b96528d37 --- /dev/null +++ b/lib/shapes/OrientationShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.HORIZONTAL_ORIENTATION, _constants.VERTICAL_ORIENTATION]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/ScrollableOrientationShape.js b/lib/shapes/ScrollableOrientationShape.js new file mode 100644 index 000000000..cb4ef90d5 --- /dev/null +++ b/lib/shapes/ScrollableOrientationShape.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _constants = require("../constants"); + +var _default = _propTypes["default"].oneOf([_constants.HORIZONTAL_ORIENTATION, _constants.VERTICAL_ORIENTATION, _constants.VERTICAL_SCROLLABLE]); + +exports["default"] = _default; \ No newline at end of file diff --git a/lib/shapes/SingleDatePickerShape.js b/lib/shapes/SingleDatePickerShape.js new file mode 100644 index 000000000..8d3057254 --- /dev/null +++ b/lib/shapes/SingleDatePickerShape.js @@ -0,0 +1,112 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _propTypes = _interopRequireDefault(require("prop-types")); + +var _reactMomentProptypes = _interopRequireDefault(require("react-moment-proptypes")); + +var _airbnbPropTypes = require("airbnb-prop-types"); + +var _defaultPhrases = require("../defaultPhrases"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../utils/getPhrasePropTypes")); + +var _IconPositionShape = _interopRequireDefault(require("./IconPositionShape")); + +var _OrientationShape = _interopRequireDefault(require("./OrientationShape")); + +var _AnchorDirectionShape = _interopRequireDefault(require("./AnchorDirectionShape")); + +var _OpenDirectionShape = _interopRequireDefault(require("./OpenDirectionShape")); + +var _DayOfWeekShape = _interopRequireDefault(require("./DayOfWeekShape")); + +var _CalendarInfoPositionShape = _interopRequireDefault(require("./CalendarInfoPositionShape")); + +var _NavPositionShape = _interopRequireDefault(require("./NavPositionShape")); + +var _default = { + // required props for a functional interactive SingleDatePicker + date: _reactMomentProptypes["default"].momentObj, + onDateChange: _propTypes["default"].func.isRequired, + focused: _propTypes["default"].bool, + onFocusChange: _propTypes["default"].func.isRequired, + // input related props + id: _propTypes["default"].string.isRequired, + placeholder: _propTypes["default"].string, + ariaLabel: _propTypes["default"].string, + titleText: _propTypes["default"].string, + disabled: _propTypes["default"].bool, + required: _propTypes["default"].bool, + readOnly: _propTypes["default"].bool, + screenReaderInputMessage: _propTypes["default"].string, + showClearDate: _propTypes["default"].bool, + customCloseIcon: _propTypes["default"].node, + showDefaultInputIcon: _propTypes["default"].bool, + inputIconPosition: _IconPositionShape["default"], + customInputIcon: _propTypes["default"].node, + noBorder: _propTypes["default"].bool, + block: _propTypes["default"].bool, + small: _propTypes["default"].bool, + regular: _propTypes["default"].bool, + verticalSpacing: _airbnbPropTypes.nonNegativeInteger, + keepFocusOnInput: _propTypes["default"].bool, + autoComplete: _propTypes["default"].string, + // calendar presentation and interaction related props + renderMonthText: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderMonthElement: (0, _airbnbPropTypes.mutuallyExclusiveProps)(_propTypes["default"].func, 'renderMonthText', 'renderMonthElement'), + renderWeekHeaderElement: _propTypes["default"].func, + orientation: _OrientationShape["default"], + anchorDirection: _AnchorDirectionShape["default"], + openDirection: _OpenDirectionShape["default"], + horizontalMargin: _propTypes["default"].number, + withPortal: _propTypes["default"].bool, + withFullScreenPortal: _propTypes["default"].bool, + appendToBody: _propTypes["default"].bool, + disableScroll: _propTypes["default"].bool, + initialVisibleMonth: _propTypes["default"].func, + firstDayOfWeek: _DayOfWeekShape["default"], + numberOfMonths: _propTypes["default"].number, + keepOpenOnDateSelect: _propTypes["default"].bool, + reopenPickerOnClearDate: _propTypes["default"].bool, + renderCalendarInfo: _propTypes["default"].func, + calendarInfoPosition: _CalendarInfoPositionShape["default"], + hideKeyboardShortcutsPanel: _propTypes["default"].bool, + daySize: _airbnbPropTypes.nonNegativeInteger, + isRTL: _propTypes["default"].bool, + verticalHeight: _airbnbPropTypes.nonNegativeInteger, + transitionDuration: _airbnbPropTypes.nonNegativeInteger, + horizontalMonthPadding: _airbnbPropTypes.nonNegativeInteger, + // navigation related props + dayPickerNavigationInlineStyles: _propTypes["default"].object, + navPosition: _NavPositionShape["default"], + navPrev: _propTypes["default"].node, + navNext: _propTypes["default"].node, + renderNavPrevButton: _propTypes["default"].func, + renderNavNextButton: _propTypes["default"].func, + onPrevMonthClick: _propTypes["default"].func, + onNextMonthClick: _propTypes["default"].func, + onClose: _propTypes["default"].func, + // day presentation and interaction related props + renderCalendarDay: _propTypes["default"].func, + renderDayContents: _propTypes["default"].func, + enableOutsideDays: _propTypes["default"].bool, + isDayBlocked: _propTypes["default"].func, + isOutsideRange: _propTypes["default"].func, + isDayHighlighted: _propTypes["default"].func, + minDate: _reactMomentProptypes["default"].momentObj, + maxDate: _reactMomentProptypes["default"].momentObj, + // internationalization props + displayFormat: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), + monthFormat: _propTypes["default"].string, + weekDayFormat: _propTypes["default"].string, + phrases: _propTypes["default"].shape((0, _getPhrasePropTypes["default"])(_defaultPhrases.SingleDatePickerPhrases)), + dayAriaLabelFormat: _propTypes["default"].string +}; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/theme/DefaultTheme.js b/lib/theme/DefaultTheme.js new file mode 100644 index 000000000..7b2192eff --- /dev/null +++ b/lib/theme/DefaultTheme.js @@ -0,0 +1,183 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; +var core = { + white: '#fff', + gray: '#484848', + grayLight: '#82888a', + grayLighter: '#cacccd', + grayLightest: '#f2f2f2', + borderMedium: '#c4c4c4', + border: '#dbdbdb', + borderLight: '#e4e7e7', + borderLighter: '#eceeee', + borderBright: '#f4f5f5', + primary: '#00a699', + primaryShade_1: '#33dacd', + primaryShade_2: '#66e2da', + primaryShade_3: '#80e8e0', + primaryShade_4: '#b2f1ec', + primary_dark: '#008489', + secondary: '#007a87', + yellow: '#ffe8bc', + yellow_dark: '#ffce71' +}; +var _default = { + reactDates: { + zIndex: 0, + border: { + input: { + border: 0, + borderTop: 0, + borderRight: 0, + borderBottom: '2px solid transparent', + borderLeft: 0, + outlineFocused: 0, + borderFocused: 0, + borderTopFocused: 0, + borderLeftFocused: 0, + borderBottomFocused: "2px solid ".concat(core.primary_dark), + borderRightFocused: 0, + borderRadius: 0 + }, + pickerInput: { + borderWidth: 1, + borderStyle: 'solid', + borderRadius: 2 + } + }, + color: { + core: core, + disabled: core.grayLightest, + background: core.white, + backgroundDark: '#f2f2f2', + backgroundFocused: core.white, + border: 'rgb(219, 219, 219)', + text: core.gray, + textDisabled: core.border, + textFocused: '#007a87', + placeholderText: '#757575', + outside: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + color: core.gray, + color_active: core.gray, + color_hover: core.gray + }, + highlighted: { + backgroundColor: core.yellow, + backgroundColor_active: core.yellow_dark, + backgroundColor_hover: core.yellow_dark, + color: core.gray, + color_active: core.gray, + color_hover: core.gray + }, + minimumNights: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + borderColor: core.borderLighter, + color: core.grayLighter, + color_active: core.grayLighter, + color_hover: core.grayLighter + }, + hoveredSpan: { + backgroundColor: core.primaryShade_4, + backgroundColor_active: core.primaryShade_3, + backgroundColor_hover: core.primaryShade_4, + borderColor: core.primaryShade_3, + borderColor_active: core.primaryShade_3, + borderColor_hover: core.primaryShade_3, + color: core.secondary, + color_active: core.secondary, + color_hover: core.secondary + }, + selectedSpan: { + backgroundColor: core.primaryShade_2, + backgroundColor_active: core.primaryShade_1, + backgroundColor_hover: core.primaryShade_1, + borderColor: core.primaryShade_1, + borderColor_active: core.primary, + borderColor_hover: core.primary, + color: core.white, + color_active: core.white, + color_hover: core.white + }, + selected: { + backgroundColor: core.primary, + backgroundColor_active: core.primary, + backgroundColor_hover: core.primary, + borderColor: core.primary, + borderColor_active: core.primary, + borderColor_hover: core.primary, + color: core.white, + color_active: core.white, + color_hover: core.white + }, + blocked_calendar: { + backgroundColor: core.grayLighter, + backgroundColor_active: core.grayLighter, + backgroundColor_hover: core.grayLighter, + borderColor: core.grayLighter, + borderColor_active: core.grayLighter, + borderColor_hover: core.grayLighter, + color: core.grayLight, + color_active: core.grayLight, + color_hover: core.grayLight + }, + blocked_out_of_range: { + backgroundColor: core.white, + backgroundColor_active: core.white, + backgroundColor_hover: core.white, + borderColor: core.borderLight, + borderColor_active: core.borderLight, + borderColor_hover: core.borderLight, + color: core.grayLighter, + color_active: core.grayLighter, + color_hover: core.grayLighter + } + }, + spacing: { + dayPickerHorizontalPadding: 9, + captionPaddingTop: 22, + captionPaddingBottom: 37, + inputPadding: 0, + displayTextPaddingVertical: undefined, + displayTextPaddingTop: 11, + displayTextPaddingBottom: 9, + displayTextPaddingHorizontal: undefined, + displayTextPaddingLeft: 11, + displayTextPaddingRight: 11, + displayTextPaddingVertical_small: undefined, + displayTextPaddingTop_small: 7, + displayTextPaddingBottom_small: 5, + displayTextPaddingHorizontal_small: undefined, + displayTextPaddingLeft_small: 7, + displayTextPaddingRight_small: 7 + }, + sizing: { + inputWidth: 130, + inputWidth_small: 97, + arrowWidth: 24 + }, + noScrollBarOnVerticalScrollable: false, + font: { + size: 14, + captionSize: 18, + input: { + size: 19, + weight: 200, + lineHeight: '24px', + size_small: 15, + lineHeight_small: '18px', + letterSpacing_small: '0.2px', + styleDisabled: 'italic' + } + } + } +}; +exports["default"] = _default; \ No newline at end of file diff --git a/lib/utils/calculateDimension.js b/lib/utils/calculateDimension.js new file mode 100644 index 000000000..a63e4ddd4 --- /dev/null +++ b/lib/utils/calculateDimension.js @@ -0,0 +1,35 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = calculateDimension; + +function calculateDimension(el, axis) { + var borderBox = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var withMargin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + if (!el) { + return 0; + } + + var axisStart = axis === 'width' ? 'Left' : 'Top'; + var axisEnd = axis === 'width' ? 'Right' : 'Bottom'; // Only read styles if we need to + + var style = !borderBox || withMargin ? window.getComputedStyle(el) : null; // Offset includes border and padding + + var offsetWidth = el.offsetWidth, + offsetHeight = el.offsetHeight; + var size = axis === 'width' ? offsetWidth : offsetHeight; // Get the inner size + + if (!borderBox) { + size -= parseFloat(style["padding".concat(axisStart)]) + parseFloat(style["padding".concat(axisEnd)]) + parseFloat(style["border".concat(axisStart, "Width")]) + parseFloat(style["border".concat(axisEnd, "Width")]); + } // Apply margin + + + if (withMargin) { + size += parseFloat(style["margin".concat(axisStart)]) + parseFloat(style["margin".concat(axisEnd)]); + } + + return size; +} \ No newline at end of file diff --git a/lib/utils/disableScroll.js b/lib/utils/disableScroll.js new file mode 100644 index 000000000..4b5d103ad --- /dev/null +++ b/lib/utils/disableScroll.js @@ -0,0 +1,85 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = disableScroll; +exports.getScrollAncestorsOverflowY = getScrollAncestorsOverflowY; +exports.getScrollParent = getScrollParent; + +var getScrollingRoot = function getScrollingRoot() { + return document.scrollingElement || document.documentElement; +}; +/** + * Recursively finds the scroll parent of a node. The scroll parrent of a node + * is the closest node that is scrollable. A node is scrollable if: + * - it is allowed to scroll via CSS ('overflow-y' not visible or hidden); + * - and its children/content are "bigger" than the node's box height. + * + * The root of the document always scrolls by default. + * + * @param {HTMLElement} node Any DOM element. + * @return {HTMLElement} The scroll parent element. + */ + + +function getScrollParent(node) { + var parent = node.parentElement; + if (parent == null) return getScrollingRoot(); + + var _window$getComputedSt = window.getComputedStyle(parent), + overflowY = _window$getComputedSt.overflowY; + + var canScroll = overflowY !== 'visible' && overflowY !== 'hidden'; + + if (canScroll && parent.scrollHeight > parent.clientHeight) { + return parent; + } + + return getScrollParent(parent); +} +/** + * Recursively traverses the tree upwards from the given node, capturing all + * ancestor nodes that scroll along with their current 'overflow-y' CSS + * property. + * + * @param {HTMLElement} node Any DOM element. + * @param {Map} [acc] Accumulator map. + * @return {Map} Map of ancestors with their 'overflow-y' value. + */ + + +function getScrollAncestorsOverflowY(node) { + var acc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Map(); + var scrollingRoot = getScrollingRoot(); + var scrollParent = getScrollParent(node); + acc.set(scrollParent, scrollParent.style.overflowY); + if (scrollParent === scrollingRoot) return acc; + return getScrollAncestorsOverflowY(scrollParent, acc); +} +/** + * Disabling the scroll on a node involves finding all the scrollable ancestors + * and set their 'overflow-y' CSS property to 'hidden'. When all ancestors have + * 'overflow-y: hidden' (up to the document element) there is no scroll + * container, thus all the scroll outside of the node is disabled. In order to + * enable scroll again, we store the previous value of the 'overflow-y' for + * every ancestor in a closure and reset it back. + * + * @param {HTMLElement} node Any DOM element. + */ + + +function disableScroll(node) { + var scrollAncestorsOverflowY = getScrollAncestorsOverflowY(node); + + var toggle = function toggle(on) { + return scrollAncestorsOverflowY.forEach(function (overflowY, ancestor) { + ancestor.style.setProperty('overflow-y', on ? 'hidden' : overflowY); + }); + }; + + toggle(true); + return function () { + return toggle(false); + }; +} \ No newline at end of file diff --git a/lib/utils/enumrateDatesBetween.js b/lib/utils/enumrateDatesBetween.js new file mode 100644 index 000000000..d84445b45 --- /dev/null +++ b/lib/utils/enumrateDatesBetween.js @@ -0,0 +1,18 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = enumrateDatesBetween; + +function enumrateDatesBetween(startDate, endDate) { + var now = startDate.clone(), + dates = []; + + while (now.isSameOrBefore(endDate)) { + dates.push(now.format('M/D/YYYY')); + now.add(1, 'days'); + } + + return dates; +} \ No newline at end of file diff --git a/lib/utils/getActiveElement.js b/lib/utils/getActiveElement.js new file mode 100644 index 000000000..3caaf5160 --- /dev/null +++ b/lib/utils/getActiveElement.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getActiveElement; + +function getActiveElement() { + return typeof document !== 'undefined' && document.activeElement; +} \ No newline at end of file diff --git a/lib/utils/getCalendarDaySettings.js b/lib/utils/getCalendarDaySettings.js new file mode 100644 index 000000000..6385cf531 --- /dev/null +++ b/lib/utils/getCalendarDaySettings.js @@ -0,0 +1,68 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getCalendarDaySettings; + +var _getPhrase = _interopRequireDefault(require("./getPhrase")); + +var _constants = require("../constants"); + +function isSelected(modifiers) { + return modifiers.has('selected') || modifiers.has('selected-span') || modifiers.has('selected-start') || modifiers.has('selected-end'); +} + +function shouldUseDefaultCursor(modifiers) { + return modifiers.has('blocked-minimum-nights') || modifiers.has('blocked-calendar') || modifiers.has('blocked-out-of-range'); +} + +function isHoveredSpan(modifiers) { + if (isSelected(modifiers)) return false; + return modifiers.has('hovered-span') || modifiers.has('after-hovered-start') || modifiers.has('before-hovered-end'); +} + +function getAriaLabel(phrases, modifiers, day, ariaLabelFormat) { + var chooseAvailableDate = phrases.chooseAvailableDate, + dateIsUnavailable = phrases.dateIsUnavailable, + dateIsSelected = phrases.dateIsSelected, + dateIsSelectedAsStartDate = phrases.dateIsSelectedAsStartDate, + dateIsSelectedAsEndDate = phrases.dateIsSelectedAsEndDate; + var formattedDate = { + date: day.format(ariaLabelFormat) + }; + + if (modifiers.has('selected-start') && dateIsSelectedAsStartDate) { + return (0, _getPhrase["default"])(dateIsSelectedAsStartDate, formattedDate); + } + + if (modifiers.has('selected-end') && dateIsSelectedAsEndDate) { + return (0, _getPhrase["default"])(dateIsSelectedAsEndDate, formattedDate); + } + + if (isSelected(modifiers) && dateIsSelected) { + return (0, _getPhrase["default"])(dateIsSelected, formattedDate); + } + + if (modifiers.has(_constants.BLOCKED_MODIFIER)) { + return (0, _getPhrase["default"])(dateIsUnavailable, formattedDate); + } + + return (0, _getPhrase["default"])(chooseAvailableDate, formattedDate); +} + +function getCalendarDaySettings(day, ariaLabelFormat, daySize, modifiers, phrases) { + return { + ariaLabel: getAriaLabel(phrases, modifiers, day, ariaLabelFormat), + hoveredSpan: isHoveredSpan(modifiers), + isOutsideRange: modifiers.has('blocked-out-of-range'), + selected: isSelected(modifiers), + useDefaultCursor: shouldUseDefaultCursor(modifiers), + daySizeStyles: { + width: daySize, + height: daySize - 1 + } + }; +} \ No newline at end of file diff --git a/lib/utils/getCalendarMonthWeeks.js b/lib/utils/getCalendarMonthWeeks.js new file mode 100644 index 000000000..555362a06 --- /dev/null +++ b/lib/utils/getCalendarMonthWeeks.js @@ -0,0 +1,54 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getCalendarMonthWeeks; + +var _moment = _interopRequireDefault(require("moment")); + +var _constants = require("../constants"); + +function getCalendarMonthWeeks(month, enableOutsideDays) { + var firstDayOfWeek = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _moment["default"].localeData().firstDayOfWeek(); + + if (!_moment["default"].isMoment(month) || !month.isValid()) { + throw new TypeError('`month` must be a valid moment object'); + } + + if (_constants.WEEKDAYS.indexOf(firstDayOfWeek) === -1) { + throw new TypeError('`firstDayOfWeek` must be an integer between 0 and 6'); + } // set utc offset to get correct dates in future (when timezone changes) + + + var firstOfMonth = month.clone().startOf('month').hour(12); + var lastOfMonth = month.clone().endOf('month').hour(12); // calculate the exact first and last days to fill the entire matrix + // (considering days outside month) + + var prevDays = (firstOfMonth.day() + 7 - firstDayOfWeek) % 7; + var nextDays = (firstDayOfWeek + 6 - lastOfMonth.day()) % 7; + var firstDay = firstOfMonth.clone().subtract(prevDays, 'day'); + var lastDay = lastOfMonth.clone().add(nextDays, 'day'); + var totalDays = lastDay.diff(firstDay, 'days') + 1; + var currentDay = firstDay.clone(); + var weeksInMonth = []; + + for (var i = 0; i < totalDays; i += 1) { + if (i % 7 === 0) { + weeksInMonth.push([]); + } + + var day = null; + + if (i >= prevDays && i < totalDays - nextDays || enableOutsideDays) { + day = currentDay.clone(); + } + + weeksInMonth[weeksInMonth.length - 1].push(day); + currentDay.add(1, 'day'); + } + + return weeksInMonth; +} \ No newline at end of file diff --git a/lib/utils/getCalendarMonthWidth.js b/lib/utils/getCalendarMonthWidth.js new file mode 100644 index 000000000..6f8bb3c73 --- /dev/null +++ b/lib/utils/getCalendarMonthWidth.js @@ -0,0 +1,11 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getCalendarMonthWidth; + +function getCalendarMonthWidth(daySize) { + var calendarMonthPadding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return 7 * daySize + 2 * calendarMonthPadding + 1; +} \ No newline at end of file diff --git a/lib/utils/getDetachedContainerStyles.js b/lib/utils/getDetachedContainerStyles.js new file mode 100644 index 000000000..3e3dde62f --- /dev/null +++ b/lib/utils/getDetachedContainerStyles.js @@ -0,0 +1,46 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getDetachedContainerStyles; + +var _constants = require("../constants"); + +/** + * Calculate and return a CSS transform style to position a detached element + * next to a reference element. The open and anchor direction indicate wether + * it should be positioned above/below and/or to the left/right of the + * reference element. + * + * Assuming r(0,0), r(1,1), d(0,0), d(1,1) for the bottom-left and top-right + * corners of the reference and detached elements, respectively: + * - openDirection = DOWN, anchorDirection = LEFT => d(0,1) == r(0,1) + * - openDirection = UP, anchorDirection = LEFT => d(0,0) == r(0,0) + * - openDirection = DOWN, anchorDirection = RIGHT => d(1,1) == r(1,1) + * - openDirection = UP, anchorDirection = RIGHT => d(1,0) == r(1,0) + * + * By using a CSS transform, we allow to further position it using + * top/bottom CSS properties for the anchor gutter. + * + * @param {string} openDirection The vertical positioning of the popup + * @param {string} anchorDirection The horizontal position of the popup + * @param {HTMLElement} referenceEl The reference element + */ +function getDetachedContainerStyles(openDirection, anchorDirection, referenceEl) { + var referenceRect = referenceEl.getBoundingClientRect(); + var offsetX = referenceRect.left; + var offsetY = referenceRect.top; + + if (openDirection === _constants.OPEN_UP) { + offsetY = -(window.innerHeight - referenceRect.bottom); + } + + if (anchorDirection === _constants.ANCHOR_RIGHT) { + offsetX = -(window.innerWidth - referenceRect.right); + } + + return { + transform: "translate3d(".concat(Math.round(offsetX), "px, ").concat(Math.round(offsetY), "px, 0)") + }; +} \ No newline at end of file diff --git a/lib/utils/getInputHeight.js b/lib/utils/getInputHeight.js new file mode 100644 index 000000000..c8b9a6ff1 --- /dev/null +++ b/lib/utils/getInputHeight.js @@ -0,0 +1,56 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getInputHeight; + +/* eslint-disable camelcase */ +function getPadding(vertical, top, bottom) { + var isTopDefined = typeof top === 'number'; + var isBottomDefined = typeof bottom === 'number'; + var isVerticalDefined = typeof vertical === 'number'; + + if (isTopDefined && isBottomDefined) { + return top + bottom; + } + + if (isTopDefined && isVerticalDefined) { + return top + vertical; + } + + if (isTopDefined) { + return top; + } + + if (isBottomDefined && isVerticalDefined) { + return bottom + vertical; + } + + if (isBottomDefined) { + return bottom; + } + + if (isVerticalDefined) { + return 2 * vertical; + } + + return 0; +} + +function getInputHeight(_ref, small) { + var _ref$font$input = _ref.font.input, + lineHeight = _ref$font$input.lineHeight, + lineHeight_small = _ref$font$input.lineHeight_small, + _ref$spacing = _ref.spacing, + inputPadding = _ref$spacing.inputPadding, + displayTextPaddingVertical = _ref$spacing.displayTextPaddingVertical, + displayTextPaddingTop = _ref$spacing.displayTextPaddingTop, + displayTextPaddingBottom = _ref$spacing.displayTextPaddingBottom, + displayTextPaddingVertical_small = _ref$spacing.displayTextPaddingVertical_small, + displayTextPaddingTop_small = _ref$spacing.displayTextPaddingTop_small, + displayTextPaddingBottom_small = _ref$spacing.displayTextPaddingBottom_small; + var calcLineHeight = small ? lineHeight_small : lineHeight; + var padding = small ? getPadding(displayTextPaddingVertical_small, displayTextPaddingTop_small, displayTextPaddingBottom_small) : getPadding(displayTextPaddingVertical, displayTextPaddingTop, displayTextPaddingBottom); + return parseInt(calcLineHeight, 10) + 2 * inputPadding + padding; +} \ No newline at end of file diff --git a/lib/utils/getNumberOfCalendarMonthWeeks.js b/lib/utils/getNumberOfCalendarMonthWeeks.js new file mode 100644 index 000000000..17fb80ec6 --- /dev/null +++ b/lib/utils/getNumberOfCalendarMonthWeeks.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getNumberOfCalendarMonthWeeks; + +var _moment = _interopRequireDefault(require("moment")); + +function getBlankDaysBeforeFirstDay(firstDayOfMonth, firstDayOfWeek) { + var weekDayDiff = firstDayOfMonth.day() - firstDayOfWeek; + return (weekDayDiff + 7) % 7; +} + +function getNumberOfCalendarMonthWeeks(month) { + var firstDayOfWeek = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _moment["default"].localeData().firstDayOfWeek(); + var firstDayOfMonth = month.clone().startOf('month').hour(12); + var numBlankDays = getBlankDaysBeforeFirstDay(firstDayOfMonth, firstDayOfWeek); + return Math.ceil((numBlankDays + month.daysInMonth()) / 7); +} \ No newline at end of file diff --git a/lib/utils/getPhrase.js b/lib/utils/getPhrase.js new file mode 100644 index 000000000..59b0af6f5 --- /dev/null +++ b/lib/utils/getPhrase.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getPhrase; + +function getPhrase(phrase, args) { + if (typeof phrase === 'string') return phrase; + + if (typeof phrase === 'function') { + return phrase(args); + } + + return ''; +} \ No newline at end of file diff --git a/lib/utils/getPhrasePropTypes.js b/lib/utils/getPhrasePropTypes.js new file mode 100644 index 000000000..54b0c7af4 --- /dev/null +++ b/lib/utils/getPhrasePropTypes.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getPhrasePropTypes; + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _propTypes = _interopRequireDefault(require("prop-types")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function getPhrasePropTypes(defaultPhrases) { + return Object.keys(defaultPhrases).reduce(function (phrases, key) { + return _objectSpread(_objectSpread({}, phrases), {}, (0, _defineProperty2["default"])({}, key, _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func, _propTypes["default"].node]))); + }, {}); +} \ No newline at end of file diff --git a/lib/utils/getPooledMoment.js b/lib/utils/getPooledMoment.js new file mode 100644 index 000000000..ed44d9aff --- /dev/null +++ b/lib/utils/getPooledMoment.js @@ -0,0 +1,20 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getPooledMoment; + +var _moment = _interopRequireDefault(require("moment")); + +var momentPool = new Map(); + +function getPooledMoment(dayString) { + if (!momentPool.has(dayString)) { + momentPool.set(dayString, (0, _moment["default"])(dayString)); + } + + return momentPool.get(dayString); +} \ No newline at end of file diff --git a/lib/utils/getPreviousMonthMemoLast.js b/lib/utils/getPreviousMonthMemoLast.js new file mode 100644 index 000000000..3658b3235 --- /dev/null +++ b/lib/utils/getPreviousMonthMemoLast.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getPreviousMonthMemoLast; +var getPreviousMonthMemoKey; +var getPreviousMonthMemoValue; + +function getPreviousMonthMemoLast(month) { + if (month !== getPreviousMonthMemoKey) { + getPreviousMonthMemoKey = month; + getPreviousMonthMemoValue = month.clone().subtract(1, 'month'); + } + + return getPreviousMonthMemoValue; +} \ No newline at end of file diff --git a/lib/utils/getResponsiveContainerStyles.js b/lib/utils/getResponsiveContainerStyles.js new file mode 100644 index 000000000..c5d812782 --- /dev/null +++ b/lib/utils/getResponsiveContainerStyles.js @@ -0,0 +1,19 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getResponsiveContainerStyles; + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _constants = require("../constants"); + +function getResponsiveContainerStyles(anchorDirection, currentOffset, containerEdge, margin) { + var windowWidth = typeof window !== 'undefined' ? window.innerWidth : 0; + var calculatedOffset = anchorDirection === _constants.ANCHOR_LEFT ? windowWidth - containerEdge : containerEdge; + var calculatedMargin = margin || 0; + return (0, _defineProperty2["default"])({}, anchorDirection, Math.min(currentOffset + calculatedOffset - calculatedMargin, 0)); +} \ No newline at end of file diff --git a/lib/utils/getSelectedDateOffset.js b/lib/utils/getSelectedDateOffset.js new file mode 100644 index 000000000..bdb6716e0 --- /dev/null +++ b/lib/utils/getSelectedDateOffset.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getSelectedDateOffset; + +var defaultModifier = function defaultModifier(day) { + return day; +}; + +function getSelectedDateOffset(fn, day) { + var modifier = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultModifier; + if (!fn) return day; + return modifier(fn(day.clone())); +} \ No newline at end of file diff --git a/lib/utils/getTransformStyles.js b/lib/utils/getTransformStyles.js new file mode 100644 index 000000000..07bfaaa9a --- /dev/null +++ b/lib/utils/getTransformStyles.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getTransformStyles; + +function getTransformStyles(transformValue) { + return { + transform: transformValue, + msTransform: transformValue, + MozTransform: transformValue, + WebkitTransform: transformValue + }; +} \ No newline at end of file diff --git a/lib/utils/getVisibleDays.js b/lib/utils/getVisibleDays.js new file mode 100644 index 000000000..b0feef852 --- /dev/null +++ b/lib/utils/getVisibleDays.js @@ -0,0 +1,56 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = getVisibleDays; + +var _moment = _interopRequireDefault(require("moment")); + +var _toISOMonthString = _interopRequireDefault(require("./toISOMonthString")); + +function getVisibleDays(month, numberOfMonths, enableOutsideDays, withoutTransitionMonths) { + if (!_moment["default"].isMoment(month)) return {}; + var visibleDaysByMonth = {}; + var currentMonth = withoutTransitionMonths ? month.clone() : month.clone().subtract(1, 'month'); + + for (var i = 0; i < (withoutTransitionMonths ? numberOfMonths : numberOfMonths + 2); i += 1) { + var visibleDays = []; // set utc offset to get correct dates in future (when timezone changes) + + var baseDate = currentMonth.clone(); + var firstOfMonth = baseDate.clone().startOf('month').hour(12); + var lastOfMonth = baseDate.clone().endOf('month').hour(12); + var currentDay = firstOfMonth.clone(); // days belonging to the previous month + + if (enableOutsideDays) { + for (var j = 0; j < currentDay.weekday(); j += 1) { + var prevDay = currentDay.clone().subtract(j + 1, 'day'); + visibleDays.unshift(prevDay); + } + } + + while (currentDay < lastOfMonth) { + visibleDays.push(currentDay.clone()); + currentDay.add(1, 'day'); + } + + if (enableOutsideDays) { + // weekday() returns the index of the day of the week according to the locale + // this means if the week starts on Monday, weekday() will return 0 for a Monday date, not 1 + if (currentDay.weekday() !== 0) { + // days belonging to the next month + for (var k = currentDay.weekday(), count = 0; k < 7; k += 1, count += 1) { + var nextDay = currentDay.clone().add(count, 'day'); + visibleDays.push(nextDay); + } + } + } + + visibleDaysByMonth[(0, _toISOMonthString["default"])(currentMonth)] = visibleDays; + currentMonth = currentMonth.clone().add(1, 'month'); + } + + return visibleDaysByMonth; +} \ No newline at end of file diff --git a/lib/utils/isAfterDay.js b/lib/utils/isAfterDay.js new file mode 100644 index 000000000..08ebe88da --- /dev/null +++ b/lib/utils/isAfterDay.js @@ -0,0 +1,19 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isAfterDay; + +var _moment = _interopRequireDefault(require("moment")); + +var _isBeforeDay = _interopRequireDefault(require("./isBeforeDay")); + +var _isSameDay = _interopRequireDefault(require("./isSameDay")); + +function isAfterDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + return !(0, _isBeforeDay["default"])(a, b) && !(0, _isSameDay["default"])(a, b); +} \ No newline at end of file diff --git a/lib/utils/isBeforeDay.js b/lib/utils/isBeforeDay.js new file mode 100644 index 000000000..5a78383e3 --- /dev/null +++ b/lib/utils/isBeforeDay.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isBeforeDay; + +var _moment = _interopRequireDefault(require("moment")); + +function isBeforeDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + var aYear = a.year(); + var aMonth = a.month(); + var bYear = b.year(); + var bMonth = b.month(); + var isSameYear = aYear === bYear; + var isSameMonth = aMonth === bMonth; + if (isSameYear && isSameMonth) return a.date() < b.date(); + if (isSameYear) return aMonth < bMonth; + return aYear < bYear; +} \ No newline at end of file diff --git a/lib/utils/isDayVisible.js b/lib/utils/isDayVisible.js new file mode 100644 index 000000000..69d27d05d --- /dev/null +++ b/lib/utils/isDayVisible.js @@ -0,0 +1,56 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isDayVisible; + +var _moment = _interopRequireDefault(require("moment")); + +var _isBeforeDay = _interopRequireDefault(require("./isBeforeDay")); + +var _isAfterDay = _interopRequireDefault(require("./isAfterDay")); + +var _toISOMonthString = _interopRequireDefault(require("./toISOMonthString")); + +var startCacheOutsideDays = new Map(); +var endCacheOutsideDays = new Map(); +var startCacheInsideDays = new Map(); +var endCacheInsideDays = new Map(); + +function isDayVisible(day, month, numberOfMonths, enableOutsideDays) { + if (!_moment["default"].isMoment(day)) return false; // Cloning is a little expensive, so we want to do it as little as possible. + + var startKey = (0, _toISOMonthString["default"])(month); // eslint-disable-next-line prefer-template + + var endKey = startKey + '+' + numberOfMonths; + + if (enableOutsideDays) { + if (!startCacheOutsideDays.has(startKey)) { + startCacheOutsideDays.set(startKey, month.clone().startOf('month').startOf('week').hour(12)); + } + + if ((0, _isBeforeDay["default"])(day, startCacheOutsideDays.get(startKey))) return false; + + if (!endCacheOutsideDays.has(endKey)) { + endCacheOutsideDays.set(endKey, month.clone().endOf('week').add(numberOfMonths - 1, 'months').endOf('month').endOf('week').hour(12)); + } + + return !(0, _isAfterDay["default"])(day, endCacheOutsideDays.get(endKey)); + } // !enableOutsideDays + + + if (!startCacheInsideDays.has(startKey)) { + startCacheInsideDays.set(startKey, month.clone().startOf('month').hour(12)); + } + + if ((0, _isBeforeDay["default"])(day, startCacheInsideDays.get(startKey))) return false; + + if (!endCacheInsideDays.has(endKey)) { + endCacheInsideDays.set(endKey, month.clone().add(numberOfMonths - 1, 'months').endOf('month').hour(12)); + } + + return !(0, _isAfterDay["default"])(day, endCacheInsideDays.get(endKey)); +} \ No newline at end of file diff --git a/lib/utils/isInclusivelyAfterDay.js b/lib/utils/isInclusivelyAfterDay.js new file mode 100644 index 000000000..d62e28a55 --- /dev/null +++ b/lib/utils/isInclusivelyAfterDay.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isInclusivelyAfterDay; + +var _moment = _interopRequireDefault(require("moment")); + +var _isBeforeDay = _interopRequireDefault(require("./isBeforeDay")); + +function isInclusivelyAfterDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + return !(0, _isBeforeDay["default"])(a, b); +} \ No newline at end of file diff --git a/lib/utils/isInclusivelyBeforeDay.js b/lib/utils/isInclusivelyBeforeDay.js new file mode 100644 index 000000000..4d209c370 --- /dev/null +++ b/lib/utils/isInclusivelyBeforeDay.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isInclusivelyBeforeDay; + +var _moment = _interopRequireDefault(require("moment")); + +var _isAfterDay = _interopRequireDefault(require("./isAfterDay")); + +function isInclusivelyBeforeDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + return !(0, _isAfterDay["default"])(a, b); +} \ No newline at end of file diff --git a/lib/utils/isNextDay.js b/lib/utils/isNextDay.js new file mode 100644 index 000000000..b2ed38bec --- /dev/null +++ b/lib/utils/isNextDay.js @@ -0,0 +1,18 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isNextDay; + +var _moment = _interopRequireDefault(require("moment")); + +var _isSameDay = _interopRequireDefault(require("./isSameDay")); + +function isNextDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + var nextDay = (0, _moment["default"])(a).add(1, 'day'); + return (0, _isSameDay["default"])(nextDay, b); +} \ No newline at end of file diff --git a/lib/utils/isNextMonth.js b/lib/utils/isNextMonth.js new file mode 100644 index 000000000..a8de0f531 --- /dev/null +++ b/lib/utils/isNextMonth.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isNextMonth; + +var _moment = _interopRequireDefault(require("moment")); + +var _isSameMonth = _interopRequireDefault(require("./isSameMonth")); + +function isNextMonth(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + return (0, _isSameMonth["default"])(a.clone().add(1, 'month'), b); +} \ No newline at end of file diff --git a/lib/utils/isPrevMonth.js b/lib/utils/isPrevMonth.js new file mode 100644 index 000000000..7d66ee3bb --- /dev/null +++ b/lib/utils/isPrevMonth.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isPrevMonth; + +var _moment = _interopRequireDefault(require("moment")); + +var _isSameMonth = _interopRequireDefault(require("./isSameMonth")); + +function isPrevMonth(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + return (0, _isSameMonth["default"])(a.clone().subtract(1, 'month'), b); +} \ No newline at end of file diff --git a/lib/utils/isPreviousDay.js b/lib/utils/isPreviousDay.js new file mode 100644 index 000000000..dab7c36cd --- /dev/null +++ b/lib/utils/isPreviousDay.js @@ -0,0 +1,18 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isPreviousDay; + +var _moment = _interopRequireDefault(require("moment")); + +var _isSameDay = _interopRequireDefault(require("./isSameDay")); + +function isPreviousDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; + var dayBefore = (0, _moment["default"])(a).subtract(1, 'day'); + return (0, _isSameDay["default"])(dayBefore, b); +} \ No newline at end of file diff --git a/lib/utils/isSameDay.js b/lib/utils/isSameDay.js new file mode 100644 index 000000000..359b13bfc --- /dev/null +++ b/lib/utils/isSameDay.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isSameDay; + +var _moment = _interopRequireDefault(require("moment")); + +function isSameDay(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; // Compare least significant, most likely to change units first + // Moment's isSame clones moment inputs and is a tad slow + + return a.date() === b.date() && a.month() === b.month() && a.year() === b.year(); +} \ No newline at end of file diff --git a/lib/utils/isSameMonth.js b/lib/utils/isSameMonth.js new file mode 100644 index 000000000..24beb8570 --- /dev/null +++ b/lib/utils/isSameMonth.js @@ -0,0 +1,17 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isSameMonth; + +var _moment = _interopRequireDefault(require("moment")); + +function isSameMonth(a, b) { + if (!_moment["default"].isMoment(a) || !_moment["default"].isMoment(b)) return false; // Compare least significant, most likely to change units first + // Moment's isSame clones moment inputs and is a tad slow + + return a.month() === b.month() && a.year() === b.year(); +} \ No newline at end of file diff --git a/lib/utils/isTransitionEndSupported.js b/lib/utils/isTransitionEndSupported.js new file mode 100644 index 000000000..583709dc0 --- /dev/null +++ b/lib/utils/isTransitionEndSupported.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = isTransitionEndSupported; + +function isTransitionEndSupported() { + return !!(typeof window !== 'undefined' && 'TransitionEvent' in window); +} \ No newline at end of file diff --git a/lib/utils/modifiers.js b/lib/utils/modifiers.js new file mode 100644 index 000000000..b68a8d0d5 --- /dev/null +++ b/lib/utils/modifiers.js @@ -0,0 +1,131 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.addModifier = addModifier; +exports.deleteModifier = deleteModifier; + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _isDayVisible = _interopRequireDefault(require("./isDayVisible")); + +var _toISODateString = _interopRequireDefault(require("./toISODateString")); + +var _toISOMonthString = _interopRequireDefault(require("./toISOMonthString")); + +var _getPreviousMonthMemoLast = _interopRequireDefault(require("./getPreviousMonthMemoLast")); + +var _constants = require("../constants"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +function addModifier(updatedDays, day, modifier, props, state) { + var numberOfVisibleMonths = props.numberOfMonths, + enableOutsideDays = props.enableOutsideDays, + orientation = props.orientation; + var firstVisibleMonth = state.currentMonth, + visibleDays = state.visibleDays; + var currentMonth = firstVisibleMonth; + var numberOfMonths = numberOfVisibleMonths; + + if (orientation === _constants.VERTICAL_SCROLLABLE) { + numberOfMonths = Object.keys(visibleDays).length; + } else { + currentMonth = (0, _getPreviousMonthMemoLast["default"])(currentMonth); + numberOfMonths += 2; + } + + if (!day || !(0, _isDayVisible["default"])(day, currentMonth, numberOfMonths, enableOutsideDays)) { + return updatedDays; + } + + var iso = (0, _toISODateString["default"])(day); + + var updatedDaysAfterAddition = _objectSpread({}, updatedDays); + + if (enableOutsideDays) { + var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { + return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; + }); + updatedDaysAfterAddition = monthsToUpdate.reduce(function (acc, monthIso) { + var month = updatedDays[monthIso] || visibleDays[monthIso]; + + if (!month[iso] || !month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers.add(modifier); + acc[monthIso] = _objectSpread(_objectSpread({}, month), {}, (0, _defineProperty2["default"])({}, iso, modifiers)); + } + + return acc; + }, updatedDaysAfterAddition); + } else { + var monthIso = (0, _toISOMonthString["default"])(day); + var month = updatedDays[monthIso] || visibleDays[monthIso] || {}; + + if (!month[iso] || !month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers.add(modifier); + updatedDaysAfterAddition[monthIso] = _objectSpread(_objectSpread({}, month), {}, (0, _defineProperty2["default"])({}, iso, modifiers)); + } + } + + return updatedDaysAfterAddition; +} + +function deleteModifier(updatedDays, day, modifier, props, state) { + var numberOfVisibleMonths = props.numberOfMonths, + enableOutsideDays = props.enableOutsideDays, + orientation = props.orientation; + var firstVisibleMonth = state.currentMonth, + visibleDays = state.visibleDays; + var currentMonth = firstVisibleMonth; + var numberOfMonths = numberOfVisibleMonths; + + if (orientation === _constants.VERTICAL_SCROLLABLE) { + numberOfMonths = Object.keys(visibleDays).length; + } else { + currentMonth = (0, _getPreviousMonthMemoLast["default"])(currentMonth); + numberOfMonths += 2; + } + + if (!day || !(0, _isDayVisible["default"])(day, currentMonth, numberOfMonths, enableOutsideDays)) { + return updatedDays; + } + + var iso = (0, _toISODateString["default"])(day); + + var updatedDaysAfterDeletion = _objectSpread({}, updatedDays); + + if (enableOutsideDays) { + var monthsToUpdate = Object.keys(visibleDays).filter(function (monthKey) { + return Object.keys(visibleDays[monthKey]).indexOf(iso) > -1; + }); + updatedDaysAfterDeletion = monthsToUpdate.reduce(function (acc, monthIso) { + var month = updatedDays[monthIso] || visibleDays[monthIso]; + + if (month[iso] && month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers["delete"](modifier); + acc[monthIso] = _objectSpread(_objectSpread({}, month), {}, (0, _defineProperty2["default"])({}, iso, modifiers)); + } + + return acc; + }, updatedDaysAfterDeletion); + } else { + var monthIso = (0, _toISOMonthString["default"])(day); + var month = updatedDays[monthIso] || visibleDays[monthIso] || {}; + + if (month[iso] && month[iso].has(modifier)) { + var modifiers = new Set(month[iso]); + modifiers["delete"](modifier); + updatedDaysAfterDeletion[monthIso] = _objectSpread(_objectSpread({}, month), {}, (0, _defineProperty2["default"])({}, iso, modifiers)); + } + } + + return updatedDaysAfterDeletion; +} \ No newline at end of file diff --git a/lib/utils/noflip.js b/lib/utils/noflip.js new file mode 100644 index 000000000..5aa19fc0c --- /dev/null +++ b/lib/utils/noflip.js @@ -0,0 +1,15 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = noflip; +var NOFLIP = '/* @noflip */'; // Appends a noflip comment to a style rule in order to prevent it from being automatically +// flipped in RTL contexts. This should be used only in situations where the style must remain +// unflipped regardless of direction context. See: https://github.com/kentcdodds/rtl-css-js#usage + +function noflip(value) { + if (typeof value === 'number') return "".concat(value, "px ").concat(NOFLIP); + if (typeof value === 'string') return "".concat(value, " ").concat(NOFLIP); + throw new TypeError('noflip expects a string or a number'); +} \ No newline at end of file diff --git a/lib/utils/registerCSSInterfaceWithDefaultTheme.js b/lib/utils/registerCSSInterfaceWithDefaultTheme.js new file mode 100644 index 000000000..745903bc6 --- /dev/null +++ b/lib/utils/registerCSSInterfaceWithDefaultTheme.js @@ -0,0 +1,16 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = registerCSSInterfaceWithDefaultTheme; + +var _reactWithStylesInterfaceCss = _interopRequireDefault(require("react-with-styles-interface-css")); + +var _registerInterfaceWithDefaultTheme = _interopRequireDefault(require("./registerInterfaceWithDefaultTheme")); + +function registerCSSInterfaceWithDefaultTheme() { + (0, _registerInterfaceWithDefaultTheme["default"])(_reactWithStylesInterfaceCss["default"]); +} \ No newline at end of file diff --git a/lib/utils/registerInterfaceWithDefaultTheme.js b/lib/utils/registerInterfaceWithDefaultTheme.js new file mode 100644 index 000000000..92fd0bebe --- /dev/null +++ b/lib/utils/registerInterfaceWithDefaultTheme.js @@ -0,0 +1,18 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = registerInterfaceWithDefaultTheme; + +var _ThemedStyleSheet = _interopRequireDefault(require("react-with-styles/lib/ThemedStyleSheet")); + +var _DefaultTheme = _interopRequireDefault(require("../theme/DefaultTheme")); + +function registerInterfaceWithDefaultTheme(reactWithStylesInterface) { + _ThemedStyleSheet["default"].registerInterface(reactWithStylesInterface); + + _ThemedStyleSheet["default"].registerTheme(_DefaultTheme["default"]); +} \ No newline at end of file diff --git a/lib/utils/toISODateString.js b/lib/utils/toISODateString.js new file mode 100644 index 000000000..5ce7c4979 --- /dev/null +++ b/lib/utils/toISODateString.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = toISODateString; + +var _moment = _interopRequireDefault(require("moment")); + +var _toMomentObject = _interopRequireDefault(require("./toMomentObject")); + +function toISODateString(date, currentFormat) { + var dateObj = _moment["default"].isMoment(date) ? date : (0, _toMomentObject["default"])(date, currentFormat); + if (!dateObj) return null; // Template strings compiled in strict mode uses concat, which is slow. Since + // this code is in a hot path and we want it to be as fast as possible, we + // want to use old-fashioned +. + // eslint-disable-next-line prefer-template + + return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0') + '-' + String(dateObj.date()).padStart(2, '0'); +} \ No newline at end of file diff --git a/lib/utils/toISOMonthString.js b/lib/utils/toISOMonthString.js new file mode 100644 index 000000000..54a778453 --- /dev/null +++ b/lib/utils/toISOMonthString.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = toISOMonthString; + +var _moment = _interopRequireDefault(require("moment")); + +var _toMomentObject = _interopRequireDefault(require("./toMomentObject")); + +function toISOMonthString(date, currentFormat) { + var dateObj = _moment["default"].isMoment(date) ? date : (0, _toMomentObject["default"])(date, currentFormat); + if (!dateObj) return null; // Template strings compiled in strict mode uses concat, which is slow. Since + // this code is in a hot path and we want it to be as fast as possible, we + // want to use old-fashioned +. + // eslint-disable-next-line prefer-template + + return dateObj.year() + '-' + String(dateObj.month() + 1).padStart(2, '0'); +} \ No newline at end of file diff --git a/lib/utils/toLocalizedDateString.js b/lib/utils/toLocalizedDateString.js new file mode 100644 index 000000000..5002fee5f --- /dev/null +++ b/lib/utils/toLocalizedDateString.js @@ -0,0 +1,20 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = toLocalizedDateString; + +var _moment = _interopRequireDefault(require("moment")); + +var _toMomentObject = _interopRequireDefault(require("./toMomentObject")); + +var _constants = require("../constants"); + +function toLocalizedDateString(date, currentFormat) { + var dateObj = _moment["default"].isMoment(date) ? date : (0, _toMomentObject["default"])(date, currentFormat); + if (!dateObj) return null; + return dateObj.format(_constants.DISPLAY_FORMAT); +} \ No newline at end of file diff --git a/lib/utils/toMomentObject.js b/lib/utils/toMomentObject.js new file mode 100644 index 000000000..2184ba583 --- /dev/null +++ b/lib/utils/toMomentObject.js @@ -0,0 +1,18 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = toMomentObject; + +var _moment = _interopRequireDefault(require("moment")); + +var _constants = require("../constants"); + +function toMomentObject(dateString, customFormat) { + var dateFormats = customFormat ? [customFormat, _constants.DISPLAY_FORMAT, _constants.ISO_FORMAT] : [_constants.DISPLAY_FORMAT, _constants.ISO_FORMAT]; + var date = (0, _moment["default"])(dateString, dateFormats, true); + return date.isValid() ? date.hour(12) : null; +} \ No newline at end of file diff --git a/test-build/_helpers/describeIfWindow.js b/test-build/_helpers/describeIfWindow.js new file mode 100644 index 000000000..0ef569789 --- /dev/null +++ b/test-build/_helpers/describeIfWindow.js @@ -0,0 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = void 0; + +var _default = typeof document === 'undefined' ? describe.skip : describe; + +exports["default"] = _default; \ No newline at end of file diff --git a/test-build/_helpers/enzymeSetup.js b/test-build/_helpers/enzymeSetup.js new file mode 100644 index 000000000..0a2b1f2dd --- /dev/null +++ b/test-build/_helpers/enzymeSetup.js @@ -0,0 +1,9 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _enzymeAdapterReactHelper = _interopRequireDefault(require("enzyme-adapter-react-helper")); + +(0, _enzymeAdapterReactHelper["default"])({ + disableLifecycleMethods: true +}); \ No newline at end of file diff --git a/test-build/_helpers/registerReactWithStylesInterface.js b/test-build/_helpers/registerReactWithStylesInterface.js new file mode 100644 index 000000000..7f8f6edb1 --- /dev/null +++ b/test-build/_helpers/registerReactWithStylesInterface.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _ThemedStyleSheet = _interopRequireDefault(require("react-with-styles/lib/ThemedStyleSheet")); + +var _reactWithStylesInterfaceAphrodite = _interopRequireDefault(require("react-with-styles-interface-aphrodite")); + +var _aphrodite = require("aphrodite"); + +var _DefaultTheme = _interopRequireDefault(require("../../lib/theme/DefaultTheme")); + +_ThemedStyleSheet["default"].registerTheme(_DefaultTheme["default"]); + +_ThemedStyleSheet["default"].registerInterface(_reactWithStylesInterfaceAphrodite["default"]); + +beforeEach(function () { + _aphrodite.StyleSheetTestUtils.suppressStyleInjection(); +}); +afterEach(function () { + _aphrodite.StyleSheetTestUtils.clearBufferAndResumeStyleInjection(); +}); \ No newline at end of file diff --git a/test-build/_helpers/restoreSinonStubs.js b/test-build/_helpers/restoreSinonStubs.js new file mode 100644 index 000000000..a3fb00460 --- /dev/null +++ b/test-build/_helpers/restoreSinonStubs.js @@ -0,0 +1,9 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +afterEach(function () { + _sinonSandbox["default"].restore(); +}); \ No newline at end of file diff --git a/test-build/_helpers/withTouchSupport.js b/test-build/_helpers/withTouchSupport.js new file mode 100644 index 000000000..d32365e66 --- /dev/null +++ b/test-build/_helpers/withTouchSupport.js @@ -0,0 +1,25 @@ +"use strict"; + +var wrap = require('mocha-wrap'); + +var withGlobal = require('mocha-wrap/withGlobal'); + +var withOverride = require('mocha-wrap/withOverride'); + +function withTouchSupport() { + return this.use(withGlobal, 'window', function () { + return typeof window !== 'undefined' ? window : {}; + }).use(withOverride, function () { + return window; + }, 'ontouchstart', function () { + return window.ontouchstart || function () {}; + }).use(withGlobal, 'navigator', function () { + return typeof navigator !== 'undefined' ? navigator : {}; + }).use(withOverride, function () { + return navigator; + }, 'maxTouchPoints', function () { + return navigator.maxTouchPoints || true; + }); +} + +wrap.register(withTouchSupport); \ No newline at end of file diff --git a/test-build/browser-main.js b/test-build/browser-main.js new file mode 100644 index 000000000..dc94ae153 --- /dev/null +++ b/test-build/browser-main.js @@ -0,0 +1,10 @@ +"use strict"; + +var requireAll = function requireAll(requireContext) { + return requireContext.keys().forEach(requireContext); +}; + +if (typeof window !== 'undefined') { + requireAll(require.context('./_helpers', true, /.jsx?$/)); + requireAll(require.context('.', true, /.jsx?$/)); +} \ No newline at end of file diff --git a/test-build/components/CalendarDay_spec.js b/test-build/components/CalendarDay_spec.js new file mode 100644 index 000000000..92c94dc7e --- /dev/null +++ b/test-build/components/CalendarDay_spec.js @@ -0,0 +1,333 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _moment = _interopRequireDefault(require("moment")); + +var _raf = _interopRequireDefault(require("raf")); + +var _constants = require("../../lib/constants"); + +var _CalendarDay = _interopRequireWildcard(require("../../lib/components/CalendarDay")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +describe('CalendarDay', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render', function () { + it('contains formatted day for single digit days', function () { + var firstOfMonth = (0, _moment["default"])().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + day: firstOfMonth + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(firstOfMonth.format('D')); + }); + it('contains formatted day for double digit days', function () { + var lastOfMonth = (0, _moment["default"])().endOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + day: lastOfMonth + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(lastOfMonth.format('D')); + }); + it('contains arbitrary content if renderDay is provided', function () { + var dayName = (0, _moment["default"])().format('dddd'); + + var renderDay = function renderDay(day) { + return day.format('dddd'); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + renderDayContents: renderDay + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(dayName); + }); + it('passes modifiers to renderDayContents', function () { + var modifiers = new Set([_constants.BLOCKED_MODIFIER]); + + var renderDayContents = function renderDayContents(day, mods) { + return "".concat(day.format('dddd')).concat(mods.has(_constants.BLOCKED_MODIFIER) ? 'BLOCKED' : ''); + }; + + var expected = "".concat((0, _moment["default"])().format('dddd'), "BLOCKED"); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + renderDayContents: renderDayContents, + modifiers: modifiers + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(expected); + }); + it('has button role', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], null)).dive(); + (0, _chai.expect)(wrapper.props().role).to.equal('button'); + }); + it('has tabIndex equal to props.tabIndex', function () { + var tabIndex = -1; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + tabIndex: tabIndex + })).dive(); + (0, _chai.expect)(wrapper.props().tabIndex).to.equal(tabIndex); + }); + describe('aria-current', function () { + it('should add aria-current to date for today date', function () { + var modifiers = new Set(['today']); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-current')).to.equal('date'); + }); + it('should not add aria-current for not today date', function () { + var modifiers = new Set(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers + })).dive(); + (0, _chai.expect)(wrapper).to.not.have.property('aria-current'); + }); + }); + describe('aria-label', function () { + var phrases = {}; + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + beforeEach(function () { + phrases.chooseAvailableDate = _sinonSandbox["default"].stub().returns('chooseAvailableDate text'); + phrases.dateIsSelected = _sinonSandbox["default"].stub().returns('dateIsSelected text'); + phrases.dateIsUnavailable = _sinonSandbox["default"].stub().returns('dateIsUnavailable text'); + phrases.dateIsSelectedAsStartDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsStartDate text'); + phrases.dateIsSelectedAsEndDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsEndDate text'); + }); + it('is formatted with the chooseAvailableDate phrase function when day is available', function () { + var modifiers = new Set(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('chooseAvailableDate text'); + }); + it('is formatted with the dateIsSelected phrase function when day is selected', function () { + var modifiers = new Set(['selected']); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelected text'); + }); + it('is formatted with the dateIsSelected phrase function when day is selected in a span', function () { + var modifiers = new Set(['selected-span']); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelected text'); + }); + it('is formatted with the dateIsSelectedAsStartDate phrase function when day is selected as the start date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-start'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelectedAsStartDate text'); + }); + it('is formatted with the dateIsSelectedAsEndDate phrase function when day is selected as the end date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-end'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelectedAsEndDate text'); + }); + it('is formatted with the dateIsUnavailable phrase function when day is not available', function () { + var modifiers = new Set([_constants.BLOCKED_MODIFIER]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsUnavailable text'); + }); + it('should set aria-label with a value pass through ariaLabelFormat prop if it exists', function () { + var modifiers = new Set(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + modifiers: modifiers, + day: day, + ariaLabelFormat: "MMMM Do YYYY" + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('October 10th 2017'); + }); + }); + describe('event handlers', function () { + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + var wrapper; + beforeEach(function () { + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + day: day, + ariaLabelFormat: "MMMM Do YYYY" + })).dive(); + }); + it('onMouseUp blurs the event target', function () { + var handler = wrapper.prop('onMouseUp'); + + var blur = _sinonSandbox["default"].spy(); + + handler({ + currentTarget: { + blur: blur + } + }); + (0, _chai.expect)(blur).to.have.property('callCount', 1); + }); + it('onKeyDown calls this.onKeyDown', function () { + var spy = _sinonSandbox["default"].spy(wrapper.instance(), 'onKeyDown'); + + var handler = wrapper.prop('onKeyDown'); + var event = {}; + handler(event); + (0, _chai.expect)(spy).to.have.property('callCount', 1); + (0, _chai.expect)(spy.calledWith(day, event)).to.equal(true); + }); + }); + it('renders an empty when no day is given', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + day: null + })).dive(); + (0, _chai.expect)(wrapper.is('td')).to.equal(true); + (0, _chai.expect)(wrapper.children()).to.have.lengthOf(0); + (0, _chai.expect)(wrapper.props()).to.eql({}); + }); + }); + describe('#onKeyDown', function () { + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + var onDayClick; + var wrapper; + beforeEach(function () { + onDayClick = _sinonSandbox["default"].spy(); + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + day: day, + onDayClick: onDayClick + })).dive(); + }); + it('calls onDayClick with the enter key', function () { + var event = { + key: 'Enter' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 1); + (0, _chai.expect)(onDayClick.calledWith(day, event)).to.equal(true); + }); + it('calls onDayClick with the space key', function () { + var event = { + key: ' ' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 1); + (0, _chai.expect)(onDayClick.calledWith(day, event)).to.equal(true); + }); + it('does not call onDayClick otherwise', function () { + var event = { + key: 'Shift' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 0); + }); + }); + describe('#componentDidUpdate', function () { + it('focuses buttonRef after a delay when isFocused, tabIndex is 0, and tabIndex was not 0', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + isFocused: true, + tabIndex: 0 + })).dive(); + + var focus = _sinonSandbox["default"].spy(); + + wrapper.instance().buttonRef = { + focus: focus + }; + wrapper.instance().componentDidUpdate({ + isFocused: true, + tabIndex: -1 + }); + (0, _chai.expect)(focus.callCount).to.eq(0); + return new Promise(function (resolve) { + (0, _raf["default"])(function () { + (0, _chai.expect)(focus.callCount).to.eq(1); + resolve(); + }); + }); + }); + }); + describe('#onDayClick', function () { + var onDayClickSpy; + beforeEach(function () { + onDayClickSpy = _sinonSandbox["default"].spy(_CalendarDay.PureCalendarDay.prototype, 'onDayClick'); + }); + it('gets triggered by click', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], null)).dive(); + wrapper.simulate('click'); + (0, _chai.expect)(onDayClickSpy).to.have.property('callCount', 1); + }); + it('calls props.onDayClick', function () { + var onDayClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + onDayClick: onDayClickStub + })).dive(); + wrapper.instance().onDayClick(); + (0, _chai.expect)(onDayClickStub).to.have.property('callCount', 1); + }); + }); + describe('#onDayMouseEnter', function () { + var onDayMouseEnterSpy; + beforeEach(function () { + onDayMouseEnterSpy = _sinonSandbox["default"].spy(_CalendarDay.PureCalendarDay.prototype, 'onDayMouseEnter'); + }); + it('gets triggered by mouseenter', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], null)).dive(); + wrapper.simulate('mouseenter'); + (0, _chai.expect)(onDayMouseEnterSpy).to.have.property('callCount', 1); + }); + it('calls props.onDayMouseEnter', function () { + var onMouseEnterStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + onDayMouseEnter: onMouseEnterStub + })).dive(); + wrapper.instance().onDayMouseEnter(); + (0, _chai.expect)(onMouseEnterStub).to.have.property('callCount', 1); + }); + }); + describe('#onDayMouseLeave', function () { + var onDayMouseLeaveSpy; + beforeEach(function () { + onDayMouseLeaveSpy = _sinonSandbox["default"].spy(_CalendarDay.PureCalendarDay.prototype, 'onDayMouseLeave'); + }); + it('gets triggered by mouseleave', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], null)).dive(); + wrapper.simulate('mouseleave'); + (0, _chai.expect)(onDayMouseLeaveSpy).to.have.property('callCount', 1); + }); + it('calls props.onDayMouseLeave', function () { + var onMouseLeaveStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], { + onDayMouseLeave: onMouseLeaveStub + })).dive(); + wrapper.instance().onDayMouseLeave(); + (0, _chai.expect)(onMouseLeaveStub).to.have.property('callCount', 1); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/CalendarMonthGrid_spec.js b/test-build/components/CalendarMonthGrid_spec.js new file mode 100644 index 000000000..274d5a633 --- /dev/null +++ b/test-build/components/CalendarMonthGrid_spec.js @@ -0,0 +1,128 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _moment = _interopRequireDefault(require("moment")); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _CalendarMonth = _interopRequireDefault(require("../../lib/components/CalendarMonth")); + +var _CalendarMonthGrid = _interopRequireDefault(require("../../lib/components/CalendarMonthGrid")); + +var _getTransformStyles = _interopRequireDefault(require("../../lib/utils/getTransformStyles")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +describe('CalendarMonthGrid', function () { + it('the number of CalendarMonths rendered matches props.numberOfMonths + 2', function () { + var NUM_OF_MONTHS = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + numberOfMonths: NUM_OF_MONTHS + })).dive(); + (0, _chai.expect)(wrapper.find(_CalendarMonth["default"])).to.have.lengthOf(NUM_OF_MONTHS + 2); + }); + it('has style equal to getTransformStyles(foo)', function () { + var translationValue = 100; + var transformStyles = (0, _getTransformStyles["default"])("translateX(".concat(translationValue, "px)")); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + translationValue: translationValue + })).dive(); + Object.keys(transformStyles).forEach(function (key) { + (0, _chai.expect)(wrapper.prop('style')[key]).to.equal(transformStyles[key]); + }); + }); + it('does not generate duplicate months', function () { + var initialMonth = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + numberOfMonths: 12, + initialMonth: initialMonth + })).dive(); + wrapper.instance().componentWillReceiveProps({ + initialMonth: initialMonth, + numberOfMonths: 24 + }); + + var _wrapper$state = wrapper.state(), + months = _wrapper$state.months; + + var collisions = months.map(function (m) { + return m.format('YYYY-MM'); + }).reduce(function (acc, m) { + return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, m, true)); + }, {}); + (0, _chai.expect)(Object.keys(collisions).length).to.equal(months.length); + }); + it('does not setState if hasMonthChanged and hasNumberOfMonthsChanged are falsy', function () { + var setState = _sinonSandbox["default"].stub(_CalendarMonthGrid["default"].prototype, 'setState'); + + var initialMonth = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + numberOfMonths: 12, + initialMonth: initialMonth + })).dive(); + wrapper.instance().componentWillReceiveProps({ + initialMonth: initialMonth, + numberOfMonths: 12 + }); + (0, _chai.expect)(setState.callCount).to.eq(0); + }); + it('works with the same number of months', function () { + var initialMonth = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + numberOfMonths: 12, + initialMonth: initialMonth + })).dive(); + wrapper.instance().componentWillReceiveProps({ + initialMonth: initialMonth, + numberOfMonths: 12, + firstVisibleMonthIndex: 0 + }); + + var _wrapper$state2 = wrapper.state(), + months = _wrapper$state2.months; + + var collisions = months.map(function (m) { + return m.format('YYYY-MM'); + }).reduce(function (acc, m) { + return _objectSpread(_objectSpread({}, acc), {}, (0, _defineProperty2["default"])({}, m, true)); + }, {}); + (0, _chai.expect)(Object.keys(collisions).length).to.equal(months.length); + }); + describe('#onMonthSelect', function () { + it('calls onMonthChange', function () { + var onMonthChangeSpy = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + onMonthChange: onMonthChangeSpy + })).dive(); + var currentMonth = (0, _moment["default"])(); + var newMonthVal = (currentMonth.month() + 5) % 12; + wrapper.instance().onMonthSelect(currentMonth, newMonthVal); + (0, _chai.expect)(onMonthChangeSpy.callCount).to.equal(1); + }); + }); + describe('#onYearSelect', function () { + it('calls onYearChange', function () { + var onYearChangeSpy = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonthGrid["default"], { + onYearChange: onYearChangeSpy + })).dive(); + var currentMonth = (0, _moment["default"])(); + var newMonthVal = (currentMonth.month() + 5) % 12; + wrapper.instance().onYearSelect(currentMonth, newMonthVal); + (0, _chai.expect)(onYearChangeSpy.callCount).to.equal(1); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/CalendarMonth_spec.js b/test-build/components/CalendarMonth_spec.js new file mode 100644 index 000000000..b687c6ace --- /dev/null +++ b/test-build/components/CalendarMonth_spec.js @@ -0,0 +1,108 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _moment = _interopRequireDefault(require("moment")); + +var _describeIfWindow = _interopRequireDefault(require("../_helpers/describeIfWindow")); + +var _CalendarMonth = _interopRequireDefault(require("../../lib/components/CalendarMonth")); + +describe('CalendarMonth', function () { + describe('#render', function () { + describe('data-visible attribute', function () { + it('data-visible attribute is truthy if props.isVisible', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + isVisible: true + })).dive(); + (0, _chai.expect)(wrapper.prop('data-visible')).to.equal(true); + }); + it('data-visible attribute is falsy if !props.isVisible', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + isVisible: false + })).dive(); + (0, _chai.expect)(wrapper.prop('data-visible')).to.equal(false); + }); + }); + describe('caption', function () { + it('text is the correctly formatted month title', function () { + var MONTH = (0, _moment["default"])(); + var captionWrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + month: MONTH + })).dive().find('strong'); + (0, _chai.expect)(captionWrapper.text()).to.equal(MONTH.format('MMMM YYYY')); + }); + }); + it('renderMonthElement renders month element when month changes', function () { + var renderMonthElementStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("div", { + id: "month-element" + })); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + renderMonthElement: renderMonthElementStub + })).dive(); + wrapper.setProps({ + month: (0, _moment["default"])().subtract(1, 'months') + }); + + var _renderMonthElementSt = (0, _slicedToArray2["default"])(renderMonthElementStub.getCall(0).args, 1), + _renderMonthElementSt2 = _renderMonthElementSt[0], + month = _renderMonthElementSt2.month, + onMonthSelect = _renderMonthElementSt2.onMonthSelect, + onYearSelect = _renderMonthElementSt2.onYearSelect, + isVisible = _renderMonthElementSt2.isVisible; + + (0, _chai.expect)(_moment["default"].isMoment(month)).to.equal(true); + (0, _chai.expect)((0, _typeof2["default"])(onMonthSelect)).to.equal('function'); + (0, _chai.expect)((0, _typeof2["default"])(onYearSelect)).to.equal('function'); + (0, _chai.expect)((0, _typeof2["default"])(isVisible)).to.equal('boolean'); + (0, _chai.expect)(wrapper.find('#month-element').exists()).to.equal(true); + }); + (0, _describeIfWindow["default"])('setMonthTitleHeight', function () { + beforeEach(function () { + _sinonSandbox["default"].stub(window, 'setTimeout').callsFake(function (handler) { + return handler(); + }); + }); + it('sets the title height after mount', function () { + var setMonthTitleHeightStub = _sinonSandbox["default"].stub(); + + (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + isVisible: true, + setMonthTitleHeight: setMonthTitleHeightStub + })); + (0, _chai.expect)(setMonthTitleHeightStub).to.have.property('callCount', 1); + }); + describe('if the callbacks gets set again', function () { + it('updates the title height', function () { + var setMonthTitleHeightStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_CalendarMonth["default"], { + isVisible: true, + setMonthTitleHeight: setMonthTitleHeightStub + })); + (0, _chai.expect)(setMonthTitleHeightStub).to.have.property('callCount', 1); + wrapper.setProps({ + setMonthTitleHeight: null + }); + wrapper.setProps({ + setMonthTitleHeight: setMonthTitleHeightStub + }); + (0, _chai.expect)(setMonthTitleHeightStub).to.have.property('callCount', 2); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/CalendarWeek_spec.js b/test-build/components/CalendarWeek_spec.js new file mode 100644 index 000000000..ec684bfaf --- /dev/null +++ b/test-build/components/CalendarWeek_spec.js @@ -0,0 +1,20 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _CalendarWeek = _interopRequireDefault(require("../../lib/components/CalendarWeek")); + +var _CalendarDay = _interopRequireDefault(require("../../lib/components/CalendarDay")); + +describe('CalendarWeek', function () { + it('renders a tr', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CalendarWeek["default"], null, /*#__PURE__*/_react["default"].createElement(_CalendarDay["default"], null))); + (0, _chai.expect)(wrapper.is('tr')).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test-build/components/CustomizableCalendarDay_spec.js b/test-build/components/CustomizableCalendarDay_spec.js new file mode 100644 index 000000000..958794968 --- /dev/null +++ b/test-build/components/CustomizableCalendarDay_spec.js @@ -0,0 +1,324 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _moment = _interopRequireDefault(require("moment")); + +var _raf = _interopRequireDefault(require("raf")); + +var _constants = require("../../lib/constants"); + +var _CustomizableCalendarDay = _interopRequireWildcard(require("../../lib/components/CustomizableCalendarDay")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +describe('CustomizableCalendarDay', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render', function () { + it('contains formatted day for single digit days', function () { + var firstOfMonth = (0, _moment["default"])().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + day: firstOfMonth + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(firstOfMonth.format('D')); + }); + it('contains formatted day for double digit days', function () { + var lastOfMonth = (0, _moment["default"])().endOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + day: lastOfMonth + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(lastOfMonth.format('D')); + }); + it('contains arbitrary content if renderDay is provided', function () { + var dayName = (0, _moment["default"])().format('dddd'); + + var renderDay = function renderDay(day) { + return day.format('dddd'); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + renderDayContents: renderDay + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(dayName); + }); + it('passes modifiers to renderDay', function () { + var modifiers = new Set([_constants.BLOCKED_MODIFIER]); + + var renderDay = function renderDay(day, mods) { + return "".concat(day.format('dddd')).concat(mods.has(_constants.BLOCKED_MODIFIER) ? 'BLOCKED' : ''); + }; + + var expected = "".concat((0, _moment["default"])().format('dddd'), "BLOCKED"); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + renderDayContents: renderDay, + modifiers: modifiers + })).dive(); + (0, _chai.expect)(wrapper.text()).to.equal(expected); + }); + it('has button role', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + (0, _chai.expect)(wrapper.props().role).to.equal('button'); + }); + it('has tabIndex equal to props.tabIndex', function () { + var tabIndex = -1; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + tabIndex: tabIndex + })).dive(); + (0, _chai.expect)(wrapper.props().tabIndex).to.equal(tabIndex); + }); + describe('aria-label', function () { + var phrases = {}; + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + beforeEach(function () { + phrases.chooseAvailableDate = _sinonSandbox["default"].stub().returns('chooseAvailableDate text'); + phrases.dateIsSelected = _sinonSandbox["default"].stub().returns('dateIsSelected text'); + phrases.dateIsUnavailable = _sinonSandbox["default"].stub().returns('dateIsUnavailable text'); + phrases.dateIsSelectedAsStartDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsStartDate text'); + phrases.dateIsSelectedAsEndDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsEndDate text'); + }); + it('is formatted with the chooseAvailableDate phrase function when day is available', function () { + var modifiers = new Set(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('chooseAvailableDate text'); + }); + it('is formatted with the dateIsSelected phrase function when day is selected', function () { + var modifiers = new Set(['selected']); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelected text'); + }); + it('is formatted with the dateIsSelectedAsStartDate phrase function when day is selected as the start date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-start'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelectedAsStartDate text'); + }); + it('is formatted with the dateIsSelectedAsEndDate phrase function when day is selected as the end date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-end'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsSelectedAsEndDate text'); + }); + it('is formatted with the dateIsUnavailable phrase function when day is not available', function () { + var modifiers = new Set([_constants.BLOCKED_MODIFIER]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + phrases: phrases, + day: day + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('dateIsUnavailable text'); + }); + it('should set aria-label with a value pass through ariaLabelFormat prop if it exists', function () { + var modifiers = new Set(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + modifiers: modifiers, + day: day, + ariaLabelFormat: "MMMM Do YYYY" + })).dive(); + (0, _chai.expect)(wrapper.prop('aria-label')).to.equal('October 10th 2017'); + }); + }); + describe('event handlers', function () { + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + var wrapper; + beforeEach(function () { + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + day: day, + ariaLabelFormat: "MMMM Do YYYY" + })).dive(); + }); + it('onMouseUp blurs the event target', function () { + var handler = wrapper.prop('onMouseUp'); + + var blur = _sinonSandbox["default"].spy(); + + handler({ + currentTarget: { + blur: blur + } + }); + (0, _chai.expect)(blur).to.have.property('callCount', 1); + }); + it('onKeyDown calls this.onKeyDown', function () { + var spy = _sinonSandbox["default"].spy(wrapper.instance(), 'onKeyDown'); + + var handler = wrapper.prop('onKeyDown'); + var event = {}; + handler(event); + (0, _chai.expect)(spy).to.have.property('callCount', 1); + (0, _chai.expect)(spy.calledWith(day, event)).to.equal(true); + }); + }); + it('renders an empty when no day is given', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + day: null + })).dive(); + (0, _chai.expect)(wrapper.is('td')).to.equal(true); + (0, _chai.expect)(wrapper.children()).to.have.lengthOf(0); + (0, _chai.expect)(wrapper.props()).to.eql({}); + }); + }); + describe('#componentDidUpdate', function () { + it('focuses buttonRef after a delay when isFocused, tabIndex is 0, and tabIndex was not 0', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + isFocused: true, + tabIndex: 0 + })).dive(); + + var focus = _sinonSandbox["default"].spy(); + + wrapper.instance().buttonRef = { + focus: focus + }; + wrapper.instance().componentDidUpdate({ + isFocused: true, + tabIndex: -1 + }); + (0, _chai.expect)(focus.callCount).to.eq(0); + return new Promise(function (resolve) { + (0, _raf["default"])(function () { + (0, _chai.expect)(focus.callCount).to.eq(1); + resolve(); + }); + }); + }); + }); + describe('#onKeyDown', function () { + var day = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); + var onDayClick; + var wrapper; + beforeEach(function () { + onDayClick = _sinonSandbox["default"].spy(); + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + day: day, + onDayClick: onDayClick + })).dive(); + }); + it('calls onDayClick with the enter key', function () { + var event = { + key: 'Enter' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 1); + (0, _chai.expect)(onDayClick.calledWith(day, event)).to.equal(true); + }); + it('calls onDayClick with the space key', function () { + var event = { + key: ' ' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 1); + (0, _chai.expect)(onDayClick.calledWith(day, event)).to.equal(true); + }); + it('does not call onDayClick otherwise', function () { + var event = { + key: 'Shift' + }; + wrapper.instance().onKeyDown(day, event); + (0, _chai.expect)(onDayClick).to.have.property('callCount', 0); + }); + }); + describe('#onDayClick', function () { + var onDayClickSpy; + beforeEach(function () { + onDayClickSpy = _sinonSandbox["default"].spy(_CustomizableCalendarDay.PureCustomizableCalendarDay.prototype, 'onDayClick'); + }); + it('gets triggered by click', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + wrapper.simulate('click'); + (0, _chai.expect)(onDayClickSpy).to.have.property('callCount', 1); + }); + it('calls props.onDayClick', function () { + var onDayClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + onDayClick: onDayClickStub + })).dive(); + wrapper.instance().onDayClick(); + (0, _chai.expect)(onDayClickStub).to.have.property('callCount', 1); + }); + }); + describe('#onDayMouseEnter', function () { + var onDayMouseEnterSpy; + beforeEach(function () { + onDayMouseEnterSpy = _sinonSandbox["default"].spy(_CustomizableCalendarDay.PureCustomizableCalendarDay.prototype, 'onDayMouseEnter'); + }); + it('gets triggered by mouseenter', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + wrapper.simulate('mouseenter'); + (0, _chai.expect)(onDayMouseEnterSpy).to.have.property('callCount', 1); + }); + it('sets state.isHovered to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + wrapper.setState({ + isHovered: false + }); + wrapper.instance().onDayMouseEnter(); + (0, _chai.expect)(wrapper.state().isHovered).to.equal(true); + }); + it('calls props.onDayMouseEnter', function () { + var onMouseEnterStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + onDayMouseEnter: onMouseEnterStub + })).dive(); + wrapper.instance().onDayMouseEnter(); + (0, _chai.expect)(onMouseEnterStub).to.have.property('callCount', 1); + }); + }); + describe('#onDayMouseLeave', function () { + var onDayMouseLeaveSpy; + beforeEach(function () { + onDayMouseLeaveSpy = _sinonSandbox["default"].spy(_CustomizableCalendarDay.PureCustomizableCalendarDay.prototype, 'onDayMouseLeave'); + }); + it('gets triggered by mouseleave', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + wrapper.simulate('mouseleave'); + (0, _chai.expect)(onDayMouseLeaveSpy).to.have.property('callCount', 1); + }); + it('sets state.isHovered to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], null)).dive(); + wrapper.setState({ + isHovered: true + }); + wrapper.instance().onDayMouseLeave(); + (0, _chai.expect)(wrapper.state().isHovered).to.equal(false); + }); + it('calls props.onDayMouseLeave', function () { + var onMouseLeaveStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_CustomizableCalendarDay["default"], { + onDayMouseLeave: onMouseLeaveStub + })).dive(); + wrapper.instance().onDayMouseLeave(); + (0, _chai.expect)(onMouseLeaveStub).to.have.property('callCount', 1); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DateInput_spec.js b/test-build/components/DateInput_spec.js new file mode 100644 index 000000000..e5a929f2f --- /dev/null +++ b/test-build/components/DateInput_spec.js @@ -0,0 +1,391 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _DateInput = _interopRequireDefault(require("../../lib/components/DateInput")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var event = { + preventDefault: function preventDefault() {}, + stopPropagation: function stopPropagation() {} +}; +describe('DateInput', function () { + describe('#render', function () { + describe('input', function () { + it('has props.ariaLabel as an aria-label if ariaLabel is passed in', function () { + var ariaLabel = 'ariaLabelExample'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + ariaLabel: ariaLabel + })).dive(); + (0, _chai.expect)(wrapper.find('input').props()['aria-label']).to.equal(ariaLabel); + }); + it('has no aria-label if props.ariaLabel is null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + ariaLabel: null + })).dive(); + (0, _chai.expect)(wrapper.find('input').props()['aria-label']).to.equal(null); + }); + it('has props.placeholder as an aria-label if ariaLabel is not passed in', function () { + var placeholder = 'placeholder foo'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + placeholder: placeholder + })).dive(); + (0, _chai.expect)(wrapper.find('input').props()['aria-label']).to.equal(placeholder); + }); + it('has props.titleText as a title attribute if titleText is passed in', function () { + var titleText = 'titleTextExample'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + titleText: titleText + })).dive(); + (0, _chai.expect)(wrapper.find('input').props().title).to.equal(titleText); + }); + it('has no title attribute if props.titleText is null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + titleText: null + })).dive(); + (0, _chai.expect)(wrapper.find('input').props().title).to.equal(null); + }); + it('has value === props.displayValue', function () { + var DISPLAY_VALUE = 'foobar'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + displayValue: DISPLAY_VALUE + })).dive(); + (0, _chai.expect)(wrapper.find('input').props().value).to.equal(DISPLAY_VALUE); + }); + it('has value === state.dateString if displayValue is not passed in', function () { + var DATE_STRING = 'foobar'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.setState({ + dateString: DATE_STRING + }); + (0, _chai.expect)(wrapper.find('input').props().value).to.equal(DATE_STRING); + }); + it('props.displayValue overrides dateString when not null', function () { + var DATE_STRING = 'foobar'; + var DISPLAY_VALUE = 'display-value'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.setState({ + dateString: DATE_STRING + }); + (0, _chai.expect)(wrapper.find('input').props().value).to.equal(DATE_STRING); + wrapper.setProps({ + displayValue: DISPLAY_VALUE + }); + (0, _chai.expect)(wrapper.find('input').props().value).to.equal(DISPLAY_VALUE); + }); + describe('props.readOnly is truthy', function () { + it('sets readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + readOnly: true + })).dive(); + (0, _chai.expect)(!!wrapper.find('input').prop('readOnly')).to.equal(true); + }); + }); + describe('props.readOnly is falsy', function () { + it('does not set readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + readOnly: false + })).dive(); + (0, _chai.expect)(!!wrapper.find('input').prop('readOnly')).to.equal(false); + }); + }); + }); + describe('screen reader message', function () { + var wrapper; + var inputId = 'date'; + var screenReaderMessage = 'My screen reader message'; + var screenReaderMessageId = "DateInput__screen-reader-message-".concat(inputId); + var screenReaderMessageSelector = "#".concat(screenReaderMessageId); + describe('props.screenReaderMessage is truthy', function () { + beforeEach(function () { + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: inputId, + screenReaderMessage: screenReaderMessage + })).dive(); + }); + it('has #DateInput__screen-reader-message id', function () { + (0, _chai.expect)(wrapper.find(screenReaderMessageSelector)).to.have.lengthOf(1); + }); + it('has props.screenReaderMessage as content', function () { + (0, _chai.expect)(wrapper.find(screenReaderMessageSelector).text()).to.equal(screenReaderMessage); + }); + it('has aria-describedby attribute === screen reader message id', function () { + (0, _chai.expect)(wrapper.find("input[aria-describedby=\"".concat(screenReaderMessageId, "\"]"))).to.have.lengthOf(1); + }); + }); + describe('props.screenReaderMessage is falsy', function () { + beforeEach(function () { + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: inputId + })).dive(); + }); + it('does not have #DateInput__screen-reader-message id', function () { + (0, _chai.expect)(wrapper.find(screenReaderMessageSelector)).to.have.lengthOf(0); + }); + it('does not have aria-describedby attribute value', function () { + (0, _chai.expect)(wrapper.find("input[aria-describedby=\"".concat(screenReaderMessageId, "\"]"))).to.have.lengthOf(0); + }); + }); + }); + }); + describe('#componentWillReceiveProps', function () { + describe('nextProps.displayValue exists', function () { + it('sets state.dateString to \'\'', function () { + var dateString = 'foo123'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.setState({ + dateString: dateString + }); + wrapper.instance().componentWillReceiveProps({ + displayValue: '1991-07-13' + }); + (0, _chai.expect)(wrapper.state()).to.have.property('dateString', ''); + }); + }); + describe('nextProps.displayValue does not exist', function () { + it('does not change state.dateString', function () { + var dateString = 'foo123'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.setState({ + dateString: dateString + }); + wrapper.instance().componentWillReceiveProps({ + displayValue: null + }); + (0, _chai.expect)(wrapper.state()).to.have.property('dateString', dateString); + }); + }); + }); + describe('#onChange', function () { + var evt = { + target: { + value: 'foobar' + } + }; + it('sets state.dateString to e.target.value', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.instance().onChange(evt); + (0, _chai.expect)(wrapper.state().dateString).to.equal('foobar'); + }); + it('calls props.onChange once', function () { + var onChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onChange: onChangeStub + })).dive(); + wrapper.instance().onChange(evt); + (0, _chai.expect)(onChangeStub.callCount).to.equal(1); + }); + it('calls props.onChange with e.target.value as arg', function () { + var onChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onChange: onChangeStub + })).dive(); + wrapper.instance().onChange(evt); + (0, _chai.expect)(onChangeStub.getCall(0).args[0]).to.equal(evt.target.value); + }); + it('calls props.onKeyDownQuestionMark if last typed character is ?', function () { + var onKeyDownQuestionMarkStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownQuestionMark: onKeyDownQuestionMarkStub + })).dive(); + wrapper.instance().onChange({ + target: { + value: 'foobar?' + } + }); + (0, _chai.expect)(onKeyDownQuestionMarkStub.callCount).to.equal(1); + }); + }); + describe('#onKeyDown', function () { + it('calls props.onKeyDownTab if e.key === `Tab` and e.shiftKey === false', function () { + var onKeyDownTabStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownTab: onKeyDownTabStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Tab', + shiftKey: false + })); + (0, _chai.expect)(onKeyDownTabStub.callCount).to.equal(1); + }); + it('calls props.onKeyDownShiftTab if e.key === `Tab` and e.shiftKey === true', function () { + var onKeyDownShiftTabStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownShiftTab: onKeyDownShiftTabStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Tab', + shiftKey: true + })); + (0, _chai.expect)(onKeyDownShiftTabStub.callCount).to.equal(1); + }); + it('does not call props.onKeyDownTab if e.key !== `Tab`', function () { + var onKeyDownTabStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownTab: onKeyDownTabStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'foo' + })); + (0, _chai.expect)(onKeyDownTabStub.callCount).to.equal(0); + }); + it('calls props.onKeyDownArrowDown if e.key === `ArrowDown`', function () { + var onKeyDownArrowDownStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownArrowDown: onKeyDownArrowDownStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowDown' + })); + (0, _chai.expect)(onKeyDownArrowDownStub.callCount).to.equal(1); + }); + it('does not call props.onKeyDownArrowDown if e.key !== `ArrowDown`', function () { + var onKeyDownArrowDownStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownArrowDown: onKeyDownArrowDownStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'foo' + })); + (0, _chai.expect)(onKeyDownArrowDownStub.callCount).to.equal(0); + }); + it('calls props.onKeyDownQuestionMark if e.key === `?`', function () { + var onKeyDownQuestionMarkStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownQuestionMark: onKeyDownQuestionMarkStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: '?' + })); + (0, _chai.expect)(onKeyDownQuestionMarkStub.callCount).to.equal(1); + }); + it('does not call props.onKeyDownQuestionMark if e.key !== `?`', function () { + var onKeyDownQuestionMarkStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + onKeyDownQuestionMark: onKeyDownQuestionMarkStub + })).dive(); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'foo' + })); + (0, _chai.expect)(onKeyDownQuestionMarkStub.callCount).to.equal(0); + }); + }); + describe('touch device detection', function () { + it('indicates no touch support on the client', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + (0, _chai.expect)(wrapper.state()).to.contain.keys({ + isTouchDevice: false + }); + }); + it('sets readOnly to true when no value was provided on a touch device', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date" + })).dive(); + wrapper.setState({ + isTouchDevice: true + }); + wrapper.update(); + (0, _chai.expect)(!!wrapper.find('input').prop('readOnly')).to.equal(true); + }); + it('sets readOnly to provided value on a touch device', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + readOnly: false + })).dive(); + wrapper.setState({ + isTouchDevice: true + }); + wrapper.update(); + (0, _chai.expect)(!!wrapper.find('input').prop('readOnly')).to.equal(false); + }); + describe('focus/isFocused', function () { + var el = { + focus: function focus() {} + }; + beforeEach(function () { + _sinonSandbox["default"].spy(el, 'focus'); + }); + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + it('focuses inputRef when becoming focused', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateInput["default"], { + id: "date", + focused: false, + isFocused: false + }), { + disableLifecycleMethods: false + }).dive(); + wrapper.instance().inputRef = el; + wrapper.setProps({ + focused: true, + isFocused: true + }); + (0, _chai.expect)(el.focus).to.have.property('callCount', 1); + }); + }); + /* + // Skip this test until we can figure out how to use `withTouchSupport` with karma + wrap() + .withTouchSupport() + .it('sets isTouchDevice state when is a touch device', () => { + const wrapper = shallow(); + wrapper.instance().componentDidMount(); + expect(wrapper.state()).to.contain.keys({ isTouchDevice: true }); + }); + */ + }); +}); \ No newline at end of file diff --git a/test-build/components/DateRangePickerInputController_spec.js b/test-build/components/DateRangePickerInputController_spec.js new file mode 100644 index 000000000..20c3a0fc8 --- /dev/null +++ b/test-build/components/DateRangePickerInputController_spec.js @@ -0,0 +1,955 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _moment = _interopRequireDefault(require("moment")); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _DateRangePickerInputController = _interopRequireDefault(require("../../lib/components/DateRangePickerInputController")); + +var _DateRangePickerInput = _interopRequireDefault(require("../../lib/components/DateRangePickerInput")); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var _constants = require("../../lib/constants"); + +// Set to noon to mimic how days in the picker are configured internally +var today = (0, _moment["default"])().startOf('day').hours(12); +describe('DateRangePickerInputController', function () { + describe('#render', function () { + it('renders a DateRangePickerInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], null)); + (0, _chai.expect)(wrapper.find(_DateRangePickerInput["default"])).to.have.lengthOf(1); + }); + it('should pass children to DateRangePickerInput when provided', function () { + var Child = function Child() { + return /*#__PURE__*/_react["default"].createElement("div", null, "CHILD"); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], null, /*#__PURE__*/_react["default"].createElement(Child, null))); + (0, _chai.expect)(wrapper.find(_DateRangePickerInput["default"])).to.have.property('children'); + (0, _chai.expect)(wrapper.find(Child)).to.have.lengthOf(1); + }); + }); + describe('#clearDates', function () { + describe('props.reopenPickerOnClearDates is truthy', function () { + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + reopenPickerOnClearDates: true + })); + wrapper.instance().clearDates(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with arg START_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + reopenPickerOnClearDates: true + })); + wrapper.instance().clearDates(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.START_DATE); + }); + }); + }); + describe('props.reopenPickerOnClearDates is falsy', function () { + describe('props.onFocusChange', function () { + it('is not called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().clearDates(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + }); + it('calls props.onDatesChange with arg { startDate: null, endDate: null }', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub + })); + wrapper.instance().clearDates(); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + }); + describe('#onClearFocus', function () { + it('calls props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onClearFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onClearFocus(); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + it('calls props.onClose with startDate and endDate args', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var endDate = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: function onFocusChange() { + return null; + }, + onClose: onCloseStub, + startDate: today, + endDate: endDate + })); + wrapper.instance().onClearFocus(); + var args = onCloseStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + (0, _chai.expect)(args.endDate).to.equal(endDate); + }); + }); + describe('#onEndDateChange', function () { + describe('is a valid end date', function () { + var validFutureDateString = (0, _moment["default"])(today).add(10, 'days').format('YYYY-MM-DD'); + describe('when props.startDate is not provided', function () { + it('calls props.onDatesChange with provided end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + + var _onDatesChangeStub$ge = (0, _slicedToArray2["default"])(onDatesChangeStub.getCall(0).args, 1), + _onDatesChangeStub$ge2 = _onDatesChangeStub$ge[0], + startDate = _onDatesChangeStub$ge2.startDate, + endDate = _onDatesChangeStub$ge2.endDate; + + (0, _chai.expect)(startDate).to.equal(wrapper.props().startDate); + (0, _chai.expect)((0, _isSameDay["default"])(endDate, (0, _moment["default"])(validFutureDateString))).to.equal(true); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + }); + }); + describe('is before props.startDate', function () { + var startDate = (0, _moment["default"])(today).add(15, 'days'); + it('calls props.onDatesChange with props.startDate and null end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(onDatesChangeArgs.startDate).to.equal(startDate); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(null); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + }); + }); + describe('is after props.startDate', function () { + var startDate = (0, _moment["default"])(today); + it('calls props.onDatesChange with props.startDate and provided end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)(onDatesChangeArgs.startDate).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.endDate, futureDate)).to.equal(true); + }); + it('calls props.onClose with props.startDate and provided end date', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onClose: onCloseStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onCloseStub).to.have.property('callCount', 1); + + var _onCloseStub$getCall$ = (0, _slicedToArray2["default"])(onCloseStub.getCall(0).args, 1), + onCloseArgs = _onCloseStub$getCall$[0]; + + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)(onCloseArgs).to.have.property('startDate', startDate); + (0, _chai.expect)((0, _isSameDay["default"])(onCloseArgs.endDate, futureDate)).to.equal(true); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + }); + }); + describe('is the same day as props.startDate', function () { + var startDate = (0, _moment["default"])(today).add(10, 'days'); + describe('props.minimumNights is 0', function () { + it('calls props.onDatesChange with props.startDate and provided end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate, + minimumNights: 0 + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)(onDatesChangeArgs.startDate).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.endDate, futureDate)).to.equal(true); + }); + }); + describe('props.minimumNights is greater than 0', function () { + it('calls props.onDatesChange with props.startDate and null end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate, + minimumNights: 1 + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(onDatesChangeArgs.startDate).to.equal(startDate); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(null); + }); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + }); + }); + }); + describe('matches custom display format', function () { + var customFormat = 'YY|MM[foobar]DD'; + var customFormatDateString = (0, _moment["default"])(today).add(5, 'days').format(customFormat); + it('calls props.onDatesChange with correct arguments', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onEndDateChange(customFormatDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var _onDatesChangeStub$ge3 = onDatesChangeStub.getCall(0).args[0], + startDate = _onDatesChangeStub$ge3.startDate, + endDate = _onDatesChangeStub$ge3.endDate; + (0, _chai.expect)(startDate).to.equal(wrapper.instance().props.startDate); + (0, _chai.expect)(endDate.format(customFormat)).to.equal(customFormatDateString); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(null)).to.equal(true); + }); + }); + }); + describe('is not a valid date string', function () { + var invalidDateString = 'foo'; + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onEndDateChange(invalidDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === props.startDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today + })); + wrapper.instance().onEndDateChange(invalidDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + }); + it('calls props.onDatesChange with endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onEndDateChange(invalidDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(null); + }); + }); + describe('is outside range', function () { + var futureDate = (0, _moment["default"])().add(7, 'day').toISOString(); + + var isOutsideRange = function isOutsideRange(day) { + return day >= (0, _moment["default"])().add(3, 'day'); + }; + + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onEndDateChange(futureDate); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === props.startDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onEndDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + }); + it('calls props.onDatesChange with endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onEndDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(null); + }); + }); + describe('is blocked', function () { + var futureDate = (0, _moment["default"])().add(7, 'days').format('DD/MM/YYYY'); + + var isDayBlocked = _sinonSandbox["default"].stub().returns(true); + + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onEndDateChange(futureDate); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onEndDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(null); + }); + }); + describe('is inclusively before state.startDate', function () { + var startDate = (0, _moment["default"])(today).add(10, 'days'); + var beforeStartDateString = today.toISOString(); + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(beforeStartDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === props.startDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(beforeStartDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(startDate); + }); + it('calls props.onDatesChange with endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: startDate + })); + wrapper.instance().onEndDateChange(beforeStartDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(null); + }); + }); + }); + describe('#onStartDateChange', function () { + describe('is a valid start date', function () { + var validFutureDateString = (0, _moment["default"])(today).add(5, 'days').format('YYYY-MM-DD'); + describe('is before props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(10, 'days'); + it('calls props.onDatesChange provided start date and props.endDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.startDate, futureDate)).to.equal(true); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(endDate); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with END_DATE arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(_constants.END_DATE)).to.equal(true); + }); + }); + }); + describe('is after props.endDate', function () { + var endDate = (0, _moment["default"])(today); + it('calls props.onDatesChange with provided start date and null end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.startDate, futureDate)).to.equal(true); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(null); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with END_DATE arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(_constants.END_DATE)).to.equal(true); + }); + }); + }); + describe('is the same day as props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + describe('props.minimumNights is 0', function () { + it('calls props.onDatesChange with provided start date and props.endDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: endDate, + minimumNights: 0 + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.startDate, futureDate)).to.equal(true); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(endDate); + }); + }); + describe('props.minimumNights is greater than 0', function () { + it('calls props.onDatesChange with provided start date and null end date', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: endDate, + minimumNights: 1 + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var onDatesChangeArgs = onDatesChangeStub.getCall(0).args[0]; + var futureDate = (0, _moment["default"])(validFutureDateString); + (0, _chai.expect)((0, _isSameDay["default"])(onDatesChangeArgs.startDate, futureDate)).to.equal(true); + (0, _chai.expect)(onDatesChangeArgs.endDate).to.equal(null); + }); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with END_DATE arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub, + endDate: endDate + })); + wrapper.instance().onStartDateChange(validFutureDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(_constants.END_DATE)).to.equal(true); + }); + }); + }); + }); + describe('matches custom display format', function () { + var customFormat = 'YY|MM[foobar]DD'; + var customFormatDateString = (0, _moment["default"])(today).add(5, 'days').format(customFormat); + it('calls props.onDatesChange with correct arguments', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onStartDateChange(customFormatDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + var _onDatesChangeStub$ge4 = onDatesChangeStub.getCall(0).args[0], + startDate = _onDatesChangeStub$ge4.startDate, + endDate = _onDatesChangeStub$ge4.endDate; + (0, _chai.expect)(startDate.format(customFormat)).to.equal(customFormatDateString); + (0, _chai.expect)(endDate).to.equal(wrapper.instance().props.endDate); + }); + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with END_DATE arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + displayFormat: customFormat, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.calledWith(_constants.END_DATE)).to.equal(true); + }); + }); + }); + describe('is not a valid date string', function () { + var invalidDateString = 'foo'; + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onStartDateChange(invalidDateString); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today + })); + wrapper.instance().onStartDateChange(invalidDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(null); + }); + it('calls props.onDatesChange with endDate === props.endDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: today + })); + wrapper.instance().onStartDateChange(invalidDateString); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(today); + }); + }); + describe('is outside range', function () { + var futureDate = (0, _moment["default"])().add(7, 'days').format('YYYY/MM/DD'); + + var isOutsideRange = function isOutsideRange(day) { + return day > (0, _moment["default"])().add(5, 'days'); + }; + + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onStartDateChange(futureDate); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onStartDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(null); + }); + it('calls props.onDatesChange with endDate === props.endDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + endDate: today, + isOutsideRange: isOutsideRange + })); + wrapper.instance().onStartDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.endDate).to.equal(today); + }); + }); + describe('is blocked', function () { + var futureDate = (0, _moment["default"])().add(7, 'days').format('DD/MM/YYYY'); + + var isDayBlocked = _sinonSandbox["default"].stub().returns(true); + + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onStartDateChange(futureDate); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + it('calls props.onDatesChange with startDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onDatesChange: onDatesChangeStub, + startDate: today, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onStartDateChange(futureDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(null); + }); + }); + }); + describe('#onStartDateFocus', function () { + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + }); + it('calls props.onFocusChange with START_DATE as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.START_DATE); + }); + describe('props.disabled', function () { + describe('props.disabled=START_DATE', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: _constants.START_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 0); + }); + }); + describe('props.disabled=END_DATE', function () { + it('does call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: _constants.END_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + }); + }); + describe('props.disabled=true', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: true, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 0); + }); + }); + describe('props.disabled=false', function () { + it('does call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: false, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onStartDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + }); + }); + }); + }); + describe('#onEndDateFocus', function () { + it('calls props.onFocusChange once with arg END_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.END_DATE); + }); + describe('props.startDate = moment', function () { + it('calls props.onFocusChange once with arg END_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + startDate: (0, _moment["default"])(today), + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.END_DATE); + }); + }); + describe('props.withFullScreenPortal is truthy', function () { + it('calls props.onFocusChange once with arg START_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + withFullScreenPortal: true, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.START_DATE); + }); + }); + describe('props.startDate = moment', function () { + it('calls props.onFocusChange once with arg END_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + startDate: (0, _moment["default"])(today), + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 1); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.END_DATE); + }); + }); + describe('props.disabled', function () { + describe('props.disabled=START_DATE', function () { + it('does call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: _constants.START_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + }); + describe('props.disabled=END_DATE', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: _constants.END_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('props.disabled=true', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: true, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('props.disabled=false', function () { + it('does call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInputController["default"], { + disabled: false, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onEndDateFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DateRangePickerInput_spec.js b/test-build/components/DateRangePickerInput_spec.js new file mode 100644 index 000000000..2cd34b719 --- /dev/null +++ b/test-build/components/DateRangePickerInput_spec.js @@ -0,0 +1,207 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _react = _interopRequireDefault(require("react")); + +var _constants = require("../../lib/constants"); + +var _DateInput = _interopRequireDefault(require("../../lib/components/DateInput")); + +var _DateRangePickerInput = _interopRequireDefault(require("../../lib/components/DateRangePickerInput")); + +describe('DateRangePickerInput', function () { + describe('#render', function () { + it('renders 2 components', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], null)).dive(); + (0, _chai.expect)(wrapper.find(_DateInput["default"])).to.have.lengthOf(2); + }); + describe('props.showClearDates', function () { + it('if true renders clear dates button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + showClearDates: true + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(1); + }); + it('if false does not render clear dates', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + showClearDates: false + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(0); + }); + }); + describe('show calendar icon', function () { + it('if true renders calendar button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + showDefaultInputIcon: true + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(1); + }); + it('if false does not render calendar button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + showDefaultInputIcon: false + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(0); + }); + describe('props.customInputIcon is a React Element', function () { + it('custom icon is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + customInputIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-icon" + }) + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-icon')).to.have.lengthOf(1); + }); + }); + }); + describe('props.children', function () { + it('should unconditionally render children when provided', function () { + var Child = function Child() { + return /*#__PURE__*/_react["default"].createElement("div", null, "CHILD"); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], null, /*#__PURE__*/_react["default"].createElement(Child, null))).dive(); + (0, _chai.expect)(wrapper.find('Child')).to.have.lengthOf(1); + }); + }); + }); + describe('props.customArrowIcon', function () { + it('custom icon is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + customArrowIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-arrow-icon" + }) + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-arrow-icon')).to.have.lengthOf(1); + }); + it('custom icon is rendered when in RTL mode', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + customArrowIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-arrow-icon" + }), + isRTL: true + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-arrow-icon')).to.have.lengthOf(1); + }); + it('custom icon is rendered when using small mode', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + customArrowIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-arrow-icon" + }), + small: true + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-arrow-icon')).to.have.lengthOf(1); + }); + }); + describe('props.customCloseIcon', function () { + it('custom icon is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + showClearDates: true, + customCloseIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-close-icon" + }) + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-close-icon')).to.have.lengthOf(1); + }); + }); + describe('clear dates interactions', function () { + describe('onClick', function () { + it('props.onClearDates gets triggered', function () { + var onClearDatesSpy = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + onClearDates: onClearDatesSpy, + showClearDates: true + })).dive(); + var clearDatesWrapper = wrapper.find('button'); + clearDatesWrapper.simulate('click'); + (0, _chai.expect)(onClearDatesSpy.called).to.equal(true); + }); + }); + }); + describe('calendar icon interaction', function () { + describe('onClick', function () { + it('props.onKeyDownArrowDown gets triggered', function () { + var onArrowDownSpy = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + onKeyDownArrowDown: onArrowDownSpy, + showDefaultInputIcon: true + })).dive(); + var calendarIconWrapper = wrapper.find('button').at(0); + calendarIconWrapper.simulate('click'); + (0, _chai.expect)(onArrowDownSpy.callCount).to.equal(1); + }); + }); + }); + describe('props.disabled', function () { + describe('props.disabled=START_DATE', function () { + it('First DateInput gets disabled prop, second does not', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + disabled: _constants.START_DATE + })).dive(); + + var _wrapper$find = wrapper.find(_DateInput["default"]), + _wrapper$find2 = (0, _slicedToArray2["default"])(_wrapper$find, 2), + startDateInput = _wrapper$find2[0], + endDateInput = _wrapper$find2[1]; + + (0, _chai.expect)(startDateInput.props.disabled).to.equal(true); + (0, _chai.expect)(endDateInput.props.disabled).to.equal(false); + }); + }); + describe('props.disabled=END_DATE', function () { + it('First DateInput gets disabled prop, second does not', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + disabled: _constants.END_DATE + })).dive(); + + var _wrapper$find3 = wrapper.find(_DateInput["default"]), + _wrapper$find4 = (0, _slicedToArray2["default"])(_wrapper$find3, 2), + startDateInput = _wrapper$find4[0], + endDateInput = _wrapper$find4[1]; + + (0, _chai.expect)(startDateInput.props.disabled).to.equal(false); + (0, _chai.expect)(endDateInput.props.disabled).to.equal(true); + }); + }); + describe('props.disabled=true', function () { + it('First DateInput gets disabled prop, second does not', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + disabled: true + })).dive(); + + var _wrapper$find5 = wrapper.find(_DateInput["default"]), + _wrapper$find6 = (0, _slicedToArray2["default"])(_wrapper$find5, 2), + startDateInput = _wrapper$find6[0], + endDateInput = _wrapper$find6[1]; + + (0, _chai.expect)(startDateInput.props.disabled).to.equal(true); + (0, _chai.expect)(endDateInput.props.disabled).to.equal(true); + }); + }); + describe('props.disabled=false', function () { + it('First DateInput gets disabled prop, second does not', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePickerInput["default"], { + disabled: false + })).dive(); + + var _wrapper$find7 = wrapper.find(_DateInput["default"]), + _wrapper$find8 = (0, _slicedToArray2["default"])(_wrapper$find7, 2), + startDateInput = _wrapper$find8[0], + endDateInput = _wrapper$find8[1]; + + (0, _chai.expect)(startDateInput.props.disabled).to.equal(false); + (0, _chai.expect)(endDateInput.props.disabled).to.equal(false); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DateRangePicker_spec.js b/test-build/components/DateRangePicker_spec.js new file mode 100644 index 000000000..f38bd198a --- /dev/null +++ b/test-build/components/DateRangePicker_spec.js @@ -0,0 +1,755 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); + +var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); + +var _react = _interopRequireDefault(require("react")); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _reactPortal = require("react-portal"); + +var _DateRangePicker = _interopRequireWildcard(require("../../lib/components/DateRangePicker")); + +var _DateRangePickerInputController = _interopRequireDefault(require("../../lib/components/DateRangePickerInputController")); + +var _DayPickerRangeController = _interopRequireDefault(require("../../lib/components/DayPickerRangeController")); + +var _DayPicker = _interopRequireDefault(require("../../lib/components/DayPicker")); + +var _constants = require("../../lib/constants"); + +var _describeIfWindow = _interopRequireDefault(require("../_helpers/describeIfWindow")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +var DateRangePickerWrapper = /*#__PURE__*/function (_React$Component) { + (0, _inheritsLoose2["default"])(DateRangePickerWrapper, _React$Component); + + function DateRangePickerWrapper(props) { + var _this; + + _this = _React$Component.call(this, props) || this; + _this.state = { + focusedInput: null, + startDate: null, + endDate: null + }; + _this.onDatesChange = _this.onDatesChange.bind((0, _assertThisInitialized2["default"])(_this)); + _this.onFocusChange = _this.onFocusChange.bind((0, _assertThisInitialized2["default"])(_this)); + return _this; + } + + var _proto = DateRangePickerWrapper.prototype; + + _proto.onDatesChange = function onDatesChange(_ref) { + var startDate = _ref.startDate, + endDate = _ref.endDate; + this.setState({ + startDate: startDate, + endDate: endDate + }); + }; + + _proto.onFocusChange = function onFocusChange(focusedInput) { + this.setState({ + focusedInput: focusedInput + }); + }; + + _proto.render = function render() { + var _this$state = this.state, + focusedInput = _this$state.focusedInput, + startDate = _this$state.startDate, + endDate = _this$state.endDate; + return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, this.props, { + onDatesChange: this.onDatesChange, + onFocusChange: this.onFocusChange, + focusedInput: focusedInput, + startDate: startDate, + endDate: endDate + })), /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Dummy button")); + }; + + return DateRangePickerWrapper; +}(_react["default"].Component); + +var requiredProps = { + onDatesChange: function onDatesChange() {}, + onFocusChange: function onFocusChange() {}, + startDateId: 'startDate', + endDateId: 'endDate' +}; +describe('DateRangePicker', function () { + describe('#render()', function () { + it('renders ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_DateRangePickerInputController["default"])).to.have.length(1); + }); + it('renders ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"])).to.have.length(1); + }); + describe('props.orientation === HORIZONTAL_ORIENTATION', function () { + it('renders with props.numberOfMonths === 2', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + orientation: _constants.HORIZONTAL_ORIENTATION, + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"]).props().numberOfMonths).to.equal(2); + }); + }); + it('should pass onDayPickerBlur as onBlur to ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE + }))).dive(); + + var _wrapper$instance = wrapper.instance(), + onDayPickerBlur = _wrapper$instance.onDayPickerBlur; + + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"]).prop('onBlur')).to.equal(onDayPickerBlur); + }); + describe('props.withPortal is truthy', function () { + describe('', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + withPortal: true, + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(1); + }); + it('is not rendered if props.focusedInput === null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + withPortal: true + }))).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(0); + }); + }); + }); + describe('props.withFullScreenPortal is truthy', function () { + it('does not render ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + withFullScreenPortal: true + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"])).to.have.length(0); + }); + describe('', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + withFullScreenPortal: true, + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(1); + }); + it('is not rendered if props.focusedInput === null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + withFullScreenPortal: true + }))).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(0); + }); + }); + }); + describe('props.isDayBlocked is defined', function () { + it('should pass props.isDayBlocked to ', function () { + var isDayBlocked = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + isDayBlocked: isDayBlocked + }))).dive(); + (0, _chai.expect)(wrapper.find(_DateRangePickerInputController["default"]).prop('isDayBlocked')).to.equal(isDayBlocked); + }); + it('is a noop when omitted', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], requiredProps)).dive(); + (0, _chai.expect)(wrapper.find(_DateRangePickerInputController["default"]).prop('isDayBlocked')).not.to["throw"](); + }); + }); + describe('props.appendToBody', function () { + it('renders inside ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + appendToBody: true, + focusedInput: _constants.START_DATE + }))).dive(); + var portal = wrapper.find(_reactPortal.Portal); + (0, _chai.expect)(portal).to.have.length(1); + (0, _chai.expect)(portal.find(_DayPickerRangeController["default"])).to.have.length(1); + }); + (0, _describeIfWindow["default"])('mounted', function () { + var wrapper; + var instance; + var onCloseStub; + beforeEach(function () { + onCloseStub = _sinonSandbox["default"].stub(); + wrapper = (0, _enzyme.mount)((0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + appendToBody: true, + focusedInput: _constants.START_DATE, + onClose: onCloseStub + }))).get(0)); + instance = wrapper.instance(); + }); + it('positions using top and transform CSS properties', function () { + var dayPickerEl = instance.dayPickerContainer; + (0, _chai.expect)(dayPickerEl.style.top).not.to.equal(''); + (0, _chai.expect)(dayPickerEl.style.transform).not.to.equal(''); + }); + it('disables scroll', function () { + (0, _chai.expect)(instance.enableScroll).to.be.a('function'); + }); + it('ignores click events from inside picker', function () { + var event = { + target: instance.dayPickerContainer + }; + instance.onOutsideClick(event); + (0, _chai.expect)(onCloseStub.callCount).to.equal(0); + }); + it('enables scroll when closed', function () { + var enableScrollSpy = _sinonSandbox["default"].spy(instance, 'enableScroll'); + + wrapper.setProps({ + focusedInput: null + }); + (0, _chai.expect)(enableScrollSpy.callCount).to.equal(1); + }); + it('enables scroll when unmounted', function () { + var enableScrollSpy = _sinonSandbox["default"].spy(instance, 'enableScroll'); + + wrapper.unmount(); + (0, _chai.expect)(enableScrollSpy.callCount).to.equal(1); + }); + }); + }); + describe('props.focusedInput', function () { + it('renders if props.focusedInput != null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"])).to.have.length(1); + }); + it('does not render if props.focusedInput = null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"])).to.have.length(0); + }); + }); + }); + describe('#onOutsideClick', function () { + it('does not call props.onFocusChange if props.focusedInput = null', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + it('calls props.onFocusChange if props.focusedInput != null', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('sets state.isDateRangePickerInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDateRangePickerInputFocused: true + }); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(wrapper.state().isDateRangePickerInputFocused).to.equal(false); + }); + it('sets state.isDayPickerFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDayPickerFocused: true + }); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(false); + }); + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + it('does not call props.onClose if props.focusedInput = null', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + onClose: onCloseStub, + onFocusChange: function onFocusChange() { + return null; + } + }))).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onCloseStub.callCount).to.equal(0); + }); + it('calls props.onClose with startDate and endDate if props.focusedInput != null', function () { + var startDate = (0, _moment["default"])(); + var endDate = startDate.add(1, 'days'); + + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + startDate: startDate, + endDate: endDate, + focusedInput: _constants.START_DATE, + onClose: onCloseStub, + onFocusChange: function onFocusChange() { + return null; + } + }))).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onCloseStub.callCount).to.equal(1); + var args = onCloseStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(startDate); + (0, _chai.expect)(args.endDate).to.equal(endDate); + }); + }); + describe('#onDateRangePickerInputFocus', function () { + it('calls onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls onFocusChange with arg', function () { + var test = 'foobar'; + + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(test); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(test); + }); + describe('new focusedInput is truthy', function () { + var onDayPickerFocusSpy; + var onDayPickerBlurSpy; + beforeEach(function () { + onDayPickerFocusSpy = _sinonSandbox["default"].spy(_DateRangePicker.PureDateRangePicker.prototype, 'onDayPickerFocus'); + onDayPickerBlurSpy = _sinonSandbox["default"].spy(_DateRangePicker.PureDateRangePicker.prototype, 'onDayPickerBlur'); + }); + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + it('calls onDayPickerFocus if focusedInput and withPortal/withFullScreenPortal', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + withPortal: true + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if focusedInput and withFullScreenPortal', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + withFullScreenPortal: true + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if focusedInput and readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + readOnly: true + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if focusedInput and isTouchDevice', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.instance().isTouchDevice = true; + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerBlur if focusedInput and !withPortal/!withFullScreenPortal/!readOnly and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true + }))).dive(); + wrapper.instance().isTouchDevice = true; + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerBlurSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if focusedInput and withPortal/withFullScreenPortal and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true, + withFullScreenPortal: true + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerBlur if focusedInput and !withPortal/!withFullScreenPortal/!readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.instance().onDateRangePickerInputFocus(_constants.START_DATE); + (0, _chai.expect)(onDayPickerBlurSpy.callCount).to.equal(1); + }); + }); + }); + describe('#onDayPickerFocus', function () { + it('sets state.isDateRangePickerInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDateRangePickerInputFocused: true + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().isDateRangePickerInputFocused).to.equal(false); + }); + it('sets state.isDayPickerFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDayPickerFocused: false + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(true); + }); + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + describe('focusedInput is truthy', function () { + it('does not call onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('focusedInput is falsy', function () { + it('calls onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls onFocusChange with START_DATE as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: null, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: onFocusChangeStub + }))).dive(); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.START_DATE); + }); + }); + }); + (0, _describeIfWindow["default"])('day picker position', function () { + it('day picker is opened after the end date input when end date input is focused', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(DateRangePickerWrapper, { + startDateId: "startDate", + endDateId: "endDate" + })); + (0, _chai.expect)(wrapper.find(_DayPicker["default"])).to.have.length(0); + wrapper.find('input').at(0).simulate('focus'); // when focusing on start date the day picker is rendered after the start date input + + (0, _chai.expect)(wrapper.find('DateRangePickerInput').children().childAt(1).find(_DayPicker["default"])).to.have.length(1); + wrapper.find('input').at(1).simulate('focus'); // when focusing on end date the day picker is rendered after the end date input + + (0, _chai.expect)(wrapper.find('DateRangePickerInput').children().childAt(1).find(_DayPicker["default"])).to.have.length(0); + (0, _chai.expect)(wrapper.find('DateRangePickerInput').children().childAt(3).find(_DayPicker["default"])).to.have.length(1); + }); + }); + (0, _describeIfWindow["default"])('#onDayPickerBlur', function () { + it('sets state.isDateRangePickerInputFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDateRangePickerInputFocused: false + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().isDateRangePickerInputFocused).to.equal(true); + }); + it('sets state.isDayPickerFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDayPickerFocused: true + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(false); + }); + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + it('tabbing out with keyboard behaves as an outside click', function () { + var target = _sinonSandbox["default"].stub(); + + var onOutsideClick = _sinonSandbox["default"].stub(); + + var dayPickerContainer = { + addEventListener: _sinonSandbox["default"].stub(), + contains: _sinonSandbox["default"].stub().returns(false) + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], requiredProps)).dive(); + wrapper.instance().setDayPickerContainerRef(dayPickerContainer); + wrapper.instance().onOutsideClick = onOutsideClick; + (0, _chai.expect)(onOutsideClick.callCount).to.equal(0); + wrapper.instance().onDayPickerFocusOut({ + key: 'Tab', + shiftKey: false, + target: target + }); + (0, _chai.expect)(onOutsideClick.callCount).to.equal(1); + }); + it('tabbing within itself does not behave as an outside click', function () { + var target = _sinonSandbox["default"].stub(); + + var onOutsideClick = _sinonSandbox["default"].stub(); + + var dayPickerContainer = { + addEventListener: _sinonSandbox["default"].stub(), + contains: _sinonSandbox["default"].stub().returns(true) + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], requiredProps)).dive(); + wrapper.instance().setDayPickerContainerRef(dayPickerContainer); + wrapper.instance().onOutsideClick = onOutsideClick; + wrapper.instance().onDayPickerFocusOut({ + key: 'Tab', + shiftKey: false, + target: target + }); + (0, _chai.expect)(onOutsideClick.callCount).to.equal(0); + }); + }); + describe('#showKeyboardShortcutsPanel', function () { + it('sets state.isDateRangePickerInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDateRangePickerInputFocused: true + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().isDateRangePickerInputFocused).to.equal(false); + }); + it('sets state.isDayPickerFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + isDayPickerFocused: false + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(true); + }); + it('sets state.showKeyboardShortcuts to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + }))).dive(); + wrapper.setState({ + showKeyboardShortcuts: false + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(true); + }); + }); + describe('initialVisibleMonth', function () { + describe('initialVisibleMonth is passed in', function () { + it('DayPickerRangeController.props.initialVisibleMonth is equal to initialVisibleMonth', function () { + var initialVisibleMonth = function initialVisibleMonth() {}; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + initialVisibleMonth: initialVisibleMonth + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth).to.equal(initialVisibleMonth); + }); + }); + describe('initialVisibleMonth is not passed in', function () { + it('DayPickerRangeController.props.initialVisibleMonth evaluates to startDate', function () { + var startDate = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + startDate: startDate + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth()).to.equal(startDate); + }); + it('DayPickerRangeController.props.initialVisibleMonth evaluates to endDate if !startDate', function () { + var endDate = (0, _moment["default"])().add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + endDate: endDate + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth()).to.equal(endDate); + }); + it('DayPickerRangeController.props.initialVisibleMonth evaluates to today if !startDate && !endDate', function () { + var today = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth().isSame(today, 'day')).to.equal(true); + }); + }); + }); + describe('dateOffsets', function () { + describe('startDateOffset is passed in', function () { + it('Should pass startDateOffset to DayPickerRangeController', function () { + var startDate = (0, _moment["default"])('2018-10-17'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + startDateOffset: function startDateOffset(date) { + return date.subtract(5, 'days'); + }, + onDatesChange: onDatesChangeStub, + focusedInput: _constants.START_DATE + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + var dayPickerStartDateOffset = dayPicker.props().startDateOffset(startDate); + (0, _chai.expect)(dayPickerStartDateOffset.format()).to.equal(startDate.format()); + }); + }); + describe('endDateOffset is passed in', function () { + it('Should pass endDateOffset to DayPickerRangeController', function () { + var endDate = (0, _moment["default"])('2018-10-17', 'YYYY-MM-DD'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + endDateOffset: function endDateOffset(date) { + return date.subtract(5, 'days'); + }, + onDatesChange: onDatesChangeStub, + focusedInput: _constants.START_DATE + }))).dive(); + var dayPicker = wrapper.find(_DayPickerRangeController["default"]); + var dayPickerEndDateOffset = dayPicker.props().endDateOffset(endDate); + (0, _chai.expect)(dayPickerEndDateOffset.format()).to.equal(endDate.format()); + }); + }); + }); + describe('minDate and maxDate props', function () { + describe('minDate is passed in', function () { + it('Should pass minDate to DayPickerRangeController', function () { + var minDate = (0, _moment["default"])('2018-10-19'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + minDate: minDate + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"]).props().minDate).to.equal(minDate); + }); + }); + describe('maxDate is passed in', function () { + it('Should pass maxDate to DayPickerRangeController', function () { + var maxDate = (0, _moment["default"])('2018-12-19'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + maxDate: maxDate + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"]).props().maxDate).to.equal(maxDate); + }); + }); + }); + it('should pass noBorder as noBorder to ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DateRangePicker["default"], (0, _extends2["default"])({}, requiredProps, { + focusedInput: _constants.START_DATE, + noBorder: true + }))).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerRangeController["default"]).prop('noBorder')).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test-build/components/DayPickerKeyboardShortcuts_spec.js b/test-build/components/DayPickerKeyboardShortcuts_spec.js new file mode 100644 index 000000000..c1e0b7021 --- /dev/null +++ b/test-build/components/DayPickerKeyboardShortcuts_spec.js @@ -0,0 +1,400 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _defaultPhrases = require("../../lib/defaultPhrases"); + +var _CloseButton = _interopRequireDefault(require("../../lib/components/CloseButton")); + +var _KeyboardShortcutRow = _interopRequireDefault(require("../../lib/components/KeyboardShortcutRow")); + +var _DayPickerKeyboardShortcuts = _interopRequireDefault(require("../../lib/components/DayPickerKeyboardShortcuts")); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var event = { + preventDefault: _sinonSandbox["default"].stub(), + stopPropagation: _sinonSandbox["default"].stub() +}; +describe('DayPickerKeyboardShortcuts', function () { + describe('#componentWillReceiveProps', function () { + describe('when the phrases have been updated', function () { + var prevProps = { + phrases: { + enterKey: 'foo', + escape: 'bar', + questionMark: 'baz' + } + }; + var newProps = { + phrases: { + enterKey: 'bleep', + escape: 'blah', + questionMark: 'boop' + } + }; + it('updates the keyboardShortcuts', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], prevProps)).dive(); + var prevKeyboardShortcuts = wrapper.instance().keyboardShortcuts; + wrapper.instance().componentWillReceiveProps(newProps); + var updatedKeyboardShortcuts = wrapper.instance().keyboardShortcuts; + (0, _chai.expect)(prevKeyboardShortcuts).to.not.equal(updatedKeyboardShortcuts); + }); + }); + describe('when the phrases have NOT been updated', function () { + var prevProps = { + phrases: { + enterKey: 'foo', + escape: 'bar', + questionMark: 'baz' + } + }; + var newProps = { + phrases: { + enterKey: 'foo', + escape: 'bar', + questionMark: 'baz' + } + }; + it('does NOT update the keyboardShortcuts', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], prevProps)).dive(); + var prevKeyboardShortcuts = wrapper.instance().keyboardShortcuts; + wrapper.instance().componentWillReceiveProps(newProps); + var updatedKeyboardShortcuts = wrapper.instance().keyboardShortcuts; + (0, _chai.expect)(prevKeyboardShortcuts).to.deep.equal(updatedKeyboardShortcuts); + }); + }); + }); + describe('#componentDidUpdate', function () { + it('focuses the hideKeyboardShortcutsButton', function () { + var hideButtonFocusStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], null)).dive(); + wrapper.instance().setHideKeyboardShortcutsButtonRef({ + focus: hideButtonFocusStub + }); + wrapper.instance().componentDidUpdate(); + (0, _chai.expect)(hideButtonFocusStub.callCount).to.equal(1); + }); + }); + describe('#onShowKeyboardShortcutsButtonClick', function () { + var openKeyboardShortcutsPanelStub = _sinonSandbox["default"].stub(); + + var showButtonFocusStub = _sinonSandbox["default"].stub(); + + beforeEach(function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + openKeyboardShortcutsPanel: openKeyboardShortcutsPanelStub + })).dive(); + wrapper.instance().setShowKeyboardShortcutsButtonRef({ + focus: showButtonFocusStub + }); + wrapper.instance().onShowKeyboardShortcutsButtonClick(); + }); + it('calls props.openKeyboardShortcutsPanel', function () { + (0, _chai.expect)(openKeyboardShortcutsPanelStub.callCount).to.equal(1); + }); + it('sends a callback that focuses the showKeyboardShortcutsButton', function () { + var callback = openKeyboardShortcutsPanelStub.firstCall.args[0]; + callback(); + (0, _chai.expect)(showButtonFocusStub.callCount).to.equal(1); + }); + }); + describe('#render', function () { + describe('#showKeyboardShortcutsButton', function () { + it('renders a button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], null)).dive(); + (0, _chai.expect)(wrapper.children('button')).to.have.lengthOf(1); + }); + describe('when showKeyboardShortcutsPanel is true', function () { + it('sets the aria-label to the hideKeyboardShortcutsPanel phrase', function () { + var hideKeyboardShortcutsPanel = 'Test HIDE Keyboard Shortcuts Panel phrase'; + + var phrases = _objectSpread(_objectSpread({}, _defaultPhrases.DayPickerKeyboardShortcutsPhrases), {}, { + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel + }); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true, + phrases: phrases + })).dive(); + (0, _chai.expect)(wrapper.children('button').prop('aria-label')).to.equal(hideKeyboardShortcutsPanel); + }); + }); + describe('when showKeyboardShortcutsPanel is false', function () { + it('sets the aria-label to the showKeyboardShortcutsPanel phrase', function () { + var showKeyboardShortcutsPanel = 'Test SHOW Keyboard Shortcuts Panel phrase'; + + var phrases = _objectSpread(_objectSpread({}, _defaultPhrases.DayPickerKeyboardShortcutsPhrases), {}, { + showKeyboardShortcutsPanel: showKeyboardShortcutsPanel + }); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: false, + phrases: phrases + })).dive(); + (0, _chai.expect)(wrapper.children('button').prop('aria-label')).to.equal(showKeyboardShortcutsPanel); + }); + }); + describe('event handlers', function () { + var openKeyboardShortcutsPanelStub; + var buttonWrapper; + beforeEach(function () { + openKeyboardShortcutsPanelStub = _sinonSandbox["default"].stub(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + openKeyboardShortcutsPanel: openKeyboardShortcutsPanelStub + })).dive(); + buttonWrapper = wrapper.children('button'); + }); + afterEach(function () { + openKeyboardShortcutsPanelStub.resetHistory(); + }); + it('onClick calls onShowKeyboardShortcutsButtonClick', function () { + buttonWrapper.simulate('click'); + (0, _chai.expect)(openKeyboardShortcutsPanelStub.callCount).to.equal(1); + }); + }); + describe('when Mouse Up', function () { + it('blurs the current target', function () { + var mockEvent = { + currentTarget: { + blur: _sinonSandbox["default"].stub() + } + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], null)).dive(); + var buttonWrapper = wrapper.children().find('button'); + buttonWrapper.prop('onMouseUp')(mockEvent); + (0, _chai.expect)(mockEvent.currentTarget.blur.callCount).to.equal(1); + }); + }); + describe('renderKeyboardShortcutsButton', function () { + it('renders the provided button', function () { + function Button() { + return /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Success!"); + } + + var props = { + renderKeyboardShortcutsButton: function renderKeyboardShortcutsButton() { + return /*#__PURE__*/_react["default"].createElement(Button, null); + } + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], props)).dive(); + (0, _chai.expect)(wrapper.children().find(Button)).to.have.lengthOf(1); + }); + it('renders the default button if renderKeyboardShortcutsButton is not provided', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], null)).dive(); + (0, _chai.expect)(wrapper.children().find('button')).to.have.lengthOf(1); + (0, _chai.expect)(wrapper.children().find('button').prop('aria-label')).to.eql(_defaultPhrases.DayPickerKeyboardShortcutsPhrases.showKeyboardShortcutsPanel); + }); + }); + describe('renderKeyboardShortcutsPanel', function () { + it('renders the provided keyboard shortcuts panel', function () { + var props = { + renderKeyboardShortcutsPanel: function renderKeyboardShortcutsPanel() { + return /*#__PURE__*/_react["default"].createElement("div", null, "Keyboard shortcuts here!"); + }, + showKeyboardShortcutsPanel: true + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], props)).dive(); + (0, _chai.expect)(wrapper.children().contains('Keyboard shortcuts here!')); + }); + }); + }); + describe('#DayPickerKeyboardShortcuts_panel', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find('div[role="dialog"]')).to.have.lengthOf(1); + }); + it('sets props.phrases.keyboardShortcuts as the aria-labelledby value', function () { + var keyboardShortcuts = 'FOOBARBAZ'; + + var phrases = _objectSpread(_objectSpread({}, _defaultPhrases.DayPickerKeyboardShortcutsPhrases), {}, { + keyboardShortcuts: keyboardShortcuts + }); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true, + phrases: phrases + })).dive(); + var ariaLabelledbyId = wrapper.find('div[role="dialog"]').prop('aria-labelledby'); + (0, _chai.expect)(wrapper.find("div#".concat(ariaLabelledbyId)).text()).to.equal(keyboardShortcuts); + }); + it('sets the unordered list of keyboard shortcuts as the aria-describedby', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + var ariaDescribedbyId = wrapper.find('div[role="dialog"]').prop('aria-describedby'); + (0, _chai.expect)(wrapper.find('ul').prop('id')).to.equal(ariaDescribedbyId); + }); + }); + describe('Close button', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find('div[role="dialog"]').children('button')).to.have.lengthOf(1); + }); + it('renders a CloseButton', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find(_CloseButton["default"])).to.have.lengthOf(1); + }); + describe('event handlers', function () { + var closeKeyboardShortcutsPanelStub; + var closeButton; + beforeEach(function () { + closeKeyboardShortcutsPanelStub = _sinonSandbox["default"].stub(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true, + closeKeyboardShortcutsPanel: closeKeyboardShortcutsPanelStub + })).dive(); + closeButton = wrapper.find('div[role="dialog"]').children('button'); + }); + afterEach(function () { + closeKeyboardShortcutsPanelStub.resetHistory(); + event.stopPropagation.resetHistory(); + event.preventDefault.resetHistory(); + }); + it('onClick calls onShowKeyboardShortcutsButtonClick', function () { + closeButton.simulate('click'); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.callCount).to.equal(1); + }); + it('onKeyDown calls e.stopPropagation and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: ' ' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.callCount).to.equal(0); + }); + it('onKeyDown Escape calls e.stopPropagation and onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'Escape' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.callCount).to.equal(1); + }); + it('onKeyDown calls e.stopPropagation and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'Enter' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.callCount).to.equal(0); + }); + it('onKeyDown Tab calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'Tab' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown Home calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'Home' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown End calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'End' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown PageUp calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageUp' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown PageDown calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageDown' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown ArrowLeft calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown ArrowRight calls e.stopPropagation and e.preventDefault and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(event.preventDefault.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown ArrowUp calls e.stopPropagation and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowUp' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + it('onKeyDown ArrowDown calls e.stopPropagation and NOT onShowKeyboardShortcutsButtonClick', function () { + closeButton.prop('onKeyDown')(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowDown' + })); + (0, _chai.expect)(event.stopPropagation.callCount).to.equal(1); + (0, _chai.expect)(closeKeyboardShortcutsPanelStub.notCalled).to.equal(true); + }); + }); + it('sets the aria-label to the hideKeyboardShortcutsPanel phrase', function () { + var hideKeyboardShortcutsPanel = 'Test HIDE Keyboard Shortcuts Panel phrase'; + + var phrases = _objectSpread(_objectSpread({}, _defaultPhrases.DayPickerKeyboardShortcutsPhrases), {}, { + hideKeyboardShortcutsPanel: hideKeyboardShortcutsPanel + }); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true, + phrases: phrases + })).dive(); + (0, _chai.expect)(wrapper.find('div[role="dialog"]').children('button').prop('aria-label')).to.equal(hideKeyboardShortcutsPanel); + }); + }); + describe('KeyboardShortcutRow list', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find('ul')).to.have.lengthOf(1); + }); + it('renders 7 KeyboardShortcutRow components', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerKeyboardShortcuts["default"], { + showKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find('ul').find(_KeyboardShortcutRow["default"])).to.have.lengthOf(7); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DayPickerNavigation_spec.js b/test-build/components/DayPickerNavigation_spec.js new file mode 100644 index 000000000..062c39c3f --- /dev/null +++ b/test-build/components/DayPickerNavigation_spec.js @@ -0,0 +1,389 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _DayPickerNavigation = _interopRequireDefault(require("../../lib/components/DayPickerNavigation")); + +var _RightArrow = _interopRequireDefault(require("../../lib/components/RightArrow")); + +var _LeftArrow = _interopRequireDefault(require("../../lib/components/LeftArrow")); + +var _constants = require("../../lib/constants"); + +describe('DayPickerNavigation', function () { + describe('#render', function () { + it('renders two role="button" divs', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], null)).dive(); + (0, _chai.expect)(wrapper.find('[role="button"]')).to.have.lengthOf(2); + }); + it('renders one button when showNavNextButton is false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + showNavNextButton: false + })).dive(); + (0, _chai.expect)(wrapper.find('[role="button"]')).to.have.lengthOf(1); + }); + it('renders one button when showNavNextButton is false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + showNavPrevButton: false + })).dive(); + (0, _chai.expect)(wrapper.find('[role="button"]')).to.have.lengthOf(1); + }); + it('is null when showNavNextButton and showNavPrevButton are both false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + showNavPrevButton: false, + showNavNextButton: false + })).dive(); + (0, _chai.expect)(wrapper.type()).to.equal(null); + }); + it('tabindex is present when the default buttons are used', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], null)).dive(); + var prevMonthButton = wrapper.find('[role="button"]').at(0); + var nextMonthButton = wrapper.find('[role="button"]').at(1); + (0, _chai.expect)(prevMonthButton.prop('tabIndex')).to.equal('0'); + (0, _chai.expect)(nextMonthButton.prop('tabIndex')).to.equal('0'); + }); + it('tabindex is not present when custom buttons are used', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + navNext: /*#__PURE__*/_react["default"].createElement("div", null), + navPrev: /*#__PURE__*/_react["default"].createElement("div", null) + })).dive(); + var prevMonthButton = wrapper.find('[role="button"]').at(0); + var nextMonthButton = wrapper.find('[role="button"]').at(1); + (0, _chai.expect)(prevMonthButton.prop('tabIndex')).to.equal(undefined); + (0, _chai.expect)(nextMonthButton.prop('tabIndex')).to.equal(undefined); + }); + it('tabindex is present when custom buttons are used and provide a tabIndex', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + navNext: /*#__PURE__*/_react["default"].createElement("div", { + id: "navNext", + tabIndex: "0" + }) // eslint-disable-line jsx-a11y/no-noninteractive-tabindex + , + navPrev: /*#__PURE__*/_react["default"].createElement("div", { + id: "navPrev", + tabIndex: "0" + }) // eslint-disable-line jsx-a11y/no-noninteractive-tabindex + + })).dive(); + var prevMonthButton = wrapper.find('#navPrev'); + var nextMonthButton = wrapper.find('#navNext'); + (0, _chai.expect)(prevMonthButton.prop('tabIndex')).to.equal('0'); + (0, _chai.expect)(nextMonthButton.prop('tabIndex')).to.equal('0'); + }); + it('uses RightArrow as the default prev icon for RTL', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + isRTL: true + })).dive(); + (0, _chai.expect)(wrapper.childAt(0).find(_RightArrow["default"])).to.have.lengthOf(1); + }); + it('uses LeftArrow as the default next icon for RTL', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + isRTL: true + })).dive(); + (0, _chai.expect)(wrapper.childAt(1).find(_LeftArrow["default"])).to.have.lengthOf(1); + }); + it('calls renderNavPrevButton when custom prev button is used', function () { + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Prev")); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + renderNavPrevButton: renderNavPrevButtonStub + })).dive(); + (0, _chai.expect)(wrapper.childAt(0).find('div[role="button"]')).to.have.lengthOf(0); + (0, _chai.expect)(renderNavPrevButtonStub).to.have.property('callCount', 1); + }); + it('calls renderNavNextButton when custom next button is used', function () { + var renderNavNextButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Next")); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + renderNavNextButton: renderNavNextButtonStub + })).dive(); + (0, _chai.expect)(wrapper.childAt(1).find('div[role="button"]')).to.have.lengthOf(0); + (0, _chai.expect)(renderNavNextButtonStub).to.have.property('callCount', 1); + }); + it('does not render default styles when custom navigation is used', function () { + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Prev")); + + var renderNavNextButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Next")); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + renderNavNextButton: renderNavNextButtonStub, + renderNavPrevButton: renderNavPrevButtonStub, + orientation: _constants.VERTICAL_ORIENTATION + })).dive(); + var wrapperDiv = wrapper.find('div').filterWhere(function (div) { + var className = div.prop('className') || ''; + return className.includes('DayPickerNavigation__verticalDefault'); + }); + (0, _chai.expect)(wrapperDiv).to.have.lengthOf(0); + }); + it('does render default styles when custom navigation is used for only one nav button', function () { + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Prev")); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + renderNavPrevButton: renderNavPrevButtonStub, + orientation: _constants.VERTICAL_ORIENTATION + })).dive(); + var wrapperDiv = wrapper.find('div').filterWhere(function (div) { + var className = div.prop('className') || ''; + return className.includes('DayPickerNavigation__verticalDefault'); + }); + (0, _chai.expect)(wrapperDiv).to.have.lengthOf(1); + }); + it('does not render default styles when custom navigation is used for only button but the other nav button is not shown', function () { + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().returns( /*#__PURE__*/_react["default"].createElement("button", { + type: "button" + }, "Prev")); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + showNavNextButton: false, + renderNavPrevButton: renderNavPrevButtonStub, + orientation: _constants.VERTICAL_ORIENTATION + })).dive(); + var wrapperDiv = wrapper.find('div').filterWhere(function (div) { + var className = div.prop('className') || ''; + return className.includes('DayPickerNavigation__verticalDefault'); + }); + (0, _chai.expect)(wrapperDiv).to.have.lengthOf(0); + }); + it('renders default styles when default navigation is used', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })).dive(); + var wrapperDiv = wrapper.find('div').filterWhere(function (div) { + var className = div.prop('className') || ''; + return className.includes('DayPickerNavigation__verticalDefault'); + }); + (0, _chai.expect)(wrapperDiv).to.have.lengthOf(1); + }); + }); + describe('interactions', function () { + it('props.onPrevMonthClick is triggered by prev month button click', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onPrevMonthClick: onPrevMonthStub + })).dive().find('[role="button"]').at(0); + prevMonthButton.simulate('click'); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 1); + }); + it('props.onNextMonthClick is triggered by next month button click', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onNextMonthClick: onNextMonthStub + })).dive().find('[role="button"]').at(1); + nextMonthButton.simulate('click'); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 1); + }); + it('props.onPrevMonthClick is not triggered by prev month disabled click', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onPrevMonthClick: onPrevMonthStub, + disablePrev: true + })).dive().find('[role="button"]').at(0); + prevMonthButton.simulate('click'); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 0); + }); + it('props.onNextMonthClick is not triggered by prev month disabled click', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onNextMonthClick: onNextMonthStub, + disableNext: true + })).dive().find('[role="button"]').at(1); + nextMonthButton.simulate('click'); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 0); + }); + it('props.onPrevMonthClick is triggered by prev month button key up', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onPrevMonthClick: onPrevMonthStub + })).dive().find('[role="button"]').at(0); + prevMonthButton.simulate('keyup', { + key: 'Enter' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 1); + prevMonthButton.simulate('keyup', { + key: ' ' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 2); + prevMonthButton.simulate('keyup', { + key: 'k' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 2); + }); + it('props.onNextMonthClick is triggered by next month button key up', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onNextMonthClick: onNextMonthStub + })).dive().find('[role="button"]').at(1); + nextMonthButton.simulate('keyup', { + key: 'Enter' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 1); + nextMonthButton.simulate('keyup', { + key: ' ' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 2); + nextMonthButton.simulate('keyup', { + key: 'k' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 2); + }); + it('props.onPrevMonthClick is triggered by custom prev month button click', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref) { + var onClick = _ref.onClick; + return /*#__PURE__*/_react["default"].createElement("button", { + onClick: onClick, + type: "button" + }, "Prev"); + }); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onPrevMonthClick: onPrevMonthStub, + renderNavPrevButton: renderNavPrevButtonStub + })).dive().find('button').at(0); + prevMonthButton.simulate('click'); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 1); + }); + it('props.onNextMonthClick is triggered by custom next month button click', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var renderNavNextButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref2) { + var onClick = _ref2.onClick; + return /*#__PURE__*/_react["default"].createElement("button", { + onClick: onClick, + type: "button" + }, "Next"); + }); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onNextMonthClick: onNextMonthStub, + renderNavNextButton: renderNavNextButtonStub + })).dive().find('button').at(0); + nextMonthButton.simulate('click'); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 1); + }); + it('props.onPrevMonthClick is not triggered by custom prev month disabled click', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref3) { + var disabled = _ref3.disabled, + onClick = _ref3.onClick; + return /*#__PURE__*/_react["default"].createElement("button", { + disabled: disabled, + onClick: onClick, + type: "button" + }, "Prev"); + }); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + disablePrev: true, + onPrevMonthClick: onPrevMonthStub, + renderNavPrevButton: renderNavPrevButtonStub + })).dive().find('button').at(0); + prevMonthButton.simulate('click'); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 0); + }); + it('props.onNextMonthClick is not triggered by custom next month disabled click', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var renderNavNextButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref4) { + var disabled = _ref4.disabled, + onClick = _ref4.onClick; + return /*#__PURE__*/_react["default"].createElement("button", { + disabled: disabled, + onClick: onClick, + type: "button" + }, "Next"); + }); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + disableNext: true, + onNextMonthClick: onNextMonthStub, + renderNavNextButton: renderNavNextButtonStub + })).dive().find('button').at(0); + nextMonthButton.simulate('click'); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 0); + }); + it('props.onPrevMonthClick is triggered by custom prev month button key up', function () { + var onPrevMonthStub = _sinonSandbox["default"].stub(); + + var renderNavPrevButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref5) { + var onKeyUp = _ref5.onKeyUp; + return /*#__PURE__*/_react["default"].createElement("button", { + onKeyUp: onKeyUp, + type: "button" + }, "Prev"); + }); + + var prevMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onPrevMonthClick: onPrevMonthStub, + renderNavPrevButton: renderNavPrevButtonStub + })).dive().find('button').at(0); + prevMonthButton.simulate('keyup', { + key: 'Enter' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 1); + prevMonthButton.simulate('keyup', { + key: ' ' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 2); + prevMonthButton.simulate('keyup', { + key: 'k' + }); + (0, _chai.expect)(onPrevMonthStub).to.have.property('callCount', 2); + }); + it('props.onNextMonthClick is triggered by custom next month button key up', function () { + var onNextMonthStub = _sinonSandbox["default"].stub(); + + var renderNavNextButtonStub = _sinonSandbox["default"].stub().onCall(0).callsFake(function (_ref6) { + var onKeyUp = _ref6.onKeyUp; + return /*#__PURE__*/_react["default"].createElement("button", { + onKeyUp: onKeyUp, + type: "button" + }, "Next"); + }); + + var nextMonthButton = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerNavigation["default"], { + onNextMonthClick: onNextMonthStub, + renderNavNextButton: renderNavNextButtonStub + })).dive().find('button').at(0); + nextMonthButton.simulate('keyup', { + key: 'Enter' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 1); + nextMonthButton.simulate('keyup', { + key: ' ' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 2); + nextMonthButton.simulate('keyup', { + key: 'k' + }); + (0, _chai.expect)(onNextMonthStub).to.have.property('callCount', 2); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DayPickerRangeController_spec.js b/test-build/components/DayPickerRangeController_spec.js new file mode 100644 index 000000000..b4b2812cc --- /dev/null +++ b/test-build/components/DayPickerRangeController_spec.js @@ -0,0 +1,5013 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _moment = _interopRequireDefault(require("moment")); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _DayPickerRangeController = _interopRequireDefault(require("../../lib/components/DayPickerRangeController")); + +var _DayPicker = _interopRequireDefault(require("../../lib/components/DayPicker")); + +var _DayPickerNavigation = _interopRequireDefault(require("../../lib/components/DayPickerNavigation")); + +var _toISODateString = _interopRequireDefault(require("../../lib/utils/toISODateString")); + +var _toISOMonthString4 = _interopRequireDefault(require("../../lib/utils/toISOMonthString")); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("../../lib/utils/isInclusivelyAfterDay")); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var _isBeforeDay = _interopRequireDefault(require("../../lib/utils/isBeforeDay")); + +var isDayVisible = _interopRequireWildcard(require("../../lib/utils/isDayVisible")); + +var _getVisibleDays = _interopRequireDefault(require("../../lib/utils/getVisibleDays")); + +var _constants = require("../../lib/constants"); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +// Set to noon to mimic how days in the picker are configured internally +var today = (0, _moment["default"])().startOf('day').hours(12); + +function getCallsByModifier(stub, modifier) { + return stub.getCalls().filter(function (call) { + return call.args[call.args.length - 1] === modifier; + }); +} + +describe('DayPickerRangeController', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render()', function () { + it('renders ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.find(_DayPicker["default"])).to.have.length(1); + }); + }); + describe('#componentDidMount', function () { + var props = _objectSpread(_objectSpread({}, _DayPickerRangeController["default"].defaultProps), {}, { + onDatesChange: function onDatesChange() {}, + onFocusChange: function onFocusChange() {} + }); + + describe('phrases', function () { + var phrases = { + chooseAvailableDate: 'test1', + chooseAvailableStartDate: 'test2', + chooseAvailableEndDate: 'test3' + }; + describe('focusedInput is START_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableStartDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.START_DATE, + phrases: phrases + }))); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableStartDate); + }); + }); + describe('focusedInput is END_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableEndDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.END_DATE, + phrases: phrases + }))); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableEndDate); + }); + }); + describe('focusedInput is null', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null, + phrases: phrases + }))); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableDate); + }); + }); + }); + }); + describe('#componentWillReceiveProps', function () { + var props = _objectSpread(_objectSpread({}, _DayPickerRangeController["default"].defaultProps), {}, { + onDatesChange: function onDatesChange() {}, + onFocusChange: function onFocusChange() {} + }); + + describe('rebuilding currentMonth/visibleDays', function () { + describe('initialVisibleMonth changed', function () { + describe('focusedInput has changed and is truthy', function () { + it('calls getStateForNewMonth with nextProps', function () { + var getStateForNewMonthSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + getStateForNewMonthSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(getStateForNewMonthSpy.callCount).to.equal(1); + }); + it('sets state.currentMonth to getStateForNewMonth.currentMonth', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: {} + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(wrapper.instance().state.currentMonth).to.equal(currentMonth); + }); + it('sets state.visibleDays to getStateForNewMonth.visibleDays', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + var visibleDays = (0, _getVisibleDays["default"])(currentMonth, 1); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: visibleDays + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(wrapper.instance().state.visibleDays).to.equal(visibleDays); + }); + }); + describe('focusedInput has not changed', function () { + it('does not call getStateForNewMonth', function () { + var getStateForNewMonthSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + getStateForNewMonthSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: null, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(getStateForNewMonthSpy.callCount).to.equal(0); + }); + it('does not change state.currentMonth', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: (0, _moment["default"])(), + visibleDays: {} + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + wrapper.setState({ + currentMonth: currentMonth + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: null, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(wrapper.instance().state.currentMonth).to.equal(currentMonth); + }); + it('does not change state.visibleDays', function () { + var visibleDays = {}; + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: (0, _moment["default"])(), + visibleDays: (0, _getVisibleDays["default"])((0, _moment["default"])(), 1) + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: null + }))); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: null, + initialVisibleMonth: function initialVisibleMonth() { + return (0, _moment["default"])(); + } + })); + (0, _chai.expect)(wrapper.instance().state.visibleDays).to.equal(visibleDays); + }); + }); + }); + describe('numberOfMonths changed', function () { + it('calls getStateForNewMonth with nextProps', function () { + var getStateForNewMonthSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + getStateForNewMonthSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + numberOfMonths: 5 + })); + (0, _chai.expect)(getStateForNewMonthSpy.callCount).to.equal(1); + }); + it('sets state.currentMonth to getStateForNewMonth.currentMonth', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: {} + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + numberOfMonths: 5 + })); + (0, _chai.expect)(wrapper.instance().state.currentMonth).to.equal(currentMonth); + }); + it('sets state.visibleDays to getStateForNewMonth.visibleDays', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + var visibleDays = (0, _getVisibleDays["default"])(currentMonth, 1); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: visibleDays + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + numberOfMonths: 5 + })); + (0, _chai.expect)(wrapper.instance().state.visibleDays).to.equal(visibleDays); + }); + }); + describe('enableOutsideDays changed', function () { + it('calls getStateForNewMonth with nextProps', function () { + var getStateForNewMonthSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + getStateForNewMonthSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + enableOutsideDays: true + })); + (0, _chai.expect)(getStateForNewMonthSpy.callCount).to.equal(1); + }); + it('sets state.currentMonth to getStateForNewMonth.currentMonth', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: {} + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + enableOutsideDays: true + })); + (0, _chai.expect)(wrapper.instance().state.currentMonth).to.equal(currentMonth); + }); + it('sets state.visibleDays to getStateForNewMonth.visibleDays', function () { + var currentMonth = (0, _moment["default"])().add(10, 'months'); + var visibleDays = (0, _getVisibleDays["default"])(currentMonth, 1); + + var getStateForNewMonthStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + getStateForNewMonthStub.returns({ + currentMonth: currentMonth, + visibleDays: visibleDays + }); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + enableOutsideDays: true + })); + (0, _chai.expect)(wrapper.instance().state.visibleDays).to.equal(visibleDays); + }); + }); + describe('startDate changed from one date to another', function () { + it('removes previous `after-hovered-start` range', function () { + var minimumNights = 5; + var startDate = (0, _moment["default"])().add(7, 'days'); + var dayAfterStartDate = startDate.clone().add(1, 'day'); + var firstAvailableDate = startDate.clone().add(minimumNights + 1, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var nextStartDate = (0, _moment["default"])().add(4, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: startDate, + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: nextStartDate + })); + var afterHoverStartCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[1], dayAfterStartDate)).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[2], firstAvailableDate)).to.equal(true); + }); + }); + describe('endDate changed from one date to another', function () { + it('removes previous `selected-end-no-selected-start` when no start date selected', function () { + var minimumNights = 5; + var endDate = (0, _moment["default"])().add(7, 'days'); + + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var nextEndDate = (0, _moment["default"])().add(4, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + endDate: endDate, + focusedInput: _constants.END_DATE, + minimumNights: minimumNights + })); + deleteModifierSpy.resetHistory(); + addModifierSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: nextEndDate + })); + var selectedEndNoStartDateDelete = getCallsByModifier(deleteModifierSpy, 'selected-end-no-selected-start'); + (0, _chai.expect)(selectedEndNoStartDateDelete.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(selectedEndNoStartDateDelete[0].args[1], endDate)).to.equal(true); + var selectedEndNoStartDateAdd = getCallsByModifier(addModifierSpy, 'selected-end-no-selected-start'); + (0, _chai.expect)(selectedEndNoStartDateAdd.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(selectedEndNoStartDateAdd[0].args[1], nextEndDate)).to.equal(true); + }); + it('calls getStateForNewMonth with nextProps when date is not visible', function () { + var getStateForNewMonthSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getStateForNewMonth'); + + var endDate = (0, _moment["default"])(); + var nextEndDate = endDate.clone().add(2, 'months'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + getStateForNewMonthSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: nextEndDate + })); + }); + }); + }); + describe('modifiers', function () { + describe('selected-start modifier', function () { + describe('props.startDate did not change', function () { + it('does not call this.addModifier with `selected-start', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var startDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate + })); + (0, _chai.expect)(getCallsByModifier(addModifierSpy, 'selected-start').length).to.equal(0); + }); + it('does not call this.deleteModifier with `selected-start', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var startDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate + })); + (0, _chai.expect)(getCallsByModifier(deleteModifierSpy, 'selected-start').length).to.equal(0); + }); + }); + describe('props.startDate changed', function () { + it('deleteModifier gets called with old startDate and `selected-start`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var startDate = today; + var newStartDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate + })); + var selectedStartCalls = getCallsByModifier(deleteModifierSpy, 'selected-start'); + (0, _chai.expect)(selectedStartCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartCalls[0].args[1]).to.equal(startDate); + }); + it('addModifier gets called with new startDate and `selected-start`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var startDate = today; + var newStartDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate + })); + var selectedStartCalls = getCallsByModifier(addModifierSpy, 'selected-start'); + (0, _chai.expect)(selectedStartCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartCalls[0].args[1]).to.equal(newStartDate); + }); + }); + }); + describe('selected-end modifier', function () { + describe('props.endDate did not change', function () { + it('does not call this.addModifier with `selected-end`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var endDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: endDate + })); + (0, _chai.expect)(getCallsByModifier(addModifierSpy, 'selected-end').length).to.equal(0); + }); + it('does not call this.deleteModifier with `selected-end`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: endDate + })); + (0, _chai.expect)(getCallsByModifier(deleteModifierSpy, 'selected-end').length).to.equal(0); + }); + }); + describe('props.endDate changed', function () { + it('deleteModifier gets called with old endDate and `selected-end`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = today; + var newEndDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: newEndDate + })); + var selectedEndCalls = getCallsByModifier(deleteModifierSpy, 'selected-end'); + (0, _chai.expect)(selectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedEndCalls[0].args[1]).to.equal(endDate); + }); + it('addModifier gets called with new endDate and `selected-end`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var endDate = today; + var newEndDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: newEndDate + })); + var selectedEndCalls = getCallsByModifier(addModifierSpy, 'selected-end'); + (0, _chai.expect)(selectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedEndCalls[0].args[1]).to.equal(newEndDate); + }); + }); + }); + describe('hovered-span modifier', function () { + describe('startDate changed', function () { + describe('new startDate does not exist', function () { + it('deleteModifierFromRange does not get called with `hovered-span`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var endDate = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: today + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: null, + endDate: endDate + })); + var hoverSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoverSpanCalls.length).to.equal(0); + }); + }); + describe('new endDate does not exist', function () { + it('deleteModifierFromRange does not get called with `hovered-span`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + endDate: null + })); + var hoverSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoverSpanCalls.length).to.equal(0); + }); + }); + describe('new startDate and new endDate both exist', function () { + it('deleteModifierFromRange gets called with startDate, endDate + 1 day, and `hovered-span`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var endDate = today.clone().add(10, 'days'); + var dayAfterEndDate = endDate.clone().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + endDate: endDate + })); + var hoverSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoverSpanCalls.length).to.equal(1); + (0, _chai.expect)(hoverSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(hoverSpanCalls[0].args[2], dayAfterEndDate)).to.equal(true); + }); + }); + }); + }); + describe('selected-span modifier', function () { + describe('startDate changed', function () { + describe('old startDate and old endDate both exist', function () { + it('deleteModifierFromRange gets called with old startDate + 1 day, old endDate, and `selected-span`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var newStartDate = (0, _moment["default"])().add(7, 'days'); + var endDate = (0, _moment["default"])().add(10, 'days'); + var dayAfterEndDate = endDate.clone().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate, + endDate: endDate + })); + var selectedSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'selected-span'); + (0, _chai.expect)(selectedSpanCalls.length).to.equal(1); + (0, _chai.expect)(selectedSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(selectedSpanCalls[0].args[2], dayAfterEndDate)).to.equal(true); + }); + }); + describe('new startDate and new endDate both exist', function () { + it('addModifierToRange gets calls with new startDate + 1 day, endDate, and `selected-span`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var startDate = (0, _moment["default"])().add(1, 'day'); + var newStartDate = today; + var dayAfterStartDate = newStartDate.clone().add(1, 'day'); + var endDate = today.clone().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate, + endDate: endDate + })); + var selectedStartCalls = getCallsByModifier(addModifierToRangeSpy, 'selected-span'); + (0, _chai.expect)(selectedStartCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(selectedStartCalls[0].args[1], dayAfterStartDate)).to.equal(true); + (0, _chai.expect)(selectedStartCalls[0].args[2]).to.equal(endDate); + }); + }); + }); + describe('endDate changed', function () { + describe('old startDate and old endDate both exist', function () { + it('deleteModifierFromRange gets called with old startDate + 1 day, old endDate, and `selected-span`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var endDate = today.clone().add(10, 'days'); + var dayAfterEndDate = endDate.clone().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + endDate: (0, _moment["default"])().add(11, 'day') + })); + var selectedSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'selected-span'); + (0, _chai.expect)(selectedSpanCalls.length).to.equal(1); + (0, _chai.expect)(selectedSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(selectedSpanCalls[0].args[2], dayAfterEndDate)).to.equal(true); + }); + }); + describe('new startDate and new endDate both exist', function () { + it('addModifierToRange gets calls with startDate + 1 day, endDate, and `selected-span`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var startDate = today; + var dayAfterStartDate = startDate.clone().add(1, 'day'); + var endDate = (0, _moment["default"])().add(1, 'day'); + var newEndDate = today.clone().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + endDate: endDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + endDate: newEndDate + })); + var selectedSpanCalls = getCallsByModifier(addModifierToRangeSpy, 'selected-span'); + (0, _chai.expect)(selectedSpanCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(selectedSpanCalls[0].args[1], dayAfterStartDate)).to.equal(true); + (0, _chai.expect)(selectedSpanCalls[0].args[2]).to.equal(newEndDate); + }); + }); + }); + }); + describe('after-hovered-start modifier', function () { + describe('start date changed, is truthy, and there is no end date', function () { + it('calls addModifierToRange with `after-hovered-start`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: (0, _moment["default"])() + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(1); + }); + it('`after-hovered-start` addModifierToRange has span beginning with day after startDate', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var startDate = (0, _moment["default"])(); + var startSpan = (0, _toISODateString["default"])(startDate.clone().add(1, 'day')); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)((0, _toISODateString["default"])(afterHoverStartCalls[0].args[1])).to.equal(startSpan); + }); + it('`after-hovered-start` addModifierToRange has span ending with startDate + minimumNights + 1', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var minimumNights = 3; + var startDate = (0, _moment["default"])(); + var endSpan = (0, _toISODateString["default"])(startDate.clone().add(minimumNights + 1, 'day')); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + minimumNights: minimumNights + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + minimumNights: minimumNights + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)((0, _toISODateString["default"])(afterHoverStartCalls[0].args[2])).to.equal(endSpan); + }); + }); + describe('start date did not change', function () { + it('does not call addModifierToRange with `after-hovered-start`', function () { + var startDate = (0, _moment["default"])(); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + describe('new start date is falsy', function () { + it('does not call addModifierToRange with `after-hovered-start`', function () { + var startDate = (0, _moment["default"])(); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: null + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + describe('end date exists', function () { + it('does not call addModifierToRange with `after-hovered-start`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: (0, _moment["default"])(), + endDate: (0, _moment["default"])() + })); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + }); + describe('blocked-minimum-nights', function () { + describe('old startDate exists', function () { + describe('neither startdate nor focusedInput changed', function () { + it('does not call deleteModifierFromRange with `blocked-minimum-nights`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var focusedInput = _constants.END_DATE; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + endDate: null, + focusedInput: focusedInput + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: focusedInput + })); + var minimumNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(0); + }); + }); + describe('startDate changed', function () { + it('calls deleteModifierFromRange with old start date, + min nights, and `blocked-minimum-nights', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var focusedInput = _constants.END_DATE; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + focusedInput: focusedInput, + minimumNights: minimumNights + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: (0, _moment["default"])().add(5, 'days'), + focusedInput: focusedInput, + minimumNights: minimumNights + })); + var minimumNightsEndSpan = startDate.clone().add(minimumNights, 'days'); + var minimumNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(1); + (0, _chai.expect)(minimumNightsCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(minimumNightsCalls[0].args[2], minimumNightsEndSpan)).to.equal(true); + }); + }); + describe('focusedInput changed', function () { + it('calls deleteModifierFromRange with old start date, + min nights, and `blocked-minimum-nights`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var focusedInput = _constants.END_DATE; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: focusedInput, + minimumNights: minimumNights + })); + var minimumNightsEndSpan = startDate.clone().add(minimumNights, 'days'); + var minimumNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(1); + (0, _chai.expect)(minimumNightsCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(minimumNightsCalls[0].args[2], minimumNightsEndSpan)).to.equal(true); + }); + }); + describe('minimumNights changed', function () { + it('calls deleteModifierFromRange with start date + old min nights, and `blocked-minimum-nights`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var startDate = today; + var focusedInput = _constants.START_DATE; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + focusedInput: focusedInput, + minimumNights: minimumNights + })); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: focusedInput, + startDate: startDate, + minimumNights: 1 + })); + var minimumNightsEndSpan = startDate.clone().add(minimumNights, 'days'); + var minimumNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(1); + (0, _chai.expect)(minimumNightsCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(minimumNightsCalls[0].args[2], minimumNightsEndSpan)).to.equal(true); + }); + }); + }); + describe('new startDate exists', function () { + describe('new focusedInput !== END_DATE', function () { + it('does not call addModifierFromRange with `blocked-minimum-nights', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var startDate = (0, _moment["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.END_DATE, + startDate: startDate, + minimumNights: 5 + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: today, + focusedInput: _constants.START_DATE, + minimumNights: 5 + })); + var minimumNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(0); + }); + it('updates state to remove `blocked-minimum-nights` and `blocked` from the appropriate days', function () { + var startDate = today; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.END_DATE, + startDate: startDate, + minimumNights: minimumNights + }))); + + var _wrapper$state = wrapper.state(), + visibleDays = _wrapper$state.visibleDays; + + var day = (0, _moment["default"])(today); + + for (var i = 0; i < minimumNights; i += 1) { + var monthString = (0, _toISOMonthString4["default"])(day); + var dateString = (0, _toISODateString["default"])(day); + (0, _chai.expect)(visibleDays[monthString][dateString]).to.include('blocked-minimum-nights'); + (0, _chai.expect)(visibleDays[monthString][dateString]).to.include('blocked'); + day.add(1, 'day'); + } + + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + + var _wrapper$state2 = wrapper.state(), + newVisibleDays = _wrapper$state2.visibleDays; + + day = (0, _moment["default"])(today); + + for (var i = 0; i < minimumNights; i += 1) { + var monthString = (0, _toISOMonthString4["default"])(day); + var dateString = (0, _toISODateString["default"])(day); + (0, _chai.expect)(newVisibleDays[monthString][dateString]).not.to.include('blocked-minimum-nights'); + (0, _chai.expect)(newVisibleDays[monthString][dateString]).not.to.include('blocked'); + day.add(1, 'day'); + } + }); + }); + describe('focusedInput === END_DATE', function () { + it('calls addModifierFromRange with startDate, + min nights, `blocked-minimum-nights`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var startDate = today; + var minimumNights = 5; + var minimumNightsEndSpan = startDate.clone().add(minimumNights, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + minimumNights: minimumNights + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: _constants.END_DATE, + minimumNights: minimumNights + })); + var minimumNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'blocked-minimum-nights'); + (0, _chai.expect)(minimumNightsCalls.length).to.equal(1); + (0, _chai.expect)(minimumNightsCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(minimumNightsCalls[0].args[2], minimumNightsEndSpan)).to.equal(true); + }); + it('updates state to include `blocked-minimum-nights` on the appropriate days', function () { + var startDate = today; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + minimumNights: minimumNights + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: _constants.END_DATE, + minimumNights: minimumNights + })); + + var _wrapper$state3 = wrapper.state(), + visibleDays = _wrapper$state3.visibleDays; + + var day = (0, _moment["default"])(today); + + for (var i = 0; i < minimumNights; i += 1) { + var monthString = (0, _toISOMonthString4["default"])(day); + var dateString = (0, _toISODateString["default"])(day); + (0, _chai.expect)(visibleDays[monthString][dateString]).to.include('blocked-minimum-nights'); + day.add(1, 'day'); + } + }); + it('updates state to include `blocked` on the appropriate days', function () { + var startDate = today; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate, + minimumNights: minimumNights + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate, + focusedInput: _constants.END_DATE, + minimumNights: minimumNights + })); + + var _wrapper$state4 = wrapper.state(), + visibleDays = _wrapper$state4.visibleDays; + + var day = (0, _moment["default"])(today); + + for (var i = 0; i < minimumNights; i += 1) { + var monthString = (0, _toISOMonthString4["default"])(day); + var dateString = (0, _toISODateString["default"])(day); + (0, _chai.expect)(visibleDays[monthString][dateString]).to.include('blocked'); + day.add(1, 'day'); + } + }); + }); + }); + }); + describe('blocked-out-of-range', function () { + describe('focusedInput did not change', function () { + it('does not call isOutsideRange if unchanged', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + isOutsideRange: isOutsideRangeStub + }))); + var prevCallCount = isOutsideRangeStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.equal(prevCallCount); + }); + it('calls isOutsideRange if changed', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.not.equal(0); + }); + }); + describe('focusedInput changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString4["default"])(startOfMonth), (_toISOMonthString = {}, (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString)); + }); + it('calls isOutsideRange for every visible day', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.equal(numVisibleDays); + }); + it('if isOutsideRange(day) is true calls addModifier with `blocked-out-of-range` for each day', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + isOutsideRange: isOutsideRangeStub + })); + var blockedCalendarCalls = getCallsByModifier(addModifierSpy, 'blocked-out-of-range'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + it('if isOutsideRange(day) is false calls deleteModifier with day and `blocked-out-of-range`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isOutsideRange: isOutsideRangeStub + })); + var blockedCalendarCalls = getCallsByModifier(deleteModifierSpy, 'blocked-out-of-range'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('blocked-calendar', function () { + describe('focusedInput did not change', function () { + it('does not call isDayBlocked if unchanged', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + isDayBlocked: isDayBlockedStub + }))); + var prevCallCount = isDayBlockedStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.equal(prevCallCount); + }); + it('calls isDayBlocked if changed', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.not.equal(0); + }); + }); + describe('focusedInput changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString2; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString4["default"])(startOfMonth), (_toISOMonthString2 = {}, (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString2)); + }); + it('calls isDayBlocked for every visible day', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.equal(numVisibleDays); + }); + it('if isDayBlocked(day) is true calls addModifier with `blocked-calendar` for each day', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + isDayBlocked: isDayBlockedStub + })); + var blockedCalendarCalls = getCallsByModifier(addModifierSpy, 'blocked-calendar'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + it('if isDayBlocked(day) is false calls deleteModifier with day and `blocked-calendar`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isDayBlocked: isDayBlockedStub + })); + var blockedCalendarCalls = getCallsByModifier(deleteModifierSpy, 'blocked-calendar'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('highlighted-calendar', function () { + describe('focusedInput did not change', function () { + it('does not call isDayHighlighted', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + isDayHighlighted: isDayHighlightedStub + }))); + var prevCallCount = isDayHighlightedStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.equal(prevCallCount); + }); + it('calls isDayHighlighted if changed', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.not.equal(0); + }); + }); + describe('focusedInput changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString3; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString4["default"])(startOfMonth), (_toISOMonthString3 = {}, (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString3)); + }); + it('calls isDayHighlighted for every visible day', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.equal(numVisibleDays); + }); + it('if isDayHighlighted(day) is true calls addModifier with day and `highlighted-calendar`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isDayHighlighted: isDayHighlightedStub + })); + var highlightedCalendarCalls = getCallsByModifier(addModifierSpy, 'highlighted-calendar'); + (0, _chai.expect)(highlightedCalendarCalls.length).to.equal(numVisibleDays); + }); + it('if isDayHighlighted(day) is false calls deleteModifier with day and `highlighted-calendar`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + isDayHighlighted: isDayHighlightedStub + })); + var highlightedCalendarCalls = getCallsByModifier(deleteModifierSpy, 'highlighted-calendar'); + (0, _chai.expect)(highlightedCalendarCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('today', function () { + describe('this.today matches today', function () { + it('does not call deleteModifier with `today`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().today = today; + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(deleteModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(0); + }); + it('does not call addModifier with `today`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().today = today; + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(addModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(0); + }); + }); + describe('this.today is no longer today', function () { + it('calls deleteModifier with this.today and `today` modifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().today = (0, _moment["default"])().subtract(1, 'day'); + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(deleteModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(1); + }); + it('calls addModifier with new today and `today` modifiers', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.instance().today = (0, _moment["default"])().subtract(1, 'day'); + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(addModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(1); + }); + }); + }); + describe('hovered-start-blocked-minimum-nights', function () { + describe('focusedInput did not change', function () { + it('does not call getMinNightsForHoverDate', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(0); + }); + }); + describe('focusedInput did change', function () { + it('does not call getMinNightsForHoverDate when there is no hoverDate state', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(0); + }); + it('calls getMinNightsForHoverDate when there is hoverDate state', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(1); + }); + describe('focusedInput === START_DATE', function () { + it('calls addModifierToRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate returns a positive integer', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[1], today.clone().add(1, 'days'))).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[2], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call addModifierToRange with `hovered-start-blocked-minimum-nights` if the hovered date is blocked', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call addModifierToRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate does not return a positive integer', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call addModifierToRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate is not supplied as a prop', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('calls deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate returns a positive integer', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[1], today.clone().add(1, 'days'))).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[2], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if the hovered date is blocked', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate is not supplied as a prop', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE + })); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + }); + }); + describe('hovered-start-first-possible-end', function () { + describe('focusedInput did not change', function () { + it('does not call getMinNightsForHoverDate', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(0); + }); + }); + describe('focusedInput did change', function () { + it('does not call getMinNightsForHoverDate when there is no hoverDate state', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(0); + }); + it('calls getMinNightsForHoverDate when there is hoverDate state', function () { + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + (0, _chai.expect)(getMinNightsForHoverDateStub.callCount).to.equal(1); + }); + describe('focusedInput === START_DATE', function () { + it('calls addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate returns a positive integer', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartFirstPossibleEndCalls[0].args[1], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call addModifierToRange with `hovered-start-first-possible-end` if the hovered date is blocked', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate does not return a positive integer', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate is not supplied as a prop', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('calls deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate returns a positive integer', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartFirstPossibleEndCalls[0].args[1], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifierFromRange with `hovered-start-first-possible-end` if the hovered date is blocked', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call deleteModifierFromRange with `hovered-start-first-possible-end` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + getMinNightsForHoverDate: getMinNightsForHoverDateStub + }))); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate is not supplied as a prop', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE + })); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + }); + }); + describe('no-selected-start-before-selected-end', function () { + describe('start or end date has changed, start date is falsey, and end date is truthy', function () { + it('calls addModifier with `no-selected-start-before-selected-end` if day is before selected end date', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var endDate = today.clone(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: null, + endDate: endDate + }))); + var newEndDate = endDate.clone().add(1, 'days'); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: newEndDate + })); + var noSelectedStartBeforeSelectedEndCalls = getCallsByModifier(addModifierSpy, 'no-selected-start-before-selected-end'); + noSelectedStartBeforeSelectedEndCalls.forEach(function (eachCall) { + var day = eachCall.args[1]; + (0, _chai.expect)((0, _isBeforeDay["default"])(day, newEndDate)).to.equal(true); + }); + }); + }); + describe('start date has changed, previous start date is falsey, start and end date is truthy', function () { + it('calls deleteModifier with `no-selected-start-before-selected-end` if day is before selected end date', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = today.clone().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: null, + endDate: endDate + }))); + var newStartDate = today; + var visibleDays = wrapper.instance().state.visibleDays; + var numberOfVisibleDays = Object.values(visibleDays).reduce(function (total, visibleDayArray) { + return total + Object.keys(visibleDayArray).length; + }, 0); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: endDate, + startDate: newStartDate + })); + var noSelectedStartBeforeSelectedEndCalls = getCallsByModifier(deleteModifierSpy, 'no-selected-start-before-selected-end'); + (0, _chai.expect)(noSelectedStartBeforeSelectedEndCalls.length).to.equal(numberOfVisibleDays); + }); + }); + }); + describe('selected-start-no-selected-end', function () { + describe('start date is truthy, and end date is falsey', function () { + it('calls addModifier with `selected-start-no-selected-end`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + var startDate = (0, _moment["default"])(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: startDate + })); + var selectedStartNoSelectedEndCalls = getCallsByModifier(addModifierSpy, 'selected-start-no-selected-end'); + (0, _chai.expect)(selectedStartNoSelectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartNoSelectedEndCalls[0].args[1]).to.equal(startDate); + }); + }); + describe('start date has changed, and end date or previous end date are falsey', function () { + it('calls deleteModifier with `selected-start-no-selected-end`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var startDate = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + startDate: startDate + }))); + var newStartDate = startDate.clone().add(1, 'days'); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate + })); + var selectedStartNoSelectedEndCalls = getCallsByModifier(deleteModifierSpy, 'selected-start-no-selected-end'); + (0, _chai.expect)(selectedStartNoSelectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartNoSelectedEndCalls[0].args[1]).to.equal(startDate); + }); + }); + }); + describe('selected-end-no-selected-start', function () { + describe('end date is truthy, and start date is falsey', function () { + it('calls addModifier with `selected-end-no-selected-start`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], props)); + var endDate = (0, _moment["default"])(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: endDate + })); + var selectedStartNoSelectedEndCalls = getCallsByModifier(addModifierSpy, 'selected-end-no-selected-start'); + (0, _chai.expect)(selectedStartNoSelectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartNoSelectedEndCalls[0].args[1]).to.equal(endDate); + }); + }); + describe('end date has changed, and start date or previous start date are falsey', function () { + it('calls deleteModifier with `selected-end-no-selected-start`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + var newEndDate = endDate.clone().add(1, 'days'); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: newEndDate + })); + var selectedStartNoSelectedEndCalls = getCallsByModifier(deleteModifierSpy, 'selected-end-no-selected-start'); + (0, _chai.expect)(selectedStartNoSelectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartNoSelectedEndCalls[0].args[1]).to.equal(endDate); + }); + }); + describe('start date has changed, and start date is truthy, and previous start date was falsey', function () { + it('calls deleteModifier with `selected-end-no-selected-start`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + var newStartDate = endDate.clone().subtract(1, 'days'); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + startDate: newStartDate + })); + var selectedStartNoSelectedEndCalls = getCallsByModifier(deleteModifierSpy, 'selected-end-no-selected-start'); + (0, _chai.expect)(selectedStartNoSelectedEndCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartNoSelectedEndCalls[0].args[1]).to.equal(endDate); + }); + }); + }); + describe('before-hovered-end', function () { + describe('end date changed, end date is truthy and start date is falsey', function () { + it('calls addModifierToRange with `before-hovered-end`', function () { + var minimumNights = 1; + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var endDate = (0, _moment["default"])(); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + minimumNights: minimumNights, + endDate: endDate + }))); + var newEndDate = endDate.clone().add(1, 'days'); + addModifierToRangeSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: newEndDate + })); + var beforeHoveredEndCalls = getCallsByModifier(addModifierToRangeSpy, 'before-hovered-end'); + (0, _chai.expect)(beforeHoveredEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _toISODateString["default"])(beforeHoveredEndCalls[0].args[1])).to.equal((0, _toISODateString["default"])(newEndDate.clone().subtract(minimumNights, 'days'))); + (0, _chai.expect)((0, _toISODateString["default"])(beforeHoveredEndCalls[0].args[2])).to.equal((0, _toISODateString["default"])(newEndDate)); + }); + }); + }); + describe('selected-end-in-hovered-span', function () { + describe('start date has changed', function () { + describe('start and end date are truthy, and previous start date is falsey', function () { + it('calls deleteModifier with `selected-end-in-hovered-span`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + endDate: endDate + }))); + var newStartDate = endDate.clone().subtract(3, 'days'); + deleteModifierSpy.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + endDate: endDate, + startDate: newStartDate + })); + var deleteModifierCalls = getCallsByModifier(deleteModifierSpy, 'selected-end-in-hovered-span'); + (0, _chai.expect)(deleteModifierCalls.length).to.equal(1); + (0, _chai.expect)(deleteModifierCalls[0].args[1]).to.equal(endDate); + }); + }); + }); + }); + }); + describe('phrases', function () { + var phrases = { + chooseAvailableDate: 'test1', + chooseAvailableStartDate: 'test2', + chooseAvailableEndDate: 'test3' + }; + describe('neither props.focusedInput nor props.phrases have changed', function () { + it('state.phrases does not change', function () { + var phrasesObject = { + hello: 'world' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + phrases: phrases + }))); + wrapper.setState({ + phrases: phrasesObject + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + phrases: phrases + })); + (0, _chai.expect)(wrapper.state().phrases).to.equal(phrasesObject); + }); + }); + describe('props.focusedInput has changed', function () { + describe('new focusedInput is START_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableStartDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + phrases: phrases + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableStartDate); + }); + }); + describe('new focusedInput is END_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableEndDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + phrases: phrases + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableEndDate); + }); + }); + describe('new focusedInput is null', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.START_DATE, + phrases: phrases + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableDate); + }); + }); + }); + describe('props.phrases has changed', function () { + describe('focusedInput is START_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableStartDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.START_DATE, + phrases: {} + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.START_DATE, + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableStartDate); + }); + }); + describe('focusedInput is END_DATE', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableEndDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + focusedInput: _constants.END_DATE, + phrases: {} + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focusedInput: _constants.END_DATE, + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableEndDate); + }); + }); + describe('focusedInput is null', function () { + it('state.phrases.chooseAvailableDate equals props.phrases.chooseAvailableDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], (0, _extends2["default"])({}, props, { + phrases: {} + }))); + wrapper.setState({ + phrases: {} + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + phrases: phrases + })); + var newAvailableDatePhrase = wrapper.state().phrases.chooseAvailableDate; + (0, _chai.expect)(newAvailableDatePhrase).to.equal(phrases.chooseAvailableDate); + }); + }); + }); + }); + }); + describe('#onDayClick', function () { + describe('day argument is a blocked day', function () { + it('props.onFocusChange is not called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onFocusChange: onFocusChangeStub, + isDayBlocked: function isDayBlocked() { + return true; + } + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + it('props.onDatesChange is not called', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + isDayBlocked: function isDayBlocked() { + return true; + } + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(0); + }); + }); + describe('daysViolatingMinNightsCanBeClicked is true', function () { + it('props.onDatesChange is called and props.onFocusChange is not called when the day does not meet min nights', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + daysViolatingMinNightsCanBeClicked: true, + focusedInput: _constants.END_DATE, + minimumNights: 3, + onFocusChange: onFocusChangeStub, + onDatesChange: onDatesChangeStub, + startDate: today + })); + wrapper.instance().onDayClick(today.clone().add(1, 'days')); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + }); + describe('props.focusedInput === START_DATE', function () { + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with END_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.END_DATE); + }); + }); + it('calls props.onDatesChange', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onDatesChangeStub.callCount).to.equal(1); + }); + describe('arg is after props.endDate', function () { + it('calls props.onDatesChange with startDate === arg and endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDate: today, + onDatesChange: onDatesChangeStub + })); + var tomorrow = (0, _moment["default"])(today).add(1, 'days'); + wrapper.instance().onDayClick(tomorrow); + (0, _chai.expect)(onDatesChangeStub.calledWith({ + startDate: tomorrow, + endDate: null + })).to.equal(true); + }); + }); + describe('arg is before props.endDate', function () { + it('calls props.onDatesChange with startDate === arg and endDate === props.endDate', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var tomorrow = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDate: tomorrow, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onDatesChangeStub.calledWith({ + startDate: today, + endDate: tomorrow + })).to.equal(true); + }); + }); + describe('props.endDate is null', function () { + it('calls props.onDatesChange with startDate === arg and endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDate: null, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onDatesChangeStub.calledWith({ + startDate: today, + endDate: null + })).to.equal(true); + }); + }); + describe('minimumNights is 0', function () { + it('calls props.onDatesChange with startDate === today and endDate === today', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + minimumNights: 0, + onDatesChange: onDatesChangeStub, + endDate: today + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onDatesChangeStub.calledWith({ + startDate: today, + endDate: today + })).to.equal(true); + }); + }); + }); + describe('props.focusedInput === END_DATE', function () { + describe('arg is before props.startDate', function () { + it('calls props.onDatesChange with startDate === arg and endDate === null', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: (0, _moment["default"])(today).add(1, 'days'), + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onDayClick(today); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + (0, _chai.expect)(args.endDate).to.equal(null); + }); + }); + describe('arg is not before props.startDate', function () { + it('calls props.onDatesChange with startDate === props.startDate and endDate === arg', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + onDatesChange: onDatesChangeStub + })); + wrapper.instance().onDayClick(today); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(wrapper.props().startDate); + (0, _chai.expect)(args.endDate).to.equal(today); + }); + describe('props.onFocusChange', function () { + describe('props.startDate === null', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with START_DATE', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick(today); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(_constants.START_DATE); + }); + }); + describe('props.startDate is truthy', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: today, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick((0, _moment["default"])(today).add(1, 'days')); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('is called with null', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: today, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onDayClick((0, _moment["default"])(today).add(1, 'days')); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.equal(null); + }); + }); + }); + describe('props.onClose', function () { + describe('props.startDate is truthy', function () { + it('is called with startDate and endDate', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: today, + onClose: onCloseStub + })); + var endDate = (0, _moment["default"])(today).add(1, 'days'); + wrapper.instance().onDayClick(endDate); + var args = onCloseStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + (0, _chai.expect)(args.endDate).to.equal(endDate); + }); + }); + }); + }); + describe('minimumNights is 0', function () { + it('calls props.onDatesChange with startDate === today and endDate === today', function () { + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + minimumNights: 0, + onDatesChange: onDatesChangeStub, + startDate: today + })); + wrapper.instance().onDayClick(today); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(today); + (0, _chai.expect)(args.endDate).to.equal(today); + }); + }); + }); + describe('props.startDateOffset / props.endDateOffset', function () { + it('calls props.onDatesChange with startDate === startDateOffset(date) and endDate === endDateOffset(date)', function () { + var clickDate = (0, _moment["default"])(today).clone().add(2, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + startDateOffset: function startDateOffset(day) { + return day.subtract(2, 'days'); + }, + endDateOffset: function endDateOffset(day) { + return day.add(4, 'days'); + } + })); + wrapper.instance().onDayClick(clickDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().subtract(2, 'days').format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().add(4, 'days').format()); + }); + it('does not call props.onDatesChange with startDate === startDateOffset(date) and endDate === endDateOffset(date)', function () { + var clickDate = (0, _moment["default"])(today).clone().add(2, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + startDateOffset: function startDateOffset(day) { + return day.subtract(2, 'days'); + }, + endDateOffset: function endDateOffset(day) { + return day.add(4, 'days'); + }, + isOutsideRange: function isOutsideRange(day) { + return day.isAfter((0, _moment["default"])(today)); + } + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 0); + }); + it('does not call props.onDatesChange when dateOffset isOutsideRange', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + endDateOffset: function endDateOffset(day) { + return day.add(5, 'days'); + }, + isOutsideRange: function isOutsideRange(day) { + return day.isAfter((0, _moment["default"])(today).clone().add(1, 'days')); + } + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 0); + }); + it('calls props.onDatesChange with startDate === startDateOffset(date) and endDate === selectedDate when endDateOffset not provided', function () { + var clickDate = (0, _moment["default"])(today).clone().add(2, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + startDateOffset: function startDateOffset(day) { + return day.subtract(5, 'days'); + } + })); + wrapper.instance().onDayClick(clickDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().subtract(5, 'days').format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.format()); + }); + it('calls props.onDatesChange with startDate === selectedDate and endDate === endDateOffset(date) when startDateOffset not provided', function () { + var clickDate = (0, _moment["default"])(today).clone().add(12, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + endDateOffset: function endDateOffset(day) { + return day.add(12, 'days'); + } + })); + wrapper.instance().onDayClick(clickDate); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().add(12, 'days').format()); + }); + }); + describe('props.onDatesChange only called once in onDayClick', function () { + it('calls props.onDatesChange once when focusedInput === START_DATE', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + focusedInput: _constants.START_DATE, + endDate: null + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().format()); + (0, _chai.expect)(args.endDate).to.equal(null); + }); + it('calls props.onDatesChange once when focusedInput === END_DATE and there is no startDate', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + focusedInput: _constants.END_DATE, + startDate: null + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate).to.equal(null); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().format()); + }); + it('calls props.onDatesChange once when focusedInput === END_DATE and the day is a valid endDate', function () { + var clickDate = (0, _moment["default"])(today); + var startDate = clickDate.clone().subtract(2, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + focusedInput: _constants.END_DATE, + minimumNights: 2, + startDate: startDate + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(startDate.clone().format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().format()); + }); + it('calls props.onDatesChange once when focusedInput === END_DATE, the day is an invalid endDate, and disabled !== START_DATE', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + focusedInput: _constants.END_DATE, + minimumNights: 2, + startDate: clickDate.clone().add(1, 'days'), + endDate: null + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().format()); + (0, _chai.expect)(args.endDate).to.equal(null); + }); + it('calls props.onDatesChange once when focusedInput === END_DATE and the day is an invalid endDate', function () { + var clickDate = (0, _moment["default"])(today); + var startDate = clickDate.clone().add(1, 'days'); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + focusedInput: _constants.END_DATE, + disabled: _constants.START_DATE, + minimumNights: 2, + startDate: startDate, + endDate: null + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(startDate.clone().format()); + (0, _chai.expect)(args.endDate).to.equal(null); + }); + it('calls props.onDatesChange once when there is a startDateOffset', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + startDateOffset: function startDateOffset(day) { + return day.subtract(2, 'days'); + } + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().subtract(2, 'days').format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().format()); + }); + it('calls props.onDatesChange once when there is a endDateOffset', function () { + var clickDate = (0, _moment["default"])(today); + + var onDatesChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChangeStub, + endDateOffset: function endDateOffset(day) { + return day.add(4, 'days'); + } + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(onDatesChangeStub).to.have.property('callCount', 1); + var args = onDatesChangeStub.getCall(0).args[0]; + (0, _chai.expect)(args.startDate.format()).to.equal(clickDate.clone().format()); + (0, _chai.expect)(args.endDate.format()).to.equal(clickDate.clone().add(4, 'days').format()); + }); + }); + describe('logic in props.onDatesChange affects props.onFocusChange', function () { + var preventFocusChange; + var focusedInput; + var onDatesChange; + var onFocusChange; + beforeEach(function () { + preventFocusChange = false; + focusedInput = _constants.START_DATE; + + onDatesChange = function onDatesChange(_ref) { + var startDate = _ref.startDate; + if ((0, _isSameDay["default"])(startDate, today)) preventFocusChange = true; + }; + + onFocusChange = function onFocusChange(input) { + if (!preventFocusChange) { + focusedInput = input; + } else { + preventFocusChange = false; + } + }; + }); + it('calls onDayClick with a day that prevents a focus change', function () { + var clickDate = (0, _moment["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChange, + onFocusChange: onFocusChange, + focusedInput: _constants.START_DATE + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(focusedInput).to.equal(_constants.START_DATE); + wrapper.instance().onDayClick(clickDate.clone().add(1, 'days')); + (0, _chai.expect)(focusedInput).to.equal(_constants.END_DATE); + }); + it('calls onDayClick with a day that does not prevent a focus change', function () { + var clickDate = (0, _moment["default"])(today).clone().add(2, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: onDatesChange, + onFocusChange: onFocusChange, + focusedInput: _constants.START_DATE + })); + wrapper.instance().onDayClick(clickDate); + (0, _chai.expect)(focusedInput).to.equal(_constants.END_DATE); + }); + }); + }); + describe('#onDayMouseEnter', function () { + it('sets state.hoverDate to the day arg', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE + })); + wrapper.instance().onDayMouseEnter(today); + (0, _chai.expect)(wrapper.state().hoverDate).to.equal(today); + }); + it('sets state.dateOffset to the start and end date range when range included', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDateOffset: function endDateOffset(day) { + return day.add(2, 'days'); + } + })); + wrapper.instance().onDayMouseEnter(today); + (0, _chai.expect)(wrapper.state().dateOffset.start.format()).to.equal(today.format()); + (0, _chai.expect)(wrapper.state().dateOffset.end.format()).to.equal(today.clone().add(3, 'days').format()); + }); + describe('modifiers', function () { + it('calls addModifier', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: null + }); + addModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + (0, _chai.expect)(addModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(addModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(addModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + it('calls deleteModifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter((0, _moment["default"])().add(10, 'days')); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + describe('startDate and !endDate and focusedInput === `END_DATE`', function () { + describe('old hoverDate is after startDate', function () { + it('calls deleteModifierFromRange with startDate, old hoverDate and `hovered-span`', function () { + var startDate = today; + var hoverDate = today.clone().add(5, 'days'); + var dayAfterHoverDate = hoverDate.clone().add(1, 'day'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + endDate: null, + onDatesChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter((0, _moment["default"])().add(10, 'days')); + var hoverSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoverSpanCalls.length).to.equal(1); + (0, _chai.expect)(hoverSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(hoverSpanCalls[0].args[2], dayAfterHoverDate)).to.equal(true); + }); + }); + describe('new hoverDate is not blocked and is after startDate', function () { + it('calls addModifierFromRange with startDate, new hoverDate, and `hovered-span`', function () { + var startDate = today; + var hoverDate = today.clone().add(5, 'days'); + var dayAfterHoverDate = hoverDate.clone().add(1, 'day'); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + endDate: null, + onDatesChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: null + }); + addModifierToRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(hoverDate); + var hoverSpanCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoverSpanCalls.length).to.equal(1); + (0, _chai.expect)(hoverSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(hoverSpanCalls[0].args[2], dayAfterHoverDate)).to.equal(true); + }); + }); + }); + describe('!startDate and endDate and focusedInput === `START_DATE`', function () { + describe('old hoverDate is before endDate', function () { + it('calls deleteModifierFromRange', function () { + var hoverDate = today; + var endDate = today.clone().add(5, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: endDate, + onDatesChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter((0, _moment["default"])().add(10, 'days')); + (0, _chai.expect)(deleteModifierFromRangeSpy.callCount).to.equal(2); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[1]).to.equal(hoverDate); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[2]).to.equal(endDate); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[3]).to.equal('hovered-span'); + (0, _chai.expect)((0, _isSameDay["default"])(deleteModifierFromRangeSpy.getCall(1).args[1], endDate.subtract(_DayPickerRangeController["default"].defaultProps.minimumNights, 'days'))).to.equal(true); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(1).args[2]).to.equal(endDate); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(1).args[3]).to.equal('before-hovered-end'); + }); + }); + describe('new hoverDate is not blocked and is before endDate', function () { + it('calls addModifierFromRange', function () { + var hoverDate = today; + var endDate = today.clone().add(5, 'days'); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: endDate, + onDatesChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: null + }); + addModifierToRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(hoverDate); + (0, _chai.expect)(addModifierToRangeSpy.callCount).to.equal(1); + (0, _chai.expect)(addModifierToRangeSpy.getCall(0).args[1]).to.equal(hoverDate); + (0, _chai.expect)(addModifierToRangeSpy.getCall(0).args[2]).to.equal(endDate); + (0, _chai.expect)(addModifierToRangeSpy.getCall(0).args[3]).to.equal('hovered-span'); + }); + }); + }); + describe('after-hovered-start modifier', function () { + describe('startDate does not exist', function () { + it('does not remove old `after-hovered-start` range (cos it doesnt exist)', function () { + var minimumNights = 5; + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + var afterHoverStartCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + describe('startDate exists', function () { + describe('hoverDate is startDate', function () { + it('adds new `after-hovered-start` range', function () { + var minimumNights = 5; + var startDate = (0, _moment["default"])().add(7, 'days'); + var dayAfterStartDate = startDate.clone().add(1, 'day'); + var firstAvailableDate = startDate.clone().add(minimumNights + 1, 'days'); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: startDate, + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + addModifierToRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(startDate); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[1], dayAfterStartDate)).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[2], firstAvailableDate)).to.equal(true); + }); + }); + describe('hoverDate is not startDate', function () { + it('does not add new `after-hovered-start` range', function () { + var minimumNights = 5; + var startDate = (0, _moment["default"])().add(7, 'days'); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: startDate, + focusedInput: _constants.START_DATE, + minimumNights: minimumNights + })); + addModifierToRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + var afterHoverStartCalls = getCallsByModifier(addModifierToRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + }); + }); + describe('hovered-start-first-possible-end modifier', function () { + it('does not call deleteModifier with `hovered-start-first-possible-end` if there is no previous hoverDate', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + describe('focusedInput === START_DATE', function () { + it('calls deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate returns a positive integer', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartFirstPossibleEndCalls[0].args[1], hoverDate.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifier with `hovered-start-first-possible-end` if the previous hovered date is blocked', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, hoverDate); + } + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('calls addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate returns a positive integer', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartFirstPossibleEndCalls[0].args[1], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call addModifier with `hovered-start-first-possible-end` if the new hovered date is blocked', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate does not return a positive integer', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate is not supplied as a prop', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('does not call deleteModifier with `hovered-start-first-possible-end`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-first-possible-end`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(addModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + }); + describe('hovered-start-blocked-minimum-nights modifier', function () { + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if there is no previous hoverDate', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + describe('focusedInput === START_DATE', function () { + it('calls deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate returns a positive integer', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[1], hoverDate.clone().add(1, 'days'))).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[2], hoverDate.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if the previous hovered date is blocked', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, hoverDate); + } + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('calls addModifierToRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate returns a positive integer', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[1], today.clone().add(1, 'days'))).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[2], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call addModifier with `hovered-start-blocked-minimum-nights` if the new hovered date is blocked', function () { + var hoverDate = today.clone().subtract(1, 'days'); + + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + })); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate does not return a positive integer', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate is not supplied as a prop', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('does not call deleteModifierFromRangeFromRange with `hovered-start-blocked-minimum-nights`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call addModifier with `hovered-start-blocked-minimum-nights`', function () { + var addModifierToRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(addModifierToRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + }); + describe('selected-start-in-hovered-span modifier', function () { + describe('end date is falsey and focusedInput === `END_DATE`', function () { + describe('day is start date or before start date', function () { + it('calls deleteModifier with `selected-start-in-hovered-span` on start date', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var startDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate + })); + var yesterday = today.clone().subtract(1, 'days'); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(yesterday); + var deleteModifierCalls = getCallsByModifier(deleteModifierSpy, 'selected-start-in-hovered-span'); + (0, _chai.expect)(deleteModifierCalls.length).to.equal(1); + (0, _chai.expect)(deleteModifierCalls[0].args[1]).to.equal(startDate); + }); + }); + describe('day is not blocked, and is after the start date', function () { + it('calls addModifier with `selected-start-in-hovered-span` on start date', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var startDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate + })); + var tomorrow = today.clone().add(1, 'days'); + addModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(tomorrow); + var addModifierCalls = getCallsByModifier(addModifierSpy, 'selected-start-in-hovered-span'); + (0, _chai.expect)(addModifierCalls.length).to.equal(1); + (0, _chai.expect)(addModifierCalls[0].args[1]).to.equal(startDate); + }); + }); + }); + }); + describe('selected-end-in-hovered-span modifier', function () { + describe('start date is falsey and focusedInput === `START_DATE`', function () { + describe('day is end date or after start date', function () { + it('calls deleteModifier with `selected-end-in-hovered-span` on end date', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var endDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDate: endDate + })); + var tomorrow = today.clone().add(1, 'days'); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(tomorrow); + var deleteModifierCalls = getCallsByModifier(deleteModifierSpy, 'selected-end-in-hovered-span'); + (0, _chai.expect)(deleteModifierCalls.length).to.equal(1); + (0, _chai.expect)(deleteModifierCalls[0].args[1]).to.equal(endDate); + }); + }); + describe('day is not blocked, and is before the end date', function () { + it('calls addModifier with `selected-end-in-hovered-span`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + + var endDate = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + endDate: endDate + })); + var yesterday = today.clone().subtract(1, 'days'); + addModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(yesterday); + var addModifierCalls = getCallsByModifier(addModifierSpy, 'selected-end-in-hovered-span'); + (0, _chai.expect)(addModifierCalls.length).to.equal(1); + (0, _chai.expect)(addModifierCalls[0].args[1]).to.equal(today); + }); + }); + }); + }); + describe('before-hovered-end modifier', function () { + describe('end date is truthy and focusedInput is truthy', function () { + it('calls deleteModifierFromRange with `before-hovered-end` on minimum nights days before end date', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var endDate = today; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + minimumNights: minimumNights, + endDate: endDate + })); + var minimumNightStartSpan = endDate.clone().subtract(minimumNights, 'days'); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + var deleteModifierFromRangeCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'before-hovered-end'); + (0, _chai.expect)(deleteModifierFromRangeCalls.length).to.equal(1); + (0, _chai.expect)((0, _toISODateString["default"])(deleteModifierFromRangeCalls[0].args[1])).to.equal((0, _toISODateString["default"])(minimumNightStartSpan)); + (0, _chai.expect)(deleteModifierFromRangeCalls[0].args[2]).to.equal(endDate); + }); + }); + describe('day is equal to end date', function () { + it('calls addModifierToRange with `before-hovered-end`', function () { + var addModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifierToRange'); + + var endDate = today; + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + minimumNights: minimumNights, + endDate: endDate + })); + var minimumNightStartSpan = endDate.clone().subtract(minimumNights, 'days'); + addModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + var addModifierFromRangeCalls = getCallsByModifier(addModifierFromRangeSpy, 'before-hovered-end'); + (0, _chai.expect)(addModifierFromRangeCalls.length).to.equal(1); + (0, _chai.expect)((0, _toISODateString["default"])(addModifierFromRangeCalls[0].args[1])).to.equal((0, _toISODateString["default"])(minimumNightStartSpan)); + (0, _chai.expect)(addModifierFromRangeCalls[0].args[2]).to.equal(endDate); + }); + }); + }); + }); + }); + describe('#onDayMouseLeave', function () { + it('sets state.hoverDate to null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseLeave(today); + (0, _chai.expect)(wrapper.state().hoverDate).to.equal(null); + }); + describe('modifiers', function () { + it('calls deleteModifier with hoverDate and `hovered` modifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + describe('startDate and !endDate and hoverDate is after startDate', function () { + it('calls deleteModifierFromRange with startDate, hoverDate and `hovered-span`', function () { + var startDate = today; + var hoverDate = today.clone().add(5, 'days'); + var dayAfterHoverDate = hoverDate.clone().add(1, 'day'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + endDate: null, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + var hoveredSpanCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-span'); + (0, _chai.expect)(hoveredSpanCalls.length).to.equal(1); + (0, _chai.expect)(hoveredSpanCalls[0].args[1]).to.equal(startDate); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredSpanCalls[0].args[2], dayAfterHoverDate)).to.equal(true); + }); + }); + describe('!startDate and endDate and hoverDate is before endDate', function () { + it('calls deleteModifierFromRange with hoverDate, endDate, and `hovered-span`', function () { + var hoverDate = today; + var endDate = today.clone().add(5, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: endDate, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + (0, _chai.expect)(deleteModifierFromRangeSpy.callCount).to.equal(1); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[1]).to.equal(hoverDate); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[2]).to.equal(endDate); + (0, _chai.expect)(deleteModifierFromRangeSpy.getCall(0).args[3]).to.equal('hovered-span'); + }); + }); + describe('after-hovered-start modifier', function () { + describe('startDate exists and is same as arg', function () { + it('clears previous `after-hovered-start` range', function () { + var minimumNights = 5; + var startDate = (0, _moment["default"])().add(13, 'days'); + var dayAfterStartDate = startDate.clone().add(1, 'day'); + var firstAvailableDate = startDate.clone().add(minimumNights + 1, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: startDate, + minimumNights: minimumNights + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(startDate); + var afterHoverStartCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[1], dayAfterStartDate)).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(afterHoverStartCalls[0].args[2], firstAvailableDate)).to.equal(true); + }); + }); + describe('startDate exists and is not the same as arg', function () { + it('does not call deleteModifierFromRange with `after-hovered-start`', function () { + var minimumNights = 5; + var startDate = (0, _moment["default"])().add(13, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: startDate, + minimumNights: minimumNights + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + var afterHoverStartCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + describe('startDate does not exist', function () { + it('does not call deleteModifierFromRange with `after-hovered-start`', function () { + var minimumNights = 5; + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + startDate: null, + minimumNights: minimumNights + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + var afterHoverStartCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'after-hovered-start'); + (0, _chai.expect)(afterHoverStartCalls.length).to.equal(0); + }); + }); + }); + describe('hovered-start-first-possible-end modifier', function () { + describe('focusedInput === START_DATE', function () { + it('calls deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate returns a positive integer', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseLeave(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartFirstPossibleEndCalls[0].args[1], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifier with `hovered-start-first-possible-end` if the hovered date is blocked', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseLeave(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + it('does not call deleteModifier with `hovered-start-first-possible-end` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('does not call deleteModifier with `hovered-start-first-possible-end`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartFirstPossibleEndCalls = getCallsByModifier(deleteModifierSpy, 'hovered-start-first-possible-end'); + (0, _chai.expect)(hoveredStartFirstPossibleEndCalls.length).to.equal(0); + }); + }); + }); + describe('hovered-start-blocked-minimum-nights modifier', function () { + describe('focusedInput === START_DATE', function () { + it('calls deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate returns a positive integer', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(1); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[1], today.clone().add(1, 'days'))).to.equal(true); + (0, _chai.expect)((0, _isSameDay["default"])(hoveredStartBlockedMinNightsCalls[0].args[2], today.clone().add(2, 'days'))).to.equal(true); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if the hovered date is blocked', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub, + isDayBlocked: function isDayBlocked(day) { + return (0, _isSameDay["default"])(day, today); + } + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseLeave(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + it('does not call deleteModifierFromRange with `hovered-start-blocked-minimum-nights` if getMinNightsForHoverDate does not return a positive integer', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(0); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.START_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + describe('focusedInput === END_DATE', function () { + it('does not call deleteModifierFromRangeFromRange with `hovered-start-blocked-minimum-nights`', function () { + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var getMinNightsForHoverDateStub = _sinonSandbox["default"].stub().returns(2); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focusedInput: _constants.END_DATE, + getMinNightsForHoverDate: getMinNightsForHoverDateStub + })); + wrapper.setState({ + hoverDate: today.clone().subtract(1, 'days') + }); + wrapper.instance().onDayMouseEnter(today); + var hoveredStartBlockedMinNightsCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'hovered-start-blocked-minimum-nights'); + (0, _chai.expect)(hoveredStartBlockedMinNightsCalls.length).to.equal(0); + }); + }); + }); + describe('selected-start-in-hovered-span modifier', function () { + describe('start date is truthy, end date is falsey and day is after start date', function () { + it('calls deleteModifier with `selected-start-in-hovered-span` on start date', function () { + var startDate = today; + var dayAfterStartDate = startDate.clone().add(1, 'day'); + var hoverDate = today.clone().add(5, 'days'); + + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: startDate, + endDate: null, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(dayAfterStartDate); + var deleteModifierCalls = getCallsByModifier(deleteModifierSpy, 'selected-start-in-hovered-span'); + (0, _chai.expect)(deleteModifierCalls.length).to.equal(1); + (0, _chai.expect)(deleteModifierCalls[0].args[1]).to.equal(startDate); + }); + }); + }); + describe('selected-end-in-hovered-span modifier', function () { + describe('end date is truthy, start date is falsey and day is before end date', function () { + it('calls deleteModifier with `selected-end-in-hovered-span` on end date', function () { + var endDate = today; + var dayBeforeEndDate = endDate.clone().subtract(1, 'day'); + var hoverDate = today.clone().add(5, 'days'); + + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: endDate, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: hoverDate + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(dayBeforeEndDate); + var deleteModifierCalls = getCallsByModifier(deleteModifierSpy, 'selected-end-in-hovered-span'); + (0, _chai.expect)(deleteModifierCalls.length).to.equal(1); + (0, _chai.expect)(deleteModifierCalls[0].args[1]).to.equal(endDate); + }); + }); + }); + describe('before-hovered-end modifier', function () { + describe('end date is truthy and day is end date', function () { + it('calls deleteModifierFromRange with `before-hovered-end` on span of end date to end date minus minimum nights', function () { + var endDate = today; + var hoverDate = today.clone().subtract(5, 'days'); + + var deleteModifierFromRangeSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifierFromRange'); + + var minimumNights = 5; + var minimumNightStartSpan = endDate.clone().subtract(minimumNights, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + minimumNights: minimumNights, + endDate: endDate, + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + deleteModifierFromRangeSpy.resetHistory(); + wrapper.setState({ + hoverDate: hoverDate + }); + wrapper.instance().onDayMouseLeave(endDate); + var deleteModifierFromRangeCalls = getCallsByModifier(deleteModifierFromRangeSpy, 'before-hovered-end'); + (0, _chai.expect)(deleteModifierFromRangeCalls.length).to.equal(1); + (0, _chai.expect)((0, _toISODateString["default"])(deleteModifierFromRangeCalls[0].args[1])).to.equal((0, _toISODateString["default"])(minimumNightStartSpan)); + (0, _chai.expect)(deleteModifierFromRangeCalls[0].args[2]).to.equal(endDate); + }); + }); + }); + }); + }); + describe('#onPrevMonthClick', function () { + it('updates state.currentMonth to subtract 1 month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state().currentMonth.month()).to.equal(today.clone().subtract(1, 'month').month()); + }); + it('new visibleDays has previous month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().subtract(1, 'month'); + wrapper.instance().onPrevMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.include((0, _toISOMonthString4["default"])(newMonth)); + }); + it('new visibleDays does not have current last month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.not.include((0, _toISOMonthString4["default"])((0, _moment["default"])().add(numberOfMonths, 'months'))); + }); + it('calls this.getModifiers', function () { + var getModifiersSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getModifiers'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersSpy.resetHistory(); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(getModifiersSpy.callCount).to.equal(1); + }); + it('calls props.onPrevMonthClick with new month', function () { + var onPrevMonthClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + onPrevMonthClick: onPrevMonthClickStub + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().subtract(1, 'month'); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(onPrevMonthClickStub.callCount).to.equal(1); + (0, _chai.expect)(onPrevMonthClickStub.firstCall.args[0].year()).to.equal(newMonth.year()); + (0, _chai.expect)(onPrevMonthClickStub.firstCall.args[0].month()).to.equal(newMonth.month()); + }); + it('calls this.shouldDisableMonthNavigation twice', function () { + var shouldDisableMonthNavigationSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'shouldDisableMonthNavigation'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + shouldDisableMonthNavigationSpy.resetHistory(); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(shouldDisableMonthNavigationSpy.callCount).to.equal(2); + }); + it('sets disablePrev and disablePrev as false on onPrevMonthClick call withouth maxDate and minDate set', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state().disablePrev).to.equal(false); + (0, _chai.expect)(wrapper.state().disableNext).to.equal(false); + }); + it('sets disableNext as true when maxDate is in visible month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + maxDate: today + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state().disableNext).to.equal(true); + (0, _chai.expect)(wrapper.state().disablePrev).to.equal(false); + }); + it('sets disablePrev as true when minDate is in visible month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + minDate: today.clone().subtract(1, 'month') + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state().disableNext).to.equal(false); + (0, _chai.expect)(wrapper.state().disablePrev).to.equal(true); + }); + }); + describe('#onNextMonthClick', function () { + it('updates state.currentMonth to add 1 month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(wrapper.state().currentMonth.month()).to.equal(today.clone().add(1, 'month').month()); + }); + it('new visibleDays has next month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().add(numberOfMonths + 1, 'months'); + wrapper.instance().onNextMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.include((0, _toISOMonthString4["default"])(newMonth)); + }); + it('new visibleDays does not have current month - 1', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: 2 + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onNextMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.not.include((0, _toISOMonthString4["default"])(today.clone().subtract(1, 'month'))); + }); + it('calls this.getModifiers', function () { + var getModifiersSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getModifiers'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersSpy.resetHistory(); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(getModifiersSpy.callCount).to.equal(1); + }); + it('calls props.onNextMonthClick with new month', function () { + var onNextMonthClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + onNextMonthClick: onNextMonthClickStub + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().add(1, 'month'); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(onNextMonthClickStub.callCount).to.equal(1); + (0, _chai.expect)(onNextMonthClickStub.firstCall.args[0].year()).to.equal(newMonth.year()); + (0, _chai.expect)(onNextMonthClickStub.firstCall.args[0].month()).to.equal(newMonth.month()); + }); + }); + describe('#getFirstFocusableDay', function () { + describe('focusedInput === START_DATE', function () { + it('returns startDate if exists and is not blocked', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + startDate: today, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay((0, _moment["default"])().subtract(10, 'days')); + (0, _chai.expect)(firstFocusableDay.isSame(today, 'day')).to.equal(true); + }); + it('returns first day of arg month if startDate is falsy', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + startDate: null, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var startOfMonth = today.clone().startOf('month'); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(startOfMonth, 'day')).to.equal(true); + }); + }); + describe('focusedInput === END_DATE', function () { + it('returns endDate if exists and is not blocked and startDate is falsy', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var endDate = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: null, + endDate: endDate, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(endDate, 'day')).to.equal(true); + }); + it('returns startDate + minimumNights if startDate is truthy and endDate is not', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var startDate = (0, _moment["default"])().add(10, 'days'); + var minimumNights = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate, + minimumNights: minimumNights, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(startDate.clone().add(minimumNights, 'days'), 'day')).to.equal(true); + }); + it('returns first day of arg month if startDate and endDate are falsy', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: null, + minimumNights: null, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(today.clone().startOf('month'), 'day')).to.equal(true); + }); + }); + it('time is a noon', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: null, + startDate: null, + endDate: null, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.hours()).to.equal(12); + }); + describe('desired day is blocked', function () { + it('returns next unblocked visible day after desired day if exists', function () { + var isBlockedStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked'); + + var startDate = (0, _moment["default"])().endOf('month').subtract(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate, + numberOfMonths: 1, + onFocusChange: _sinonSandbox["default"].stub(), + onDatesChange: _sinonSandbox["default"].stub() + })); + isBlockedStub.resetHistory(); + isBlockedStub.returns(true).onCall(8).returns(false); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(startDate.clone().add(9, 'days'), 'day')).to.equal(true); + }); + }); + }); + describe('#getModifiers', function () { + it('return object has the same number of days as input', function () { + var monthISO = (0, _toISOMonthString4["default"])(today); + var visibleDays = (0, _defineProperty2["default"])({}, monthISO, [today, (0, _moment["default"])().add(1, 'day'), (0, _moment["default"])().add(2, 'days')]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiers(visibleDays); + (0, _chai.expect)(Object.keys(modifiers[monthISO]).length).to.equal(visibleDays[monthISO].length); + }); + it('calls this.getModifiersForDay for each day in input', function () { + var getModifiersForDaySpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'getModifiersForDay'); + + var monthISO = (0, _toISOMonthString4["default"])(today); + var visibleDays = (0, _defineProperty2["default"])({}, monthISO, [today, (0, _moment["default"])().add(1, 'day'), (0, _moment["default"])().add(2, 'days')]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersForDaySpy.resetHistory(); + wrapper.instance().getModifiers(visibleDays); + (0, _chai.expect)(getModifiersForDaySpy.callCount).to.equal(visibleDays[monthISO].length); + }); + }); + describe('#getModifiersForDay', function () { + it('only contains `valid` if all modifier methods return false', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isToday').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(false); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isStartDate').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isEndDate').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'doesNotMeetMinimumNights').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isInSelectedSpan').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isLastInRange').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isHovered').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isInHoveredSpan').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isDayAfterHoveredStartDate').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isFirstDayOfWeek').returns(false); + + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isLastDayOfWeek').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub, + isDayHighlighted: isDayHighlightedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.size).to.equal(1); + (0, _chai.expect)(modifiers.has('valid')).to.equal(true); + }); + it('contains `today` if this.isToday returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isToday').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('today')).to.equal(true); + }); + it('contains `blocked` if this.isBlocked returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked')).to.equal(true); + }); + it('contains `blocked-calendar` if props.isDayBlocked returns true', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayBlocked: isDayBlockedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked-calendar')).to.equal(true); + }); + it('contains `blocked-out-of-range` if props.isOutsideRange returns true', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isOutsideRange: isOutsideRangeStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked-out-of-range')).to.equal(true); + }); + it('contains `highlighted-calendar` if props.isDayHighlighted returns true', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayHighlighted: isDayHighlightedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('highlighted-calendar')).to.equal(true); + }); + it('contains `valid` if this.isBlocked returns false', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('valid')).to.equal(true); + }); + it('contains `selected-start` if this.isStartDate returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isStartDate').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('selected-start')).to.equal(true); + }); + it('contains `selected-end` if this.isEndDate returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isEndDate').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('selected-end')).to.equal(true); + }); + it('contains `blocked-minimum-nights` if this.doesNotMeetMinimumNights returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'doesNotMeetMinimumNights').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked-minimum-nights')).to.equal(true); + }); + it('contains `selected-span` if this.isInSelectedSpan returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isInSelectedSpan').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('selected-span')).to.equal(true); + }); + it('contains `last-in-range` if this.isLastInRange returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isLastInRange').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('last-in-range')).to.equal(true); + }); + it('contains `hovered` if this.isHovered returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isHovered').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('hovered')).to.equal(true); + }); + it('contains `hovered-span` if this.isInHoveredSpan returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isInHoveredSpan').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('hovered-span')).to.equal(true); + }); + it('contains `after-hovered-start` if this.isDayAfterHoveredStartDate returns true', function () { + _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isDayAfterHoveredStartDate').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('after-hovered-start')).to.equal(true); + }); + }); + describe('#addModifier', function () { + it('returns first arg if no day given', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier(updatedDays); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('returns first arg if day is not visible', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var modifiers = wrapper.instance().addModifier(updatedDays, (0, _moment["default"])()); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('has day args month ISO as key', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers)).to.contain((0, _toISOMonthString4["default"])(today)); + }); + it('is resilient when visibleDays is an empty object', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().setState({ + visibleDays: {} + }); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString4["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('has day ISO as key one layer down', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString4["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('return value now has modifier arg for day if was in first arg', function () { + var modifierToAdd = 'foo'; + var monthISO = (0, _toISOMonthString4["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier(updatedDays, today, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.contain(modifierToAdd); + }); + it('return value now has modifier arg for day if was in state', function () { + var modifierToAdd = 'foo'; + var monthISO = (0, _toISOMonthString4["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + visibleDays: (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set(['bar', 'baz']))) + }); + var modifiers = wrapper.instance().addModifier({}, today, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.contain(modifierToAdd); + }); + it('return new modifier if vertically scrollable load more months', function () { + var modifierToAdd = 'foo'; + var numberOfMonths = 2; + var nextMonth = today.clone().add(numberOfMonths, 'month'); + var nextMonthISO = (0, _toISOMonthString4["default"])(nextMonth); + var nextMonthDayISO = (0, _toISODateString["default"])(nextMonth); + var updatedDays = (0, _defineProperty2["default"])({}, nextMonthISO, (0, _defineProperty2["default"])({}, nextMonthDayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })); + wrapper.setState({ + currentMonth: today, + visibleDays: _objectSpread(_objectSpread({}, (0, _getVisibleDays["default"])(today, numberOfMonths)), (0, _getVisibleDays["default"])(nextMonth, numberOfMonths)) + }); + var modifiers = wrapper.instance().addModifier(updatedDays, nextMonth, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.contain(modifierToAdd); + }); + }); + it('return value now has modifier arg for day after getting next scrollable months', function () { + var modifierToAdd = 'foo'; + var futureDateAfterMultiply = today.clone().add(4, 'months'); + var monthISO = (0, _toISOMonthString4["default"])(futureDateAfterMultiply); + var todayISO = (0, _toISODateString["default"])(futureDateAfterMultiply); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + orientation: _constants.VERTICAL_SCROLLABLE, + numberOfMonths: 3 + })).instance(); + var modifiers = wrapper.addModifier(updatedDays, futureDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.not.contain(modifierToAdd); + wrapper.onGetNextScrollableMonths(); + modifiers = wrapper.addModifier(updatedDays, futureDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.contain(modifierToAdd); + }); + it('return value now has modifier arg for day after getting previous scrollable months', function () { + var modifierToAdd = 'foo'; + var pastDateAfterMultiply = today.clone().subtract(3, 'months'); + var monthISO = (0, _toISOMonthString4["default"])(pastDateAfterMultiply); + var dayISO = (0, _toISODateString["default"])(pastDateAfterMultiply); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, dayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + orientation: _constants.VERTICAL_SCROLLABLE, + numberOfMonths: 3 + })).instance(); + var modifiers = wrapper.addModifier(updatedDays, pastDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][dayISO])).to.not.contain(modifierToAdd); + wrapper.onGetPrevScrollableMonths(); + modifiers = wrapper.addModifier(updatedDays, pastDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][dayISO])).to.contain(modifierToAdd); + }); + describe('#addModifierToRange', function () { + var addModifierSpy; + beforeEach(function () { + addModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'addModifier'); + }); + it('calls addModifier for each day between the span start and the span end', function () { + var numOfDays = 10; + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().add(numOfDays, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().addModifierToRange({}, spanStart, spanEnd); + (0, _chai.expect)(addModifierSpy.callCount).to.equal(numOfDays); + }); + it('calls addModifier with modifier arg as modifier', function () { + var modifier = 'foo-bar-baz'; + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().addModifierToRange({}, spanStart, spanEnd, modifier); + (0, _chai.expect)(addModifierSpy.callCount).to.not.equal(0); + + for (var i = 0; i < addModifierSpy.callCount; i += 1) { + (0, _chai.expect)(addModifierSpy.getCall(i).args[2]).to.equal(modifier); + } + }); + it('does not call addModifier if span end is after span start', function () { + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().subtract(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().addModifierToRange({}, spanStart, spanEnd); + (0, _chai.expect)(addModifierSpy.callCount).to.equal(0); + }); + }); + describe('#deleteModifier', function () { + it('returns first arg if no day given', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().deleteModifier(updatedDays); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('returns first arg if day is not visible', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var modifiers = wrapper.instance().deleteModifier(updatedDays, (0, _moment["default"])()); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('has day args month ISO as key', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var isoMonth = (0, _toISOMonthString4["default"])(today); + var isoDate = (0, _toISODateString["default"])(today); + var modifiers = wrapper.instance().deleteModifier((0, _defineProperty2["default"])({}, isoMonth, (0, _defineProperty2["default"])({}, isoDate, new Set(['foo']))), today, 'foo'); + (0, _chai.expect)(Object.keys(modifiers)).to.contain(isoMonth); + (0, _chai.expect)(modifiers[isoMonth][isoDate].size).to.equal(0); + }); + it('has day ISO as key one layer down', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString4["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('is resilient when visibleDays is an empty object', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().setState({ + visibleDays: {} + }); + (0, _chai.expect)(function () { + wrapper.instance().deleteModifier({}, today); + }).to.not["throw"](); + }); + it('return value no longer has modifier arg for day if was in first arg', function () { + var modifierToDelete = 'foo'; + var monthISO = (0, _toISOMonthString4["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set([modifierToDelete, 'bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().deleteModifier(updatedDays, today, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.not.contain(modifierToDelete); + }); + it('return value no longer has modifier arg for day if was in state', function () { + var modifierToDelete = 'foo'; + var monthISO = (0, _toISOMonthString4["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + visibleDays: (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set([modifierToDelete, 'bar', 'baz']))) + }); + var modifiers = wrapper.instance().deleteModifier({}, today, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.not.contain(modifierToDelete); + }); + it('return new modifier if vertically scrollable load more months', function () { + var modifierToDelete = 'foo'; + var numberOfMonths = 2; + var nextMonth = today.clone().add(numberOfMonths, 'month'); + var nextMonthISO = (0, _toISOMonthString4["default"])(nextMonth); + var nextMonthDayISO = (0, _toISODateString["default"])(nextMonth); + var updatedDays = (0, _defineProperty2["default"])({}, nextMonthISO, (0, _defineProperty2["default"])({}, nextMonthDayISO, new Set(['foo', 'bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })); + wrapper.setState({ + currentMonth: today, + visibleDays: _objectSpread(_objectSpread({}, (0, _getVisibleDays["default"])(today, numberOfMonths)), (0, _getVisibleDays["default"])(nextMonth, numberOfMonths)) + }); + var modifiers = wrapper.instance().deleteModifier(updatedDays, nextMonth, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.not.contain(modifierToDelete); + }); + }); + describe('#deleteModifierFromRange', function () { + var deleteModifierSpy; + beforeEach(function () { + deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerRangeController["default"].prototype, 'deleteModifier'); + }); + it('calls deleteModifier for each day between the span start and the span end', function () { + var numOfDays = 10; + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().add(numOfDays, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().deleteModifierFromRange({}, spanStart, spanEnd); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(numOfDays); + }); + it('calls deleteModifier with modifier arg as modifier', function () { + var modifier = 'foo-bar-baz'; + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().deleteModifierFromRange({}, spanStart, spanEnd, modifier); + (0, _chai.expect)(deleteModifierSpy.callCount).to.not.equal(0); + + for (var i = 0; i < deleteModifierSpy.callCount; i += 1) { + (0, _chai.expect)(deleteModifierSpy.getCall(i).args[2]).to.equal(modifier); + } + }); + it('does not call deleteModifier if span end is after span start', function () { + var spanStart = (0, _moment["default"])(); + var spanEnd = (0, _moment["default"])().subtract(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().deleteModifierFromRange({}, spanStart, spanEnd); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(0); + }); + }); + describe('day modifier methods', function () { + describe('#doesNotMeetMinimumNights', function () { + var MIN_NIGHTS = 3; + describe('state.startDate !== null', function () { + var startDate = (0, _moment["default"])(today).add(3, 'days'); // rand day not equal to today + + describe('props.focusedInput === END_DATE', function () { + it('returns true if arg is < props.minimumNights after props.startDate', function () { + var testDate = (0, _moment["default"])(startDate).add(MIN_NIGHTS - 1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate, + minimumNights: MIN_NIGHTS + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(true); + }); + it('returns false if arg is > props.minimumNights after props.startDate', function () { + var testDate = (0, _moment["default"])(startDate).add(MIN_NIGHTS + 1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: startDate, + minimumNights: MIN_NIGHTS + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(false); + }); + it('handles time differences of less than 1 full day properly', function () { + var partialDate = (0, _moment["default"])(startDate).add(5, 'minutes'); + var testDate = (0, _moment["default"])(startDate).add(MIN_NIGHTS, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: partialDate, + minimumNights: MIN_NIGHTS + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(false); + }); + }); + describe('props.focusedInput !== END_DATE', function () { + it('returns false', function () { + var testDate = (0, _moment["default"])(startDate).add(MIN_NIGHTS - 1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + startDate: startDate, + minimumNights: MIN_NIGHTS + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(false); + }); + }); + }); + describe('props.startDate === null', function () { + describe('props.focusedInput === END_DATE', function () { + it('returns true if arg - props.minimumNights is outside allowed range', function () { + var isOutsideRange = function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, today); + }; + + var testDate = (0, _moment["default"])(today).add(MIN_NIGHTS - 1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: null, + minimumNights: MIN_NIGHTS, + isOutsideRange: isOutsideRange + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(true); + }); + it('returns false if arg - props.minimumNights is inside allowed range', function () { + var isOutsideRange = function isOutsideRange(day) { + return !(0, _isInclusivelyAfterDay["default"])(day, today); + }; + + var testDate = (0, _moment["default"])(today).add(MIN_NIGHTS, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.END_DATE, + startDate: null, + minimumNights: MIN_NIGHTS, + isOutsideRange: isOutsideRange + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(false); + }); + }); + describe('state.focusedInput !== END_DATE', function () { + it('returns false', function () { + var testDate = (0, _moment["default"])(today).add(MIN_NIGHTS - 1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE, + startDate: null, + minimumNights: MIN_NIGHTS + })); + (0, _chai.expect)(wrapper.instance().doesNotMeetMinimumNights(testDate)).to.equal(false); + }); + }); + }); + }); + describe('#isDayAfterHoveredStartDate', function () { + it('returns true if arg startDate is hovered and arg is the day after the startDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today + })); + wrapper.setState({ + hoverDate: today + }); + var testDate = (0, _moment["default"])(today).add(1, 'days'); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(true); + }); + it('returns false if props.startDate is falsy', function () { + var testDate = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(false); + }); + it('returns false if props.endDate is truthy', function () { + var testDate = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: (0, _moment["default"])(today).add(3, 'days') + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(false); + }); + it('returns false if arg is not day after state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today + })); + wrapper.setState({ + hoverDate: today + }); + var testDate = (0, _moment["default"])(today).add(2, 'days'); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(false); + }); + it('returns false if state.hoverDate is not the same as props.startDate', function () { + var testDate = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today + })); + wrapper.setState({ + hoverDate: testDate + }); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(false); + }); + it('returns false if arg is day after state.hoverDate and props.minimumNights is 0', function () { + var testDate = (0, _moment["default"])(today).add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + minimumNights: 0 + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isDayAfterHoveredStartDate(testDate)).to.equal(false); + }); + }); + describe('#isEndDate', function () { + it('returns true if arg === props.endDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: today + })); + (0, _chai.expect)(wrapper.instance().isEndDate(today)).to.equal(true); + }); + it('returns false if arg !== props.endDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: (0, _moment["default"])(today).add(1, 'days') + })); + (0, _chai.expect)(wrapper.instance().isEndDate(today)).to.equal(false); + }); + }); + describe('#isHovered', function () { + it('returns false if focusedInput is falsy', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: null + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isHovered(today)).to.equal(false); + }); + it('returns true if arg === state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isHovered(today)).to.equal(true); + }); + it('returns false if arg !== state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + focusedInput: _constants.START_DATE + })); + wrapper.setState({ + hoverDate: (0, _moment["default"])(today).add(1, 'days') + }); + (0, _chai.expect)(wrapper.instance().isHovered(today)).to.equal(false); + }); + }); + describe('#isInHoveredSpan', function () { + describe('props.endDate === null', function () { + it('returns true if arg is in between props.startDate and state.hoverDate', function () { + var HOVER_DATE_DIFF = 5; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: null + })); + wrapper.setState({ + hoverDate: (0, _moment["default"])(today).add(HOVER_DATE_DIFF, 'days') + }); + var testDate = (0, _moment["default"])(today).add(HOVER_DATE_DIFF - 1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(true); + }); + it('returns true if arg is equal to state.hoverDate', function () { + var testDate = (0, _moment["default"])(today).add(3, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: null + })); + wrapper.setState({ + hoverDate: testDate + }); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(true); + }); + it('returns false if arg is < props.startDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: null + })); + wrapper.setState({ + hoverDate: (0, _moment["default"])(today).add(3, 'days') + }); + var testDate = (0, _moment["default"])(today).subtract(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(false); + }); + it('returns false if arg is > state.hoverDate', function () { + var hoverDate = (0, _moment["default"])(today).add(3, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: null + })); + wrapper.setState({ + hoverDate: hoverDate + }); + var testDate = (0, _moment["default"])(hoverDate).add(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(false); + }); + }); + describe('props.startDate === null', function () { + it('returns true if arg is in between state.hoverDate and props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: (0, _moment["default"])(today).add(5, 'days') + })); + wrapper.setState({ + hoverDate: today + }); + var testDate = (0, _moment["default"])(endDate).subtract(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(true); + }); + it('returns true if arg is equal to state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: (0, _moment["default"])(today).add(5, 'days') + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(today)).to.equal(true); + }); + it('returns false if arg is < state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: (0, _moment["default"])(today).add(5, 'days') + })); + wrapper.setState({ + hoverDate: today + }); + var testDate = (0, _moment["default"])(today).subtract(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(false); + }); + it('returns false if arg is > props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: endDate + })); + wrapper.setState({ + hoverDate: today + }); + var testDate = (0, _moment["default"])(endDate).add(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInHoveredSpan(testDate)).to.equal(false); + }); + }); + }); + describe('#isInSelectedSpan', function () { + it('returns true if props.startDate < arg < props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: endDate + })); + var testDate = (0, _moment["default"])(endDate).subtract(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(true); + }); + it('returns false if arg = props.startDate && arg < 12', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: endDate + })); + var testDate = (0, _moment["default"])(today.hours(10)); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(false); + }); + it('returns false if arg = props.startDate && arg > 12', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: endDate + })); + var testDate = (0, _moment["default"])(today.hours(16)); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(false); + }); + it('returns false if arg < props.startDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: endDate + })); + var testDate = (0, _moment["default"])(today).subtract(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(false); + }); + it('returns false if arg > props.endDate', function () { + var endDate = (0, _moment["default"])(today).add(5, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: endDate + })); + var testDate = (0, _moment["default"])(endDate).add(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(false); + }); + it('returns false if props.startDate === null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: null, + endDate: (0, _moment["default"])(today).add(5, 'days') + })); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(today)).to.equal(false); + }); + it('returns false if props.endDate === null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today, + endDate: null + })); + var testDate = (0, _moment["default"])(today).add(1, 'days'); + (0, _chai.expect)(wrapper.instance().isInSelectedSpan(testDate)).to.equal(false); + }); + }); + describe('#isLastInRange', function () { + var isInSelectedSpanStub; + beforeEach(function () { + isInSelectedSpanStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'isInSelectedSpan'); + }); + it('returns true if arg is day before props.endDate and is in the selected span', function () { + isInSelectedSpanStub.returns(true); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: (0, _moment["default"])(today).add(1, 'days') + })); + (0, _chai.expect)(wrapper.instance().isLastInRange(today)).to.equal(true); + }); + it('returns false if arg is not in the selected span', function () { + isInSelectedSpanStub.returns(false); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: (0, _moment["default"])(today).add(1, 'days') + })); + (0, _chai.expect)(wrapper.instance().isLastInRange(today)).to.equal(false); + }); + it('returns false if arg is not the day before props.endDate', function () { + isInSelectedSpanStub.returns(true); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: (0, _moment["default"])(today).add(2, 'days') + })); + (0, _chai.expect)(wrapper.instance().isLastInRange(today)).to.equal(false); + }); + }); + describe('#isStartDate', function () { + it('returns true if arg === props.startDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: today + })); + (0, _chai.expect)(wrapper.instance().isStartDate(today)).to.equal(true); + }); + it('returns false if arg !== props.startDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + startDate: (0, _moment["default"])(today).add(1, 'days') + })); + (0, _chai.expect)(wrapper.instance().isStartDate(today)).to.equal(false); + }); + }); + describe('#isBlocked', function () { + var isDayBlockedStub; + var isOutsideRangeStub; + var doesNotMeetMinimumNightsStub; + beforeEach(function () { + isDayBlockedStub = _sinonSandbox["default"].stub(); + isOutsideRangeStub = _sinonSandbox["default"].stub(); + doesNotMeetMinimumNightsStub = _sinonSandbox["default"].stub(_DayPickerRangeController["default"].prototype, 'doesNotMeetMinimumNights'); + }); + it('returns true if arg is calendar blocked', function () { + isDayBlockedStub.returns(true); + isOutsideRangeStub.returns(false); + doesNotMeetMinimumNightsStub.returns(false); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked(today)).to.equal(true); + }); + it('returns true if arg is out of range', function () { + isDayBlockedStub.returns(false); + isOutsideRangeStub.returns(true); + doesNotMeetMinimumNightsStub.returns(false); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked(today)).to.equal(true); + }); + it('returns true if arg does not meet minimum nights', function () { + isDayBlockedStub.returns(false); + isOutsideRangeStub.returns(false); + doesNotMeetMinimumNightsStub.returns(true); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked(today)).to.equal(true); + }); + it('returns false if arg is not blocked, not out of range, and meets minimum nights', function () { + isDayBlockedStub.returns(false); + isOutsideRangeStub.returns(false); + doesNotMeetMinimumNightsStub.returns(false); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked(today)).to.equal(false); + }); + it('returns false if arg does not meet minimum nights but blockDaysViolatingMinNights is false', function () { + isDayBlockedStub.returns(false); + isOutsideRangeStub.returns(false); + doesNotMeetMinimumNightsStub.returns(true); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked(today, false)).to.equal(false); + }); + }); + describe('#isToday', function () { + it('returns true if today', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isToday(today)).to.equal(true); + }); + it('returns false if tomorrow', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isToday((0, _moment["default"])(today).add(1, 'days'))).to.equal(false); + }); + it('returns false if last month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isToday((0, _moment["default"])(today).subtract(1, 'months'))).to.equal(false); + }); + }); + describe('#isFirstDayOfWeek', function () { + it('returns true if first day of this week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week'))).to.equal(true); + }); + it('returns true if same day as firstDayOfWeek prop', function () { + var firstDayOfWeek = 3; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns true if first day of week and prop are both zero', function () { + var firstDayOfWeek = 0; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns true if first day of week is not zero, and prop is zero', function () { + _sinonSandbox["default"].stub(_moment["default"].localeData(), 'firstDayOfWeek').returns(1); + + var firstDayOfWeek = 0; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns false if not the first day of the week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().endOf('week'))).to.equal(false); + }); + }); + describe('#isLastDayOfWeek', function () { + it('returns true if last day of week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().endOf('week'))).to.equal(true); + }); + it('returns true if 6 days after firstDayOfWeek prop', function () { + var firstDayOfWeek = 3; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().day(firstDayOfWeek).add(6, 'days'))).to.equal(true); + }); + it('returns false if not last of week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().startOf('week').add(1, 'day'))).to.equal(false); + }); + }); + describe('#beforeSelectedEnd', function () { + it('returns true if day is before end date', function () { + var endDate = today; + var dayBeforeEndDate = endDate.clone().subtract(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: endDate + })); + (0, _chai.expect)(wrapper.instance().beforeSelectedEnd(dayBeforeEndDate)).to.equal(true); + }); + it('returns false if day is after or equal to end date', function () { + var endDate = today; + var dayAfterEndDate = endDate.clone().add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: endDate + })); + (0, _chai.expect)(wrapper.instance().beforeSelectedEnd(dayAfterEndDate)).to.equal(false); + }); + }); + describe('#isDayBeforeHoveredEndDate', function () { + it('returns false if day is after hovered end date', function () { + var endDate = today; + var dayAfterEndDate = endDate.clone().add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: endDate + })); + wrapper.setState({ + hoverDate: endDate + }); + (0, _chai.expect)(wrapper.instance().isDayBeforeHoveredEndDate(dayAfterEndDate)).to.equal(false); + }); + it('returns true if day is before hovered end date', function () { + var endDate = today; + var dayBeforeEndDate = endDate.clone().subtract(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + endDate: endDate + })); + wrapper.setState({ + hoverDate: endDate + }); + (0, _chai.expect)(wrapper.instance().isDayBeforeHoveredEndDate(dayBeforeEndDate)).to.equal(true); + }); + }); + describe('noNavButtons prop', function () { + it('renders navigation button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], null)).dive().dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(1); + }); + it('does not render navigation button when noNavButtons prop applied', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + noNavButtons: true + })).dive().dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(0); + }); + }); + describe('renderKeyboardShortcutsButton prop', function () { + it('pass down custom button render function', function () { + var testRenderKeyboardShortcutsButton = function testRenderKeyboardShortcutsButton() {}; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + renderKeyboardShortcutsButton: testRenderKeyboardShortcutsButton + })); + var dayPicker = wrapper.find(_DayPicker["default"]); + (0, _chai.expect)(dayPicker).to.have.lengthOf(1); + (0, _chai.expect)(dayPicker.prop('renderKeyboardShortcutsButton')).to.eql(testRenderKeyboardShortcutsButton); + }); + }); + describe('renderKeyboardShortcutsPanel prop', function () { + it('passes down custom panel render function', function () { + var testRenderKeyboardShortcutsPanel = function testRenderKeyboardShortcutsPanel() {}; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerRangeController["default"], { + renderKeyboardShortcutsPanel: testRenderKeyboardShortcutsPanel + })); + var dayPicker = wrapper.find(_DayPicker["default"]); + (0, _chai.expect)(dayPicker).to.have.lengthOf(1); + (0, _chai.expect)(dayPicker.prop('renderKeyboardShortcutsPanel')).to.eql(testRenderKeyboardShortcutsPanel); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DayPickerSingleDateController_spec.js b/test-build/components/DayPickerSingleDateController_spec.js new file mode 100644 index 000000000..029120260 --- /dev/null +++ b/test-build/components/DayPickerSingleDateController_spec.js @@ -0,0 +1,1578 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _moment = _interopRequireDefault(require("moment")); + +var _DayPicker = _interopRequireDefault(require("../../lib/components/DayPicker")); + +var _DayPickerSingleDateController = _interopRequireDefault(require("../../lib/components/DayPickerSingleDateController")); + +var _DayPickerNavigation = _interopRequireDefault(require("../../lib/components/DayPickerNavigation")); + +var _toISODateString = _interopRequireDefault(require("../../lib/utils/toISODateString")); + +var _toISOMonthString5 = _interopRequireDefault(require("../../lib/utils/toISOMonthString")); + +var isDayVisible = _interopRequireWildcard(require("../../lib/utils/isDayVisible")); + +var _getVisibleDays = _interopRequireDefault(require("../../lib/utils/getVisibleDays")); + +var _constants = require("../../lib/constants"); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +// Set to noon to mimic how days in the picker are configured internally +var today = (0, _moment["default"])().startOf('day').hours(12); + +function getCallsByModifier(stub, modifier) { + return stub.getCalls().filter(function (call) { + return call.args[call.args.length - 1] === modifier; + }); +} + +describe('DayPickerSingleDateController', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render', function () { + it('renders a DayPicker', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: true + })); + (0, _chai.expect)(wrapper.find(_DayPicker["default"])).to.have.lengthOf(1); + }); + }); + describe('#componentWillReceiveProps', function () { + var props = _objectSpread(_objectSpread({}, _DayPickerSingleDateController["default"].defaultProps), {}, { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + }); + + describe('props.date changed', function () { + describe('date is not visible', function () { + it('setState gets called with new month', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var date = today; + var newDate = (0, _moment["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + (0, _chai.expect)(wrapper.state()).to.have.property('currentMonth', date); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate + })); + (0, _chai.expect)(wrapper.state()).to.have.property('currentMonth', newDate); + }); + }); + describe('date is visible', function () { + it('setState gets called with existing month', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var date = today; + var newDate = (0, _moment["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + (0, _chai.expect)(wrapper.state()).to.have.property('currentMonth', date); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate + })); + (0, _chai.expect)(wrapper.state()).to.have.property('currentMonth', date); + }); + }); + }); + describe('modifiers', function () { + describe('selected modifier', function () { + describe('props.date did not change', function () { + it('does not call this.addModifier with `selected', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var date = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: date + })); + (0, _chai.expect)(getCallsByModifier(addModifierSpy, 'selected').length).to.equal(0); + }); + it('does not call this.deleteModifier with `selected', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var date = today; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: date + })); + (0, _chai.expect)(getCallsByModifier(deleteModifierSpy, 'selected').length).to.equal(0); + }); + }); + describe('props.date changed', function () { + it('deleteModifier gets called with old date and `selected`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var date = today; + var newDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate + })); + var selectedCalls = getCallsByModifier(deleteModifierSpy, 'selected'); + (0, _chai.expect)(selectedCalls.length).to.equal(1); + (0, _chai.expect)(selectedCalls[0].args[1]).to.equal(date); + }); + it('addModifier gets called with new date and `selected-start`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var date = today; + var newDate = (0, _moment["default"])().add(1, 'day'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + date: date + }))); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate + })); + var selectedStartCalls = getCallsByModifier(addModifierSpy, 'selected'); + (0, _chai.expect)(selectedStartCalls.length).to.equal(1); + (0, _chai.expect)(selectedStartCalls[0].args[1]).to.equal(newDate); + }); + }); + }); + describe('blocked', function () { + describe('props.focused did not change', function () { + it('does not call isBlocked', function () { + var isBlockedStub = _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + isBlockedStub.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread({}, props)); + (0, _chai.expect)(isBlockedStub.callCount).to.equal(0); + }); + }); + describe('props.focused changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString5["default"])(startOfMonth), (_toISOMonthString = {}, (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString)); + }); + it('calls isBlocked for every visible day', function () { + var isBlockedStub = _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + isBlockedStub.resetHistory(); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true + })); + (0, _chai.expect)(isBlockedStub.callCount).to.equal(numVisibleDays); + }); + it('if isBlocked(day) is true calls addModifier with `blocked` for each day', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true + })); + var blockedOutOfRangeCalls = getCallsByModifier(addModifierSpy, 'blocked'); + (0, _chai.expect)(blockedOutOfRangeCalls.length).to.equal(numVisibleDays); + }); + it('if isBlocked(day) is false calls deleteModifier with day and `blocked`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true + })); + var blockedOutOfRangeCalls = getCallsByModifier(deleteModifierSpy, 'blocked'); + (0, _chai.expect)(blockedOutOfRangeCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('blocked-out-of-range', function () { + describe('props.focused did not change', function () { + it('does not call isOutsideRange if unchanged', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + isOutsideRange: isOutsideRangeStub + }))); + var prevCallCount = isOutsideRangeStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.equal(prevCallCount); + }); + it('calls isOutsideRange if changed', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.not.equal(0); + }); + }); + describe('props.focused changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString2; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString5["default"])(startOfMonth), (_toISOMonthString2 = {}, (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString2, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString2)); + }); + it('calls isOutsideRange for every visible day', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(isOutsideRangeStub.callCount).to.equal(numVisibleDays); + }); + it('if isOutsideRange(day) is true calls addModifier with `blocked-out-of-range` for each day', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isOutsideRange: isOutsideRangeStub + })); + var blockedOutOfRangeCalls = getCallsByModifier(addModifierSpy, 'blocked-out-of-range'); + (0, _chai.expect)(blockedOutOfRangeCalls.length).to.equal(numVisibleDays); + }); + it('if isOutsideRange(day) is false calls deleteModifier with day and `blocked-out-of-range`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isOutsideRange: isOutsideRangeStub + })); + var blockedOutOfRangeCalls = getCallsByModifier(deleteModifierSpy, 'blocked-out-of-range'); + (0, _chai.expect)(blockedOutOfRangeCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('blocked-calendar', function () { + describe('props.focused did not change', function () { + it('does not call isDayBlocked if unchanged', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + isDayBlocked: isDayBlockedStub + }))); + var prevCallCount = isDayBlockedStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.equal(prevCallCount); + }); + it('calls isDayBlocked if changed', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.not.equal(0); + }); + }); + describe('props.focused changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString3; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString5["default"])(startOfMonth), (_toISOMonthString3 = {}, (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString3, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString3)); + }); + it('calls isDayBlocked for every visible day', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayBlocked: isDayBlockedStub + })); + (0, _chai.expect)(isDayBlockedStub.callCount).to.equal(numVisibleDays); + }); + it('if isDayBlocked(day) is true calls addModifier with `blocked-calendar` for each day', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayBlocked: isDayBlockedStub + })); + var blockedCalendarCalls = getCallsByModifier(addModifierSpy, 'blocked-calendar'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + it('if isDayBlocked(day) is false calls deleteModifier with day and `blocked-calendar`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayBlocked: isDayBlockedStub + })); + var blockedCalendarCalls = getCallsByModifier(deleteModifierSpy, 'blocked-calendar'); + (0, _chai.expect)(blockedCalendarCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('highlighted-calendar', function () { + describe('focusedInput did not change', function () { + it('does not call isDayHighlighted if unchanged', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], (0, _extends2["default"])({}, props, { + isDayHighlighted: isDayHighlightedStub + }))); + var prevCallCount = isDayHighlightedStub.callCount; + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.equal(prevCallCount); + }); + it('calls isDayHighlighted if changed', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.not.equal(0); + }); + }); + describe('focusedInput changed', function () { + var numVisibleDays = 3; + var visibleDays; + beforeEach(function () { + var _toISOMonthString4; + + var startOfMonth = today.clone().startOf('month'); + visibleDays = (0, _defineProperty2["default"])({}, (0, _toISOMonthString5["default"])(startOfMonth), (_toISOMonthString4 = {}, (0, _defineProperty2["default"])(_toISOMonthString4, (0, _toISODateString["default"])(startOfMonth), new Set()), (0, _defineProperty2["default"])(_toISOMonthString4, (0, _toISODateString["default"])(startOfMonth.clone().add(1, 'day')), new Set()), (0, _defineProperty2["default"])(_toISOMonthString4, (0, _toISODateString["default"])(startOfMonth.clone().add(2, 'days')), new Set()), _toISOMonthString4)); + }); + it('calls isDayHighlighted for every visible day', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayHighlighted: isDayHighlightedStub + })); + (0, _chai.expect)(isDayHighlightedStub.callCount).to.equal(numVisibleDays); + }); + it('if isDayHighlighted(day) is true calls addModifier with day and `highlighted-calendar`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayHighlighted: isDayHighlightedStub + })); + var highlightedCalendarCalls = getCallsByModifier(addModifierSpy, 'highlighted-calendar'); + (0, _chai.expect)(highlightedCalendarCalls.length).to.equal(numVisibleDays); + }); + it('if isDayHighlighted(day) is false calls deleteModifier with day and `highlighted-calendar`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.setState({ + visibleDays: visibleDays + }); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + focused: true, + isDayHighlighted: isDayHighlightedStub + })); + var highlightedCalendarCalls = getCallsByModifier(deleteModifierSpy, 'highlighted-calendar'); + (0, _chai.expect)(highlightedCalendarCalls.length).to.equal(numVisibleDays); + }); + }); + }); + describe('today', function () { + describe('this.today matches today', function () { + it('does not call deleteModifier with `today`', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().today = today; + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(deleteModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(0); + }); + it('does not call addModifier with `today`', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().today = today; + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(addModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(0); + }); + }); + describe('this.today is no longer today', function () { + it('calls deleteModifier with this.today and `today` modifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().today = (0, _moment["default"])().subtract(1, 'day'); + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(deleteModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(1); + }); + it('calls addModifier with new today and `today` modifiers', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], props)); + wrapper.instance().today = (0, _moment["default"])().subtract(1, 'day'); + wrapper.instance().componentWillReceiveProps(props); + var todayCalls = getCallsByModifier(addModifierSpy, 'today'); + (0, _chai.expect)(todayCalls.length).to.equal(1); + }); + }); + }); + }); + }); + describe('#onDayClick', function () { + describe('day arg is blocked', function () { + it('props.onDateChange is not called', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + isDayBlocked: function isDayBlocked() { + return true; + } + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(0); + }); + it('props.onFocusChange is not called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + isDayBlocked: function isDayBlocked() { + return true; + } + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + it('props.onClose is not called', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub, + isDayBlocked: function isDayBlocked() { + return true; + } + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onCloseStub.callCount).to.equal(0); + }); + it('calls props.onClose with { date } as arg', function () { + var date = (0, _moment["default"])(); + + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: null, + onDateChange: function onDateChange() {}, + focused: true, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub + })); + wrapper.instance().onDayClick(date); + (0, _chai.expect)(onCloseStub.getCall(0).args[0].date).to.equal(date); + }); + }); + describe('day arg is not blocked', function () { + it('props.onDateChange is called', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('props.onDateChange receives undefined when day selected', function () { + var date = (0, _moment["default"])(); + + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + date: date, + allowUnselect: true + })); // Click same day as the provided date. + + wrapper.instance().onDayClick(date); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + (0, _chai.expect)(onDateChangeStub.getCall(0).args[0]).to.equal(undefined); + }); + it('props.onDateChange receives day when allowUnselect is disabled', function () { + var date = (0, _moment["default"])(); + + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + date: date, + allowUnselect: false + })); // Click same day as the provided date. + + wrapper.instance().onDayClick(date); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + (0, _chai.expect)(onDateChangeStub.getCall(0).args[0]).to.equal(date); + }); + describe('props.keepOpenOnDateSelect is false', function () { + it('props.onFocusChange is called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + keepOpenOnDateSelect: false + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('props.onClose is called', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub, + keepOpenOnDateSelect: false + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onCloseStub.callCount).to.equal(1); + }); + }); + describe('props.keepOpenOnDateSelect is true', function () { + it('props.onFocusChange is not called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + keepOpenOnDateSelect: true + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + it('props.onClose is not called', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub, + keepOpenOnDateSelect: true + })); + wrapper.instance().onDayClick((0, _moment["default"])()); + (0, _chai.expect)(onCloseStub.callCount).to.equal(0); + }); + }); + }); + }); + describe('#onDayMouseEnter', function () { + it('sets state.hoverDate to day arg', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onDayMouseEnter(today); + (0, _chai.expect)(wrapper.state().hoverDate).to.equal(today); + }); + describe('modifiers', function () { + it('calls addModifier', function () { + var addModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'addModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: null + }); + addModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter(today); + (0, _chai.expect)(addModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(addModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(addModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + it('calls deleteModifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseEnter((0, _moment["default"])().add(10, 'days')); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + }); + }); + describe('#onDayMouseLeave', function () { + it('sets state.hoverDate to null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onDayMouseLeave(); + (0, _chai.expect)(wrapper.state().hoverDate).to.equal(null); + }); + it('calls deleteModifier with hoverDate and `hovered` modifier', function () { + var deleteModifierSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'deleteModifier'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + hoverDate: today + }); + deleteModifierSpy.resetHistory(); + wrapper.instance().onDayMouseLeave(today); + (0, _chai.expect)(deleteModifierSpy.callCount).to.equal(1); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[1]).to.equal(today); + (0, _chai.expect)(deleteModifierSpy.getCall(0).args[2]).to.equal('hovered'); + }); + }); + describe('#onPrevMonthClick', function () { + it('updates state.currentMonth to subtract 1 month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state().currentMonth.month()).to.equal(today.clone().subtract(1, 'month').month()); + }); + it('new visibleDays has previous month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().subtract(1, 'month'); + wrapper.instance().onPrevMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.include((0, _toISOMonthString5["default"])(newMonth)); + }); + it('new visibleDays does not have current last month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.not.include((0, _toISOMonthString5["default"])((0, _moment["default"])().add(numberOfMonths, 'months'))); + }); + it('calls this.getModifiers', function () { + var getModifiersSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'getModifiers'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersSpy.resetHistory(); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(getModifiersSpy.callCount).to.equal(1); + }); + it('calls props.onPrevMonthClick with new month', function () { + var onPrevMonthClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + onPrevMonthClick: onPrevMonthClickStub + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().subtract(1, 'month'); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(onPrevMonthClickStub.callCount).to.equal(1); + (0, _chai.expect)(onPrevMonthClickStub.firstCall.args[0].year()).to.equal(newMonth.year()); + (0, _chai.expect)(onPrevMonthClickStub.firstCall.args[0].month()).to.equal(newMonth.month()); + }); + it('calls this.shouldDisableMonthNavigation twice', function () { + var shouldDisableMonthNavigationSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'shouldDisableMonthNavigation'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + shouldDisableMonthNavigationSpy.resetHistory(); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(shouldDisableMonthNavigationSpy).to.have.property('callCount', 2); + }); + it('sets disablePrev and disablePrev as false on onPrevMonthClick call withouth maxDate and minDate set', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state()).to.have.property('disablePrev', false); + (0, _chai.expect)(wrapper.state()).to.have.property('disableNext', false); + }); + it('sets disableNext as true when maxDate is in visible month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + maxDate: today + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state()).to.have.property('disablePrev', false); + (0, _chai.expect)(wrapper.state()).to.have.property('disableNext', true); + }); + it('sets disablePrev as true when minDate is in visible month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + minDate: today.clone().subtract(1, 'month') + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(wrapper.state()).to.have.property('disablePrev', true); + (0, _chai.expect)(wrapper.state()).to.have.property('disableNext', false); + }); + }); + describe('#onNextMonthClick', function () { + it('updates state.currentMonth to add 1 month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(wrapper.state().currentMonth.month()).to.equal(today.clone().add(1, 'month').month()); + }); + it('new visibleDays has next month', function () { + var numberOfMonths = 2; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().add(numberOfMonths + 1, 'months'); + wrapper.instance().onNextMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.include((0, _toISOMonthString5["default"])(newMonth)); + }); + it('new visibleDays does not have current month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: 2 + })); + wrapper.setState({ + currentMonth: today + }); + wrapper.instance().onNextMonthClick(); + var visibleDays = Object.keys(wrapper.state().visibleDays); + (0, _chai.expect)(visibleDays).to.not.include((0, _toISOMonthString5["default"])(today.clone().subtract(1, 'month'))); + }); + it('calls this.getModifiers', function () { + var getModifiersSpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'getModifiers'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersSpy.resetHistory(); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(getModifiersSpy.callCount).to.equal(1); + }); + it('calls props.onNextMonthClick with new month', function () { + var onNextMonthClickStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + onNextMonthClick: onNextMonthClickStub + })); + wrapper.setState({ + currentMonth: today + }); + var newMonth = (0, _moment["default"])().add(1, 'month'); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(onNextMonthClickStub.callCount).to.equal(1); + (0, _chai.expect)(onNextMonthClickStub.firstCall.args[0].year()).to.equal(newMonth.year()); + (0, _chai.expect)(onNextMonthClickStub.firstCall.args[0].month()).to.equal(newMonth.month()); + }); + }); + describe('#getFirstFocusableDay', function () { + it('returns first day of arg month if not blocked and props.date is falsy', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: null, + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(today.clone().startOf('month'), 'day')).to.equal(true); + }); + it('returns props.date if exists and is not blocked', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var date = today.clone().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: date, + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(date, 'day')).to.equal(true); + }); + it('time is a noon', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: null, + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.hours()).to.equal(12); + }); + describe('desired date is blocked', function () { + it('returns first unblocked visible day if exists', function () { + var isBlockedStub = _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked'); + + var date = (0, _moment["default"])().endOf('month').subtract(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + date: date, + onFocusChange: _sinonSandbox["default"].stub(), + onDateChange: _sinonSandbox["default"].stub() + })); + isBlockedStub.resetHistory(); + isBlockedStub.returns(true); + isBlockedStub.onCall(8).returns(false); + var firstFocusableDay = wrapper.instance().getFirstFocusableDay(today); + (0, _chai.expect)(firstFocusableDay.isSame(date.clone().add(8, 'days'), 'day')).to.equal(true); + }); + }); + }); + describe('#getModifiers', function () { + it('return object has the same number of days as input', function () { + var monthISO = (0, _toISOMonthString5["default"])(today); + var visibleDays = (0, _defineProperty2["default"])({}, monthISO, [today, (0, _moment["default"])().add(1, 'day'), (0, _moment["default"])().add(2, 'days')]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiers(visibleDays); + (0, _chai.expect)(Object.keys(modifiers[monthISO]).length).to.equal(visibleDays[monthISO].length); + }); + it('calls this.getModifiersForDay for each day in input', function () { + var getModifiersForDaySpy = _sinonSandbox["default"].spy(_DayPickerSingleDateController["default"].prototype, 'getModifiersForDay'); + + var monthISO = (0, _toISOMonthString5["default"])(today); + var visibleDays = (0, _defineProperty2["default"])({}, monthISO, [today, (0, _moment["default"])().add(1, 'day'), (0, _moment["default"])().add(2, 'days')]); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + getModifiersForDaySpy.resetHistory(); + wrapper.instance().getModifiers(visibleDays); + (0, _chai.expect)(getModifiersForDaySpy.callCount).to.equal(visibleDays[monthISO].length); + }); + }); + describe('#getModifiersForDay', function () { + it('only contains `valid` if all modifier methods return false', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isToday').returns(false); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(false); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(false); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isSelected').returns(false); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isHovered').returns(false); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isFirstDayOfWeek').returns(false); + + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isLastDayOfWeek').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub, + isDayHighlighted: isDayHighlightedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.size).to.equal(1); + (0, _chai.expect)(modifiers.has('valid')).to.equal(true); + }); + it('contains `today` if this.isToday returns true', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isToday').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('today')).to.equal(true); + }); + it('contains `blocked` if this.isBlocked returns true', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked')).to.equal(true); + }); + it('contains `blocked-calendar` if props.isDayBlocked returns true', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayBlocked: isDayBlockedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked-calendar')).to.equal(true); + }); + it('contains `blocked-out-of-range` if props.isOutsideRange returns true', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isOutsideRange: isOutsideRangeStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('blocked-out-of-range')).to.equal(true); + }); + it('contains `highlighted-calendar` if props.isDayHighlighted returns true', function () { + var isDayHighlightedStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + isDayHighlighted: isDayHighlightedStub + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('highlighted-calendar')).to.equal(true); + }); + it('contains `valid` if this.isBlocked returns false', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isBlocked').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('valid')).to.equal(true); + }); + it('contains `selected` if this.isSelected returns true', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isSelected').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('selected')).to.equal(true); + }); + it('contains `hovered` if this.isHovered returns true', function () { + _sinonSandbox["default"].stub(_DayPickerSingleDateController["default"].prototype, 'isHovered').returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().getModifiersForDay((0, _moment["default"])()); + (0, _chai.expect)(modifiers.has('hovered')).to.equal(true); + }); + }); + describe('#addModifier', function () { + it('returns first arg if no day given', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier(updatedDays); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('returns first arg if day is not visible', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var modifiers = wrapper.instance().addModifier(updatedDays, (0, _moment["default"])()); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('has day args month ISO as key', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today, 'foo'); + (0, _chai.expect)(Object.keys(modifiers)).to.contain((0, _toISOMonthString5["default"])(today)); + }); + it('has day ISO as key one layer down', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString5["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('is resilient when visibleDays is an empty object', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().setState({ + visibleDays: {} + }); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString5["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('return value no longer has modifier arg for day if was in first arg', function () { + var modifierToAdd = 'foo'; + var monthISO = (0, _toISOMonthString5["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier(updatedDays, today, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.contain(modifierToAdd); + }); + it('return value no longer has modifier arg for day if was in state', function () { + var modifierToAdd = 'foo'; + var monthISO = (0, _toISOMonthString5["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + visibleDays: (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set(['bar', 'baz']))) + }); + var modifiers = wrapper.instance().addModifier({}, today, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.contain(modifierToAdd); + }); + it('return new modifier if vertically scrollable load more months', function () { + var modifierToAdd = 'foo'; + var numberOfMonths = 2; + var nextMonth = today.clone().add(numberOfMonths, 'month'); + var nextMonthISO = (0, _toISOMonthString5["default"])(nextMonth); + var nextMonthDayISO = (0, _toISODateString["default"])(nextMonth); + var updatedDays = (0, _defineProperty2["default"])({}, nextMonthISO, (0, _defineProperty2["default"])({}, nextMonthDayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })); + wrapper.setState({ + currentMonth: today, + visibleDays: _objectSpread(_objectSpread({}, (0, _getVisibleDays["default"])(today, numberOfMonths)), (0, _getVisibleDays["default"])(nextMonth, numberOfMonths)) + }); + var modifiers = wrapper.instance().addModifier(updatedDays, nextMonth, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.contain(modifierToAdd); + }); + it('return value now has modifier arg for day after getting next scrollable months', function () { + var modifierToAdd = 'foo'; + var numberOfMonths = 2; + var nextMonth = today.clone().add(numberOfMonths, 'month'); + var nextMonthISO = (0, _toISOMonthString5["default"])(nextMonth); + var nextMonthDayISO = (0, _toISODateString["default"])(nextMonth); + var updatedDays = (0, _defineProperty2["default"])({}, nextMonthISO, (0, _defineProperty2["default"])({}, nextMonthDayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })).instance(); + var modifiers = wrapper.addModifier(updatedDays, nextMonth, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.not.contain(modifierToAdd); + wrapper.onGetNextScrollableMonths(); + modifiers = wrapper.addModifier(updatedDays, nextMonth, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.contain(modifierToAdd); + }); + it('return value now has modifier arg for day after getting previous scrollable months', function () { + var modifierToAdd = 'foo'; + var numberOfMonths = 2; + var pastDateAfterMultiply = today.clone().subtract(numberOfMonths, 'months'); + var monthISO = (0, _toISOMonthString5["default"])(pastDateAfterMultiply); + var dayISO = (0, _toISODateString["default"])(pastDateAfterMultiply); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, dayISO, new Set(['bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })).instance(); + var modifiers = wrapper.addModifier(updatedDays, pastDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][dayISO])).to.not.contain(modifierToAdd); + wrapper.onGetPrevScrollableMonths(); + modifiers = wrapper.addModifier(updatedDays, pastDateAfterMultiply, modifierToAdd); + (0, _chai.expect)(Array.from(modifiers[monthISO][dayISO])).to.contain(modifierToAdd); + }); + }); + describe('#deleteModifier', function () { + it('returns first arg if no day given', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().deleteModifier(updatedDays); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('returns first arg if day is not visible', function () { + var updatedDays = { + foo: 'bar' + }; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var modifiers = wrapper.instance().deleteModifier(updatedDays, (0, _moment["default"])()); + (0, _chai.expect)(modifiers).to.equal(updatedDays); + }); + it('has day args month ISO as key', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var isoMonth = (0, _toISOMonthString5["default"])(today); + var isoDate = (0, _toISODateString["default"])(today); + var modifiers = wrapper.instance().deleteModifier((0, _defineProperty2["default"])({}, isoMonth, (0, _defineProperty2["default"])({}, isoDate, new Set(['foo']))), today, 'foo'); + (0, _chai.expect)(Object.keys(modifiers)).to.contain(isoMonth); + (0, _chai.expect)(modifiers[isoMonth][isoDate].size).to.equal(0); + }); + it('has day ISO as key one layer down', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().addModifier({}, today); + (0, _chai.expect)(Object.keys(modifiers[(0, _toISOMonthString5["default"])(today)])).to.contain((0, _toISODateString["default"])(today)); + }); + it('is resilient when visibleDays is an empty object', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.instance().setState({ + visibleDays: {} + }); + (0, _chai.expect)(function () { + wrapper.instance().deleteModifier({}, today); + }).to.not["throw"](); + }); + it('return value no longer has modifier arg for day if was in first arg', function () { + var modifierToDelete = 'foo'; + var monthISO = (0, _toISOMonthString5["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var updatedDays = (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set([modifierToDelete, 'bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + var modifiers = wrapper.instance().deleteModifier(updatedDays, today, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.not.contain(modifierToDelete); + }); + it('return value no longer has modifier arg for day if was in state', function () { + var modifierToDelete = 'foo'; + var monthISO = (0, _toISOMonthString5["default"])(today); + var todayISO = (0, _toISODateString["default"])(today); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })); + wrapper.setState({ + visibleDays: (0, _defineProperty2["default"])({}, monthISO, (0, _defineProperty2["default"])({}, todayISO, new Set([modifierToDelete, 'bar', 'baz']))) + }); + var modifiers = wrapper.instance().deleteModifier({}, today, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[monthISO][todayISO])).to.not.contain(modifierToDelete); + }); + it('return new modifier if vertically scrollable load more months', function () { + var modifierToDelete = 'foo'; + var numberOfMonths = 2; + var nextMonth = today.clone().add(numberOfMonths, 'month'); + var nextMonthISO = (0, _toISOMonthString5["default"])(nextMonth); + var nextMonthDayISO = (0, _toISODateString["default"])(nextMonth); + var updatedDays = (0, _defineProperty2["default"])({}, nextMonthISO, (0, _defineProperty2["default"])({}, nextMonthDayISO, new Set(['foo', 'bar', 'baz']))); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDatesChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + numberOfMonths: numberOfMonths, + orientation: _constants.VERTICAL_SCROLLABLE + })); + wrapper.setState({ + currentMonth: today, + visibleDays: _objectSpread(_objectSpread({}, (0, _getVisibleDays["default"])(today, numberOfMonths)), (0, _getVisibleDays["default"])(nextMonth, numberOfMonths)) + }); + var modifiers = wrapper.instance().deleteModifier(updatedDays, nextMonth, modifierToDelete); + (0, _chai.expect)(Array.from(modifiers[nextMonthISO][nextMonthDayISO])).to.not.contain(modifierToDelete); + }); + }); + describe('modifiers', function () { + describe('#isBlocked', function () { + it('returns true if props.isDayBlocked returns true', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(true); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked()).to.equal(true); + }); + it('returns true if props.isOutsideRange returns true', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked()).to.equal(true); + }); + it('returns false if props.isDayBlocked and props.isOutsideRange both refurns false', function () { + var isDayBlockedStub = _sinonSandbox["default"].stub().returns(false); + + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + isDayBlocked: isDayBlockedStub, + isOutsideRange: isOutsideRangeStub + })); + (0, _chai.expect)(wrapper.instance().isBlocked()).to.equal(false); + }); + }); + describe('#isHovered', function () { + it('returns true if day arg is equal to state.hoverDate', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isHovered(today)).to.equal(true); + }); + it('returns false if day arg is not equal to state.hoverDate', function () { + var tomorrow = (0, _moment["default"])().add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + wrapper.setState({ + hoverDate: today + }); + (0, _chai.expect)(wrapper.instance().isHovered(tomorrow)).to.equal(false); + }); + }); + describe('#isSelected', function () { + it('returns true if day arg is equal to props.date', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + date: today + })); + (0, _chai.expect)(wrapper.instance().isSelected(today)).to.equal(true); + }); + it('returns false if day arg is not equal to props.date', function () { + var tomorrow = (0, _moment["default"])().add(1, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + date: tomorrow + })); + (0, _chai.expect)(wrapper.instance().isSelected(today)).to.equal(false); + }); + }); + describe('#isToday', function () { + it('returns true if today', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + (0, _chai.expect)(wrapper.instance().isToday(today)).to.equal(true); + }); + it('returns false if tomorrow', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + (0, _chai.expect)(wrapper.instance().isToday((0, _moment["default"])(today).add(1, 'days'))).to.equal(false); + }); + it('returns false if last month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + (0, _chai.expect)(wrapper.instance().isToday((0, _moment["default"])(today).subtract(1, 'months'))).to.equal(false); + }); + }); + describe('#isFirstDayOfWeek', function () { + it('returns true if first day of this week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], null)); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week'))).to.equal(true); + }); + it('returns true if same day as firstDayOfWeek prop', function () { + var firstDayOfWeek = 3; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns true if first day of week and prop are both zero', function () { + var firstDayOfWeek = 0; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns true if first day of week is not zero, and prop is zero', function () { + _sinonSandbox["default"].stub(_moment["default"].localeData(), 'firstDayOfWeek').returns(1); + + var firstDayOfWeek = 0; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().startOf('week').day(firstDayOfWeek))).to.equal(true); + }); + it('returns false if not the first day of the week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], null)); + (0, _chai.expect)(wrapper.instance().isFirstDayOfWeek((0, _moment["default"])().endOf('week'))).to.equal(false); + }); + }); + describe('#isLastDayOfWeek', function () { + it('returns true if last day of week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], null)); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().endOf('week'))).to.equal(true); + }); + it('returns true if 6 days after firstDayOfWeek prop', function () { + var firstDayOfWeek = 3; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + firstDayOfWeek: firstDayOfWeek + })); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().day(firstDayOfWeek).add(6, 'days'))).to.equal(true); + }); + it('returns false if not last of week', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], null)); + (0, _chai.expect)(wrapper.instance().isLastDayOfWeek((0, _moment["default"])().startOf('week').add(1, 'day'))).to.equal(false); + }); + }); + }); + describe('initialVisibleMonth', function () { + describe('initialVisibleMonth is passed in', function () { + it('DayPickerSingleDateController.props.initialVisibleMonth is equal to initialVisibleMonth', function () { + var _initialVisibleMonth = (0, _moment["default"])().add(7, 'months'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + initialVisibleMonth: function initialVisibleMonth() { + return _initialVisibleMonth; + }, + focused: true + })); + var dayPicker = wrapper.find(_DayPicker["default"]); + var month = dayPicker.props().initialVisibleMonth().month(); + (0, _chai.expect)(month).to.equal(_initialVisibleMonth.month()); + }); + }); + describe('initialVisibleMonth is not passed in', function () { + it('DayPickerSingleDateController.props.initialVisibleMonth evaluates to date', function () { + var date = (0, _moment["default"])().add(10, 'days'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + date: date, + focused: true + })); + var dayPicker = wrapper.find(_DayPicker["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth().month()).to.equal(date.month()); + }); + it('DayPickerSingleDateController.props.initialVisibleMonth evaluates to today if !date', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: true + })); + var dayPicker = wrapper.find(_DayPicker["default"]); + (0, _chai.expect)(dayPicker.props().initialVisibleMonth().isSame(today, 'day')).to.equal(true); + }); + }); + describe('noNavButtons prop', function () { + it('renders navigation button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], null)).dive().dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(1); + }); + it('does not render navigation button when noNavButtons prop applied', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPickerSingleDateController["default"], { + noNavButtons: true + })).dive().dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(0); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/DayPicker_spec.js b/test-build/components/DayPicker_spec.js new file mode 100644 index 000000000..4727fe6d2 --- /dev/null +++ b/test-build/components/DayPicker_spec.js @@ -0,0 +1,1477 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); + +var _react = _interopRequireDefault(require("react")); + +var _momentWithLocales = _interopRequireDefault(require("moment/min/moment-with-locales")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _enzyme = require("enzyme"); + +var _lodash = require("lodash"); + +var isDayVisible = _interopRequireWildcard(require("../../lib/utils/isDayVisible")); + +var _isSameMonth = _interopRequireDefault(require("../../lib/utils/isSameMonth")); + +var _DayPicker = _interopRequireWildcard(require("../../lib/components/DayPicker")); + +var _CalendarMonthGrid = _interopRequireDefault(require("../../lib/components/CalendarMonthGrid")); + +var _DayPickerNavigation = _interopRequireDefault(require("../../lib/components/DayPickerNavigation")); + +var _DayPickerKeyboardShortcuts = _interopRequireDefault(require("../../lib/components/DayPickerKeyboardShortcuts")); + +var _constants = require("../../lib/constants"); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } + +var today = (0, _momentWithLocales["default"])().locale('en'); +var event = { + preventDefault: function preventDefault() {}, + stopPropagation: function stopPropagation() {} +}; +describe('DayPicker', function () { + var adjustDayPickerHeightSpy; + beforeEach(function () { + adjustDayPickerHeightSpy = _sinonSandbox["default"].stub(_DayPicker.PureDayPicker.prototype, 'adjustDayPickerHeight'); + }); + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render', function () { + describe('renderWeekHeader', function () { + it('there are 7 elements on each .DayPicker__week-header class', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var weekHeaders = wrapper.find('.DayPicker__week-header'); + weekHeaders.forEach(function (weekHeader) { + (0, _chai.expect)(weekHeader.find('li')).to.have.lengthOf(7); + }); + }); + describe('props.renderWeekHeaderElement', function () { + it('there are 7 custom elements on each .DayPicker__week-header class', function () { + var testWeekHeaderClassName = 'test-week-header'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + renderWeekHeaderElement: function renderWeekHeaderElement(day) { + return /*#__PURE__*/_react["default"].createElement("strong", { + className: testWeekHeaderClassName + }, day); + } + })).dive(); + var weekHeaders = wrapper.find('.DayPicker__week-header'); + weekHeaders.forEach(function (weekHeader) { + (0, _chai.expect)(weekHeader.find(".".concat(testWeekHeaderClassName))).to.have.lengthOf(7); + }); + }); + }); + describe('props.orientation === HORIZONTAL_ORIENTATION', function () { + it('props.numberOfMonths ul (week header) elements exists', function () { + var NUM_OF_MONTHS = 3; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION, + numberOfMonths: NUM_OF_MONTHS + })).dive(); + (0, _chai.expect)(wrapper.find('ul')).to.have.lengthOf(NUM_OF_MONTHS); + }); + }); + describe('props.orientation === VERTICAL_ORIENTATION', function () { + it('1 ul (week header) element exists', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })).dive(); + (0, _chai.expect)(wrapper.find('ul')).to.have.lengthOf(1); + }); + }); + }); + describe('renderCalendarInfo', function () { + it('info exists', function () { + var testInfoClass = 'test-info-container'; + + var infoElement = /*#__PURE__*/_react["default"].createElement("div", { + className: testInfoClass + }); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + renderCalendarInfo: function renderCalendarInfo() { + return infoElement; + } + })).dive(); + (0, _chai.expect)(wrapper.find(".".concat(testInfoClass))).to.have.lengthOf(1); + }); + }); + describe('CalendarMonthGrid', function () { + it('component exists', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + (0, _chai.expect)(wrapper.find(_CalendarMonthGrid["default"])).to.have.lengthOf(1); + }); + describe('prop.isAnimating', function () { + it('is true if state.monthTransition is truthy', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + monthTransition: 'foo' + }); + var CalendarMonthGridComponent = wrapper.find(_CalendarMonthGrid["default"]); + (0, _chai.expect)(CalendarMonthGridComponent.prop('isAnimating')).to.equal(true); + }); + it('is false if state.monthTransition is falsy', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + monthTransition: null + }); + var CalendarMonthGridComponent = wrapper.find(_CalendarMonthGrid["default"]); + (0, _chai.expect)(CalendarMonthGridComponent.prop('isAnimating')).to.equal(false); + }); + }); + }); + describe('DayPickerNavigation', function () { + it('is rendered before CalendarMonthGrid in DayPicker_focusRegion', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(1); + (0, _chai.expect)(wrapper.find('[className^="DayPicker_focusRegion"]').childAt(0).type()).to.equal(_DayPickerNavigation["default"]); + }); + describe('navPosition === NAV_POSITION_BOTTOM', function () { + it('is rendered after CalendarMonthGrid in DayPicker_focusRegion', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + navPosition: _constants.NAV_POSITION_BOTTOM + })).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.lengthOf(1); + (0, _chai.expect)(wrapper.find('[className^="DayPicker_focusRegion"]').childAt(1).type()).to.equal(_DayPickerNavigation["default"]); + }); + }); + }); + describe('DayPickerKeyboardShortcuts', function () { + it('component exists if state.isTouchDevice is false and hideKeyboardShortcutsPanel is false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + hideKeyboardShortcutsPanel: false + })).dive(); + wrapper.setState({ + isTouchDevice: false + }); + (0, _chai.expect)(wrapper.find(_DayPickerKeyboardShortcuts["default"])).to.have.lengthOf(1); + }); + it('component does not exist if isTouchDevice() is true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + isTouchDevice: true + }); + (0, _chai.expect)(wrapper.find(_DayPickerKeyboardShortcuts["default"])).to.have.lengthOf(0); + }); + it('component does not exist if hideKeyboardShortcutsPanel is true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + hideKeyboardShortcutsPanel: true + })).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerKeyboardShortcuts["default"])).to.have.lengthOf(0); + }); + it('component exists with custom button render function if renderKeyboardShortcutsButton is passed down', function () { + var testRenderKeyboardShortcutsButton = function testRenderKeyboardShortcutsButton() {}; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + renderKeyboardShortcutsButton: testRenderKeyboardShortcutsButton + })).dive(); + var dayPickerKeyboardShortcuts = wrapper.find(_DayPickerKeyboardShortcuts["default"]); + (0, _chai.expect)(dayPickerKeyboardShortcuts).to.have.lengthOf(1); + (0, _chai.expect)(dayPickerKeyboardShortcuts.prop('renderKeyboardShortcutsButton')).to.eql(testRenderKeyboardShortcutsButton); + }); + it('component exists with custom panel render function if renderKeyboardShortcutsPanel is passed down', function () { + var testRenderKeyboardShortcutsPanel = function testRenderKeyboardShortcutsPanel() {}; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + renderKeyboardShortcutsPanel: testRenderKeyboardShortcutsPanel + })).dive(); + var dayPickerKeyboardShortcuts = wrapper.find(_DayPickerKeyboardShortcuts["default"]); + (0, _chai.expect)(dayPickerKeyboardShortcuts).to.have.lengthOf(1); + (0, _chai.expect)(dayPickerKeyboardShortcuts.prop('renderKeyboardShortcutsPanel')).to.eql(testRenderKeyboardShortcutsPanel); + }); + }); + }); + describe('#isHorizontal', function () { + it('returns true if props.orientation === HORIZONTAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })).dive(); + (0, _chai.expect)(wrapper.instance().isHorizontal()).to.equal(true); + }); + it('returns false if props.orientation === VERTICAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + }), { + disableLifecycleMethods: false + }).dive(); + (0, _chai.expect)(wrapper.instance().isHorizontal()).to.equal(false); + }); + }); + describe('#isVertical', function () { + it('returns true if props.orientation === VERTICAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + }), { + disableLifecycleMethods: false + }).dive(); + (0, _chai.expect)(wrapper.instance().isVertical()).to.equal(true); + }); + it('returns false if props.orientation === HORIZONTAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })).dive(); + (0, _chai.expect)(wrapper.instance().isVertical()).to.equal(false); + }); + }); + describe('props.orientation === VERTICAL_SCROLLABLE', function () { + it('renders two DayPickerNavigations', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + }), { + disableLifecycleMethods: false + }).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.length(2); + }); + it('uses getNextScrollableMonths instead of onNextMonthClick', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + }), { + disableLifecycleMethods: false + }).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.length(2); + var nav = wrapper.find(_DayPickerNavigation["default"]).get(1); + (0, _chai.expect)(nav.props.onNextMonthClick).to.equal(wrapper.instance().getNextScrollableMonths); + }); + it('uses getPrevScrollableMonths instead of onNextMonthClick', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + }), { + disableLifecycleMethods: false + }).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerNavigation["default"])).to.have.length(2); + var nav = wrapper.find(_DayPickerNavigation["default"]).get(0); + (0, _chai.expect)(nav.props.onPrevMonthClick).to.equal(wrapper.instance().getPrevScrollableMonths); + }); + }); + describe('#onKeyDown', function () { + describe('focusedDate is truthy', function () { + it('sets state.withMouseInteractions to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + withMouseInteractions: true + }); + wrapper.instance().onKeyDown(_objectSpread({}, event)); + (0, _chai.expect)(wrapper.state().withMouseInteractions).to.equal(false); + }); + describe('ArrowUp', function () { + it('calls maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowUp' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 week before focusedDate', function () { + var oneWeekBefore = today.clone().subtract(1, 'week'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowUp' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneWeekBefore, 'day')).to.equal(true); + }); + }); + describe('ArrowLeft', function () { + it('calls maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 day before focusedDate', function () { + var oneDayBefore = today.clone().subtract(1, 'day'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneDayBefore, 'day')).to.equal(true); + }); + it('arg is end of previous month', function () { + var startOfThisMonth = today.clone().startOf('month'); + var endOfPrevMonth = startOfThisMonth.clone().subtract(1, 'day'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: startOfThisMonth + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(endOfPrevMonth, 'day')).to.equal(true); + }); + }); + describe('ArrowLeft -- RTL', function () { + it('calls maybeTransitionNextMonth', function () { + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + (0, _chai.expect)(maybeTransitionNextMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 day after focusedDate', function () { + var oneDayAfter = today.clone().add(1, 'day'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneDayAfter, 'day')).to.equal(true); + }); + it('arg is start of next month', function () { + var endOfThisMonth = today.clone().endOf('month'); + var startOfNextMonth = endOfThisMonth.clone().add(1, 'day'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: endOfThisMonth + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(startOfNextMonth, 'day')).to.equal(true); + }); + }); + describe('Home', function () { + it('calls maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Home' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(1); + }); + it('arg is beginning of focusedDate week', function () { + var startOfWeek = today.clone().startOf('week'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Home' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(startOfWeek, 'day')).to.equal(true); + }); + }); + describe('PageUp', function () { + it('calls maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageUp' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 month before focusedDate', function () { + var oneMonthBefore = today.clone().subtract(1, 'month'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageUp' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneMonthBefore, 'day')).to.equal(true); + }); + }); + describe('ArrowDown', function () { + it('calls maybeTransitionNextMonth', function () { + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowDown' + })); + (0, _chai.expect)(maybeTransitionNextMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 week after focusedDate', function () { + var oneWeekAfter = today.clone().add(1, 'week'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowDown' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneWeekAfter, 'day')).to.equal(true); + }); + }); + describe('ArrowRight', function () { + it('calls maybeTransitionNextMonth', function () { + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + (0, _chai.expect)(maybeTransitionNextMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 day after focusedDate', function () { + var oneDayAfter = today.clone().add(1, 'day'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneDayAfter, 'day')).to.equal(true); + }); + it('arg is start of next month', function () { + var endOfThisMonth = today.clone().endOf('month'); + var startOfNextMonth = endOfThisMonth.clone().add(1, 'day'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: endOfThisMonth + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(startOfNextMonth, 'day')).to.equal(true); + }); + }); + describe('ArrowRight -- RTL', function () { + it('calls maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 day before focusedDate', function () { + var oneDayBefore = today.clone().subtract(1, 'day'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneDayBefore, 'day')).to.equal(true); + }); + it('arg is end of previous month', function () { + var startOfThisMonth = today.clone().startOf('month'); + var endOfPrevMonth = startOfThisMonth.clone().subtract(1, 'day'); + + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + isRTL: true + })).dive(); + wrapper.setState({ + focusedDate: startOfThisMonth + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + var arg = maybeTransitionPrevMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(endOfPrevMonth, 'day')).to.equal(true); + }); + }); + describe('End', function () { + it('calls maybeTransitionNextMonth', function () { + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'End' + })); + (0, _chai.expect)(maybeTransitionNextMonthSpy.callCount).to.equal(1); + }); + it('arg is end of focusedDate week', function () { + var endOfWeek = today.clone().endOf('week'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'End' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(endOfWeek, 'day')).to.equal(true); + }); + }); + describe('PageDown', function () { + it('calls maybeTransitionNextMonth', function () { + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageDown' + })); + (0, _chai.expect)(maybeTransitionNextMonthSpy.callCount).to.equal(1); + }); + it('arg is 1 month after focusedDate', function () { + var oneMonthAfter = today.clone().add(1, 'month'); + + var maybeTransitionNextMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionNextMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'PageDown' + })); + var arg = maybeTransitionNextMonthSpy.getCall(0).args[0]; + (0, _chai.expect)(arg.isSame(oneMonthAfter, 'day')).to.equal(true); + }); + }); + describe('?', function () { + it('calls openKeyboardShortcutsPanel', function () { + var openKeyboardShortcutsPanelSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'openKeyboardShortcutsPanel'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: '?' + })); + (0, _chai.expect)(openKeyboardShortcutsPanelSpy.callCount).to.equal(1); + }); + }); + describe('Escape', function () { + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today, + showKeyboardShortcuts: true + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Escape' + })); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + it('calls closeKeyboardShortcutsPanel if state.showKeyboardShortcuts === true', function () { + var closeKeyboardShortcutsPanelSpy = _sinonSandbox["default"].stub(_DayPicker.PureDayPicker.prototype, 'closeKeyboardShortcutsPanel'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: today, + showKeyboardShortcuts: true + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Escape' + })); + (0, _chai.expect)(closeKeyboardShortcutsPanelSpy.callCount).to.equal(1); + }); + it('calls props.onBlur if state.showKeyboardShortcuts === false', function () { + var onBlurStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + onBlur: onBlurStub + })).dive(); + wrapper.setState({ + focusedDate: today, + showKeyboardShortcuts: false + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Escape' + })); + (0, _chai.expect)(onBlurStub.callCount).to.equal(1); + }); + }); + describe('Tab', function () { + it('triggers onShiftTab when shift tab is pressed', function () { + var onTabStub = _sinonSandbox["default"].stub(); + + var onShiftTabStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + onTab: onTabStub, + onShiftTab: onShiftTabStub + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Tab', + shiftKey: true + })); + (0, _chai.expect)(onTabStub.callCount).to.equal(0); + (0, _chai.expect)(onShiftTabStub.callCount).to.equal(1); + }); + it('triggers onTab', function () { + var onTabStub = _sinonSandbox["default"].stub(); + + var onShiftTabStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + onTab: onTabStub, + onShiftTab: onShiftTabStub + })).dive(); + wrapper.setState({ + focusedDate: today + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'Tab' + })); + (0, _chai.expect)(onTabStub.callCount).to.equal(1); + (0, _chai.expect)(onShiftTabStub.callCount).to.equal(0); + }); + }); + }); + describe('focusedDate is falsy', function () { + it('does not call maybeTransitionPrevMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: null + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowLeft' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(0); + }); + it('does not call maybeTransitionNextMonth', function () { + var maybeTransitionPrevMonthSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'maybeTransitionPrevMonth'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + focusedDate: null + }); + wrapper.instance().onKeyDown(_objectSpread(_objectSpread({}, event), {}, { + key: 'ArrowRight' + })); + (0, _chai.expect)(maybeTransitionPrevMonthSpy.callCount).to.equal(0); + }); + }); + }); + describe('#onMonthChange', function () { + it('sets state.monthTransition to "month_selection"', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onMonthChange(date); + (0, _chai.expect)(wrapper.state().monthTransition).to.equal('month_selection'); + }); + it('sets state.nextFocusedDate to passed in date', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onMonthChange(date); + (0, _chai.expect)(wrapper.state().nextFocusedDate).to.equal(date); + }); + it('sets state.currentMonth to passed in month', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onMonthChange(date); + (0, _chai.expect)(wrapper.state().currentMonth).to.equal(date); + }); + }); + describe('#onYearChange', function () { + it('sets state.yearTransition to "year_selection"', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onYearChange(date); + (0, _chai.expect)(wrapper.state().monthTransition).to.equal('year_selection'); + }); + it('sets state.nextFocusedDate to passed in date', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onYearChange(date); + (0, _chai.expect)(wrapper.state().nextFocusedDate).to.equal(date); + }); + it('sets state.currentMonth to passed in year', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + var date = (0, _momentWithLocales["default"])(); + wrapper.instance().onYearChange(date); + (0, _chai.expect)(wrapper.state().currentMonth).to.equal(date); + }); + }); + describe('#onPrevMonthClick', function () { + it('calls onPrevMonthTransition', function () { + var onPrevMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onPrevMonthTransition'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onPrevMonthClick(); + (0, _chai.expect)(onPrevMonthTransitionSpy.callCount).to.equal(1); + }); + }); + describe('#onPrevMonthTransition', function () { + it('sets state.monthTransition to "prev"', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onPrevMonthTransition(); + (0, _chai.expect)(wrapper.state().monthTransition).to.equal('prev'); + }); + it('sets state.nextFocusedDate to first arg', function () { + var test = 'FOOBARBAZ'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onPrevMonthTransition(test); + (0, _chai.expect)(wrapper.state().nextFocusedDate).to.equal(test); + }); + }); + describe('monthTitleHeight', function () { + it('change monthTitleHeight correctly with setMonthTitleHeight', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().setMonthTitleHeight(80); + (0, _chai.expect)(wrapper.state().monthTitleHeight).to.equal(80); + }); + it('do not change monthTitleHeight with renderMonthText === prevRenderMonthText', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + renderMonthText: function renderMonthText() { + return 'foo'; + } + })).dive(); + wrapper.instance().setMonthTitleHeight(80); + wrapper.setProps({ + renderMonthText: function renderMonthText() { + return 'foo'; + } + }); + (0, _chai.expect)(wrapper.state().monthTitleHeight).to.equal(80); + }); + }); + describe('#onNextMonthClick', function () { + it('calls onNextMonthTransition', function () { + var onNextMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onNextMonthTransition'); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onNextMonthClick(); + (0, _chai.expect)(onNextMonthTransitionSpy.callCount).to.equal(1); + }); + }); + describe('#onNextMonthTransition', function () { + it('sets state.monthTransition to "next"', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onNextMonthTransition(); + (0, _chai.expect)(wrapper.state().monthTransition).to.equal('next'); + }); + it('sets state.nextFocusedDate to first arg', function () { + var test = 'FOOBARBAZ'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().onNextMonthTransition(test); + (0, _chai.expect)(wrapper.state().nextFocusedDate).to.equal(test); + }); + }); + describe('#getFocusedDay', function () { + describe('props.getFirstFocusableDay is truthy', function () { + it('calls getFirstFocusableDay with arg if exists', function () { + var getFirstFocusableDayStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + getFirstFocusableDay: getFirstFocusableDayStub + })).dive(); // getFirstFocusableDay gets called in the constructor + + getFirstFocusableDayStub.resetHistory(); + wrapper.instance().getFocusedDay(); + (0, _chai.expect)(getFirstFocusableDayStub.callCount).to.equal(1); + }); + it('calls getFirstFocusableDay with arg if exists', function () { + var getFirstFocusableDayStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + getFirstFocusableDay: getFirstFocusableDayStub + })).dive(); // getFirstFocusableDay gets called in the constructor + + getFirstFocusableDayStub.resetHistory(); + wrapper.instance().getFocusedDay(today); + (0, _chai.expect)(getFirstFocusableDayStub.getCall(0).args[0].isSame(today, 'day')).to.equal(true); + }); + it('returns getFirstFocusableDay() value', function () { + var getFirstFocusableDayStub = _sinonSandbox["default"].stub().returns(today); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + getFirstFocusableDay: getFirstFocusableDayStub + })).dive(); + (0, _chai.expect)(wrapper.instance().getFocusedDay().isSame(today, 'day')).to.equal(true); + }); + it('returns first day of arg if getFirstFocusableDay returns invisible day', function () { + var test = (0, _momentWithLocales["default"])().add(3, 'months'); + + var getFirstFocusableDayStub = _sinonSandbox["default"].stub().returns(today); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + getFirstFocusableDay: getFirstFocusableDayStub + })).dive(); + (0, _chai.expect)(wrapper.instance().getFocusedDay(test).isSame(test.startOf('month'), 'day')).to.equal(true); + }); + }); + describe('props.getFirstFocusableDay is falsy', function () { + it('returns undefined if no arg', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + (0, _chai.expect)(wrapper.instance().getFocusedDay()).to.equal(undefined); + }); + it('returns first day of arg month if exists', function () { + var test = (0, _momentWithLocales["default"])().add(3, 'months'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + (0, _chai.expect)(wrapper.instance().getFocusedDay(test).isSame(test.startOf('month'), 'day')).to.equal(true); + }); + }); + }); + describe('#maybeTransitionNextMonth', function () { + describe('arg has same month as state.focusedDate', function () { + it('does not call `onNextMonthTransition`', function () { + var onNextMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onNextMonthTransition'); + + var firstOfTodaysMonth = (0, _momentWithLocales["default"])().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = firstOfTodaysMonth; + wrapper.instance().maybeTransitionNextMonth(today); + (0, _chai.expect)(onNextMonthTransitionSpy.callCount).to.equal(0); + }); + it('returns false', function () { + var firstOfTodaysMonth = today.clone().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = firstOfTodaysMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionNextMonth(today)).to.equal(false); + }); + }); + describe('arg has different month as state.focusedDate', function () { + describe('arg is visible', function () { + it('does not call `onNextMonthClick`', function () { + var onNextMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onNextMonthTransition'); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + wrapper.instance().maybeTransitionNextMonth(today); + (0, _chai.expect)(onNextMonthTransitionSpy.callCount).to.equal(0); + }); + it('returns false', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionNextMonth(today)).to.equal(false); + }); + }); + describe('arg is not visible', function () { + it('calls `onNextMonthTransition`', function () { + var onNextMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onNextMonthTransition'); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + wrapper.instance().maybeTransitionNextMonth(today); + (0, _chai.expect)(onNextMonthTransitionSpy.callCount).to.equal(1); + }); + it('returns true', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionNextMonth(today)).to.equal(true); + }); + }); + }); + }); + describe('#maybeTransitionPrevMonth', function () { + describe('arg has same month as state.focusedDate', function () { + it('does not call `onPrevMonthTransition`', function () { + var onPrevMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onPrevMonthTransition'); + + var firstOfTodaysMonth = (0, _momentWithLocales["default"])().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = firstOfTodaysMonth; + wrapper.instance().maybeTransitionPrevMonth(today); + (0, _chai.expect)(onPrevMonthTransitionSpy.callCount).to.equal(0); + }); + it('returns false', function () { + var firstOfTodaysMonth = today.clone().startOf('month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = firstOfTodaysMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionPrevMonth(today)).to.equal(false); + }); + }); + describe('arg has different month as state.focusedDate', function () { + describe('arg is visible', function () { + it('does not call `onPrevMonthTransition`', function () { + var onPrevMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onPrevMonthTransition'); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + wrapper.instance().maybeTransitionPrevMonth(today); + (0, _chai.expect)(onPrevMonthTransitionSpy.callCount).to.equal(0); + }); + it('returns false', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionPrevMonth(today)).to.equal(false); + }); + }); + describe('arg is not visible', function () { + it('calls `onPrevMonthTransition`', function () { + var onPrevMonthTransitionSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'onPrevMonthTransition'); + + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + wrapper.instance().maybeTransitionPrevMonth(today); + (0, _chai.expect)(onPrevMonthTransitionSpy.callCount).to.equal(1); + }); + it('returns true', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var nextMonth = (0, _momentWithLocales["default"])().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.state().focusedDate = nextMonth; + (0, _chai.expect)(wrapper.instance().maybeTransitionPrevMonth(today)).to.equal(true); + }); + }); + }); + }); + describe('#getNextScrollableMonths', function () { + it('increments scrollableMonthMultiple', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().getNextScrollableMonths(event); + (0, _chai.expect)(wrapper.state().scrollableMonthMultiple).to.equal(2); + }); + }); + describe('#getPrevScrollableMonths', function () { + it('increments scrollableMonthMultiple and updates currentMonth', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.instance().getPrevScrollableMonths(); + (0, _chai.expect)(wrapper.state().scrollableMonthMultiple).to.equal(2); + (0, _chai.expect)((0, _isSameMonth["default"])(wrapper.state().currentMonth, (0, _momentWithLocales["default"])().subtract(2, 'month'))).to.equal(true); + }); + }); + describe('#openKeyboardShortcutsPanel', function () { + it('sets state.showKeyboardShortcuts to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + showKeyboardShortcuts: false + }); + wrapper.instance().openKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(true); + }); + it('sets state.onKeyboardShortcutsPanelClose to arg', function () { + var test = 'FOOBARBAZ'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + onKeyboardShortcutsPanelClose: null + }); + wrapper.instance().openKeyboardShortcutsPanel(test); + (0, _chai.expect)(wrapper.state().onKeyboardShortcutsPanelClose).to.equal(test); + }); + }); + describe('#closeKeyboardShortcutsPanel', function () { + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().closeKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + it('sets state.onKeyboardShortcutsPanelClose to null', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + showKeyboardShortcuts: true, + onKeyboardShortcutsPanelClose: _sinonSandbox["default"].stub() + }); + wrapper.instance().closeKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().onKeyboardShortcutsPanelClose).to.equal(null); + }); + it('calls state.onKeyboardShortcutsPanelClose if exists', function () { + var onKeyboardShortcutsPanelCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], null)).dive(); + wrapper.setState({ + showKeyboardShortcuts: true, + onKeyboardShortcutsPanelClose: onKeyboardShortcutsPanelCloseStub + }); + wrapper.instance().closeKeyboardShortcutsPanel(); + (0, _chai.expect)(onKeyboardShortcutsPanelCloseStub.callCount).to.equal(1); + }); + }); + describe('#weekHeaderNames', function () { + it('returns weekheaders in fr', function () { + var INITIAL_MONTH = (0, _momentWithLocales["default"])().locale('fr'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + initialVisibleMonth: function initialVisibleMonth() { + return INITIAL_MONTH; + } + })).dive(); + var instance = wrapper.instance(); + (0, _chai.expect)(instance.getWeekHeaders()).to.be.eql(INITIAL_MONTH.localeData().weekdaysMin()); + }); + }); + describe('#getWeekHeaders', function () { + it('returns unmutated weekday headers for currentMonth in a future', function () { + _sinonSandbox["default"].stub(_DayPicker.PureDayPicker.prototype, 'render').returns(null); + + var getWeekHeadersSpy = _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'getWeekHeaders'); + + var INITIAL_MONTH = (0, _momentWithLocales["default"])().add(2, 'Months').week(3).weekday(3); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + initialVisibleMonth: function initialVisibleMonth() { + return INITIAL_MONTH; + } + })).dive(); + var instance = wrapper.instance(); + var state = (0, _lodash.cloneDeep)(wrapper.state()); + (0, _chai.expect)(instance.getWeekHeaders()).to.be.eql(INITIAL_MONTH.localeData().weekdaysMin()); + (0, _chai.expect)(instance.state).not.to.equal(state); + (0, _chai.expect)(instance.state).to.eql(state); + (0, _chai.expect)(getWeekHeadersSpy).to.have.property('callCount', 1); + }); + }); + describe('life cycle methods', function () { + describe.skip('#componentDidMount', function () { + describe('props.orientation === HORIZONTAL_ORIENTATION', function () { + it('calls adjustDayPickerHeight', function () { + (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 1); + }); + it('does not update state.currentMonthScrollTop', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + (0, _chai.expect)(wrapper.state().currentMonthScrollTop).to.equal(null); + }); + }); + describe.skip('props.orientation === VERTICAL_ORIENTATION', function () { + it('does not call adjustDayPickerHeight', function () { + (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + (0, _chai.expect)(adjustDayPickerHeightSpy.called).to.equal(false); + }); + it('does not update state.currentMonthScrollTop', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + (0, _chai.expect)(wrapper.state().currentMonthScrollTop).to.equal(null); + }); + }); + describe('props.orientation === VERTICAL_SCROLLABLE', function () { + it('updates state.currentMonthScrollTop', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + })); + (0, _chai.expect)(wrapper.state().currentMonthScrollTop).to.not.equal(null); + }); + }); + }); + describe('#componentWillReceiveProps', function () { + describe.skip('props.orientation === VERTICAL_SCROLLABLE', function () { + it('updates state.currentMonthScrollTop', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + })); + var prevCurrentMonthScrollTop = wrapper.state().currentMonthScrollTop; + wrapper.setState({ + currentMonth: (0, _momentWithLocales["default"])().subtract(1, 'months') + }); + wrapper.setProps({ + initialVisibleMonth: function initialVisibleMonth() { + return (0, _momentWithLocales["default"])().subtract(1, 'month'); + } + }); + (0, _chai.expect)(wrapper.state().currentMonthScrollTop).to.not.equal(prevCurrentMonthScrollTop); + }); + }); + describe('props.date changed', function () { + var props = _objectSpread(_objectSpread({}, _DayPicker.defaultProps), {}, { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + initialVisibleMonth: function initialVisibleMonth() { + return today; + }, + theme: { + reactDates: { + spacing: {} + } + }, + styles: {}, + css: function css() {} + }); + + describe('date is not visible', function () { + it('setState gets called with new month', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(false); + + var date = today; + var newDate = date.clone().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker.PureDayPicker, (0, _extends2["default"])({}, props, { + date: date + }))); + (0, _chai.expect)(wrapper.state().currentMonth).to.eql(date); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate, + initialVisibleMonth: function initialVisibleMonth() { + return newDate; + } + }), {}); + (0, _chai.expect)(wrapper.state().currentMonth).to.eql(newDate); + }); + }); + describe('date is visible', function () { + it('setState gets called with existing month', function () { + _sinonSandbox["default"].stub(isDayVisible, 'default').returns(true); + + var date = today; + var newDate = date.clone().add(1, 'month'); + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker.PureDayPicker, (0, _extends2["default"])({}, props, { + date: date + }))); + (0, _chai.expect)(wrapper.state().currentMonth).to.eql(date); + wrapper.instance().componentWillReceiveProps(_objectSpread(_objectSpread({}, props), {}, { + date: newDate, + initialVisibleMonth: function initialVisibleMonth() { + return newDate; + } + }), {}); + (0, _chai.expect)(wrapper.state().currentMonth).to.eql(date); + }); + }); + }); + }); + describe('#componentDidUpdate', function () { + var updateStateAfterMonthTransitionSpy; + beforeEach(function () { + updateStateAfterMonthTransitionSpy = _sinonSandbox["default"].stub(_DayPicker.PureDayPicker.prototype, 'updateStateAfterMonthTransition'); + }); + describe('props.orientation === HORIZONTAL_ORIENTATION', function () { + it.skip('calls adjustDayPickerHeight if state.monthTransition is truthy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: 'foo' + }); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 2); + }); + it.skip('does not call adjustDayPickerHeight if state.monthTransition is falsy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: null + }); + (0, _chai.expect)(adjustDayPickerHeightSpy.calledTwice).to.equal(false); + }); + it.skip('calls adjustDayPickerHeight if orientation has changed from HORIZONTAL_ORIENTATION to VERTICAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + orientation: _constants.VERTICAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 2); + }); + it.skip('calls adjustDayPickerHeight if daySize has changed', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + daySize: 39, + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + daySize: 40, + orientation: _constants.HORIZONTAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 2); + }); + it.skip('calls updateStateAfterMonthTransition if state.monthTransition is truthy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: 'foo' + }); + (0, _chai.expect)(updateStateAfterMonthTransitionSpy).to.have.property('callCount', 1); + }); + it.skip('does not call updateStateAfterMonthTransition if state.monthTransition is falsy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.HORIZONTAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: null + }); + (0, _chai.expect)(updateStateAfterMonthTransitionSpy.calledOnce).to.equal(false); + }); + it('calls adjustDayPickerHeightSpy if props.numberOfMonths changes', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + numberOfMonths: 2 + })).dive(); + wrapper.instance().componentDidUpdate({ + daySize: _constants.DAY_SIZE, + numberOfMonths: 3, + orientation: _constants.HORIZONTAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy.callCount).to.equal(1); + }); + it('does not call adjustDayPickerHeightSpy if props.numberOfMonths does not change', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + numberOfMonths: 2 + })).dive(); + wrapper.instance().componentDidUpdate({ + daySize: _constants.DAY_SIZE, + numberOfMonths: 2, + orientation: _constants.HORIZONTAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy.called).to.equal(false); + }); + }); + describe.skip('props.orientation === VERTICAL_ORIENTATION', function () { + it('does not call adjustDayPickerHeight if state.monthTransition is truthy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: 'foo' + }); + (0, _chai.expect)(adjustDayPickerHeightSpy.called).to.equal(false); + }); + it('does not call adjustDayPickerHeight if state.monthTransition is falsy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: null + }); + (0, _chai.expect)(adjustDayPickerHeightSpy.called).to.equal(false); + }); + it('calls adjustDayPickerHeight if orientation has changed from VERTICAL_ORIENTATION to HORIZONTAL_ORIENTATION', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + orientation: _constants.HORIZONTAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 2); + }); + it('calls adjustDayPickerHeight if daySize has changed', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + daySize: 39, + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + daySize: 40, + orientation: _constants.VERTICAL_ORIENTATION + }); + (0, _chai.expect)(adjustDayPickerHeightSpy).to.have.property('callCount', 2); + }); + it('calls updateStateAfterMonthTransition if state.monthTransition is truthy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: 'foo' + }); + (0, _chai.expect)(updateStateAfterMonthTransitionSpy).to.have.property('callCount', 1); + }); + it('does not call updateStateAfterMonthTransition if state.monthTransition is falsy', function () { + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_ORIENTATION + })); + wrapper.setState({ + monthTransition: null + }); + (0, _chai.expect)(updateStateAfterMonthTransitionSpy.calledOnce).to.equal(false); + }); + }); + describe.skip('props.orientation === VERTICAL_SCROLLABLE', function () { + it('does not update transitionContainer ref`s scrollTop currentMonth stays the same', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + })); + var prevScrollTop = wrapper.transitionContainer.scrollTop; + wrapper.setState({ + currentMonth: (0, _momentWithLocales["default"])() + }); + (0, _chai.expect)(wrapper.transitionContainer).to.have.property('scrollTop', prevScrollTop); + }); + it('updates transitionContainer ref`s scrollTop currentMonth changes', function () { + _sinonSandbox["default"].spy(_DayPicker.PureDayPicker.prototype, 'setTransitionContainerRef'); + + var wrapper = (0, _enzyme.mount)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], { + orientation: _constants.VERTICAL_SCROLLABLE + })); + var prevScrollTop = wrapper.transitionContainer.scrollTop; + wrapper.setState({ + currentMonth: (0, _momentWithLocales["default"])().subtract(1, 'months') + }); + (0, _chai.expect)(wrapper.transitionContainer).to.not.have.property('scrollTop', prevScrollTop); + }); + }); + describe.skip('when isFocused is updated to true', function () { + var prevProps = { + isFocused: false + }; + var newProps = { + isFocused: true + }; + var containerFocusStub; + var wrapper; + beforeEach(function () { + containerFocusStub = _sinonSandbox["default"].stub(); + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_DayPicker["default"], newProps)).dive(); + wrapper.instance().container = { + focus: containerFocusStub + }; + }); + afterEach(function () { + containerFocusStub.resetHistory(); + }); + describe('when focusedDate is not defined', function () { + before(function () { + wrapper.state().focusedDate = undefined; + wrapper.instance().componentDidUpdate(prevProps); + }); + it('sets focus on the container', function () { + (0, _chai.expect)(containerFocusStub.callCount).to.equal(1); + }); + }); + describe('when focusedDate is defined', function () { + before(function () { + wrapper.state().focusedDate = (0, _momentWithLocales["default"])(); + wrapper.instance().componentDidUpdate(prevProps); + }); + it('should not set focus on the container', function () { + (0, _chai.expect)(containerFocusStub.notCalled).to.equal(true); + }); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/KeyboardShortcutRow_spec.js b/test-build/components/KeyboardShortcutRow_spec.js new file mode 100644 index 000000000..e58e9336d --- /dev/null +++ b/test-build/components/KeyboardShortcutRow_spec.js @@ -0,0 +1,22 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _KeyboardShortcutRow = _interopRequireDefault(require("../../lib/components/KeyboardShortcutRow")); + +describe('KeyboardShortcutRow', function () { + it('is an li', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_KeyboardShortcutRow["default"], { + unicode: "foo", + label: "bar", + action: "baz" + })).dive(); + (0, _chai.expect)(wrapper.is('li')).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test-build/components/SingleDatePickerInputController_spec.js b/test-build/components/SingleDatePickerInputController_spec.js new file mode 100644 index 000000000..db21b550c --- /dev/null +++ b/test-build/components/SingleDatePickerInputController_spec.js @@ -0,0 +1,404 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _moment = _interopRequireDefault(require("moment")); + +var _SingleDatePickerInput = _interopRequireDefault(require("../../lib/components/SingleDatePickerInput")); + +var _SingleDatePickerInputController = _interopRequireDefault(require("../../lib/components/SingleDatePickerInputController")); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +// Set to noon to mimic how days in the picker are configured internally +var today = (0, _moment["default"])().startOf('day').hours(12); +describe('SingleDatePickerInputController', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + it('renders a SingleDatePickerInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInput["default"])).to.have.lengthOf(1); + }); + it('should pass children to the SingleDatePickerInput', function () { + var Child = function Child() { + return /*#__PURE__*/_react["default"].createElement("div", null, "CHILD"); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date" + }, /*#__PURE__*/_react["default"].createElement(Child, null))); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInput["default"])).to.have.property('children'); + (0, _chai.expect)(wrapper.find(Child)).to.have.lengthOf(1); + }); + describe('#onChange', function () { + describe('valid future date string', function () { + var futureDateString = (0, _moment["default"])().add(10, 'days').format('YYYY-MM-DD'); + it('calls props.onDateChange once', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(futureDateString); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('calls props.onDateChange with date as arg', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(futureDateString); + var newDate = onDateChangeStub.getCall(0).args[0]; + (0, _chai.expect)((0, _isSameDay["default"])(newDate, (0, _moment["default"])(futureDateString))).to.equal(true); + }); + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onChange(futureDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: false } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onChange(futureDateString); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(false); + }); + it('calls props.onClose once', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub + })); + wrapper.instance().onChange(futureDateString); + (0, _chai.expect)(onCloseStub.callCount).to.equal(1); + }); + it('calls props.onClose with { date } as arg', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + onClose: onCloseStub + })); + wrapper.instance().onChange(futureDateString); + var newDate = onCloseStub.getCall(0).args[0].date; + (0, _chai.expect)((0, _isSameDay["default"])(newDate, (0, _moment["default"])(futureDateString))).to.equal(true); + }); + }); + describe('matches custom display format', function () { + var customFormat = 'YY|MM[foobar]DD'; + var customFormatDateString = (0, _moment["default"])().add(5, 'days').format(customFormat); + it('calls props.onDateChange once', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + displayFormat: customFormat, + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(customFormatDateString); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('calls props.onDateChange with date as arg', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + displayFormat: customFormat, + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(customFormatDateString); + var formattedFirstArg = onDateChangeStub.getCall(0).args[0].format(customFormat); + (0, _chai.expect)(formattedFirstArg).to.equal(customFormatDateString); + }); + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + displayFormat: customFormat, + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: false } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + displayFormat: customFormat, + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onChange(customFormatDateString); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(false); + }); + }); + describe('invalid date string', function () { + var invalidDateString = 'foobar'; + it('calls props.onDateChange once', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(invalidDateString); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('calls props.onDateChange with null as arg', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().onChange(invalidDateString); + (0, _chai.expect)(onDateChangeStub.getCall(0).args[0]).to.equal(null); + }); + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onChange(invalidDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('date string outside range', function () { + var isOutsideRangeStub = _sinonSandbox["default"].stub().returns(true); + + var todayDateString = today.format('DD/MM/YYYY'); + it('calls props.onDateChange once', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + isOutsideRange: isOutsideRangeStub + })); + wrapper.instance().onChange(todayDateString); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('calls props.onDateChange with null as arg', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + isOutsideRange: isOutsideRangeStub + })); + wrapper.instance().onChange(todayDateString); + (0, _chai.expect)(onDateChangeStub.getCall(0).args[0]).to.equal(null); + }); + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + isOutsideRange: isOutsideRangeStub + })); + wrapper.instance().onChange(todayDateString); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('date string is blocked', function () { + var isDayBlocked = _sinonSandbox["default"].stub().returns(true); + + var todayDateString = today.format('DD/MM/YYYY'); + it('calls props.onDateChange once', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onChange(todayDateString); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + it('calls props.onDateChange with null as arg', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {}, + isDayBlocked: isDayBlocked + })); + wrapper.instance().onChange(todayDateString); + (0, _chai.expect)(onDateChangeStub.getCall(0).args[0]).to.equal(null); + }); + }); + }); + describe('#onFocus', function () { + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: true } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onFocus(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(true); + }); + describe('props.disabled = true', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + disabled: true, + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().onFocus(); + (0, _chai.expect)(onFocusChangeStub).to.have.property('callCount', 0); + }); + }); + }); + describe('#onClearFocus', function () { + describe('props.focused = false', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: false + })); + wrapper.instance().onClearFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('props.focused = true', function () { + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: true + })); + wrapper.instance().onClearFocus(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: false } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: true + })); + wrapper.instance().onClearFocus(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(false); + }); + }); + }); + describe('#clearDate', function () { + describe('props.reopenPickerOnClearDate is truthy', function () { + describe('props.onFocusChange', function () { + it('is called once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + reopenPickerOnClearDate: true + })); + wrapper.instance().clearDate(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + }); + }); + describe('props.reopenPickerOnClearDate is falsy', function () { + describe('props.onFocusChange', function () { + it('is not called', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })); + wrapper.instance().clearDate(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + }); + it('calls props.onDateChange with null date', function () { + var onDateChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInputController["default"], { + id: "date", + onDateChange: onDateChangeStub, + onFocusChange: function onFocusChange() {} + })); + wrapper.instance().clearDate(); + (0, _chai.expect)(onDateChangeStub.callCount).to.equal(1); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/SingleDatePickerInput_spec.js b/test-build/components/SingleDatePickerInput_spec.js new file mode 100644 index 000000000..c49d364a9 --- /dev/null +++ b/test-build/components/SingleDatePickerInput_spec.js @@ -0,0 +1,135 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _SingleDatePickerInput = _interopRequireDefault(require("../../lib/components/SingleDatePickerInput")); + +var _DateInput = _interopRequireDefault(require("../../lib/components/DateInput")); + +var _defaultPhrases = require("../../lib/defaultPhrases"); + +describe('SingleDatePickerInput', function () { + describe('render', function () { + it('should render any children provided', function () { + var Child = function Child() { + return /*#__PURE__*/_react["default"].createElement("div", null, "CHILD"); + }; + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date" + }, /*#__PURE__*/_react["default"].createElement(Child, null))).dive(); + (0, _chai.expect)(wrapper.find(Child)).to.have.lengthOf(1); + }); + }); + describe('clear date', function () { + describe('props.showClearDate is falsy', function () { + it('does not render a clear date button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + showClearDate: false + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(0); + }); + }); + describe('props.showClearDate is truthy', function () { + it('has a clear date button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + showClearDate: true + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(1); + }); + }); + describe('props.customCloseIcon is a React Element', function () { + it('has custom icon', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + showClearDate: true, + customCloseIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-close-icon" + }) + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-close-icon')).to.have.lengthOf(1); + }); + }); + }); + describe('show calendar icon', function () { + describe('props.showInputIcon is falsy', function () { + it('does not have a calendar button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + showDefaultInputIcon: false + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(0); + }); + }); + describe('props.showInputIcon is truthy', function () { + it('has button', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + showDefaultInputIcon: true + })).dive(); + (0, _chai.expect)(wrapper.find('button')).to.have.lengthOf(1); + }); + }); + describe('props.customInputIcon is a React Element', function () { + it('has custom icon', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + customInputIcon: /*#__PURE__*/_react["default"].createElement("span", { + className: "custom-icon" + }) + })).dive(); + (0, _chai.expect)(wrapper.find('.custom-icon')).to.have.lengthOf(1); + }); + }); + }); + describe('clear date interactions', function () { + describe('onClick', function () { + it('props.onClearDate gets triggered', function () { + var onClearDateSpy = _sinonSandbox["default"].spy(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + onClearDate: onClearDateSpy, + showClearDate: true + })).dive(); + var clearDateWrapper = wrapper.find('button'); + clearDateWrapper.simulate('click'); + (0, _chai.expect)(onClearDateSpy).to.have.property('called', true); + }); + }); + }); + describe('screen reader message', function () { + describe('props.screenReaderMessage is falsy', function () { + it('default value is passed to DateInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date" + })).dive(); + var dateInput = wrapper.find(_DateInput["default"]); + (0, _chai.expect)(dateInput).to.have.lengthOf(1); + (0, _chai.expect)(dateInput.props()).to.have.property('screenReaderMessage', _defaultPhrases.SingleDatePickerInputPhrases.keyboardForwardNavigationInstructions); + }); + }); + describe('props.screenReaderMessage is truthy', function () { + it('prop value is passed to DateInput', function () { + var message = 'test message'; + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePickerInput["default"], { + id: "date", + screenReaderMessage: message + })).dive(); + var dateInput = wrapper.find(_DateInput["default"]); + (0, _chai.expect)(dateInput).to.have.lengthOf(1); + (0, _chai.expect)(dateInput.props()).to.have.property('screenReaderMessage', message); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/components/SingleDatePicker_spec.js b/test-build/components/SingleDatePicker_spec.js new file mode 100644 index 000000000..aeb470725 --- /dev/null +++ b/test-build/components/SingleDatePicker_spec.js @@ -0,0 +1,624 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); + +var _react = _interopRequireDefault(require("react")); + +var _chai = require("chai"); + +var _enzyme = require("enzyme"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _reactPortal = require("react-portal"); + +var _CloseButton = _interopRequireDefault(require("../../lib/components/CloseButton")); + +var _DayPickerSingleDateController = _interopRequireDefault(require("../../lib/components/DayPickerSingleDateController")); + +var _SingleDatePickerInputController = _interopRequireDefault(require("../../lib/components/SingleDatePickerInputController")); + +var _SingleDatePicker = _interopRequireWildcard(require("../../lib/components/SingleDatePicker")); + +var _describeIfWindow = _interopRequireDefault(require("../_helpers/describeIfWindow")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +describe('SingleDatePicker', function () { + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + describe('#render', function () { + describe('SingleDatePickerInputController', function () { + it('renders a SingleDatePickerInputController', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + })).dive(); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInputController["default"])).to.have.lengthOf(1); + }); + it('renders with a DayPickerSingleDateController child when focused', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + focused: true + })).dive(); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInputController["default"])).to.have.property('children'); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInputController["default"]).find(_DayPickerSingleDateController["default"])).to.have.lengthOf(1); + }); + describe('props.isOutsideRange is defined', function () { + it('should pass props.isOutsideRange to ', function () { + var isOutsideRange = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + isOutsideRange: isOutsideRange + })).dive(); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInputController["default"]).prop('isOutsideRange')).to.equal(isOutsideRange); + }); + }); + describe('props.isDayBlocked is defined', function () { + it('should pass props.isDayBlocked to ', function () { + var isDayBlocked = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + isDayBlocked: isDayBlocked + })).dive(); + (0, _chai.expect)(wrapper.find(_SingleDatePickerInputController["default"]).prop('isDayBlocked')).to.equal(isDayBlocked); + }); + }); + }); + describe('DayPickerSingleDateController', function () { + describe('props.focused === true', function () { + it('renders a ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: true + })).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerSingleDateController["default"])).to.have.lengthOf(1); + }); + }); + describe('props.focused === false', function () { + it('does not render a ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: false + })).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerSingleDateController["default"])).to.have.lengthOf(0); + }); + }); + describe('props.onClose is defined', function () { + it('should pass props.onClose in to ', function () { + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: true, + onClose: onCloseStub + })).dive(); + (0, _chai.expect)(wrapper.find(_DayPickerSingleDateController["default"]).prop('onClose')).to.equal(onCloseStub); + }); + }); + it('should pass onDayPickerBlur as onBlur to ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + focused: true + })).dive(); + + var _wrapper$instance = wrapper.instance(), + onDayPickerBlur = _wrapper$instance.onDayPickerBlur; + + (0, _chai.expect)(wrapper.find(_DayPickerSingleDateController["default"]).prop('onBlur')).to.equal(onDayPickerBlur); + }); + }); + describe('props.withPortal is truthy', function () { + describe('', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + withPortal: true, + focused: true + })).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(1); + }); + it('is not rendered if props.focused is falsy', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + withPortal: true + })).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(0); + }); + }); + }); + describe('props.withFullScreenPortal is truthy', function () { + it('renders CloseButton', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + withFullScreenPortal: true, + focused: true + })).dive(); + (0, _chai.expect)(wrapper.find(_CloseButton["default"])).to.have.length(1); + }); + describe('', function () { + it('is rendered', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + withFullScreenPortal: true, + focused: true + })).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(1); + }); + it('is not rendered when props.focused is falsy', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {}, + withFullScreenPortal: true + })).dive(); + (0, _chai.expect)(wrapper.find(_reactPortal.Portal)).to.have.length(0); + }); + }); + }); + describe('props.appendToBody', function () { + var requiredProps = { + onDateChange: function onDateChange() {}, + onFocusChange: function onFocusChange() {} + }; + it('renders inside ', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], (0, _extends2["default"])({}, requiredProps, { + appendToBody: true, + focused: true + }))).dive(); + var portal = wrapper.find(_reactPortal.Portal); + (0, _chai.expect)(portal).to.have.length(1); + (0, _chai.expect)(portal.find(_DayPickerSingleDateController["default"])).to.have.length(1); + }); + (0, _describeIfWindow["default"])('mounted', function () { + var wrapper; + var instance; + var onCloseStub; + beforeEach(function () { + onCloseStub = _sinonSandbox["default"].stub(); + wrapper = (0, _enzyme.mount)((0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], (0, _extends2["default"])({}, requiredProps, { + appendToBody: true, + focused: true, + onClose: onCloseStub + }))).get(0)); + instance = wrapper.instance(); + }); + it('positions using top and transform CSS properties', function () { + var dayPickerEl = instance.dayPickerContainer; + (0, _chai.expect)(dayPickerEl.style.top).not.to.equal(''); + (0, _chai.expect)(dayPickerEl.style.transform).not.to.equal(''); + }); + it('disables scroll', function () { + (0, _chai.expect)(instance.enableScroll).to.be.a('function'); + }); + it('ignores click events from inside picker', function () { + var event = { + target: instance.dayPickerContainer + }; + instance.onOutsideClick(event); + (0, _chai.expect)(onCloseStub.callCount).to.equal(0); + }); + it('enables scroll when closed', function () { + var enableScrollSpy = _sinonSandbox["default"].spy(instance, 'enableScroll'); + + wrapper.setProps({ + focused: false + }); + (0, _chai.expect)(enableScrollSpy.callCount).to.equal(1); + }); + it('enables scroll when unmounted', function () { + var enableScrollSpy = _sinonSandbox["default"].spy(instance, 'enableScroll'); + + wrapper.unmount(); + (0, _chai.expect)(enableScrollSpy.callCount).to.equal(1); + }); + }); + }); + }); + describe('#onInputFocus', function () { + var onDayPickerFocusSpy; + var onDayPickerBlurSpy; + beforeEach(function () { + onDayPickerFocusSpy = _sinonSandbox["default"].spy(_SingleDatePicker.PureSingleDatePicker.prototype, 'onDayPickerFocus'); + onDayPickerBlurSpy = _sinonSandbox["default"].spy(_SingleDatePicker.PureSingleDatePicker.prototype, 'onDayPickerBlur'); + }); + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: true } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(true); + }); + it('calls onDayPickerFocus if withPortal', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + withPortal: true + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if withFullScreenPortal', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + withFullScreenPortal: true + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + readOnly: true + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if isTouchDevice', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.instance().isTouchDevice = true; + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerBlur if isTouchDevice and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true + })).dive(); + wrapper.instance().isTouchDevice = true; + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerBlurSpy.callCount).to.equal(1); + }); + it('calls onDayPickerBlur if !withPortal/!withFullScreenPortal and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true + })).dive(); + wrapper.instance().isTouchDevice = true; + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerBlurSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if withPortal/withFullScreenPortal and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true, + withFullScreenPortal: true + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerFocus if readOnly and keepFocusOnInput', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + keepFocusOnInput: true, + withFullScreenPortal: true + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerFocusSpy.callCount).to.equal(1); + }); + it('calls onDayPickerBlur if !withPortal/!withFullScreenPortal/!readOnly', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.instance().onInputFocus({ + focused: true + }); + (0, _chai.expect)(onDayPickerBlurSpy.callCount).to.equal(1); + }); + }); + describe('#onOutsideClick', function () { + describe('props.focused = false', function () { + it('does not call props.onFocusChange', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: false + })).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + }); + describe('props.focused = true', function () { + it('sets state.isDayPickerFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focused: true + })).dive(); + wrapper.setState({ + isDayPickerFocused: true + }); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(false); + }); + it('sets state.isInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub(), + focused: true + })).dive(); + wrapper.setState({ + isInputFocused: true + }); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(wrapper.state().isInputFocused).to.equal(false); + }); + it('calls props.onFocusChange once', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: true + })).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + }); + it('calls props.onFocusChange with { focused: false } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: true + })).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0].focused).to.equal(false); + }); + it('calls props.onClose with { date: "08-06-2019" } as arg', function () { + var onFocusChangeStub = _sinonSandbox["default"].stub(); + + var onCloseStub = _sinonSandbox["default"].stub(); + + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onClose: onCloseStub, + onDateChange: function onDateChange() {}, + onFocusChange: onFocusChangeStub, + focused: true, + date: "08-06-2019" + })).dive(); + wrapper.instance().onOutsideClick(); + (0, _chai.expect)(onCloseStub.getCall(0).args[0].date).to.equal('08-06-2019'); + }); + }); + }); + describe('#onDayPickerFocus', function () { + it('sets state.isDayPickerFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isDayPickerFocused: false + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(true); + }); + it('sets state.isInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isInputFocused: true + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().isInputFocused).to.equal(false); + }); + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().onDayPickerFocus(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + }); + describe('#onDayPickerBlur', function () { + it('sets state.isDayPickerFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isDayPickerFocused: true + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(false); + }); + it('sets state.isInputFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isInputFocused: false + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().isInputFocused).to.equal(true); + }); + it('sets state.showKeyboardShortcuts to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + showKeyboardShortcuts: true + }); + wrapper.instance().onDayPickerBlur(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(false); + }); + }); + describe('#showKeyboardShortcutsPanel', function () { + it('sets state.isInputFocused to false', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isInputFocused: true + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().isInputFocused).to.equal(false); + }); + it('sets state.isDayPickerFocused to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + isDayPickerFocused: false + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().isDayPickerFocused).to.equal(true); + }); + it('sets state.showKeyboardShortcuts to true', function () { + var wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + onDateChange: _sinonSandbox["default"].stub(), + onFocusChange: _sinonSandbox["default"].stub() + })).dive(); + wrapper.setState({ + showKeyboardShortcuts: false + }); + wrapper.instance().showKeyboardShortcutsPanel(); + (0, _chai.expect)(wrapper.state().showKeyboardShortcuts).to.equal(true); + }); + }); + (0, _describeIfWindow["default"])('#onFocusOut', function () { + var wrapper; + var ctrl; + var onFocusChangeStub; + var dpcContainsStub; + beforeEach(function () { + onFocusChangeStub = _sinonSandbox["default"].stub(); + dpcContainsStub = _sinonSandbox["default"].stub(); + wrapper = (0, _enzyme.shallow)( /*#__PURE__*/_react["default"].createElement(_SingleDatePicker["default"], { + id: "date", + onFocusChange: onFocusChangeStub + })).dive(); + ctrl = wrapper.instance(); + ctrl.dayPickerContainer = { + contains: dpcContainsStub.returns(true) + }; + }); + afterEach(function () { + onFocusChangeStub.reset(); + dpcContainsStub.reset(); + }); + it('calls props.onFocusChange with focused: false when dayPickerContainer does not contain the target', function () { + dpcContainsStub.returns(false); + ctrl.onFocusOut({}); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(1); + (0, _chai.expect)(onFocusChangeStub.getCall(0).args[0]).to.deep.equal({ + focused: false + }); + }); + it('should not call props.onFocusChange when dayPickerContainer contains the target', function () { + ctrl.onFocusOut({}); + (0, _chai.expect)(onFocusChangeStub.callCount).to.equal(0); + }); + it('should check the target when related target is the same as the document body', function () { + var event = { + relatedTarget: document.body, + target: 'target' + }; + ctrl.onFocusOut(event); + (0, _chai.expect)(dpcContainsStub.getCall(0).args[0]).to.equal(event.target); + }); + it('should check the target when related target is defined', function () { + var event = { + relatedTarget: 'related target', + target: 'target' + }; + ctrl.onFocusOut(event); + (0, _chai.expect)(dpcContainsStub.getCall(0).args[0]).to.equal(event.relatedTarget); + }); + it('should check the target when related target is not defined', function () { + var event = { + relatedTarget: undefined, + target: 'target' + }; + ctrl.onFocusOut(event); + (0, _chai.expect)(dpcContainsStub.getCall(0).args[0]).to.equal(event.target); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/calculateDimension_spec.js b/test-build/utils/calculateDimension_spec.js new file mode 100644 index 000000000..b51aa0ca2 --- /dev/null +++ b/test-build/utils/calculateDimension_spec.js @@ -0,0 +1,65 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _calculateDimension = _interopRequireDefault(require("../../lib/utils/calculateDimension")); + +describe('#calculateDimension', function () { + it('returns 0 for an empty element', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(null, 'width')).to.equal(0); + (0, _chai.expect)((0, _calculateDimension["default"])(null, 'width', false)).to.equal(0); + (0, _chai.expect)((0, _calculateDimension["default"])(null, 'width', true)).to.equal(0); + }); + describe('borderBox true', function () { + var el = { + offsetWidth: 17, + offsetHeight: 42 + }; + it('returns el.offsetWidth for "width"', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(el, 'width', true)).to.equal(el.offsetWidth); + }); + it('returns el.offsetHeight for "height"', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(el, 'height', true)).to.equal(el.offsetHeight); + }); + }); + /* Requires a DOM */ + + describe.skip('withMargin false and borderBox true', function () { + var testElement = null; + beforeEach(function () { + testElement = document.createElement('div'); + testElement.style.width = '100px'; + testElement.style.height = '250px'; + testElement.style.padding = '15px 10px'; + testElement.style.border = '1px solid red'; + testElement.style.margin = '3px 6px 5px 2px'; + testElement.boxSizing = 'border-box'; + }); + it('calculates border-box height', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'height', true)).to.equal(282); + }); + it('calculates border-box height with margin', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'height', true, true)).to.equal(290); + }); + it('calculates border-box width', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'width', true)).to.equal(122); + }); + it('calculates border-box width with margin', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'width', true, true)).to.equal(130); + }); + it('calculates content-box height', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'height')).to.equal(250); + }); + it('calculates content-box height with margin', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'height', false, true)).to.equal(258); + }); + it('calculates content-box width', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'width')).to.equal(100); + }); + it('calculates content-box width with margin', function () { + (0, _chai.expect)((0, _calculateDimension["default"])(testElement, 'width', false, true)).to.equal(108); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/disableScroll_spec.js b/test-build/utils/disableScroll_spec.js new file mode 100644 index 000000000..5b47cb169 --- /dev/null +++ b/test-build/utils/disableScroll_spec.js @@ -0,0 +1,187 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof = require("@babel/runtime/helpers/typeof"); + +var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); + +var _chai = require("chai"); + +var _disableScroll = _interopRequireWildcard(require("../../lib/utils/disableScroll")); + +var _describeIfWindow = _interopRequireDefault(require("../_helpers/describeIfWindow")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +var createScrollContainer = function createScrollContainer() { + var level = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + var el = document.createElement('div'); + el.style.width = '300px'; + el.style.height = "".concat(level * 100, "px"); + el.style.overflow = 'auto'; + return el; +}; + +var createScrollContent = function createScrollContent() { + var el = document.createElement('div'); + el.style.width = '100%'; + el.style.height = '99999px'; + return el; +}; + +var createTargetElement = function createTargetElement() { + var el = document.createElement('div'); + return el; +}; + +(0, _describeIfWindow["default"])('#disableScroll', function () { + var grandParentScrollContainer; + var parentScrollContainer; + var scrollContent; + var targetElement; + before(function () { + grandParentScrollContainer = createScrollContainer(1); + parentScrollContainer = createScrollContainer(2); + scrollContent = createScrollContent(); + targetElement = createTargetElement(); + scrollContent.appendChild(targetElement); + }); + describe('#getScrollParent', function () { + describe('with no parent', function () { + before(function () { + document.body.appendChild(scrollContent); + }); + after(function () { + document.body.removeChild(scrollContent); + }); + it('returns scrolling root if no scroll parent', function () { + var scrollParent = (0, _disableScroll.getScrollParent)(targetElement); + (0, _chai.expect)(scrollParent).to.equal(document.documentElement); + }); + }); + describe('with a single scroll container', function () { + before(function () { + parentScrollContainer.appendChild(scrollContent); + document.body.appendChild(parentScrollContainer); + }); + after(function () { + parentScrollContainer.appendChild(scrollContent); + document.body.removeChild(parentScrollContainer); + }); + it('returns the scroll container', function () { + var scrollParent = (0, _disableScroll.getScrollParent)(targetElement); + (0, _chai.expect)(scrollParent).to.equal(parentScrollContainer); + }); + }); + describe('with multiple scroll containers', function () { + before(function () { + parentScrollContainer.appendChild(scrollContent); + grandParentScrollContainer.appendChild(parentScrollContainer); + document.body.appendChild(grandParentScrollContainer); + }); + after(function () { + parentScrollContainer.removeChild(scrollContent); + grandParentScrollContainer.removeChild(parentScrollContainer); + document.body.removeChild(grandParentScrollContainer); + }); + it('returns the closest scroll container', function () { + var scrollParent = (0, _disableScroll.getScrollParent)(targetElement); + (0, _chai.expect)(scrollParent).to.equal(parentScrollContainer); + }); + }); + }); + describe('#getScrollAncestorsOverflowY', function () { + before(function () { + parentScrollContainer.appendChild(scrollContent); + grandParentScrollContainer.appendChild(parentScrollContainer); + document.body.appendChild(grandParentScrollContainer); + }); + after(function () { + parentScrollContainer.removeChild(scrollContent); + grandParentScrollContainer.removeChild(parentScrollContainer); + document.body.removeChild(grandParentScrollContainer); + }); + it('returns a map with the overflowY of all scrollable ancestors', function () { + var scrollAncestorsOverflowY = (0, _disableScroll.getScrollAncestorsOverflowY)(targetElement); + (0, _chai.expect)(scrollAncestorsOverflowY.size).to.equal(3); // both scroll containers + root + + (0, _chai.expect)(scrollAncestorsOverflowY.has(parentScrollContainer)).to.equal(true); + (0, _chai.expect)(scrollAncestorsOverflowY.has(grandParentScrollContainer)).to.equal(true); + (0, _chai.expect)(scrollAncestorsOverflowY.has(document.documentElement)).to.equal(true); + (0, _chai.expect)(scrollAncestorsOverflowY.get(parentScrollContainer)).to.equal('auto'); + (0, _chai.expect)(scrollAncestorsOverflowY.get(grandParentScrollContainer)).to.equal('auto'); + (0, _chai.expect)(scrollAncestorsOverflowY.get(document.documentElement)).to.be.a('string'); + }); + }); + describe('#disableScroll', function () { + before(function () { + parentScrollContainer.appendChild(scrollContent); + grandParentScrollContainer.appendChild(parentScrollContainer); + document.body.appendChild(grandParentScrollContainer); + }); + after(function () { + parentScrollContainer.removeChild(scrollContent); + grandParentScrollContainer.removeChild(parentScrollContainer); + document.body.removeChild(grandParentScrollContainer); + }); + describe('disable', function () { + it('should set all scroll ancestors overflow to hidden', function () { + var enableScroll = (0, _disableScroll["default"])(targetElement); + var scrollAncestorsOverflowY = (0, _disableScroll.getScrollAncestorsOverflowY)(targetElement); // eslint-disable-next-line no-restricted-syntax + + var _iterator = _createForOfIteratorHelper(scrollAncestorsOverflowY), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var _step$value = (0, _slicedToArray2["default"])(_step.value, 2), + overflowY = _step$value[1]; + + (0, _chai.expect)(overflowY).to.equal('hidden'); + } // reset to initial state + + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + enableScroll(); + }); + }); + describe('enable', function () { + it('should set all scroll ancestors overflow to their previous value', function () { + var scrollAncestorsOverflowYBefore = (0, _disableScroll.getScrollAncestorsOverflowY)(targetElement); + var enableScroll = (0, _disableScroll["default"])(targetElement); + enableScroll(); + var scrollAncestorsOverflowY = (0, _disableScroll.getScrollAncestorsOverflowY)(targetElement); // eslint-disable-next-line no-restricted-syntax + + var _iterator2 = _createForOfIteratorHelper(scrollAncestorsOverflowY), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var _step2$value = (0, _slicedToArray2["default"])(_step2.value, 2), + element = _step2$value[0], + overflowY = _step2$value[1]; + + (0, _chai.expect)(scrollAncestorsOverflowYBefore.get(element)).to.equal(overflowY); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getActiveElement_spec.js b/test-build/utils/getActiveElement_spec.js new file mode 100644 index 000000000..ae6537220 --- /dev/null +++ b/test-build/utils/getActiveElement_spec.js @@ -0,0 +1,36 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); + +var _chai = require("chai"); + +var _mochaWrap = _interopRequireDefault(require("mocha-wrap")); + +var _getActiveElement = _interopRequireDefault(require("../../lib/utils/getActiveElement")); + +var describeIfNoWindow = typeof document === 'undefined' ? describe : describe.skip; +var test = 'FOOBARBAZ'; +describeIfNoWindow('getActiveElement', function () { + describe('without `document`', function () { + it('returns false', function () { + (0, _chai.expect)(typeof document === "undefined" ? "undefined" : (0, _typeof2["default"])(document)).to.equal('undefined'); + (0, _chai.expect)((0, _getActiveElement["default"])()).to.equal(false); + }); + }); + (0, _mochaWrap["default"])().withGlobal('document', function () { + return {}; + }).describe('with `document`', function () { + it('returns undefined without `document.activeElement`', function () { + (0, _chai.expect)((0, _getActiveElement["default"])()).to.be.an('undefined'); + }); + (0, _mochaWrap["default"])().withOverride(function () { + return document; + }, 'activeElement', function () { + return test; + }).it('returns activeElement value with `document.activeElement', function () { + (0, _chai.expect)((0, _getActiveElement["default"])()).to.equal(test); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getCalendarDaySettings_spec.js b/test-build/utils/getCalendarDaySettings_spec.js new file mode 100644 index 000000000..9a783458e --- /dev/null +++ b/test-build/utils/getCalendarDaySettings_spec.js @@ -0,0 +1,202 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _getCalendarDaySettings = _interopRequireDefault(require("../../lib/utils/getCalendarDaySettings")); + +var _constants = require("../../lib/constants"); + +var testDay = (0, _moment["default"])('10/10/2017', 'MM/DD/YYYY'); +var expectedFormattedDay = { + date: 'Tuesday, October 10, 2017' +}; +var testAriaLabelFormat = 'dddd, LL'; +var testDaySize = 39; +var testModifiers = new Set(); +var testPhrases = { + chooseAvailableDate: _sinonSandbox["default"].stub(), + dateIsSelected: _sinonSandbox["default"].stub(), + dateIsUnavailable: _sinonSandbox["default"].stub(), + dateIsSelectedAsStartDate: _sinonSandbox["default"].stub(), + dateIsSelectedAsEndDate: _sinonSandbox["default"].stub() +}; +describe('getCalendarDaySettings', function () { + describe('daySizeStyles', function () { + var _getCalendarDaySettin = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, testModifiers, testPhrases), + daySizeStyles = _getCalendarDaySettin.daySizeStyles; + + it('includes width equal to daySize', function () { + (0, _chai.expect)(daySizeStyles.width).to.equal(testDaySize); + }); + it('includes height equal to daySize - 1', function () { + (0, _chai.expect)(daySizeStyles.height).to.equal(testDaySize - 1); + }); + }); + describe('useDefaultCursor', function () { + it('should be true when day is some kind of blocked', function () { + var blockedModifiers = new Set(['blocked-minimum-nights', 'blocked-calendar', 'blocked-out-of-range']); + blockedModifiers.forEach(function (blockedModifier) { + var modifiers = new Set([blockedModifier]); + + var _getCalendarDaySettin2 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + useDefaultCursor = _getCalendarDaySettin2.useDefaultCursor; + + (0, _chai.expect)(useDefaultCursor).to.equal(true); + }); + }); + it('should be false when day is not blocked', function () { + var modifiers = new Set(['some-kind-of-not-blocked']); + + var _getCalendarDaySettin3 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + useDefaultCursor = _getCalendarDaySettin3.useDefaultCursor; + + (0, _chai.expect)(useDefaultCursor).to.equal(false); + }); + }); + describe('selected', function () { + it('should be true when day is some kind of selected', function () { + var selectedModifiers = new Set(['selected', 'selected-start', 'selected-end']); + selectedModifiers.forEach(function (selectedModifier) { + var modifiers = new Set([selectedModifier]); + + var _getCalendarDaySettin4 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + selected = _getCalendarDaySettin4.selected; + + (0, _chai.expect)(selected).to.equal(true); + }); + }); + it('should be false when day is not selected', function () { + var modifiers = new Set(['some-kind-of-not-selected']); + + var _getCalendarDaySettin5 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + selected = _getCalendarDaySettin5.selected; + + (0, _chai.expect)(selected).to.equal(false); + }); + }); + describe('hoveredSpan', function () { + it('should be true when day is not selected and hovered-span', function () { + var modifiers = new Set(['hovered-span']); + + var _getCalendarDaySettin6 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + hoveredSpan = _getCalendarDaySettin6.hoveredSpan; + + (0, _chai.expect)(hoveredSpan).to.equal(true); + }); + it('should be true when day is not selected and after-hovered-start', function () { + var modifiers = new Set(['hovered-span']); + + var _getCalendarDaySettin7 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + hoveredSpan = _getCalendarDaySettin7.hoveredSpan; + + (0, _chai.expect)(hoveredSpan).to.equal(true); + }); + it('should be false when day is some kind of selected', function () { + var selectedModifiers = new Set(['selected', 'selected-start', 'selected-end']); + selectedModifiers.forEach(function (selectedModifier) { + var modifiers = new Set([selectedModifier]); + + var _getCalendarDaySettin8 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + hoveredSpan = _getCalendarDaySettin8.hoveredSpan; + + (0, _chai.expect)(hoveredSpan).to.equal(false); + }); + }); + }); + describe('isOutsideRange', function () { + it('should be true when blocked-out-of-range', function () { + var modifiers = new Set(['blocked-out-of-range']); + + var _getCalendarDaySettin9 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + isOutsideRange = _getCalendarDaySettin9.isOutsideRange; + + (0, _chai.expect)(isOutsideRange).to.equal(true); + }); + it('should be false when not blocked-out-of-range', function () { + var modifiers = new Set(); + + var _getCalendarDaySettin10 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, testPhrases), + isOutsideRange = _getCalendarDaySettin10.isOutsideRange; + + (0, _chai.expect)(isOutsideRange).to.equal(false); + }); + }); + describe('ariaLabel', function () { + var phrases = {}; + beforeEach(function () { + phrases.chooseAvailableDate = _sinonSandbox["default"].stub().returns('chooseAvailableDate text'); + phrases.dateIsSelected = _sinonSandbox["default"].stub().returns('dateIsSelected text'); + phrases.dateIsUnavailable = _sinonSandbox["default"].stub().returns('dateIsUnavailable text'); + phrases.dateIsSelectedAsStartDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsStartDate text'); + phrases.dateIsSelectedAsEndDate = _sinonSandbox["default"].stub().returns('dateIsSelectedAsEndDate text'); + }); + afterEach(function () { + _sinonSandbox["default"].restore(); + }); + it('is formatted with the chooseAvailableDate phrase function when day is available', function () { + var modifiers = new Set(); + + var _getCalendarDaySettin11 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin11.ariaLabel; + + (0, _chai.expect)(phrases.chooseAvailableDate.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('chooseAvailableDate text'); + }); + it('is formatted with the dateIsSelected phrase function when day is selected', function () { + var modifiers = new Set(['selected']); + + var _getCalendarDaySettin12 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin12.ariaLabel; + + (0, _chai.expect)(phrases.dateIsSelected.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('dateIsSelected text'); + }); + it('is formatted with the dateIsSelectedAsStartDate phrase function when day is selected as the start date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-start'); + + var _getCalendarDaySettin13 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin13.ariaLabel; + + (0, _chai.expect)(phrases.dateIsSelectedAsStartDate.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('dateIsSelectedAsStartDate text'); + }); + it('is formatted with the dateIsSelectedAsEndDate phrase function when day is selected as the end date', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER).add('selected-end'); + + var _getCalendarDaySettin14 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin14.ariaLabel; + + (0, _chai.expect)(phrases.dateIsSelectedAsEndDate.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('dateIsSelectedAsEndDate text'); + }); + it('is formatted with the dateIsSelected phrase function when day is selected as the start or end date and no selected start or end date phrase function is specified', function () { + phrases.dateIsSelectedAsStartDate = null; + phrases.dateIsSelectedAsEndDate = null; + var selectedModifiers = new Set(['selected-end', 'selected-start']); + selectedModifiers.forEach(function (selectedModifier) { + var modifiers = new Set([selectedModifier]); + + var _getCalendarDaySettin15 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin15.ariaLabel; + + (0, _chai.expect)(phrases.dateIsSelected.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('dateIsSelected text'); + }); + }); + it('is formatted with the dateIsUnavailable phrase function when day is not available', function () { + var modifiers = new Set().add(_constants.BLOCKED_MODIFIER); + + var _getCalendarDaySettin16 = (0, _getCalendarDaySettings["default"])(testDay, testAriaLabelFormat, testDaySize, modifiers, phrases), + ariaLabel = _getCalendarDaySettin16.ariaLabel; + + (0, _chai.expect)(phrases.dateIsUnavailable.calledWith(expectedFormattedDay)).to.equal(true); + (0, _chai.expect)(ariaLabel).to.equal('dateIsUnavailable text'); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getCalendarMonthWeeks_spec.js b/test-build/utils/getCalendarMonthWeeks_spec.js new file mode 100644 index 000000000..5d52c97cf --- /dev/null +++ b/test-build/utils/getCalendarMonthWeeks_spec.js @@ -0,0 +1,262 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var _getCalendarMonthWeeks = _interopRequireDefault(require("../../lib/utils/getCalendarMonthWeeks")); + +var today = (0, _moment["default"])(); +var weeks = (0, _getCalendarMonthWeeks["default"])(today); +var weeksWithOutsideDays = (0, _getCalendarMonthWeeks["default"])(today, true); +describe('getCalendarMonthWeeks', function () { + describe('input validation', function () { + it('throws a TypeError if first arg is not a valid moment object', function () { + var invalidValues = [null, '2017-01-01T00:00:00Z', new Date(), _moment["default"].invalid()]; + invalidValues.forEach(function (value) { + (0, _chai.expect)(function () { + return (0, _getCalendarMonthWeeks["default"])(value); + }).to["throw"](TypeError, '`month` must be a valid moment object'); + }); + }); + it('throws a TypeError if third arg is not an integer between 0 and 6', function () { + var invalidValues = [null, -1, 7, '0', '1', 1.5]; + invalidValues.forEach(function (value) { + (0, _chai.expect)(function () { + return (0, _getCalendarMonthWeeks["default"])(today, true, value); + }).to["throw"](TypeError, '`firstDayOfWeek` must be an integer between 0 and 6'); + }); + }); + }); + it('returns an array of arrays', function () { + (0, _chai.expect)(weeks).to.be["instanceof"](Array); + weeks.forEach(function (week) { + (0, _chai.expect)(week).to.be["instanceof"](Array); + }); + }); + it('today is included', function () { + var isIncluded = false; + weeks.forEach(function (week) { + week.forEach(function (day) { + if (day && day.isSame(today, 'day')) isIncluded = true; + }); + }); + (0, _chai.expect)(isIncluded).to.equal(true); + }); + it('all days have a time of 12PM', function () { + weeks.forEach(function (week) { + week.forEach(function (day) { + if (day) { + (0, _chai.expect)(day.hours()).to.equal(12); + } + }); + }); + }); + describe('padding when enableOutsideDays is false', function () { + var weeksWithPadding; + beforeEach(function () { + // using specific month Feb 2017 to manually compare with calendar + weeksWithPadding = (0, _getCalendarMonthWeeks["default"])((0, _moment["default"])('2017-02-01'), false); + }); + it('null pads leading days', function () { + var firstWeek = weeksWithPadding[0]; + (0, _chai.expect)(firstWeek[0]).to.equal(null); // Sun Jan 29 + + (0, _chai.expect)(firstWeek[1]).to.equal(null); // Mon Jan 30 + + (0, _chai.expect)(firstWeek[2]).to.equal(null); // Tue Jan 31 + + (0, _chai.expect)(firstWeek[3]).to.not.equal(null); // Wed Feb 1 + }); + it('null pads trailing days', function () { + var lastWeek = weeksWithPadding[weeksWithPadding.length - 1]; + (0, _chai.expect)(lastWeek[2]).to.not.equal(null); // Tue Feb 28 + + (0, _chai.expect)(lastWeek[3]).to.equal(null); // Wed Mar 1 + + (0, _chai.expect)(lastWeek[4]).to.equal(null); // Thu Mar 2 + + (0, _chai.expect)(lastWeek[5]).to.equal(null); // Fri Mar 3 + + (0, _chai.expect)(lastWeek[6]).to.equal(null); // Sat Mar 4 + }); + }); + describe('Daylight Savings Time issues', function () { + it('last of February does not equal first of March', function () { + var february = (0, _getCalendarMonthWeeks["default"])(today.clone().month(1)); + var lastWeekOfFebruary = february[february.length - 1].filter(Boolean); + var lastOfFebruary = lastWeekOfFebruary[lastWeekOfFebruary.length - 1]; + var march = (0, _getCalendarMonthWeeks["default"])(today.clone().month(2)); + var firstOfMarch = march[0].filter(Boolean)[0]; + (0, _chai.expect)((0, _isSameDay["default"])(lastOfFebruary, firstOfMarch)).to.equal(false); + }); + it('last of March does not equal first of April', function () { + var march = (0, _getCalendarMonthWeeks["default"])(today.clone().month(2)); + var lastWeekOfMarch = march[march.length - 1].filter(Boolean); + var lastOfMarch = lastWeekOfMarch[lastWeekOfMarch.length - 1]; + var april = (0, _getCalendarMonthWeeks["default"])(today.clone().month(3)); + var firstOfApril = april[0].filter(Boolean)[0]; + (0, _chai.expect)((0, _isSameDay["default"])(lastOfMarch, firstOfApril)).to.equal(false); + }); + }); + describe('enableOutsideDays arg is false', function () { + it('first non-null element is first of the month', function () { + var firstOfMonth = today.clone().startOf('month'); + var firstNonNullDay = weeks[0].filter(function (day) { + return day; + })[0]; + (0, _chai.expect)(firstOfMonth.isSame(firstNonNullDay, 'day')).to.equal(true); + }); + it('last non-null element is last of the month', function () { + var lastOfMonth = today.clone().endOf('month'); + var lastWeek = weeks[weeks.length - 1].filter(function (day) { + return day; + }); + var lastNonNullDay = lastWeek[lastWeek.length - 1]; + (0, _chai.expect)(lastOfMonth.isSame(lastNonNullDay, 'day')).to.equal(true); + }); + it('number of non-null elements is equal to number of days in month', function () { + var daysInCalendarMonthWeeks = weeks.reduce(function (a, b) { + return a + b.filter(function (day) { + return day; + }).length; + }, 0); + (0, _chai.expect)(daysInCalendarMonthWeeks).to.equal(today.daysInMonth()); + }); + }); + describe('enableOutsideDays arg is true', function () { + it('contains first of the month', function () { + var firstOfMonth = today.clone().startOf('month'); + var containsFirstOfMonth = weeksWithOutsideDays[0].filter(function (day) { + return firstOfMonth.isSame(day, 'day'); + }).length > 0; + (0, _chai.expect)(containsFirstOfMonth).to.equal(true); + }); + it('last week contains last of the month', function () { + var lastOfMonth = today.clone().endOf('month'); + var containsLastOfMonth = weeks[weeksWithOutsideDays.length - 1].filter(function (day) { + return lastOfMonth.isSame(day, 'day'); + }).length > 0; + (0, _chai.expect)(containsLastOfMonth).to.equal(true); + }); + it('last week contains last of the month if next month begins on Sunday', function () { + var december2016 = (0, _moment["default"])('2016-12-01'); + var lastOfMonth = december2016.clone().endOf('month'); + var weeksInDecember = (0, _getCalendarMonthWeeks["default"])(december2016); + var containsLastOfMonth = weeksInDecember[weeksInDecember.length - 1].filter(function (day) { + return lastOfMonth.isSame(day, 'day'); + }).length > 0; + (0, _chai.expect)(containsLastOfMonth).to.equal(true); + }); + it('last week contains last of the month if next month begins on Monday', function () { + _moment["default"].locale('es'); + + var april2017 = (0, _moment["default"])('2017-04-01'); + var lastOfMonth = april2017.clone().endOf('month'); + var weeksInApril = (0, _getCalendarMonthWeeks["default"])(april2017); + var containsLastOfMonth = weeksInApril[weeksInApril.length - 1].filter(function (day) { + return lastOfMonth.isSame(day, 'day'); + }).length > 0; + (0, _chai.expect)(containsLastOfMonth).to.equal(true); + }); + it('last week contains last of the month if next month begins on Saturday', function () { + var september2016 = (0, _moment["default"])('2016-09-01'); + var lastOfMonth = september2016.clone().endOf('month'); + var weeksInSeptember = (0, _getCalendarMonthWeeks["default"])(september2016); + var containsLastOfMonth = weeksInSeptember[weeksInSeptember.length - 1].filter(function (day) { + return lastOfMonth.isSame(day, 'day'); + }).length > 0; + (0, _chai.expect)(containsLastOfMonth).to.equal(true); + }); + it('each week has 7 non-null elements', function () { + var hasNoNullElements = weeksWithOutsideDays.reduce(function (w1, w2) { + return w1 && w2.reduce(function (d1, d2) { + return d1 && !!d2; + }, true); + }, true); + (0, _chai.expect)(hasNoNullElements).to.equal(true); + }); + }); + describe('setting firstDayOfWeek argument', function () { + // using these known dates to see if they appear at the right position of the calendar + // trying different firstDayOfWeek values + var january2017Start = (0, _moment["default"])('2017-01-01'); // Sunday + + var january2017End = january2017Start.clone().endOf('month'); // Tuesday + + it('month starts at [0][0] when first day is Sunday and first day of week is Sunday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start, false, 0); // 0: Sun + + var firstDayOfMonth = weeksInJanuary2017[0][0]; + var rightPosition = january2017Start.isSame(firstDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + it('month ends at [n][2] when last day is Tuesday and first day of week is Sunday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start, false, 0); // 0: Sun + + var lastDayOfMonth = weeksInJanuary2017[weeksInJanuary2017.length - 1][2]; + var rightPosition = january2017End.isSame(lastDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + it('month starts at [0][4] when first day is Sunday and first day of week is Wednesday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start, false, 3); // 3: Wed + + var firstDayOfMonth = weeksInJanuary2017[0][4]; + var rightPosition = january2017Start.isSame(firstDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + it('month ends at [n][6] when last day is Tuesday and first day of week is Wednesday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start, false, 3); // 3: Wed + + var lastDayOfMonth = weeksInJanuary2017[weeksInJanuary2017.length - 1][6]; + var rightPosition = january2017End.isSame(lastDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + }); + describe('firstDayOfWeek default value locale-aware', function () { + // using these known dates to see if they appear at the right position of the calendar + // trying different firstDayOfWeek values + var january2017Start = (0, _moment["default"])('2017-01-01'); // Sunday + + var january2017End = january2017Start.clone().endOf('month'); // Tuesday + + describe('locale with Sunday as first day of week', function () { + beforeEach(function () { + _moment["default"].locale('en'); + }); + it('month starts at [0][0] if first day is Sunday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start); + var firstDayOfMonth = weeksInJanuary2017[0][0]; + var rightPosition = january2017Start.isSame(firstDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + it('month ends at [n][2] if last day is Tuesday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start); + var lastDayOfMonth = weeksInJanuary2017[weeksInJanuary2017.length - 1][2]; + var rightPosition = january2017End.isSame(lastDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + }); + describe('locale with Monday as first day of week', function () { + beforeEach(function () { + _moment["default"].locale('es'); + }); + it('month starts at [0][6] if first day is Sunday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start); + var firstDayOfMonth = weeksInJanuary2017[0][6]; + var rightPosition = january2017Start.isSame(firstDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + it('month ends at [n][1] if last day is Tuesday', function () { + var weeksInJanuary2017 = (0, _getCalendarMonthWeeks["default"])(january2017Start); + var lastDayOfMonth = weeksInJanuary2017[weeksInJanuary2017.length - 1][1]; + var rightPosition = january2017End.isSame(lastDayOfMonth, 'day'); + (0, _chai.expect)(rightPosition).to.equal(true); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getCalendarMonthWidth_spec.js b/test-build/utils/getCalendarMonthWidth_spec.js new file mode 100644 index 000000000..1ec27ad74 --- /dev/null +++ b/test-build/utils/getCalendarMonthWidth_spec.js @@ -0,0 +1,19 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _getCalendarMonthWidth = _interopRequireDefault(require("../../lib/utils/getCalendarMonthWidth")); + +describe('#getCalendarMonthWidth', function () { + it('correctly calculates width for default day size of 39', function () { + (0, _chai.expect)((0, _getCalendarMonthWidth["default"])(39, 13)).to.equal(300); + }); + it('returns a number when padding is undefined', function () { + (0, _chai.expect)(Number.isNaN((0, _getCalendarMonthWidth["default"])(39, undefined))).to.equal(false); + }); + it('returns a number when padding is null', function () { + (0, _chai.expect)(Number.isNaN((0, _getCalendarMonthWidth["default"])(39, null))).to.equal(false); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getDetachedContainerStyles_spec.js b/test-build/utils/getDetachedContainerStyles_spec.js new file mode 100644 index 000000000..da562bc8a --- /dev/null +++ b/test-build/utils/getDetachedContainerStyles_spec.js @@ -0,0 +1,69 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _mochaWrap = _interopRequireDefault(require("mocha-wrap")); + +var _getDetachedContainerStyles = _interopRequireDefault(require("../../lib/utils/getDetachedContainerStyles")); + +var _constants = require("../../lib/constants"); + +var describeIfNoWindow = typeof document === 'undefined' ? describe : describe.skip; +var windowWidth = 100; +var windowHeight = 100; // Fake 30x100px element on x,y = 10,10 + +var referenceElRect = { + top: 10, + bottom: 40, + left: 10, + right: 110 +}; +var referenceEl = { + getBoundingClientRect: function getBoundingClientRect() { + return referenceElRect; + } +}; +describeIfNoWindow('#getDetachedContainerStyles', function () { + (0, _mochaWrap["default"])().withGlobal('window', function () { + return {}; + }).withOverride(function () { + return window; + }, 'innerWidth', function () { + return windowWidth; + }).withOverride(function () { + return window; + }, 'innerHeight', function () { + return windowHeight; + }).describe('with `window`', function () { + describe('on down-left positioning', function () { + it('returns translation from top-left of window to top-left of reference el', function () { + var styles = (0, _getDetachedContainerStyles["default"])(_constants.OPEN_DOWN, _constants.ANCHOR_LEFT, referenceEl); + (0, _chai.expect)(styles.transform).to.equal("translate3d(".concat(Math.round(referenceElRect.left), "px, ").concat(Math.round(referenceElRect.top), "px, 0)")); + }); + }); + describe('on up-left positioning', function () { + it('returns translation from bottom-left of window to bottom-left of reference el', function () { + var styles = (0, _getDetachedContainerStyles["default"])(_constants.OPEN_UP, _constants.ANCHOR_LEFT, referenceEl); + var offsetY = -(windowHeight - referenceElRect.bottom); + (0, _chai.expect)(styles.transform).to.equal("translate3d(".concat(Math.round(referenceElRect.left), "px, ").concat(Math.round(offsetY), "px, 0)")); + }); + }); + describe('on down-right positioning', function () { + it('returns translation from top-right of window to top-right of reference el', function () { + var styles = (0, _getDetachedContainerStyles["default"])(_constants.OPEN_DOWN, _constants.ANCHOR_RIGHT, referenceEl); + var offsetX = -(windowWidth - referenceElRect.right); + (0, _chai.expect)(styles.transform).to.equal("translate3d(".concat(Math.round(offsetX), "px, ").concat(Math.round(referenceElRect.top), "px, 0)")); + }); + }); + describe('on up-right positioning', function () { + it('returns translation from bottom-right of window to bottom-right of reference el', function () { + var styles = (0, _getDetachedContainerStyles["default"])(_constants.OPEN_UP, _constants.ANCHOR_RIGHT, referenceEl); + var offsetX = -(windowWidth - referenceElRect.right); + var offsetY = -(windowHeight - referenceElRect.bottom); + (0, _chai.expect)(styles.transform).to.equal("translate3d(".concat(Math.round(offsetX), "px, ").concat(Math.round(offsetY), "px, 0)")); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getInputHeight_spec.js b/test-build/utils/getInputHeight_spec.js new file mode 100644 index 000000000..beab9648c --- /dev/null +++ b/test-build/utils/getInputHeight_spec.js @@ -0,0 +1,35 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _getInputHeight = _interopRequireDefault(require("../../lib/utils/getInputHeight")); + +var theme = { + font: { + input: { + lineHeight: 13, + lineHeight_small: 7 + } + }, + spacing: { + inputPadding: 10, + displayTextPaddingVertical: 8, + displayTextPaddingTop: 10, + displayTextPaddingBottom: 12, + displayTextPaddingVertical_small: 2, + displayTextPaddingTop_small: 4, + displayTextPaddingBottom_small: 6 + } +}; +describe('#getInputHeight', function () { + it('returns the expected value with falsy second arg', function () { + var inputHeight = (0, _getInputHeight["default"])(theme); + (0, _chai.expect)(inputHeight).to.equal(55); + }); + it('returns the expected value with truthy second arg', function () { + var inputHeight = (0, _getInputHeight["default"])(theme, true); + (0, _chai.expect)(inputHeight).to.equal(37); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getNumberOfCalendarMonthWeeks_spec.js b/test-build/utils/getNumberOfCalendarMonthWeeks_spec.js new file mode 100644 index 000000000..bdee966e0 --- /dev/null +++ b/test-build/utils/getNumberOfCalendarMonthWeeks_spec.js @@ -0,0 +1,28 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _getNumberOfCalendarMonthWeeks = _interopRequireDefault(require("../../lib/utils/getNumberOfCalendarMonthWeeks")); + +describe('getNumberOfCalendarMonthWeeks', function () { + it('returns 4 weeks for a 4-week month', function () { + var february2018 = (0, _moment["default"])('2018-02-01', 'YYYY-MM-DD'); + (0, _chai.expect)((0, _getNumberOfCalendarMonthWeeks["default"])(february2018, 4)).to.equal(4); + }); + it('returns 5 weeks for a 5-week month', function () { + var july2018 = (0, _moment["default"])('2018-07-01', 'YYYY-MM-DD'); + (0, _chai.expect)((0, _getNumberOfCalendarMonthWeeks["default"])(july2018, 0)).to.equal(5); + }); + it('returns 6 weeks for a 6-week month', function () { + var september2018 = (0, _moment["default"])('2018-09-01', 'YYYY-MM-DD'); + (0, _chai.expect)((0, _getNumberOfCalendarMonthWeeks["default"])(september2018, 0)).to.equal(6); + }); + it('changing the first day of week changes the number of weeks', function () { + var september2018 = (0, _moment["default"])('2018-09-01', 'YYYY-MM-DD'); + (0, _chai.expect)((0, _getNumberOfCalendarMonthWeeks["default"])(september2018, 6)).to.equal(5); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getPhrasePropTypes_spec.js b/test-build/utils/getPhrasePropTypes_spec.js new file mode 100644 index 000000000..dbafabd0c --- /dev/null +++ b/test-build/utils/getPhrasePropTypes_spec.js @@ -0,0 +1,23 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _getPhrasePropTypes = _interopRequireDefault(require("../../lib/utils/getPhrasePropTypes")); + +var PhraseObject = { + foo: 'x', + bar: 'y', + baz: 'z' +}; +describe('#getPhrasePropTypes', function () { + it('contains each key from the original object', function () { + var propTypes = (0, _getPhrasePropTypes["default"])(PhraseObject); + Object.keys(PhraseObject).forEach(function (key) { + (0, _chai.expect)(Object.keys(propTypes).filter(function (type) { + return type === key; + }).length).to.not.equal(0); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getPhrase_spec.js b/test-build/utils/getPhrase_spec.js new file mode 100644 index 000000000..fb6f76c64 --- /dev/null +++ b/test-build/utils/getPhrase_spec.js @@ -0,0 +1,40 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _sinonSandbox = _interopRequireDefault(require("sinon-sandbox")); + +var _getPhrase = _interopRequireDefault(require("../../lib/utils/getPhrase")); + +describe('getPhrase', function () { + it('returns empty string when arg is falsy', function () { + (0, _chai.expect)((0, _getPhrase["default"])()).to.equal(''); + }); + it('returns arg if arg is a string', function () { + var test = 'foobarbaz'; + (0, _chai.expect)((0, _getPhrase["default"])(test)).to.equal(test); + }); + describe('arg is a function', function () { + it('returns invoked arg', function () { + var test = 'this is a new test string'; + + var phraseFunc = _sinonSandbox["default"].stub().returns(test); + + var phrase = (0, _getPhrase["default"])(phraseFunc); + (0, _chai.expect)(phraseFunc.callCount).to.equal(1); + (0, _chai.expect)(phrase).to.equal(test); + }); + it('passes second arg into the invoked function', function () { + var testObj = { + hello: 'world' + }; + + var phraseFunc = _sinonSandbox["default"].stub(); + + (0, _getPhrase["default"])(phraseFunc, testObj); + (0, _chai.expect)(phraseFunc.getCall(0).args[0]).to.equal(testObj); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getPooledMoment_spec.js b/test-build/utils/getPooledMoment_spec.js new file mode 100644 index 000000000..93f40b5de --- /dev/null +++ b/test-build/utils/getPooledMoment_spec.js @@ -0,0 +1,27 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _moment = _interopRequireDefault(require("moment")); + +var _getPooledMoment = _interopRequireDefault(require("../../lib/utils/getPooledMoment")); + +describe('getPooledMoment', function () { + it('returns a moment given a day string', function () { + var momentObj = (0, _getPooledMoment["default"])('2017-12-10'); + (0, _chai.expect)(_moment["default"].isMoment(momentObj)).to.equal(true); + (0, _chai.expect)(momentObj.format('YYYY MM DD')).to.equal('2017 12 10'); + }); + it('returns the same moment given the same day string', function () { + var momentObj1 = (0, _getPooledMoment["default"])('2017-12-10'); + var momentObj2 = (0, _getPooledMoment["default"])('2017-12-10'); + (0, _chai.expect)(momentObj1).to.equal(momentObj2); + }); + it('returns a different moment given a different day string', function () { + var momentObj1 = (0, _getPooledMoment["default"])('2017-12-10'); + var momentObj2 = (0, _getPooledMoment["default"])('2017-12-11'); + (0, _chai.expect)(momentObj1).not.to.equal(momentObj2); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getResponsiveContainerStyles_spec.js b/test-build/utils/getResponsiveContainerStyles_spec.js new file mode 100644 index 000000000..d0807c8a5 --- /dev/null +++ b/test-build/utils/getResponsiveContainerStyles_spec.js @@ -0,0 +1,39 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _mochaWrap = _interopRequireDefault(require("mocha-wrap")); + +var _getResponsiveContainerStyles = _interopRequireDefault(require("../../lib/utils/getResponsiveContainerStyles")); + +var _constants = require("../../lib/constants"); + +var describeUnlessWindow = typeof window === 'undefined' ? describe : describe.skip; +describe('#getResponsiveContainerStyles', function () { + describeUnlessWindow('window.innerWidth', function () { + (0, _mochaWrap["default"])().withGlobal('window', function () { + return {}; + }).withOverride(function () { + return window; + }, 'innerWidth', function () { + return -42; + }).it('uses window.innerWidth', function () { + var styles = (0, _getResponsiveContainerStyles["default"])(_constants.ANCHOR_LEFT, 0, 0); + (0, _chai.expect)(styles[_constants.ANCHOR_LEFT]).to.equal(window.innerWidth); + }); + }); + it('returns a numerical value when margin is not included', function () { + var styles = (0, _getResponsiveContainerStyles["default"])(_constants.ANCHOR_LEFT, 0, 0); + (0, _chai.expect)(styles[_constants.ANCHOR_LEFT]).to.be.a('number'); + }); + it('returns left style for left anchored container', function () { + var styles = (0, _getResponsiveContainerStyles["default"])(_constants.ANCHOR_LEFT, 0, 0, 0); + (0, _chai.expect)(styles[_constants.ANCHOR_LEFT]).to.not.be.an('undefined'); + }); + it('returns right style for right anchored container', function () { + var styles = (0, _getResponsiveContainerStyles["default"])(_constants.ANCHOR_RIGHT, 0, 0, 0); + (0, _chai.expect)(styles[_constants.ANCHOR_RIGHT]).to.not.be.an('undefined'); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getSelectedDateOffset_spec.js b/test-build/utils/getSelectedDateOffset_spec.js new file mode 100644 index 000000000..1ac113f73 --- /dev/null +++ b/test-build/utils/getSelectedDateOffset_spec.js @@ -0,0 +1,45 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _moment = _interopRequireDefault(require("moment")); + +var _getSelectedDateOffset = _interopRequireDefault(require("../../lib/utils/getSelectedDateOffset")); + +var today = (0, _moment["default"])(); +describe('#getSelectedDateOffset', function () { + it('returns a function modified moment object', function () { + var fn = function fn(day) { + return day.add(2, 'days'); + }; + + var modifiedDay = (0, _getSelectedDateOffset["default"])(fn, today); + (0, _chai.expect)(modifiedDay.format()).to.equal(today.clone().add(2, 'days').format()); + }); + it('returns the passed day when function is undefined', function () { + var modifiedDay = (0, _getSelectedDateOffset["default"])(undefined, today); + (0, _chai.expect)(modifiedDay.format()).to.equal(today.format()); + }); + it('modifies the returned day using the modifier callback', function () { + var fn = function fn(day) { + return day.add(2, 'days'); + }; + + var modifier = function modifier(day) { + return day.subtract(2, 'days'); + }; + + var modifiedDay = (0, _getSelectedDateOffset["default"])(fn, today, modifier); + (0, _chai.expect)(modifiedDay.format()).to.equal(today.clone().format()); + }); + it('does not apply the modifier if function is undefined', function () { + var modifier = function modifier(day) { + return day.subtract(2, 'days'); + }; + + var modifiedDay = (0, _getSelectedDateOffset["default"])(undefined, today, modifier); + (0, _chai.expect)(modifiedDay.format()).to.equal(today.format()); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getTransformStyles_spec.js b/test-build/utils/getTransformStyles_spec.js new file mode 100644 index 000000000..592ef1764 --- /dev/null +++ b/test-build/utils/getTransformStyles_spec.js @@ -0,0 +1,30 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _getTransformStyles = _interopRequireDefault(require("../../lib/utils/getTransformStyles")); + +describe('#getTransformStyles', function () { + it('returns non-prefixed transform style', function () { + var TRANSFORM_VALUE = 'foo'; + var transformStyles = (0, _getTransformStyles["default"])(TRANSFORM_VALUE); + (0, _chai.expect)(transformStyles.transform).to.equal(TRANSFORM_VALUE); + }); + it('returns ms-prefixed transform style', function () { + var TRANSFORM_VALUE = 'foo'; + var transformStyles = (0, _getTransformStyles["default"])(TRANSFORM_VALUE); + (0, _chai.expect)(transformStyles.msTransform).to.equal(TRANSFORM_VALUE); + }); + it('returns moz-prefixed transform style', function () { + var TRANSFORM_VALUE = 'foo'; + var transformStyles = (0, _getTransformStyles["default"])(TRANSFORM_VALUE); + (0, _chai.expect)(transformStyles.MozTransform).to.equal(TRANSFORM_VALUE); + }); + it('returns webkit-prefixed transform style', function () { + var TRANSFORM_VALUE = 'foo'; + var transformStyles = (0, _getTransformStyles["default"])(TRANSFORM_VALUE); + (0, _chai.expect)(transformStyles.WebkitTransform).to.equal(TRANSFORM_VALUE); + }); +}); \ No newline at end of file diff --git a/test-build/utils/getVisibleDays_spec.js b/test-build/utils/getVisibleDays_spec.js new file mode 100644 index 000000000..12efdaeda --- /dev/null +++ b/test-build/utils/getVisibleDays_spec.js @@ -0,0 +1,38 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var _getVisibleDays = _interopRequireDefault(require("../../lib/utils/getVisibleDays")); + +var today = (0, _moment["default"])(); +describe('getVisibleDays', function () { + it('has numberOfMonths entries', function () { + var numberOfMonths = 3; + var visibleDays = (0, _getVisibleDays["default"])(today, numberOfMonths, false); + (0, _chai.expect)(Object.keys(visibleDays).length).to.equal(numberOfMonths + 2); + }); + it('values are all arrays of moment objects', function () { + var visibleDays = (0, _getVisibleDays["default"])(today, 3, false); + Object.values(visibleDays).forEach(function (days) { + (0, _chai.expect)(Array.isArray(days)).to.equal(true); + days.forEach(function (day) { + (0, _chai.expect)(_moment["default"].isMoment(day)).to.equal(true); + }); + }); + }); + it('contains first arg day', function () { + var visibleDays = (0, _getVisibleDays["default"])(today, 3, false); + var containsToday = Object.values(visibleDays).filter(function (days) { + return days.filter(function (day) { + return (0, _isSameDay["default"])(day, today); + }).length > 0; + }); + (0, _chai.expect)(containsToday.length > 0).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isAfterDay_spec.js b/test-build/utils/isAfterDay_spec.js new file mode 100644 index 000000000..38499670b --- /dev/null +++ b/test-build/utils/isAfterDay_spec.js @@ -0,0 +1,37 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isAfterDay = _interopRequireDefault(require("../../lib/utils/isAfterDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isAfterDay', function () { + it('returns true if first arg is after the second but have same month and year', function () { + (0, _chai.expect)((0, _isAfterDay["default"])(tomorrow, today)).to.equal(true); + }); + it('returns true if first arg is after the second but have same day and year', function () { + (0, _chai.expect)((0, _isAfterDay["default"])((0, _moment["default"])().clone().add(1, 'month'), today)).to.equal(true); + }); + it('returns true if first arg is after the second but have same day and month', function () { + (0, _chai.expect)((0, _isAfterDay["default"])((0, _moment["default"])().clone().add(1, 'year'), today)).to.equal(true); + }); + it('returns false if args are the same day', function () { + (0, _chai.expect)((0, _isAfterDay["default"])(today, today)).to.equal(false); + }); + it('returns false if first arg is after the second', function () { + (0, _chai.expect)((0, _isAfterDay["default"])(today, tomorrow)).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isAfterDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isAfterDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isBeforeDay_spec.js b/test-build/utils/isBeforeDay_spec.js new file mode 100644 index 000000000..a854bc417 --- /dev/null +++ b/test-build/utils/isBeforeDay_spec.js @@ -0,0 +1,37 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isBeforeDay = _interopRequireDefault(require("../../lib/utils/isBeforeDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isBeforeDay', function () { + it('returns true if first arg is before the second but have same month and year', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(today, tomorrow)).to.equal(true); + }); + it('returns true if first arg is before the second but have same day and year', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(today, (0, _moment["default"])().clone().add(1, 'month'))).to.equal(true); + }); + it('returns true if first arg is before the second but have same day and month', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(today, (0, _moment["default"])().clone().add(1, 'year'))).to.equal(true); + }); + it('returns false if args are the same day', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(today, today)).to.equal(false); + }); + it('returns false if first arg is after the second', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(tomorrow, today)).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isBeforeDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isDayVisible_spec.js b/test-build/utils/isDayVisible_spec.js new file mode 100644 index 000000000..e1b1e61d0 --- /dev/null +++ b/test-build/utils/isDayVisible_spec.js @@ -0,0 +1,62 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isDayVisible = _interopRequireDefault(require("../../lib/utils/isDayVisible")); + +describe('#isDayVisible', function () { + it('returns true if arg is in visible months', function () { + var test = (0, _moment["default"])().add(3, 'months'); + var currentMonth = (0, _moment["default"])().add(2, 'months'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 2)).to.equal(true); + }); + it('returns false if arg is before first month', function () { + var test = (0, _moment["default"])().add(1, 'months'); + var currentMonth = (0, _moment["default"])().add(2, 'months'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 2)).to.equal(false); + }); + it('returns false if arg is after last month', function () { + var test = (0, _moment["default"])().add(4, 'months'); + var currentMonth = (0, _moment["default"])().add(2, 'months'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 2)).to.equal(false); + }); + describe('enableOutsideDays', function () { + it('returns true if arg is in partial week before visible months', function () { + var test = (0, _moment["default"])('2019-04-30'); + var currentMonth = (0, _moment["default"])('2019-05-01'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, false)).to.equal(false); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, true)).to.equal(true); + }); + it('returns true if arg is in partial week after visible months', function () { + var test = (0, _moment["default"])('2019-06-01'); + var currentMonth = (0, _moment["default"])('2019-05-01'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, false)).to.equal(false); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, true)).to.equal(true); + }); + it('returns false if arg is before partial week before visible months', function () { + var test = (0, _moment["default"])('2019-04-27'); + var currentMonth = (0, _moment["default"])('2019-05-01'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, true)).to.equal(false); + }); + it('returns false if arg is after partial week after visible months', function () { + var test = (0, _moment["default"])('2019-06-03'); + var currentMonth = (0, _moment["default"])('2019-05-01'); + (0, _chai.expect)((0, _isDayVisible["default"])(test, currentMonth, 1, true)).to.equal(false); + }); + }); // this test fails when run with the whole suite, + // potentially due to cache pollution from other tests + + it.skip('works when the first day of the week that starts the month does not have a midnight', function () { + var march29 = (0, _moment["default"])('2020-03-29').utcOffset(-1 + /* 'Atlantic/Azores' */ + ); + var april2020 = (0, _moment["default"])('2020-04-02').utcOffset(-1 + /* 'Atlantic/Azores' */ + ); + (0, _chai.expect)((0, _isDayVisible["default"])(march29, april2020, 1, true)).to.equal(true); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isInclusivelyAfterDay_spec.js b/test-build/utils/isInclusivelyAfterDay_spec.js new file mode 100644 index 000000000..dd0f24798 --- /dev/null +++ b/test-build/utils/isInclusivelyAfterDay_spec.js @@ -0,0 +1,31 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isInclusivelyAfterDay = _interopRequireDefault(require("../../lib/utils/isInclusivelyAfterDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isInclusivelyAfterDay', function () { + it('returns true if first argument is after the second', function () { + (0, _chai.expect)((0, _isInclusivelyAfterDay["default"])(tomorrow, today)).to.equal(true); + }); + it('returns true for same day arguments', function () { + (0, _chai.expect)((0, _isInclusivelyAfterDay["default"])(today, today)).to.equal(true); + }); + it('returns false if first argument is before the second', function () { + (0, _chai.expect)((0, _isInclusivelyAfterDay["default"])(today, tomorrow)).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isInclusivelyAfterDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isInclusivelyAfterDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isInclusivelyBeforeDay_spec.js b/test-build/utils/isInclusivelyBeforeDay_spec.js new file mode 100644 index 000000000..baebce3c6 --- /dev/null +++ b/test-build/utils/isInclusivelyBeforeDay_spec.js @@ -0,0 +1,31 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isInclusivelyBeforeDay = _interopRequireDefault(require("../../lib/utils/isInclusivelyBeforeDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isInclusivelyBeforeDay', function () { + it('returns true if first argument is before the second', function () { + (0, _chai.expect)((0, _isInclusivelyBeforeDay["default"])(today, tomorrow)).to.equal(true); + }); + it('returns true for same day arguments', function () { + (0, _chai.expect)((0, _isInclusivelyBeforeDay["default"])(today, today)).to.equal(true); + }); + it('returns false if first argument is after the second', function () { + (0, _chai.expect)((0, _isInclusivelyBeforeDay["default"])(tomorrow, today)).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isInclusivelyBeforeDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isInclusivelyBeforeDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isNextDay_spec.js b/test-build/utils/isNextDay_spec.js new file mode 100644 index 000000000..c0654e9e6 --- /dev/null +++ b/test-build/utils/isNextDay_spec.js @@ -0,0 +1,28 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isNextDay = _interopRequireDefault(require("../../lib/utils/isNextDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isNextDay', function () { + it('returns true if second argument is the next day after the first', function () { + (0, _chai.expect)((0, _isNextDay["default"])(today, tomorrow)).to.equal(true); + }); + it('returns false if the second arg is not the next day after the first', function () { + (0, _chai.expect)((0, _isNextDay["default"])(tomorrow, today)).to.equal(false); + }); + describe('non-moment arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isNextDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isNextDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isNextMonth_spec.js b/test-build/utils/isNextMonth_spec.js new file mode 100644 index 000000000..f2572cb5b --- /dev/null +++ b/test-build/utils/isNextMonth_spec.js @@ -0,0 +1,32 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isNextMonth = _interopRequireDefault(require("../../lib/utils/isNextMonth")); + +var today = (0, _moment["default"])(); +var nextMonth = (0, _moment["default"])().add(1, 'months'); +var twoMonths = (0, _moment["default"])().add(2, 'months'); +describe('isNextMonth', function () { + it('returns true if second argument is the next month after the first', function () { + (0, _chai.expect)((0, _isNextMonth["default"])(today, nextMonth)).to.equal(true); + }); + it('returns false if second argument is not the next month after the first', function () { + (0, _chai.expect)((0, _isNextMonth["default"])(nextMonth, today)).to.equal(false); + }); + it('returns false if second argument is more than one month after the first', function () { + (0, _chai.expect)((0, _isNextMonth["default"])(today, twoMonths)).to.equal(false); + }); + describe('non-moment arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isNextMonth["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isNextMonth["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isPrevMonth_spec.js b/test-build/utils/isPrevMonth_spec.js new file mode 100644 index 000000000..7e096ea4f --- /dev/null +++ b/test-build/utils/isPrevMonth_spec.js @@ -0,0 +1,32 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isPrevMonth = _interopRequireDefault(require("../../lib/utils/isPrevMonth")); + +var today = (0, _moment["default"])(); +var lastMonth = (0, _moment["default"])().subtract(1, 'months'); +var twoMonthsAgo = (0, _moment["default"])().subtract(2, 'months'); +describe('isPrevMonth', function () { + it('returns true if second argument is the month before the first', function () { + (0, _chai.expect)((0, _isPrevMonth["default"])(today, lastMonth)).to.equal(true); + }); + it('returns false if second argument is not the month before the first', function () { + (0, _chai.expect)((0, _isPrevMonth["default"])(lastMonth, today)).to.equal(false); + }); + it('returns false if second argument is more than one month before the first', function () { + (0, _chai.expect)((0, _isPrevMonth["default"])(today, twoMonthsAgo)).to.equal(false); + }); + describe('non-moment arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isPrevMonth["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isPrevMonth["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isPreviousDay_spec.js b/test-build/utils/isPreviousDay_spec.js new file mode 100644 index 000000000..6973c9257 --- /dev/null +++ b/test-build/utils/isPreviousDay_spec.js @@ -0,0 +1,28 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isPreviousDay = _interopRequireDefault(require("../../lib/utils/isPreviousDay")); + +var today = (0, _moment["default"])(); +var yesterday = (0, _moment["default"])().subtract(1, 'days'); +describe('isPreviousDay', function () { + it('returns true if second argument is the day immediately before the first', function () { + (0, _chai.expect)((0, _isPreviousDay["default"])(today, yesterday)).to.equal(true); + }); + it('returns false if the second arg is not the day immediately before the first', function () { + (0, _chai.expect)((0, _isPreviousDay["default"])(yesterday, today)).to.equal(false); + }); + describe('non-moment arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isPreviousDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isPreviousDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isSameDay_spec.js b/test-build/utils/isSameDay_spec.js new file mode 100644 index 000000000..851b931b1 --- /dev/null +++ b/test-build/utils/isSameDay_spec.js @@ -0,0 +1,33 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var today = (0, _moment["default"])(); +var tomorrow = (0, _moment["default"])().add(1, 'days'); +describe('isSameDay', function () { + it('returns true if args are the same day', function () { + (0, _chai.expect)((0, _isSameDay["default"])(today, today)).to.equal(true); + }); + it('returns false if args are not the same day', function () { + (0, _chai.expect)((0, _isSameDay["default"])(today, tomorrow)).to.equal(false); + }); + it('returns false for same days of week', function () { + // Flags accidentally use of moment's day() function, which returns index + // within the week. + (0, _chai.expect)((0, _isSameDay["default"])((0, _moment["default"])('2000-01-01'), (0, _moment["default"])('2000-01-08'))).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isSameDay["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isSameDay["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isSameMonth_spec.js b/test-build/utils/isSameMonth_spec.js new file mode 100644 index 000000000..32ff21b8c --- /dev/null +++ b/test-build/utils/isSameMonth_spec.js @@ -0,0 +1,28 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isSameMonth = _interopRequireDefault(require("../../lib/utils/isSameMonth")); + +var today = (0, _moment["default"])(); +var nextMonth = (0, _moment["default"])().add(1, 'month'); +describe('isSameMonth', function () { + it('returns true if args are the same month', function () { + (0, _chai.expect)((0, _isSameMonth["default"])(today, today)).to.equal(true); + }); + it('returns false if args are not the same month', function () { + (0, _chai.expect)((0, _isSameMonth["default"])(today, nextMonth)).to.equal(false); + }); + describe('non-moment object arguments', function () { + it('is false if first argument is not a moment object', function () { + (0, _chai.expect)((0, _isSameMonth["default"])(null, today)).to.equal(false); + }); + it('is false if second argument is not a moment object', function () { + (0, _chai.expect)((0, _isSameMonth["default"])(today, 'foo')).to.equal(false); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/isTransitionEndSupported_spec.js b/test-build/utils/isTransitionEndSupported_spec.js new file mode 100644 index 000000000..4aa8a1944 --- /dev/null +++ b/test-build/utils/isTransitionEndSupported_spec.js @@ -0,0 +1,35 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); + +var _chai = require("chai"); + +var _mochaWrap = _interopRequireDefault(require("mocha-wrap")); + +var _isTransitionEndSupported = _interopRequireDefault(require("../../lib/utils/isTransitionEndSupported")); + +var describeIfNoWindow = typeof window === 'undefined' ? describe : describe.skip; +describeIfNoWindow('isTransitionEndSupported', function () { + describe('without `window`', function () { + it('returns false', function () { + (0, _chai.expect)(typeof window === "undefined" ? "undefined" : (0, _typeof2["default"])(window)).to.equal('undefined'); + (0, _chai.expect)((0, _isTransitionEndSupported["default"])()).to.equal(false); + }); + }); + (0, _mochaWrap["default"])().withGlobal('window', function () { + return {}; + }).describe('with `window`', function () { + it('returns false without `window.TransitionEvent`', function () { + (0, _chai.expect)((0, _isTransitionEndSupported["default"])()).to.equal(false); + }); + (0, _mochaWrap["default"])().withOverride(function () { + return window; + }, 'TransitionEvent', function () { + return function () {}; + }).it('returns true with `window.ontouchstart', function () { + (0, _chai.expect)((0, _isTransitionEndSupported["default"])()).to.equal(true); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/noflip_spec.js b/test-build/utils/noflip_spec.js new file mode 100644 index 000000000..bf2100e73 --- /dev/null +++ b/test-build/utils/noflip_spec.js @@ -0,0 +1,21 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _chai = require("chai"); + +var _noflip = _interopRequireDefault(require("../../lib/utils/noflip")); + +describe('noflip', function () { + it('appends a noflip comment to a number', function () { + (0, _chai.expect)((0, _noflip["default"])(42)).to.equal('42px /* @noflip */'); + }); + it('appends a noflip comment to a string', function () { + (0, _chai.expect)((0, _noflip["default"])('foo')).to.equal('foo /* @noflip */'); + }); + it('throws when value is unexpected type', function () { + (0, _chai.expect)(function () { + (0, _noflip["default"])([]); + }).to["throw"](TypeError); + }); +}); \ No newline at end of file diff --git a/test-build/utils/toISODateString_spec.js b/test-build/utils/toISODateString_spec.js new file mode 100644 index 000000000..6d369f3da --- /dev/null +++ b/test-build/utils/toISODateString_spec.js @@ -0,0 +1,42 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _toISODateString = _interopRequireDefault(require("../../lib/utils/toISODateString")); + +var _constants = require("../../lib/constants"); + +describe('toISODateString', function () { + it('returns null for falsy argument', function () { + (0, _chai.expect)((0, _toISODateString["default"])()).to.equal(null); + }); + it('converts moment object to localized date string', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toISODateString["default"])(testDate); + (0, _chai.expect)(dateString).to.equal('1991-07-13'); + }); + it('matches moment format behavior', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toISODateString["default"])(testDate); + (0, _chai.expect)(dateString).to.equal(testDate.format(_constants.ISO_FORMAT)); + }); + it('converts iso date string to ISO date string', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toISODateString["default"])(testDate.format(_constants.ISO_FORMAT)); + (0, _chai.expect)(dateString).to.equal('1991-07-13'); + }); + it('convers localized date strings to ISO date string', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toISODateString["default"])(testDate.format('L')); + (0, _chai.expect)(dateString).to.equal('1991-07-13'); + }); + it('converts custom format date strings with format passed in', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toISODateString["default"])(testDate.format('YYYY---DD/MM'), 'YYYY---DD/MM'); + (0, _chai.expect)(dateString).to.equal('1991-07-13'); + }); +}); \ No newline at end of file diff --git a/test-build/utils/toISOMonthString_spec.js b/test-build/utils/toISOMonthString_spec.js new file mode 100644 index 000000000..61f22af52 --- /dev/null +++ b/test-build/utils/toISOMonthString_spec.js @@ -0,0 +1,51 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _constants = require("../../lib/constants"); + +var _toISOMonthString = _interopRequireDefault(require("../../lib/utils/toISOMonthString")); + +describe('#toISOMonthString', function () { + describe('arg is a moment object', function () { + it('returns month in ISO_MONTH_FORMAT format', function () { + var today = (0, _moment["default"])(); + (0, _chai.expect)((0, _toISOMonthString["default"])(today)).to.equal(today.format(_constants.ISO_MONTH_FORMAT)); + }); + }); + describe('arg is a string', function () { + describe('arg is in ISO format', function () { + it('returns month in ISO_MONTH_FORMAT format', function () { + var today = (0, _moment["default"])(); + var todayISO = today.format(_constants.ISO_FORMAT); + (0, _chai.expect)((0, _toISOMonthString["default"])(todayISO)).to.equal(today.format(_constants.ISO_MONTH_FORMAT)); + }); + }); + describe('arg matches the second arg date format provided', function () { + it('returns month in ISO_MONTH_FORMAT format', function () { + var today = (0, _moment["default"])(); + var dateFormat = 'MM_DD_YYYY'; + var formattedDate = today.format(dateFormat); + var monthString = (0, _toISOMonthString["default"])(formattedDate, dateFormat); + (0, _chai.expect)(monthString).to.equal(today.format(_constants.ISO_MONTH_FORMAT)); + }); + }); + describe('arg is neither in iso format or in the provided format', function () { + it('returns null', function () { + var today = (0, _moment["default"])(); + var dateFormat = 'MM_DD_YYYY'; + var formattedDate = today.format('MM-DD-YYYY'); + (0, _chai.expect)((0, _toISOMonthString["default"])(formattedDate, dateFormat)).to.equal(null); + }); + }); + describe('arg is not a valid date string', function () { + it('returns null', function () { + (0, _chai.expect)((0, _toISOMonthString["default"])('This is not a date')).to.equal(null); + }); + }); + }); +}); \ No newline at end of file diff --git a/test-build/utils/toLocalizedDateString_spec.js b/test-build/utils/toLocalizedDateString_spec.js new file mode 100644 index 000000000..e32a3e87b --- /dev/null +++ b/test-build/utils/toLocalizedDateString_spec.js @@ -0,0 +1,37 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _toLocalizedDateString = _interopRequireDefault(require("../../lib/utils/toLocalizedDateString")); + +var _constants = require("../../lib/constants"); + +describe('toLocalizedDateString', function () { + it('returns null for falsy argument', function () { + (0, _chai.expect)((0, _toLocalizedDateString["default"])()).to.equal(null); + }); + it('converts moment object to localized date string', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toLocalizedDateString["default"])(testDate); + (0, _chai.expect)(dateString).to.equal(testDate.format('L')); + }); + it('converts iso date string to localized date string', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toLocalizedDateString["default"])(testDate.format(_constants.ISO_FORMAT)); + (0, _chai.expect)(dateString).to.equal(testDate.format('L')); + }); + it('localized date strings stay the same', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toLocalizedDateString["default"])(testDate.format('L')); + (0, _chai.expect)(dateString).to.equal(testDate.format('L')); + }); + it('converts custom format date strings with format passed in', function () { + var testDate = (0, _moment["default"])('1991-07-13'); + var dateString = (0, _toLocalizedDateString["default"])(testDate.format('YYYY---DD/MM'), 'YYYY---DD/MM'); + (0, _chai.expect)(dateString).to.equal(testDate.format('L')); + }); +}); \ No newline at end of file diff --git a/test-build/utils/toMomentObject_spec.js b/test-build/utils/toMomentObject_spec.js new file mode 100644 index 000000000..c26c0ad2c --- /dev/null +++ b/test-build/utils/toMomentObject_spec.js @@ -0,0 +1,53 @@ +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _moment = _interopRequireDefault(require("moment")); + +var _chai = require("chai"); + +var _isSameDay = _interopRequireDefault(require("../../lib/utils/isSameDay")); + +var _toMomentObject = _interopRequireDefault(require("../../lib/utils/toMomentObject")); + +describe('toMomentObject', function () { + it('returns null for null input', function () { + (0, _chai.expect)((0, _toMomentObject["default"])(null)).to.equal(null); + }); + it('returns null for undefined input', function () { + (0, _chai.expect)((0, _toMomentObject["default"])(undefined)).to.equal(null); + }); + it('returns null for empty string', function () { + (0, _chai.expect)((0, _toMomentObject["default"])('')).to.equal(null); + }); + it('returns null for no input', function () { + (0, _chai.expect)((0, _toMomentObject["default"])()).to.equal(null); + }); + it('output has time of 12PM', function () { + (0, _chai.expect)((0, _toMomentObject["default"])('1991-07-13').hour()).to.equal(12); + }); + it('parses custom format', function () { + var date = (0, _toMomentObject["default"])('1991---13/07', 'YYYY---DD/MM'); + (0, _chai.expect)(date).not.to.equal(null); + (0, _chai.expect)(date.month()).to.equal(6); // moment months are zero-indexed + + (0, _chai.expect)(date.date()).to.equal(13); + (0, _chai.expect)(date.year()).to.equal(1991); + }); + it('parses localized format', function () { + var date = (0, _toMomentObject["default"])((0, _moment["default"])('1991-07-13').format('L')); + (0, _chai.expect)(date).not.to.equal(null); + (0, _chai.expect)(date.month()).to.equal(6); // moment months are zero-indexed + + (0, _chai.expect)(date.date()).to.equal(13); + (0, _chai.expect)(date.year()).to.equal(1991); + }); + describe('Daylight Savings Time issues', function () { + it('last of February does not equal first of March', function () { + (0, _chai.expect)((0, _isSameDay["default"])((0, _toMomentObject["default"])('2017-02-28'), (0, _toMomentObject["default"])('2017-03-01'))).to.equal(false); + }); + it('last of March does not equal first of April', function () { + (0, _chai.expect)((0, _isSameDay["default"])((0, _toMomentObject["default"])('2017-03-31'), (0, _toMomentObject["default"])('2017-04-01'))).to.equal(false); + }); + }); +}); \ No newline at end of file