@birdnet/advanced-react-dates 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/.babelrc +67 -0
  2. package/.eslintrc +66 -0
  3. package/.nvmrc +1 -0
  4. package/.nyc_output/4d8efcd220c2aec1f2b4ffd49d875001.json +1 -0
  5. package/.nyc_output/66d34779498a5d49bcf9d757dfc7fdb5.json +1 -0
  6. package/.nyc_output/8ca7e04140934515928bc7d4ae476b73.json +1 -0
  7. package/.nyc_output/afc270bb597bfc50e690436959c2ae54.json +1 -0
  8. package/.nycrc +19 -0
  9. package/.travis.yml +13 -0
  10. package/CHANGELOG.md +665 -0
  11. package/CLAUDE.md +56 -0
  12. package/INTHEWILD.md +9 -0
  13. package/LICENSE +21 -0
  14. package/README.md +421 -2
  15. package/constants.js +2 -0
  16. package/esm/components/CalendarDay.js +321 -0
  17. package/esm/components/CalendarIcon.js +11 -0
  18. package/esm/components/CalendarMonth.js +254 -0
  19. package/esm/components/CalendarMonthGrid.js +365 -0
  20. package/esm/components/CalendarWeek.js +11 -0
  21. package/esm/components/ChevronDown.js +11 -0
  22. package/esm/components/ChevronUp.js +11 -0
  23. package/esm/components/CloseButton.js +12 -0
  24. package/esm/components/CustomizableCalendarDay.js +341 -0
  25. package/esm/components/DateInput.js +344 -0
  26. package/esm/components/DateRangePicker.js +647 -0
  27. package/esm/components/DateRangePickerInput.js +341 -0
  28. package/esm/components/DateRangePickerInputController.js +348 -0
  29. package/esm/components/DayPicker.js +1167 -0
  30. package/esm/components/DayPickerKeyboardShortcuts.js +364 -0
  31. package/esm/components/DayPickerNavigation.js +314 -0
  32. package/esm/components/DayPickerRangeController.js +1202 -0
  33. package/esm/components/DayPickerSingleDateController.js +690 -0
  34. package/esm/components/KeyboardShortcutRow.js +69 -0
  35. package/esm/components/LeftArrow.js +11 -0
  36. package/esm/components/RightArrow.js +11 -0
  37. package/esm/components/SingleDatePicker.js +605 -0
  38. package/esm/components/SingleDatePickerInput.js +264 -0
  39. package/esm/components/SingleDatePickerInputController.js +260 -0
  40. package/esm/constants.js +28 -0
  41. package/esm/defaultPhrases.js +225 -0
  42. package/esm/index.js +20 -0
  43. package/esm/initialize.js +2 -0
  44. package/esm/shapes/AnchorDirectionShape.js +3 -0
  45. package/esm/shapes/CalendarInfoPositionShape.js +3 -0
  46. package/esm/shapes/DateRangePickerShape.js +101 -0
  47. package/esm/shapes/DayOfWeekShape.js +3 -0
  48. package/esm/shapes/DisabledShape.js +3 -0
  49. package/esm/shapes/FocusedInputShape.js +3 -0
  50. package/esm/shapes/IconPositionShape.js +3 -0
  51. package/esm/shapes/ModifiersShape.js +18 -0
  52. package/esm/shapes/NavPositionShape.js +3 -0
  53. package/esm/shapes/OpenDirectionShape.js +3 -0
  54. package/esm/shapes/OrientationShape.js +3 -0
  55. package/esm/shapes/ScrollableOrientationShape.js +3 -0
  56. package/esm/shapes/SingleDatePickerShape.js +90 -0
  57. package/esm/theme/DefaultTheme.js +176 -0
  58. package/esm/utils/calculateDimension.js +28 -0
  59. package/esm/utils/disableScroll.js +67 -0
  60. package/esm/utils/getActiveElement.js +3 -0
  61. package/esm/utils/getCalendarDaySettings.js +48 -0
  62. package/esm/utils/getCalendarMonthWeeks.js +37 -0
  63. package/esm/utils/getCalendarMonthWidth.js +4 -0
  64. package/esm/utils/getDetachedContainerStyles.js +36 -0
  65. package/esm/utils/getInputHeight.js +42 -0
  66. package/esm/utils/getNumberOfCalendarMonthWeeks.js +11 -0
  67. package/esm/utils/getPhrase.js +7 -0
  68. package/esm/utils/getPhrasePropTypes.js +9 -0
  69. package/esm/utils/getPooledMoment.js +8 -0
  70. package/esm/utils/getPreviousMonthMemoLast.js +9 -0
  71. package/esm/utils/getResponsiveContainerStyles.js +8 -0
  72. package/esm/utils/getSelectedDateOffset.js +8 -0
  73. package/esm/utils/getTransformStyles.js +8 -0
  74. package/esm/utils/getVisibleDays.js +42 -0
  75. package/esm/utils/isAfterDay.js +7 -0
  76. package/esm/utils/isBeforeDay.js +13 -0
  77. package/esm/utils/isDayVisible.js +38 -0
  78. package/esm/utils/isInclusivelyAfterDay.js +6 -0
  79. package/esm/utils/isInclusivelyBeforeDay.js +6 -0
  80. package/esm/utils/isNextDay.js +7 -0
  81. package/esm/utils/isNextMonth.js +6 -0
  82. package/esm/utils/isPrevMonth.js +6 -0
  83. package/esm/utils/isPreviousDay.js +7 -0
  84. package/esm/utils/isSameDay.js +7 -0
  85. package/esm/utils/isSameMonth.js +7 -0
  86. package/esm/utils/isTransitionEndSupported.js +3 -0
  87. package/esm/utils/modifiers.js +94 -0
  88. package/esm/utils/noflip.js +10 -0
  89. package/esm/utils/registerCSSInterfaceWithDefaultTheme.js +5 -0
  90. package/esm/utils/registerInterfaceWithDefaultTheme.js +6 -0
  91. package/esm/utils/toISODateString.js +12 -0
  92. package/esm/utils/toISOMonthString.js +12 -0
  93. package/esm/utils/toLocalizedDateString.js +8 -0
  94. package/esm/utils/toMomentObject.js +7 -0
  95. package/index.js +2 -0
  96. package/initialize.js +2 -0
  97. package/karma.conf.js +82 -0
  98. package/lib/components/CalendarDay.js +327 -0
  99. package/lib/components/CalendarIcon.js +18 -0
  100. package/lib/components/CalendarMonth.js +259 -0
  101. package/lib/components/CalendarMonthGrid.js +372 -0
  102. package/lib/components/CalendarWeek.js +18 -0
  103. package/lib/components/ChevronDown.js +18 -0
  104. package/lib/components/ChevronUp.js +18 -0
  105. package/lib/components/CloseButton.js +19 -0
  106. package/lib/components/CustomizableCalendarDay.js +347 -0
  107. package/lib/components/DateInput.js +351 -0
  108. package/lib/components/DateRangePicker.js +653 -0
  109. package/lib/components/DateRangePickerInput.js +348 -0
  110. package/lib/components/DateRangePickerInputController.js +354 -0
  111. package/lib/components/DayPicker.js +1175 -0
  112. package/lib/components/DayPickerKeyboardShortcuts.js +371 -0
  113. package/lib/components/DayPickerNavigation.js +321 -0
  114. package/lib/components/DayPickerRangeController.js +1208 -0
  115. package/lib/components/DayPickerSingleDateController.js +695 -0
  116. package/lib/components/KeyboardShortcutRow.js +76 -0
  117. package/lib/components/LeftArrow.js +18 -0
  118. package/lib/components/RightArrow.js +18 -0
  119. package/lib/components/SingleDatePicker.js +611 -0
  120. package/lib/components/SingleDatePickerInput.js +271 -0
  121. package/lib/components/SingleDatePickerInputController.js +266 -0
  122. package/lib/constants.js +34 -0
  123. package/lib/css/_datepicker.css +886 -0
  124. package/lib/defaultPhrases.js +231 -0
  125. package/lib/index.js +146 -0
  126. package/lib/initialize.js +5 -0
  127. package/lib/shapes/AnchorDirectionShape.js +10 -0
  128. package/lib/shapes/CalendarInfoPositionShape.js +10 -0
  129. package/lib/shapes/DateRangePickerShape.js +108 -0
  130. package/lib/shapes/DayOfWeekShape.js +10 -0
  131. package/lib/shapes/DisabledShape.js +10 -0
  132. package/lib/shapes/FocusedInputShape.js +10 -0
  133. package/lib/shapes/IconPositionShape.js +10 -0
  134. package/lib/shapes/ModifiersShape.js +25 -0
  135. package/lib/shapes/NavPositionShape.js +10 -0
  136. package/lib/shapes/OpenDirectionShape.js +10 -0
  137. package/lib/shapes/OrientationShape.js +10 -0
  138. package/lib/shapes/ScrollableOrientationShape.js +10 -0
  139. package/lib/shapes/SingleDatePickerShape.js +97 -0
  140. package/lib/theme/DefaultTheme.js +182 -0
  141. package/lib/utils/calculateDimension.js +34 -0
  142. package/lib/utils/disableScroll.js +75 -0
  143. package/lib/utils/getActiveElement.js +9 -0
  144. package/lib/utils/getCalendarDaySettings.js +55 -0
  145. package/lib/utils/getCalendarMonthWeeks.js +44 -0
  146. package/lib/utils/getCalendarMonthWidth.js +10 -0
  147. package/lib/utils/getDetachedContainerStyles.js +41 -0
  148. package/lib/utils/getInputHeight.js +48 -0
  149. package/lib/utils/getNumberOfCalendarMonthWeeks.js +18 -0
  150. package/lib/utils/getPhrase.js +13 -0
  151. package/lib/utils/getPhrasePropTypes.js +16 -0
  152. package/lib/utils/getPooledMoment.js +15 -0
  153. package/lib/utils/getPreviousMonthMemoLast.js +15 -0
  154. package/lib/utils/getResponsiveContainerStyles.js +15 -0
  155. package/lib/utils/getSelectedDateOffset.js +14 -0
  156. package/lib/utils/getTransformStyles.js +14 -0
  157. package/lib/utils/getVisibleDays.js +49 -0
  158. package/lib/utils/isAfterDay.js +14 -0
  159. package/lib/utils/isBeforeDay.js +20 -0
  160. package/lib/utils/isDayVisible.js +45 -0
  161. package/lib/utils/isInclusivelyAfterDay.js +13 -0
  162. package/lib/utils/isInclusivelyBeforeDay.js +13 -0
  163. package/lib/utils/isNextDay.js +14 -0
  164. package/lib/utils/isNextMonth.js +13 -0
  165. package/lib/utils/isPrevMonth.js +13 -0
  166. package/lib/utils/isPreviousDay.js +14 -0
  167. package/lib/utils/isSameDay.js +14 -0
  168. package/lib/utils/isSameMonth.js +14 -0
  169. package/lib/utils/isTransitionEndSupported.js +9 -0
  170. package/lib/utils/modifiers.js +102 -0
  171. package/lib/utils/noflip.js +16 -0
  172. package/lib/utils/registerCSSInterfaceWithDefaultTheme.js +12 -0
  173. package/lib/utils/registerInterfaceWithDefaultTheme.js +13 -0
  174. package/lib/utils/toISODateString.js +19 -0
  175. package/lib/utils/toISOMonthString.js +19 -0
  176. package/lib/utils/toLocalizedDateString.js +15 -0
  177. package/lib/utils/toMomentObject.js +14 -0
  178. package/package.json +141 -4
  179. package/scripts/.eslintrc +7 -0
  180. package/scripts/buildCSS.js +37 -0
  181. package/scripts/pure-component-fallback.js +70 -0
  182. package/scripts/renderAllComponents.jsx +25 -0
  183. package/src/components/CalendarDay.jsx +366 -0
  184. package/src/components/CalendarIcon.jsx +3 -0
  185. package/src/components/CalendarMonth.jsx +300 -0
  186. package/src/components/CalendarMonthGrid.jsx +427 -0
  187. package/src/components/CalendarWeek.jsx +17 -0
  188. package/src/components/ChevronDown.jsx +3 -0
  189. package/src/components/ChevronUp.jsx +3 -0
  190. package/src/components/CloseButton.jsx +3 -0
  191. package/src/components/CustomizableCalendarDay.jsx +382 -0
  192. package/src/components/DateInput.jsx +401 -0
  193. package/src/components/DateRangePicker.jsx +777 -0
  194. package/src/components/DateRangePickerInput.jsx +434 -0
  195. package/src/components/DateRangePickerInputController.jsx +379 -0
  196. package/src/components/DayPicker.jsx +1407 -0
  197. package/src/components/DayPickerKeyboardShortcuts.jsx +443 -0
  198. package/src/components/DayPickerNavigation.jsx +445 -0
  199. package/src/components/DayPickerRangeController.jsx +1409 -0
  200. package/src/components/DayPickerSingleDateController.jsx +769 -0
  201. package/src/components/KeyboardShortcutRow.jsx +93 -0
  202. package/src/components/LeftArrow.jsx +3 -0
  203. package/src/components/RightArrow.jsx +3 -0
  204. package/src/components/SingleDatePicker.jsx +731 -0
  205. package/src/components/SingleDatePickerInput.jsx +329 -0
  206. package/src/components/SingleDatePickerInputController.jsx +280 -0
  207. package/src/constants.js +37 -0
  208. package/src/defaultPhrases.js +215 -0
  209. package/src/index.js +20 -0
  210. package/src/initialize.js +3 -0
  211. package/src/shapes/AnchorDirectionShape.js +8 -0
  212. package/src/shapes/CalendarInfoPositionShape.js +15 -0
  213. package/src/shapes/DateRangePickerShape.js +111 -0
  214. package/src/shapes/DayOfWeekShape.js +5 -0
  215. package/src/shapes/DisabledShape.js +5 -0
  216. package/src/shapes/FocusedInputShape.js +8 -0
  217. package/src/shapes/IconPositionShape.js +8 -0
  218. package/src/shapes/ModifiersShape.js +20 -0
  219. package/src/shapes/NavPositionShape.js +8 -0
  220. package/src/shapes/OpenDirectionShape.js +8 -0
  221. package/src/shapes/OrientationShape.js +8 -0
  222. package/src/shapes/ScrollableOrientationShape.js +13 -0
  223. package/src/shapes/SingleDatePickerShape.js +100 -0
  224. package/src/svg/arrow-left.svg +1 -0
  225. package/src/svg/arrow-right.svg +1 -0
  226. package/src/svg/calendar.svg +1 -0
  227. package/src/svg/chevron-down.svg +1 -0
  228. package/src/svg/chevron-up.svg +1 -0
  229. package/src/svg/close.svg +1 -0
  230. package/src/theme/DefaultTheme.js +196 -0
  231. package/src/utils/calculateDimension.js +32 -0
  232. package/src/utils/disableScroll.js +65 -0
  233. package/src/utils/getActiveElement.js +3 -0
  234. package/src/utils/getCalendarDaySettings.js +61 -0
  235. package/src/utils/getCalendarMonthWeeks.js +49 -0
  236. package/src/utils/getCalendarMonthWidth.js +3 -0
  237. package/src/utils/getDetachedContainerStyles.js +39 -0
  238. package/src/utils/getInputHeight.js +67 -0
  239. package/src/utils/getNumberOfCalendarMonthWeeks.js +15 -0
  240. package/src/utils/getPhrase.jsx +9 -0
  241. package/src/utils/getPhrasePropTypes.js +9 -0
  242. package/src/utils/getPooledMoment.js +10 -0
  243. package/src/utils/getPreviousMonthMemoLast.js +11 -0
  244. package/src/utils/getResponsiveContainerStyles.js +18 -0
  245. package/src/utils/getSelectedDateOffset.js +6 -0
  246. package/src/utils/getTransformStyles.js +8 -0
  247. package/src/utils/getVisibleDays.js +54 -0
  248. package/src/utils/isAfterDay.js +9 -0
  249. package/src/utils/isBeforeDay.js +18 -0
  250. package/src/utils/isDayVisible.js +57 -0
  251. package/src/utils/isInclusivelyAfterDay.js +8 -0
  252. package/src/utils/isInclusivelyBeforeDay.js +8 -0
  253. package/src/utils/isNextDay.js +9 -0
  254. package/src/utils/isNextMonth.js +8 -0
  255. package/src/utils/isPrevMonth.js +8 -0
  256. package/src/utils/isPreviousDay.js +9 -0
  257. package/src/utils/isSameDay.js +10 -0
  258. package/src/utils/isSameMonth.js +9 -0
  259. package/src/utils/isTransitionEndSupported.js +3 -0
  260. package/src/utils/modifiers.js +116 -0
  261. package/src/utils/noflip.js +11 -0
  262. package/src/utils/registerCSSInterfaceWithDefaultTheme.js +7 -0
  263. package/src/utils/registerInterfaceWithDefaultTheme.js +7 -0
  264. package/src/utils/toISODateString.js +14 -0
  265. package/src/utils/toISOMonthString.js +14 -0
  266. package/src/utils/toLocalizedDateString.js +12 -0
  267. package/src/utils/toMomentObject.js +12 -0
@@ -0,0 +1,1409 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import momentPropTypes from 'react-moment-proptypes';
4
+ import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
5
+ import moment from 'moment';
6
+ import values from 'object.values';
7
+ import isTouchDevice from 'is-touch-device';
8
+
9
+ import { DayPickerPhrases } from '../defaultPhrases';
10
+ import getPhrasePropTypes from '../utils/getPhrasePropTypes';
11
+
12
+ import isInclusivelyAfterDay from '../utils/isInclusivelyAfterDay';
13
+ import isNextDay from '../utils/isNextDay';
14
+ import isSameDay from '../utils/isSameDay';
15
+ import isAfterDay from '../utils/isAfterDay';
16
+ import isBeforeDay from '../utils/isBeforeDay';
17
+ import isPreviousDay from '../utils/isPreviousDay';
18
+
19
+ import getVisibleDays from '../utils/getVisibleDays';
20
+ import isDayVisible from '../utils/isDayVisible';
21
+
22
+ import getSelectedDateOffset from '../utils/getSelectedDateOffset';
23
+
24
+ import toISODateString from '../utils/toISODateString';
25
+ import { addModifier, deleteModifier } from '../utils/modifiers';
26
+
27
+ import DisabledShape from '../shapes/DisabledShape';
28
+ import FocusedInputShape from '../shapes/FocusedInputShape';
29
+ import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
30
+ import DayOfWeekShape from '../shapes/DayOfWeekShape';
31
+ import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape';
32
+ import NavPositionShape from '../shapes/NavPositionShape';
33
+
34
+ import {
35
+ START_DATE,
36
+ END_DATE,
37
+ HORIZONTAL_ORIENTATION,
38
+ VERTICAL_SCROLLABLE,
39
+ DAY_SIZE,
40
+ INFO_POSITION_BOTTOM,
41
+ NAV_POSITION_TOP,
42
+ } from '../constants';
43
+
44
+ import DayPicker from './DayPicker';
45
+ import getPooledMoment from '../utils/getPooledMoment';
46
+
47
+ const propTypes = forbidExtraProps({
48
+ startDate: momentPropTypes.momentObj,
49
+ endDate: momentPropTypes.momentObj,
50
+ onDatesChange: PropTypes.func,
51
+ startDateOffset: PropTypes.func,
52
+ endDateOffset: PropTypes.func,
53
+ minDate: momentPropTypes.momentObj,
54
+ maxDate: momentPropTypes.momentObj,
55
+
56
+ focusedInput: FocusedInputShape,
57
+ onFocusChange: PropTypes.func,
58
+ onClose: PropTypes.func,
59
+
60
+ keepOpenOnDateSelect: PropTypes.bool,
61
+ minimumNights: PropTypes.number,
62
+ disabled: DisabledShape,
63
+ isOutsideRange: PropTypes.func,
64
+ isDayBlocked: PropTypes.func,
65
+ isDayHighlighted: PropTypes.func,
66
+ getMinNightsForHoverDate: PropTypes.func,
67
+ daysViolatingMinNightsCanBeClicked: PropTypes.bool,
68
+
69
+ // DayPicker props
70
+ renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
71
+ renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
72
+ renderWeekHeaderElement: PropTypes.func,
73
+ enableOutsideDays: PropTypes.bool,
74
+ numberOfMonths: PropTypes.number,
75
+ orientation: ScrollableOrientationShape,
76
+ withPortal: PropTypes.bool,
77
+ initialVisibleMonth: PropTypes.func,
78
+ hideKeyboardShortcutsPanel: PropTypes.bool,
79
+ daySize: nonNegativeInteger,
80
+ noBorder: PropTypes.bool,
81
+ verticalBorderSpacing: nonNegativeInteger,
82
+ horizontalMonthPadding: nonNegativeInteger,
83
+
84
+ dayPickerNavigationInlineStyles: PropTypes.object,
85
+ navPosition: NavPositionShape,
86
+ navPrev: PropTypes.node,
87
+ navNext: PropTypes.node,
88
+ renderNavPrevButton: PropTypes.func,
89
+ renderNavNextButton: PropTypes.func,
90
+ noNavButtons: PropTypes.bool,
91
+ noNavNextButton: PropTypes.bool,
92
+ noNavPrevButton: PropTypes.bool,
93
+
94
+ onPrevMonthClick: PropTypes.func,
95
+ onNextMonthClick: PropTypes.func,
96
+ onOutsideClick: PropTypes.func,
97
+ renderCalendarDay: PropTypes.func,
98
+ renderDayContents: PropTypes.func,
99
+ renderCalendarInfo: PropTypes.func,
100
+ renderKeyboardShortcutsButton: PropTypes.func,
101
+ renderKeyboardShortcutsPanel: PropTypes.func,
102
+ calendarInfoPosition: CalendarInfoPositionShape,
103
+ firstDayOfWeek: DayOfWeekShape,
104
+ verticalHeight: nonNegativeInteger,
105
+ transitionDuration: nonNegativeInteger,
106
+
107
+ // accessibility
108
+ onBlur: PropTypes.func,
109
+ isFocused: PropTypes.bool,
110
+ showKeyboardShortcuts: PropTypes.bool,
111
+ onTab: PropTypes.func,
112
+ onShiftTab: PropTypes.func,
113
+
114
+ // i18n
115
+ monthFormat: PropTypes.string,
116
+ weekDayFormat: PropTypes.string,
117
+ phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)),
118
+ dayAriaLabelFormat: PropTypes.string,
119
+
120
+ isRTL: PropTypes.bool,
121
+ });
122
+
123
+ const defaultProps = {
124
+ startDate: undefined, // TODO: use null
125
+ endDate: undefined, // TODO: use null
126
+ minDate: null,
127
+ maxDate: null,
128
+ onDatesChange() {},
129
+ startDateOffset: undefined,
130
+ endDateOffset: undefined,
131
+
132
+ focusedInput: null,
133
+ onFocusChange() {},
134
+ onClose() {},
135
+
136
+ keepOpenOnDateSelect: false,
137
+ minimumNights: 1,
138
+ disabled: false,
139
+ isOutsideRange() {},
140
+ isDayBlocked() {},
141
+ isDayHighlighted() {},
142
+ getMinNightsForHoverDate() {},
143
+ daysViolatingMinNightsCanBeClicked: false,
144
+
145
+ // DayPicker props
146
+ renderMonthText: null,
147
+ renderWeekHeaderElement: null,
148
+ enableOutsideDays: false,
149
+ numberOfMonths: 1,
150
+ orientation: HORIZONTAL_ORIENTATION,
151
+ withPortal: false,
152
+ hideKeyboardShortcutsPanel: false,
153
+ initialVisibleMonth: null,
154
+ daySize: DAY_SIZE,
155
+
156
+ dayPickerNavigationInlineStyles: null,
157
+ navPosition: NAV_POSITION_TOP,
158
+ navPrev: null,
159
+ navNext: null,
160
+ renderNavPrevButton: null,
161
+ renderNavNextButton: null,
162
+ noNavButtons: false,
163
+ noNavNextButton: false,
164
+ noNavPrevButton: false,
165
+
166
+ onPrevMonthClick() {},
167
+ onNextMonthClick() {},
168
+ onOutsideClick() {},
169
+
170
+ renderCalendarDay: undefined,
171
+ renderDayContents: null,
172
+ renderCalendarInfo: null,
173
+ renderMonthElement: null,
174
+ renderKeyboardShortcutsButton: undefined,
175
+ renderKeyboardShortcutsPanel: undefined,
176
+ calendarInfoPosition: INFO_POSITION_BOTTOM,
177
+ firstDayOfWeek: null,
178
+ verticalHeight: null,
179
+ noBorder: false,
180
+ transitionDuration: undefined,
181
+ verticalBorderSpacing: undefined,
182
+ horizontalMonthPadding: 13,
183
+
184
+ // accessibility
185
+ onBlur() {},
186
+ isFocused: false,
187
+ showKeyboardShortcuts: false,
188
+ onTab() {},
189
+ onShiftTab() {},
190
+
191
+ // i18n
192
+ monthFormat: 'MMMM YYYY',
193
+ weekDayFormat: 'dd',
194
+ phrases: DayPickerPhrases,
195
+ dayAriaLabelFormat: undefined,
196
+
197
+ isRTL: false,
198
+ };
199
+
200
+ const getChooseAvailableDatePhrase = (phrases, focusedInput) => {
201
+ if (focusedInput === START_DATE) {
202
+ return phrases.chooseAvailableStartDate;
203
+ }
204
+ if (focusedInput === END_DATE) {
205
+ return phrases.chooseAvailableEndDate;
206
+ }
207
+ return phrases.chooseAvailableDate;
208
+ };
209
+
210
+ export default class DayPickerRangeController extends React.PureComponent {
211
+ constructor(props) {
212
+ super(props);
213
+
214
+ this.isTouchDevice = isTouchDevice();
215
+ this.today = moment();
216
+ this.modifiers = {
217
+ today: (day) => this.isToday(day),
218
+ blocked: (day) => this.isBlocked(day),
219
+ 'blocked-calendar': (day) => props.isDayBlocked(day),
220
+ 'blocked-out-of-range': (day) => props.isOutsideRange(day),
221
+ 'highlighted-calendar': (day) => props.isDayHighlighted(day),
222
+ valid: (day) => !this.isBlocked(day),
223
+ 'selected-start': (day) => this.isStartDate(day),
224
+ 'selected-end': (day) => this.isEndDate(day),
225
+ 'blocked-minimum-nights': (day) => this.doesNotMeetMinimumNights(day),
226
+ 'selected-span': (day) => this.isInSelectedSpan(day),
227
+ 'last-in-range': (day) => this.isLastInRange(day),
228
+ hovered: (day) => this.isHovered(day),
229
+ 'hovered-span': (day) => this.isInHoveredSpan(day),
230
+ 'hovered-offset': (day) => this.isInHoveredSpan(day),
231
+ 'after-hovered-start': (day) => this.isDayAfterHoveredStartDate(day),
232
+ 'first-day-of-week': (day) => this.isFirstDayOfWeek(day),
233
+ 'last-day-of-week': (day) => this.isLastDayOfWeek(day),
234
+ 'hovered-start-first-possible-end': (day, hoverDate) => this.isFirstPossibleEndDateForHoveredStartDate(day, hoverDate),
235
+ 'hovered-start-blocked-minimum-nights': (day, hoverDate) => this.doesNotMeetMinNightsForHoveredStartDate(day, hoverDate),
236
+ 'before-hovered-end': (day) => this.isDayBeforeHoveredEndDate(day),
237
+ 'no-selected-start-before-selected-end': (day) => this.beforeSelectedEnd(day) && !props.startDate,
238
+ 'selected-start-in-hovered-span': (day, hoverDate) => this.isStartDate(day) && isAfterDay(hoverDate, day),
239
+ 'selected-start-no-selected-end': (day) => this.isStartDate(day) && !props.endDate,
240
+ 'selected-end-no-selected-start': (day) => this.isEndDate(day) && !props.startDate,
241
+ };
242
+
243
+ const { currentMonth, visibleDays } = this.getStateForNewMonth(props);
244
+
245
+ // initialize phrases
246
+ // set the appropriate CalendarDay phrase based on focusedInput
247
+ const chooseAvailableDate = getChooseAvailableDatePhrase(props.phrases, props.focusedInput);
248
+
249
+ this.state = {
250
+ hoverDate: null,
251
+ currentMonth,
252
+ phrases: {
253
+ ...props.phrases,
254
+ chooseAvailableDate,
255
+ },
256
+ visibleDays,
257
+ disablePrev: this.shouldDisableMonthNavigation(props.minDate, currentMonth),
258
+ disableNext: this.shouldDisableMonthNavigation(props.maxDate, currentMonth),
259
+ };
260
+
261
+ this.onDayClick = this.onDayClick.bind(this);
262
+ this.onDayMouseEnter = this.onDayMouseEnter.bind(this);
263
+ this.onDayMouseLeave = this.onDayMouseLeave.bind(this);
264
+ this.onPrevMonthClick = this.onPrevMonthClick.bind(this);
265
+ this.onNextMonthClick = this.onNextMonthClick.bind(this);
266
+ this.onMonthChange = this.onMonthChange.bind(this);
267
+ this.onYearChange = this.onYearChange.bind(this);
268
+ this.onGetNextScrollableMonths = this.onGetNextScrollableMonths.bind(this);
269
+ this.onGetPrevScrollableMonths = this.onGetPrevScrollableMonths.bind(this);
270
+ this.getFirstFocusableDay = this.getFirstFocusableDay.bind(this);
271
+ }
272
+
273
+ componentDidUpdate(prevProps) {
274
+ const {
275
+ startDate,
276
+ endDate,
277
+ focusedInput,
278
+ getMinNightsForHoverDate,
279
+ minimumNights,
280
+ isOutsideRange,
281
+ isDayBlocked,
282
+ isDayHighlighted,
283
+ phrases,
284
+ initialVisibleMonth,
285
+ numberOfMonths,
286
+ enableOutsideDays,
287
+ } = this.props;
288
+
289
+ const {
290
+ startDate: prevStartDate,
291
+ endDate: prevEndDate,
292
+ focusedInput: prevFocusedInput,
293
+ minimumNights: prevMinimumNights,
294
+ isOutsideRange: prevIsOutsideRange,
295
+ isDayBlocked: prevIsDayBlocked,
296
+ isDayHighlighted: prevIsDayHighlighted,
297
+ phrases: prevPhrases,
298
+ initialVisibleMonth: prevInitialVisibleMonth,
299
+ numberOfMonths: prevNumberOfMonths,
300
+ enableOutsideDays: prevEnableOutsideDays,
301
+ } = prevProps;
302
+
303
+ const { hoverDate } = this.state;
304
+ let { visibleDays } = this.state;
305
+
306
+ let recomputeOutsideRange = false;
307
+ let recomputeDayBlocked = false;
308
+ let recomputeDayHighlighted = false;
309
+
310
+ if (isOutsideRange !== prevIsOutsideRange) {
311
+ this.modifiers['blocked-out-of-range'] = (day) => isOutsideRange(day);
312
+ recomputeOutsideRange = true;
313
+ }
314
+
315
+ if (isDayBlocked !== prevIsDayBlocked) {
316
+ this.modifiers['blocked-calendar'] = (day) => isDayBlocked(day);
317
+ recomputeDayBlocked = true;
318
+ }
319
+
320
+ if (isDayHighlighted !== prevIsDayHighlighted) {
321
+ this.modifiers['highlighted-calendar'] = (day) => isDayHighlighted(day);
322
+ recomputeDayHighlighted = true;
323
+ }
324
+
325
+ const recomputePropModifiers = (
326
+ recomputeOutsideRange || recomputeDayBlocked || recomputeDayHighlighted
327
+ );
328
+
329
+ const didStartDateChange = startDate !== prevStartDate;
330
+ const didEndDateChange = endDate !== prevEndDate;
331
+ const didFocusChange = focusedInput !== prevFocusedInput;
332
+
333
+ if (
334
+ numberOfMonths !== prevNumberOfMonths
335
+ || enableOutsideDays !== prevEnableOutsideDays
336
+ || (
337
+ initialVisibleMonth !== prevInitialVisibleMonth
338
+ && !prevFocusedInput
339
+ && didFocusChange
340
+ )
341
+ ) {
342
+ const newMonthState = this.getStateForNewMonth(this.props);
343
+ const { currentMonth } = newMonthState;
344
+ ({ visibleDays } = newMonthState);
345
+ this.setState({
346
+ currentMonth,
347
+ visibleDays,
348
+ });
349
+ }
350
+
351
+ let modifiers = {};
352
+
353
+ if (didStartDateChange) {
354
+ modifiers = this.deleteModifier(modifiers, prevStartDate, 'selected-start');
355
+ modifiers = this.addModifier(modifiers, startDate, 'selected-start');
356
+
357
+ if (prevStartDate) {
358
+ const startSpan = prevStartDate.clone().add(1, 'day');
359
+ const endSpan = prevStartDate.clone().add(prevMinimumNights + 1, 'days');
360
+ modifiers = this.deleteModifierFromRange(modifiers, startSpan, endSpan, 'after-hovered-start');
361
+
362
+ if (!endDate || !prevEndDate) {
363
+ modifiers = this.deleteModifier(modifiers, prevStartDate, 'selected-start-no-selected-end');
364
+ }
365
+ }
366
+
367
+ if (!prevStartDate && endDate && startDate) {
368
+ modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-no-selected-start');
369
+ modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span');
370
+
371
+ values(visibleDays).forEach((days) => {
372
+ Object.keys(days).forEach((day) => {
373
+ const momentObj = moment(day);
374
+ modifiers = this.deleteModifier(modifiers, momentObj, 'no-selected-start-before-selected-end');
375
+ });
376
+ });
377
+ }
378
+ }
379
+
380
+ if (didEndDateChange) {
381
+ modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end');
382
+ modifiers = this.addModifier(modifiers, endDate, 'selected-end');
383
+
384
+ if (prevEndDate && (!startDate || !prevStartDate)) {
385
+ modifiers = this.deleteModifier(modifiers, prevEndDate, 'selected-end-no-selected-start');
386
+ }
387
+ }
388
+
389
+ if (didStartDateChange || didEndDateChange) {
390
+ if (prevStartDate && prevEndDate) {
391
+ modifiers = this.deleteModifierFromRange(
392
+ modifiers,
393
+ prevStartDate,
394
+ prevEndDate.clone().add(1, 'day'),
395
+ 'selected-span',
396
+ );
397
+ }
398
+
399
+ if (startDate && endDate) {
400
+ modifiers = this.deleteModifierFromRange(
401
+ modifiers,
402
+ startDate,
403
+ endDate.clone().add(1, 'day'),
404
+ 'hovered-span',
405
+ );
406
+
407
+ modifiers = this.addModifierToRange(
408
+ modifiers,
409
+ startDate.clone().add(1, 'day'),
410
+ endDate,
411
+ 'selected-span',
412
+ );
413
+ }
414
+
415
+ if (startDate && !endDate) {
416
+ modifiers = this.addModifier(modifiers, startDate, 'selected-start-no-selected-end');
417
+ }
418
+
419
+ if (endDate && !startDate) {
420
+ modifiers = this.addModifier(modifiers, endDate, 'selected-end-no-selected-start');
421
+ }
422
+
423
+ if (!startDate && endDate) {
424
+ values(visibleDays).forEach((days) => {
425
+ Object.keys(days).forEach((day) => {
426
+ const momentObj = moment(day);
427
+
428
+ if (isBeforeDay(momentObj, endDate)) {
429
+ modifiers = this.addModifier(modifiers, momentObj, 'no-selected-start-before-selected-end');
430
+ }
431
+ });
432
+ });
433
+ }
434
+ }
435
+
436
+ if (!this.isTouchDevice && didStartDateChange && startDate && !endDate) {
437
+ const startSpan = startDate.clone().add(1, 'day');
438
+ const endSpan = startDate.clone().add(minimumNights + 1, 'days');
439
+ modifiers = this.addModifierToRange(modifiers, startSpan, endSpan, 'after-hovered-start');
440
+ }
441
+
442
+ if (!this.isTouchDevice && didEndDateChange && !startDate && endDate) {
443
+ const startSpan = endDate.clone().subtract(minimumNights, 'days');
444
+ const endSpan = endDate.clone();
445
+ modifiers = this.addModifierToRange(modifiers, startSpan, endSpan, 'before-hovered-end');
446
+ }
447
+
448
+ if (prevMinimumNights > 0) {
449
+ if (didFocusChange || didStartDateChange || minimumNights !== prevMinimumNights) {
450
+ const startSpan = prevStartDate || this.today;
451
+ modifiers = this.deleteModifierFromRange(
452
+ modifiers,
453
+ startSpan,
454
+ startSpan.clone().add(prevMinimumNights, 'days'),
455
+ 'blocked-minimum-nights',
456
+ );
457
+
458
+ modifiers = this.deleteModifierFromRange(
459
+ modifiers,
460
+ startSpan,
461
+ startSpan.clone().add(prevMinimumNights, 'days'),
462
+ 'blocked',
463
+ );
464
+ }
465
+ }
466
+
467
+ if (didFocusChange || recomputePropModifiers) {
468
+ values(visibleDays).forEach((days) => {
469
+ Object.keys(days).forEach((day) => {
470
+ const momentObj = getPooledMoment(day);
471
+ let isBlocked = false;
472
+
473
+ if (didFocusChange || recomputeOutsideRange) {
474
+ if (isOutsideRange(momentObj)) {
475
+ modifiers = this.addModifier(modifiers, momentObj, 'blocked-out-of-range');
476
+ isBlocked = true;
477
+ } else {
478
+ modifiers = this.deleteModifier(modifiers, momentObj, 'blocked-out-of-range');
479
+ }
480
+ }
481
+
482
+ if (didFocusChange || recomputeDayBlocked) {
483
+ if (isDayBlocked(momentObj)) {
484
+ modifiers = this.addModifier(modifiers, momentObj, 'blocked-calendar');
485
+ isBlocked = true;
486
+ } else {
487
+ modifiers = this.deleteModifier(modifiers, momentObj, 'blocked-calendar');
488
+ }
489
+ }
490
+
491
+ if (isBlocked) {
492
+ modifiers = this.addModifier(modifiers, momentObj, 'blocked');
493
+ } else {
494
+ modifiers = this.deleteModifier(modifiers, momentObj, 'blocked');
495
+ }
496
+
497
+ if (didFocusChange || recomputeDayHighlighted) {
498
+ if (isDayHighlighted(momentObj)) {
499
+ modifiers = this.addModifier(modifiers, momentObj, 'highlighted-calendar');
500
+ } else {
501
+ modifiers = this.deleteModifier(modifiers, momentObj, 'highlighted-calendar');
502
+ }
503
+ }
504
+ });
505
+ });
506
+ }
507
+
508
+ if (!this.isTouchDevice && didFocusChange && hoverDate && !this.isBlocked(hoverDate)) {
509
+ const minNightsForHoverDate = getMinNightsForHoverDate(hoverDate);
510
+ if (minNightsForHoverDate > 0 && focusedInput === END_DATE) {
511
+ modifiers = this.deleteModifierFromRange(
512
+ modifiers,
513
+ hoverDate.clone().add(1, 'days'),
514
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
515
+ 'hovered-start-blocked-minimum-nights',
516
+ );
517
+
518
+ modifiers = this.deleteModifier(
519
+ modifiers,
520
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
521
+ 'hovered-start-first-possible-end',
522
+ );
523
+ }
524
+
525
+ if (minNightsForHoverDate > 0 && focusedInput === START_DATE) {
526
+ modifiers = this.addModifierToRange(
527
+ modifiers,
528
+ hoverDate.clone().add(1, 'days'),
529
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
530
+ 'hovered-start-blocked-minimum-nights',
531
+ );
532
+
533
+ modifiers = this.addModifier(
534
+ modifiers,
535
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
536
+ 'hovered-start-first-possible-end',
537
+ );
538
+ }
539
+ }
540
+
541
+ if (minimumNights > 0 && startDate && focusedInput === END_DATE) {
542
+ modifiers = this.addModifierToRange(
543
+ modifiers,
544
+ startDate,
545
+ startDate.clone().add(minimumNights, 'days'),
546
+ 'blocked-minimum-nights',
547
+ );
548
+
549
+ modifiers = this.addModifierToRange(
550
+ modifiers,
551
+ startDate,
552
+ startDate.clone().add(minimumNights, 'days'),
553
+ 'blocked',
554
+ );
555
+ }
556
+
557
+ const today = moment();
558
+ if (!isSameDay(this.today, today)) {
559
+ modifiers = this.deleteModifier(modifiers, this.today, 'today');
560
+ modifiers = this.addModifier(modifiers, today, 'today');
561
+ this.today = today;
562
+ }
563
+
564
+ if (Object.keys(modifiers).length > 0) {
565
+ this.setState({
566
+ visibleDays: {
567
+ ...visibleDays,
568
+ ...modifiers,
569
+ },
570
+ });
571
+ }
572
+
573
+ if (didFocusChange || phrases !== prevPhrases) {
574
+ // set the appropriate CalendarDay phrase based on focusedInput
575
+ const chooseAvailableDate = getChooseAvailableDatePhrase(phrases, focusedInput);
576
+
577
+ this.setState({
578
+ phrases: {
579
+ ...phrases,
580
+ chooseAvailableDate,
581
+ },
582
+ });
583
+ }
584
+ }
585
+
586
+ onDayClick(day, e) {
587
+ const {
588
+ keepOpenOnDateSelect,
589
+ minimumNights,
590
+ onBlur,
591
+ focusedInput,
592
+ onFocusChange,
593
+ onClose,
594
+ onDatesChange,
595
+ startDateOffset,
596
+ endDateOffset,
597
+ disabled,
598
+ daysViolatingMinNightsCanBeClicked,
599
+ } = this.props;
600
+
601
+ if (e) e.preventDefault();
602
+ if (this.isBlocked(day, !daysViolatingMinNightsCanBeClicked)) return;
603
+
604
+ let { startDate, endDate } = this.props;
605
+
606
+ if (startDateOffset || endDateOffset) {
607
+ startDate = getSelectedDateOffset(startDateOffset, day);
608
+ endDate = getSelectedDateOffset(endDateOffset, day);
609
+
610
+ if (this.isBlocked(startDate) || this.isBlocked(endDate)) {
611
+ return;
612
+ }
613
+
614
+ onDatesChange({ startDate, endDate });
615
+
616
+ if (!keepOpenOnDateSelect) {
617
+ onFocusChange(null);
618
+ onClose({ startDate, endDate });
619
+ }
620
+ } else if (focusedInput === START_DATE) {
621
+ const lastAllowedStartDate = endDate && endDate.clone().subtract(minimumNights, 'days');
622
+ const isStartDateAfterEndDate = isBeforeDay(lastAllowedStartDate, day)
623
+ || isAfterDay(startDate, endDate);
624
+ const isEndDateDisabled = disabled === END_DATE;
625
+
626
+ if (!isEndDateDisabled || !isStartDateAfterEndDate) {
627
+ startDate = day;
628
+ if (isStartDateAfterEndDate) {
629
+ endDate = null;
630
+ }
631
+ }
632
+
633
+ onDatesChange({ startDate, endDate });
634
+
635
+ if (isEndDateDisabled && !isStartDateAfterEndDate) {
636
+ onFocusChange(null);
637
+ onClose({ startDate, endDate });
638
+ } else if (!isEndDateDisabled) {
639
+ onFocusChange(END_DATE);
640
+ }
641
+ } else if (focusedInput === END_DATE) {
642
+ const firstAllowedEndDate = startDate && startDate.clone().add(minimumNights, 'days');
643
+
644
+ if (!startDate) {
645
+ endDate = day;
646
+ onDatesChange({ startDate, endDate });
647
+ onFocusChange(START_DATE);
648
+ } else if (isInclusivelyAfterDay(day, firstAllowedEndDate)) {
649
+ endDate = day;
650
+ onDatesChange({ startDate, endDate });
651
+ if (!keepOpenOnDateSelect) {
652
+ onFocusChange(null);
653
+ onClose({ startDate, endDate });
654
+ }
655
+ } else if (
656
+ daysViolatingMinNightsCanBeClicked
657
+ && this.doesNotMeetMinimumNights(day)
658
+ ) {
659
+ endDate = day;
660
+ onDatesChange({ startDate, endDate });
661
+ } else if (disabled !== START_DATE) {
662
+ startDate = day;
663
+ endDate = null;
664
+ onDatesChange({ startDate, endDate });
665
+ } else {
666
+ onDatesChange({ startDate, endDate });
667
+ }
668
+ } else {
669
+ onDatesChange({ startDate, endDate });
670
+ }
671
+
672
+ onBlur();
673
+ }
674
+
675
+ onDayMouseEnter(day) {
676
+ /* eslint react/destructuring-assignment: 1 */
677
+ if (this.isTouchDevice) return;
678
+ const {
679
+ startDate,
680
+ endDate,
681
+ focusedInput,
682
+ getMinNightsForHoverDate,
683
+ minimumNights,
684
+ startDateOffset,
685
+ endDateOffset,
686
+ } = this.props;
687
+
688
+ const {
689
+ hoverDate,
690
+ visibleDays,
691
+ dateOffset,
692
+ } = this.state;
693
+
694
+ let nextDateOffset = null;
695
+
696
+ if (focusedInput) {
697
+ const hasOffset = startDateOffset || endDateOffset;
698
+ let modifiers = {};
699
+
700
+ if (hasOffset) {
701
+ const start = getSelectedDateOffset(startDateOffset, day);
702
+ const end = getSelectedDateOffset(endDateOffset, day, (rangeDay) => rangeDay.add(1, 'day'));
703
+
704
+ nextDateOffset = {
705
+ start,
706
+ end,
707
+ };
708
+
709
+ // eslint-disable-next-line react/destructuring-assignment
710
+ if (dateOffset && dateOffset.start && dateOffset.end) {
711
+ modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, dateOffset.end, 'hovered-offset');
712
+ }
713
+ modifiers = this.addModifierToRange(modifiers, start, end, 'hovered-offset');
714
+ }
715
+
716
+ if (!hasOffset) {
717
+ modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered');
718
+ modifiers = this.addModifier(modifiers, day, 'hovered');
719
+
720
+ if (startDate && !endDate && focusedInput === END_DATE) {
721
+ if (isAfterDay(hoverDate, startDate)) {
722
+ const endSpan = hoverDate.clone().add(1, 'day');
723
+ modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span');
724
+ }
725
+
726
+ if (isBeforeDay(day, startDate) || isSameDay(day, startDate)) {
727
+ modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span');
728
+ }
729
+
730
+ if (!this.isBlocked(day) && isAfterDay(day, startDate)) {
731
+ const endSpan = day.clone().add(1, 'day');
732
+ modifiers = this.addModifierToRange(modifiers, startDate, endSpan, 'hovered-span');
733
+ modifiers = this.addModifier(modifiers, startDate, 'selected-start-in-hovered-span');
734
+ }
735
+ }
736
+
737
+ if (!startDate && endDate && focusedInput === START_DATE) {
738
+ if (isBeforeDay(hoverDate, endDate)) {
739
+ modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span');
740
+ }
741
+
742
+ if (isAfterDay(day, endDate) || isSameDay(day, endDate)) {
743
+ modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span');
744
+ }
745
+
746
+ if (!this.isBlocked(day) && isBeforeDay(day, endDate)) {
747
+ modifiers = this.addModifierToRange(modifiers, day, endDate, 'hovered-span');
748
+ modifiers = this.addModifier(modifiers, endDate, 'selected-end-in-hovered-span');
749
+ }
750
+ }
751
+
752
+ if (startDate) {
753
+ const startSpan = startDate.clone().add(1, 'day');
754
+ const endSpan = startDate.clone().add(minimumNights + 1, 'days');
755
+ modifiers = this.deleteModifierFromRange(modifiers, startSpan, endSpan, 'after-hovered-start');
756
+
757
+ if (isSameDay(day, startDate)) {
758
+ const newStartSpan = startDate.clone().add(1, 'day');
759
+ const newEndSpan = startDate.clone().add(minimumNights + 1, 'days');
760
+ modifiers = this.addModifierToRange(
761
+ modifiers,
762
+ newStartSpan,
763
+ newEndSpan,
764
+ 'after-hovered-start',
765
+ );
766
+ }
767
+ }
768
+
769
+ if (endDate) {
770
+ const startSpan = endDate.clone().subtract(minimumNights, 'days');
771
+ modifiers = this.deleteModifierFromRange(modifiers, startSpan, endDate, 'before-hovered-end');
772
+
773
+ if (isSameDay(day, endDate)) {
774
+ const newStartSpan = endDate.clone().subtract(minimumNights, 'days');
775
+ modifiers = this.addModifierToRange(
776
+ modifiers,
777
+ newStartSpan,
778
+ endDate,
779
+ 'before-hovered-end',
780
+ );
781
+ }
782
+ }
783
+
784
+ if (hoverDate && !this.isBlocked(hoverDate)) {
785
+ const minNightsForPrevHoverDate = getMinNightsForHoverDate(hoverDate);
786
+ if (minNightsForPrevHoverDate > 0 && focusedInput === START_DATE) {
787
+ modifiers = this.deleteModifierFromRange(
788
+ modifiers,
789
+ hoverDate.clone().add(1, 'days'),
790
+ hoverDate.clone().add(minNightsForPrevHoverDate, 'days'),
791
+ 'hovered-start-blocked-minimum-nights',
792
+ );
793
+
794
+ modifiers = this.deleteModifier(
795
+ modifiers,
796
+ hoverDate.clone().add(minNightsForPrevHoverDate, 'days'),
797
+ 'hovered-start-first-possible-end',
798
+ );
799
+ }
800
+ }
801
+
802
+ if (!this.isBlocked(day)) {
803
+ const minNightsForHoverDate = getMinNightsForHoverDate(day);
804
+ if (minNightsForHoverDate > 0 && focusedInput === START_DATE) {
805
+ modifiers = this.addModifierToRange(
806
+ modifiers,
807
+ day.clone().add(1, 'days'),
808
+ day.clone().add(minNightsForHoverDate, 'days'),
809
+ 'hovered-start-blocked-minimum-nights',
810
+ );
811
+
812
+ modifiers = this.addModifier(
813
+ modifiers,
814
+ day.clone().add(minNightsForHoverDate, 'days'),
815
+ 'hovered-start-first-possible-end',
816
+ );
817
+ }
818
+ }
819
+ }
820
+
821
+ this.setState({
822
+ hoverDate: day,
823
+ dateOffset: nextDateOffset,
824
+ visibleDays: {
825
+ ...visibleDays,
826
+ ...modifiers,
827
+ },
828
+ });
829
+ }
830
+ }
831
+
832
+ onDayMouseLeave(day) {
833
+ const {
834
+ startDate,
835
+ endDate,
836
+ focusedInput,
837
+ getMinNightsForHoverDate,
838
+ minimumNights,
839
+ } = this.props;
840
+ const { hoverDate, visibleDays, dateOffset } = this.state;
841
+
842
+ if (this.isTouchDevice || !hoverDate) return;
843
+
844
+ let modifiers = {};
845
+ modifiers = this.deleteModifier(modifiers, hoverDate, 'hovered');
846
+
847
+ if (dateOffset) {
848
+ modifiers = this.deleteModifierFromRange(modifiers, dateOffset.start, dateOffset.end, 'hovered-offset');
849
+ }
850
+
851
+ if (startDate && !endDate) {
852
+ if (isAfterDay(hoverDate, startDate)) {
853
+ const endSpan = hoverDate.clone().add(1, 'day');
854
+ modifiers = this.deleteModifierFromRange(modifiers, startDate, endSpan, 'hovered-span');
855
+ }
856
+
857
+ if (isAfterDay(day, startDate)) {
858
+ modifiers = this.deleteModifier(modifiers, startDate, 'selected-start-in-hovered-span');
859
+ }
860
+ }
861
+
862
+ if (!startDate && endDate) {
863
+ if (isAfterDay(endDate, hoverDate)) {
864
+ modifiers = this.deleteModifierFromRange(modifiers, hoverDate, endDate, 'hovered-span');
865
+ }
866
+
867
+ if (isBeforeDay(day, endDate)) {
868
+ modifiers = this.deleteModifier(modifiers, endDate, 'selected-end-in-hovered-span');
869
+ }
870
+ }
871
+
872
+ if (startDate && isSameDay(day, startDate)) {
873
+ const startSpan = startDate.clone().add(1, 'day');
874
+ const endSpan = startDate.clone().add(minimumNights + 1, 'days');
875
+ modifiers = this.deleteModifierFromRange(modifiers, startSpan, endSpan, 'after-hovered-start');
876
+ }
877
+
878
+ if (endDate && isSameDay(day, endDate)) {
879
+ const startSpan = endDate.clone().subtract(minimumNights, 'days');
880
+ modifiers = this.deleteModifierFromRange(modifiers, startSpan, endDate, 'before-hovered-end');
881
+ }
882
+
883
+ if (!this.isBlocked(hoverDate)) {
884
+ const minNightsForHoverDate = getMinNightsForHoverDate(hoverDate);
885
+ if (minNightsForHoverDate > 0 && focusedInput === START_DATE) {
886
+ modifiers = this.deleteModifierFromRange(
887
+ modifiers,
888
+ hoverDate.clone().add(1, 'days'),
889
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
890
+ 'hovered-start-blocked-minimum-nights',
891
+ );
892
+
893
+ modifiers = this.deleteModifier(
894
+ modifiers,
895
+ hoverDate.clone().add(minNightsForHoverDate, 'days'),
896
+ 'hovered-start-first-possible-end',
897
+ );
898
+ }
899
+ }
900
+
901
+ this.setState({
902
+ hoverDate: null,
903
+ visibleDays: {
904
+ ...visibleDays,
905
+ ...modifiers,
906
+ },
907
+ });
908
+ }
909
+
910
+ onPrevMonthClick() {
911
+ const {
912
+ enableOutsideDays,
913
+ maxDate,
914
+ minDate,
915
+ numberOfMonths,
916
+ onPrevMonthClick,
917
+ } = this.props;
918
+ const { currentMonth, visibleDays } = this.state;
919
+
920
+ const newVisibleDays = {};
921
+ Object.keys(visibleDays).sort().slice(0, numberOfMonths + 1).forEach((month) => {
922
+ newVisibleDays[month] = visibleDays[month];
923
+ });
924
+
925
+ const prevMonth = currentMonth.clone().subtract(2, 'months');
926
+ const prevMonthVisibleDays = getVisibleDays(prevMonth, 1, enableOutsideDays, true);
927
+
928
+ const newCurrentMonth = currentMonth.clone().subtract(1, 'month');
929
+ this.setState({
930
+ currentMonth: newCurrentMonth,
931
+ disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth),
932
+ disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth),
933
+ visibleDays: {
934
+ ...newVisibleDays,
935
+ ...this.getModifiers(prevMonthVisibleDays),
936
+ },
937
+ }, () => {
938
+ onPrevMonthClick(newCurrentMonth.clone());
939
+ });
940
+ }
941
+
942
+ onNextMonthClick() {
943
+ const {
944
+ enableOutsideDays,
945
+ maxDate,
946
+ minDate,
947
+ numberOfMonths,
948
+ onNextMonthClick,
949
+ } = this.props;
950
+ const { currentMonth, visibleDays } = this.state;
951
+
952
+ const newVisibleDays = {};
953
+ Object.keys(visibleDays).sort().slice(1).forEach((month) => {
954
+ newVisibleDays[month] = visibleDays[month];
955
+ });
956
+
957
+ const nextMonth = currentMonth.clone().add(numberOfMonths + 1, 'month');
958
+ const nextMonthVisibleDays = getVisibleDays(nextMonth, 1, enableOutsideDays, true);
959
+ const newCurrentMonth = currentMonth.clone().add(1, 'month');
960
+ this.setState({
961
+ currentMonth: newCurrentMonth,
962
+ disablePrev: this.shouldDisableMonthNavigation(minDate, newCurrentMonth),
963
+ disableNext: this.shouldDisableMonthNavigation(maxDate, newCurrentMonth),
964
+ visibleDays: {
965
+ ...newVisibleDays,
966
+ ...this.getModifiers(nextMonthVisibleDays),
967
+ },
968
+ }, () => {
969
+ onNextMonthClick(newCurrentMonth.clone());
970
+ });
971
+ }
972
+
973
+ onMonthChange(newMonth) {
974
+ const { numberOfMonths, enableOutsideDays, orientation } = this.props;
975
+ const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
976
+ const newVisibleDays = getVisibleDays(
977
+ newMonth,
978
+ numberOfMonths,
979
+ enableOutsideDays,
980
+ withoutTransitionMonths,
981
+ );
982
+
983
+ this.setState({
984
+ currentMonth: newMonth.clone(),
985
+ visibleDays: this.getModifiers(newVisibleDays),
986
+ });
987
+ }
988
+
989
+ onYearChange(newMonth) {
990
+ const { numberOfMonths, enableOutsideDays, orientation } = this.props;
991
+ const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
992
+ const newVisibleDays = getVisibleDays(
993
+ newMonth,
994
+ numberOfMonths,
995
+ enableOutsideDays,
996
+ withoutTransitionMonths,
997
+ );
998
+
999
+ this.setState({
1000
+ currentMonth: newMonth.clone(),
1001
+ visibleDays: this.getModifiers(newVisibleDays),
1002
+ });
1003
+ }
1004
+
1005
+ onGetNextScrollableMonths() {
1006
+ const { numberOfMonths, enableOutsideDays } = this.props;
1007
+ const { currentMonth, visibleDays } = this.state;
1008
+
1009
+ const numberOfVisibleMonths = Object.keys(visibleDays).length;
1010
+ const nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month');
1011
+ const newVisibleDays = getVisibleDays(nextMonth, numberOfMonths, enableOutsideDays, true);
1012
+
1013
+ this.setState({
1014
+ visibleDays: {
1015
+ ...visibleDays,
1016
+ ...this.getModifiers(newVisibleDays),
1017
+ },
1018
+ });
1019
+ }
1020
+
1021
+ onGetPrevScrollableMonths() {
1022
+ const { numberOfMonths, enableOutsideDays } = this.props;
1023
+ const { currentMonth, visibleDays } = this.state;
1024
+
1025
+ const firstPreviousMonth = currentMonth.clone().subtract(numberOfMonths, 'month');
1026
+ const newVisibleDays = getVisibleDays(firstPreviousMonth, numberOfMonths, enableOutsideDays, true);
1027
+
1028
+ this.setState({
1029
+ currentMonth: firstPreviousMonth.clone(),
1030
+ visibleDays: {
1031
+ ...visibleDays,
1032
+ ...this.getModifiers(newVisibleDays),
1033
+ },
1034
+ });
1035
+ }
1036
+
1037
+ getFirstDayOfWeek() {
1038
+ const { firstDayOfWeek } = this.props;
1039
+ if (firstDayOfWeek == null) {
1040
+ return moment.localeData().firstDayOfWeek();
1041
+ }
1042
+
1043
+ return firstDayOfWeek;
1044
+ }
1045
+
1046
+ getFirstFocusableDay(newMonth) {
1047
+ const {
1048
+ startDate,
1049
+ endDate,
1050
+ focusedInput,
1051
+ minimumNights,
1052
+ numberOfMonths,
1053
+ } = this.props;
1054
+
1055
+ let focusedDate = newMonth.clone().startOf('month').hour(12);
1056
+ if (focusedInput === START_DATE && startDate) {
1057
+ focusedDate = startDate.clone();
1058
+ } else if (focusedInput === END_DATE && !endDate && startDate) {
1059
+ focusedDate = startDate.clone().add(minimumNights, 'days');
1060
+ } else if (focusedInput === END_DATE && endDate) {
1061
+ focusedDate = endDate.clone();
1062
+ }
1063
+
1064
+ if (this.isBlocked(focusedDate)) {
1065
+ const days = [];
1066
+ const lastVisibleDay = newMonth.clone().add(numberOfMonths - 1, 'months').endOf('month');
1067
+ let currentDay = focusedDate.clone();
1068
+ while (!isAfterDay(currentDay, lastVisibleDay)) {
1069
+ currentDay = currentDay.clone().add(1, 'day');
1070
+ days.push(currentDay);
1071
+ }
1072
+
1073
+ const viableDays = days.filter((day) => !this.isBlocked(day));
1074
+
1075
+ if (viableDays.length > 0) {
1076
+ ([focusedDate] = viableDays);
1077
+ }
1078
+ }
1079
+
1080
+ return focusedDate;
1081
+ }
1082
+
1083
+ getModifiers(visibleDays) {
1084
+ const modifiers = {};
1085
+ Object.keys(visibleDays).forEach((month) => {
1086
+ modifiers[month] = {};
1087
+ visibleDays[month].forEach((day) => {
1088
+ modifiers[month][toISODateString(day)] = this.getModifiersForDay(day);
1089
+ });
1090
+ });
1091
+
1092
+ return modifiers;
1093
+ }
1094
+
1095
+ getModifiersForDay(day) {
1096
+ return new Set(Object.keys(this.modifiers).filter((modifier) => this.modifiers[modifier](day)));
1097
+ }
1098
+
1099
+ getStateForNewMonth(nextProps) {
1100
+ const {
1101
+ initialVisibleMonth,
1102
+ numberOfMonths,
1103
+ enableOutsideDays,
1104
+ orientation,
1105
+ startDate,
1106
+ } = nextProps;
1107
+ const initialVisibleMonthThunk = initialVisibleMonth || (
1108
+ startDate ? () => startDate : () => this.today
1109
+ );
1110
+ const currentMonth = initialVisibleMonthThunk();
1111
+ const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
1112
+ const visibleDays = this.getModifiers(getVisibleDays(
1113
+ currentMonth,
1114
+ numberOfMonths,
1115
+ enableOutsideDays,
1116
+ withoutTransitionMonths,
1117
+ ));
1118
+ return { currentMonth, visibleDays };
1119
+ }
1120
+
1121
+ shouldDisableMonthNavigation(date, visibleMonth) {
1122
+ if (!date) return false;
1123
+
1124
+ const {
1125
+ numberOfMonths,
1126
+ enableOutsideDays,
1127
+ } = this.props;
1128
+
1129
+ return isDayVisible(date, visibleMonth, numberOfMonths, enableOutsideDays);
1130
+ }
1131
+
1132
+ addModifier(updatedDays, day, modifier) {
1133
+ return addModifier(updatedDays, day, modifier, this.props, this.state);
1134
+ }
1135
+
1136
+ addModifierToRange(updatedDays, start, end, modifier) {
1137
+ let days = updatedDays;
1138
+
1139
+ let spanStart = start.clone();
1140
+ while (isBeforeDay(spanStart, end)) {
1141
+ days = this.addModifier(days, spanStart, modifier);
1142
+ spanStart = spanStart.clone().add(1, 'day');
1143
+ }
1144
+
1145
+ return days;
1146
+ }
1147
+
1148
+ deleteModifier(updatedDays, day, modifier) {
1149
+ return deleteModifier(updatedDays, day, modifier, this.props, this.state);
1150
+ }
1151
+
1152
+ deleteModifierFromRange(updatedDays, start, end, modifier) {
1153
+ let days = updatedDays;
1154
+
1155
+ let spanStart = start.clone();
1156
+ while (isBeforeDay(spanStart, end)) {
1157
+ days = this.deleteModifier(days, spanStart, modifier);
1158
+ spanStart = spanStart.clone().add(1, 'day');
1159
+ }
1160
+
1161
+ return days;
1162
+ }
1163
+
1164
+ doesNotMeetMinimumNights(day) {
1165
+ const {
1166
+ startDate,
1167
+ isOutsideRange,
1168
+ focusedInput,
1169
+ minimumNights,
1170
+ } = this.props;
1171
+ if (focusedInput !== END_DATE) return false;
1172
+
1173
+ if (startDate) {
1174
+ const dayDiff = day.diff(startDate.clone().startOf('day').hour(12), 'days');
1175
+ return dayDiff < minimumNights && dayDiff >= 0;
1176
+ }
1177
+ return isOutsideRange(moment(day).subtract(minimumNights, 'days'));
1178
+ }
1179
+
1180
+ doesNotMeetMinNightsForHoveredStartDate(day, hoverDate) {
1181
+ const {
1182
+ focusedInput,
1183
+ getMinNightsForHoverDate,
1184
+ } = this.props;
1185
+ if (focusedInput !== END_DATE) return false;
1186
+
1187
+ if (hoverDate && !this.isBlocked(hoverDate)) {
1188
+ const minNights = getMinNightsForHoverDate(hoverDate);
1189
+ const dayDiff = day.diff(hoverDate.clone().startOf('day').hour(12), 'days');
1190
+ return dayDiff < minNights && dayDiff >= 0;
1191
+ }
1192
+ return false;
1193
+ }
1194
+
1195
+ isDayAfterHoveredStartDate(day) {
1196
+ const { startDate, endDate, minimumNights } = this.props;
1197
+ const { hoverDate } = this.state || {};
1198
+ return !!startDate
1199
+ && !endDate
1200
+ && !this.isBlocked(day)
1201
+ && isNextDay(hoverDate, day)
1202
+ && minimumNights > 0
1203
+ && isSameDay(hoverDate, startDate);
1204
+ }
1205
+
1206
+ isEndDate(day) {
1207
+ const { endDate } = this.props;
1208
+ return isSameDay(day, endDate);
1209
+ }
1210
+
1211
+ isHovered(day) {
1212
+ const { hoverDate } = this.state || {};
1213
+ const { focusedInput } = this.props;
1214
+ return !!focusedInput && isSameDay(day, hoverDate);
1215
+ }
1216
+
1217
+ isInHoveredSpan(day) {
1218
+ const { startDate, endDate } = this.props;
1219
+ const { hoverDate } = this.state || {};
1220
+
1221
+ const isForwardRange = !!startDate && !endDate && (
1222
+ day.isBetween(startDate, hoverDate) || isSameDay(hoverDate, day)
1223
+ );
1224
+ const isBackwardRange = !!endDate && !startDate && (
1225
+ day.isBetween(hoverDate, endDate) || isSameDay(hoverDate, day)
1226
+ );
1227
+
1228
+ const isValidDayHovered = hoverDate && !this.isBlocked(hoverDate);
1229
+
1230
+ return (isForwardRange || isBackwardRange) && isValidDayHovered;
1231
+ }
1232
+
1233
+ isInSelectedSpan(day) {
1234
+ const { startDate, endDate } = this.props;
1235
+ return day.isBetween(startDate, endDate, 'days');
1236
+ }
1237
+
1238
+ isLastInRange(day) {
1239
+ const { endDate } = this.props;
1240
+ return this.isInSelectedSpan(day) && isNextDay(day, endDate);
1241
+ }
1242
+
1243
+ isStartDate(day) {
1244
+ const { startDate } = this.props;
1245
+ return isSameDay(day, startDate);
1246
+ }
1247
+
1248
+ isBlocked(day, blockDaysViolatingMinNights = true) {
1249
+ const { isDayBlocked, isOutsideRange } = this.props;
1250
+ return isDayBlocked(day)
1251
+ || isOutsideRange(day)
1252
+ || (blockDaysViolatingMinNights && this.doesNotMeetMinimumNights(day));
1253
+ }
1254
+
1255
+ isToday(day) {
1256
+ return isSameDay(day, this.today);
1257
+ }
1258
+
1259
+ isFirstDayOfWeek(day) {
1260
+ return day.day() === this.getFirstDayOfWeek();
1261
+ }
1262
+
1263
+ isLastDayOfWeek(day) {
1264
+ return day.day() === (this.getFirstDayOfWeek() + 6) % 7;
1265
+ }
1266
+
1267
+ isFirstPossibleEndDateForHoveredStartDate(day, hoverDate) {
1268
+ const { focusedInput, getMinNightsForHoverDate } = this.props;
1269
+ if (focusedInput !== END_DATE || !hoverDate || this.isBlocked(hoverDate)) return false;
1270
+ const minNights = getMinNightsForHoverDate(hoverDate);
1271
+ const firstAvailableEndDate = hoverDate.clone().add(minNights, 'days');
1272
+ return isSameDay(day, firstAvailableEndDate);
1273
+ }
1274
+
1275
+ beforeSelectedEnd(day) {
1276
+ const { endDate } = this.props;
1277
+ return isBeforeDay(day, endDate);
1278
+ }
1279
+
1280
+ isDayBeforeHoveredEndDate(day) {
1281
+ const { startDate, endDate, minimumNights } = this.props;
1282
+ const { hoverDate } = this.state || {};
1283
+
1284
+ return !!endDate
1285
+ && !startDate
1286
+ && !this.isBlocked(day)
1287
+ && isPreviousDay(hoverDate, day)
1288
+ && minimumNights > 0
1289
+ && isSameDay(hoverDate, endDate);
1290
+ }
1291
+
1292
+ render() {
1293
+ const {
1294
+ numberOfMonths,
1295
+ orientation,
1296
+ monthFormat,
1297
+ renderMonthText,
1298
+ renderWeekHeaderElement,
1299
+ dayPickerNavigationInlineStyles,
1300
+ navPosition,
1301
+ navPrev,
1302
+ navNext,
1303
+ renderNavPrevButton,
1304
+ renderNavNextButton,
1305
+ noNavButtons,
1306
+ noNavNextButton,
1307
+ noNavPrevButton,
1308
+ onOutsideClick,
1309
+ withPortal,
1310
+ enableOutsideDays,
1311
+ firstDayOfWeek,
1312
+ renderKeyboardShortcutsButton,
1313
+ renderKeyboardShortcutsPanel,
1314
+ hideKeyboardShortcutsPanel,
1315
+ daySize,
1316
+ focusedInput,
1317
+ renderCalendarDay,
1318
+ renderDayContents,
1319
+ renderCalendarInfo,
1320
+ renderMonthElement,
1321
+ calendarInfoPosition,
1322
+ onBlur,
1323
+ onShiftTab,
1324
+ onTab,
1325
+ isFocused,
1326
+ showKeyboardShortcuts,
1327
+ isRTL,
1328
+ weekDayFormat,
1329
+ dayAriaLabelFormat,
1330
+ verticalHeight,
1331
+ noBorder,
1332
+ transitionDuration,
1333
+ verticalBorderSpacing,
1334
+ horizontalMonthPadding,
1335
+ } = this.props;
1336
+
1337
+ const {
1338
+ currentMonth,
1339
+ phrases,
1340
+ visibleDays,
1341
+ disablePrev,
1342
+ disableNext,
1343
+ } = this.state;
1344
+
1345
+ return (
1346
+ <DayPicker
1347
+ orientation={orientation}
1348
+ enableOutsideDays={enableOutsideDays}
1349
+ modifiers={visibleDays}
1350
+ numberOfMonths={numberOfMonths}
1351
+ onDayClick={this.onDayClick}
1352
+ onDayMouseEnter={this.onDayMouseEnter}
1353
+ onDayMouseLeave={this.onDayMouseLeave}
1354
+ onPrevMonthClick={this.onPrevMonthClick}
1355
+ onNextMonthClick={this.onNextMonthClick}
1356
+ onMonthChange={this.onMonthChange}
1357
+ onTab={onTab}
1358
+ onShiftTab={onShiftTab}
1359
+ onYearChange={this.onYearChange}
1360
+ onGetNextScrollableMonths={this.onGetNextScrollableMonths}
1361
+ onGetPrevScrollableMonths={this.onGetPrevScrollableMonths}
1362
+ monthFormat={monthFormat}
1363
+ renderMonthText={renderMonthText}
1364
+ renderWeekHeaderElement={renderWeekHeaderElement}
1365
+ withPortal={withPortal}
1366
+ hidden={!focusedInput}
1367
+ initialVisibleMonth={() => currentMonth}
1368
+ daySize={daySize}
1369
+ onOutsideClick={onOutsideClick}
1370
+ disablePrev={disablePrev}
1371
+ disableNext={disableNext}
1372
+ dayPickerNavigationInlineStyles={dayPickerNavigationInlineStyles}
1373
+ navPosition={navPosition}
1374
+ navPrev={navPrev}
1375
+ navNext={navNext}
1376
+ renderNavPrevButton={renderNavPrevButton}
1377
+ renderNavNextButton={renderNavNextButton}
1378
+ noNavButtons={noNavButtons}
1379
+ noNavPrevButton={noNavPrevButton}
1380
+ noNavNextButton={noNavNextButton}
1381
+ renderCalendarDay={renderCalendarDay}
1382
+ renderDayContents={renderDayContents}
1383
+ renderCalendarInfo={renderCalendarInfo}
1384
+ renderMonthElement={renderMonthElement}
1385
+ renderKeyboardShortcutsButton={renderKeyboardShortcutsButton}
1386
+ renderKeyboardShortcutsPanel={renderKeyboardShortcutsPanel}
1387
+ calendarInfoPosition={calendarInfoPosition}
1388
+ firstDayOfWeek={firstDayOfWeek}
1389
+ hideKeyboardShortcutsPanel={hideKeyboardShortcutsPanel}
1390
+ isFocused={isFocused}
1391
+ getFirstFocusableDay={this.getFirstFocusableDay}
1392
+ onBlur={onBlur}
1393
+ showKeyboardShortcuts={showKeyboardShortcuts}
1394
+ phrases={phrases}
1395
+ isRTL={isRTL}
1396
+ weekDayFormat={weekDayFormat}
1397
+ dayAriaLabelFormat={dayAriaLabelFormat}
1398
+ verticalHeight={verticalHeight}
1399
+ verticalBorderSpacing={verticalBorderSpacing}
1400
+ noBorder={noBorder}
1401
+ transitionDuration={transitionDuration}
1402
+ horizontalMonthPadding={horizontalMonthPadding}
1403
+ />
1404
+ );
1405
+ }
1406
+ }
1407
+
1408
+ DayPickerRangeController.propTypes = propTypes;
1409
+ DayPickerRangeController.defaultProps = defaultProps;