@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,1407 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
4
+ import { withStyles, withStylesPropTypes } from 'react-with-styles';
5
+
6
+ import moment from 'moment';
7
+ import throttle from 'lodash/throttle';
8
+ import isTouchDevice from 'is-touch-device';
9
+ import OutsideClickHandler from 'react-outside-click-handler';
10
+
11
+ import { DayPickerPhrases } from '../defaultPhrases';
12
+ import getPhrasePropTypes from '../utils/getPhrasePropTypes';
13
+ import noflip from '../utils/noflip';
14
+
15
+ import CalendarMonthGrid from './CalendarMonthGrid';
16
+ import DayPickerNavigation from './DayPickerNavigation';
17
+ import DayPickerKeyboardShortcuts, {
18
+ TOP_LEFT,
19
+ TOP_RIGHT,
20
+ BOTTOM_RIGHT,
21
+ } from './DayPickerKeyboardShortcuts';
22
+
23
+ import getNumberOfCalendarMonthWeeks from '../utils/getNumberOfCalendarMonthWeeks';
24
+ import getCalendarMonthWidth from '../utils/getCalendarMonthWidth';
25
+ import calculateDimension from '../utils/calculateDimension';
26
+ import getActiveElement from '../utils/getActiveElement';
27
+ import isDayVisible from '../utils/isDayVisible';
28
+ import isSameMonth from '../utils/isSameMonth';
29
+
30
+ import ModifiersShape from '../shapes/ModifiersShape';
31
+ import NavPositionShape from '../shapes/NavPositionShape';
32
+ import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
33
+ import DayOfWeekShape from '../shapes/DayOfWeekShape';
34
+ import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape';
35
+
36
+ import {
37
+ HORIZONTAL_ORIENTATION,
38
+ VERTICAL_ORIENTATION,
39
+ VERTICAL_SCROLLABLE,
40
+ DAY_SIZE,
41
+ INFO_POSITION_TOP,
42
+ INFO_POSITION_BOTTOM,
43
+ INFO_POSITION_BEFORE,
44
+ INFO_POSITION_AFTER,
45
+ MODIFIER_KEY_NAMES,
46
+ NAV_POSITION_TOP,
47
+ NAV_POSITION_BOTTOM,
48
+ } from '../constants';
49
+
50
+ const MONTH_PADDING = 23;
51
+ const PREV_TRANSITION = 'prev';
52
+ const NEXT_TRANSITION = 'next';
53
+ const MONTH_SELECTION_TRANSITION = 'month_selection';
54
+ const YEAR_SELECTION_TRANSITION = 'year_selection';
55
+ const PREV_NAV = 'prev_nav';
56
+ const NEXT_NAV = 'next_nav';
57
+
58
+ const propTypes = forbidExtraProps({
59
+ ...withStylesPropTypes,
60
+
61
+ // calendar presentation props
62
+ enableOutsideDays: PropTypes.bool,
63
+ numberOfMonths: PropTypes.number,
64
+ orientation: ScrollableOrientationShape,
65
+ withPortal: PropTypes.bool,
66
+ onOutsideClick: PropTypes.func,
67
+ hidden: PropTypes.bool,
68
+ initialVisibleMonth: PropTypes.func,
69
+ firstDayOfWeek: DayOfWeekShape,
70
+ renderCalendarInfo: PropTypes.func,
71
+ calendarInfoPosition: CalendarInfoPositionShape,
72
+ hideKeyboardShortcutsPanel: PropTypes.bool,
73
+ daySize: nonNegativeInteger,
74
+ isRTL: PropTypes.bool,
75
+ verticalHeight: nonNegativeInteger,
76
+ noBorder: PropTypes.bool,
77
+ transitionDuration: nonNegativeInteger,
78
+ verticalBorderSpacing: nonNegativeInteger,
79
+ horizontalMonthPadding: nonNegativeInteger,
80
+ renderKeyboardShortcutsButton: PropTypes.func,
81
+ renderKeyboardShortcutsPanel: PropTypes.func,
82
+
83
+ // navigation props
84
+ dayPickerNavigationInlineStyles: PropTypes.object,
85
+ disablePrev: PropTypes.bool,
86
+ disableNext: PropTypes.bool,
87
+ navPosition: NavPositionShape,
88
+ navPrev: PropTypes.node,
89
+ navNext: PropTypes.node,
90
+ renderNavPrevButton: PropTypes.func,
91
+ renderNavNextButton: PropTypes.func,
92
+ noNavButtons: PropTypes.bool,
93
+ noNavNextButton: PropTypes.bool,
94
+ noNavPrevButton: PropTypes.bool,
95
+ onPrevMonthClick: PropTypes.func,
96
+ onNextMonthClick: PropTypes.func,
97
+ onMonthChange: PropTypes.func,
98
+ onYearChange: PropTypes.func,
99
+ onGetNextScrollableMonths: PropTypes.func, // VERTICAL_SCROLLABLE daypickers only
100
+ onGetPrevScrollableMonths: PropTypes.func, // VERTICAL_SCROLLABLE daypickers only
101
+
102
+ // month props
103
+ renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
104
+ renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
105
+ renderWeekHeaderElement: PropTypes.func,
106
+
107
+ // day props
108
+ modifiers: PropTypes.objectOf(PropTypes.objectOf(ModifiersShape)),
109
+ renderCalendarDay: PropTypes.func,
110
+ renderDayContents: PropTypes.func,
111
+ onDayClick: PropTypes.func,
112
+ onDayMouseEnter: PropTypes.func,
113
+ onDayMouseLeave: PropTypes.func,
114
+
115
+ // accessibility props
116
+ isFocused: PropTypes.bool,
117
+ getFirstFocusableDay: PropTypes.func,
118
+ onBlur: PropTypes.func,
119
+ showKeyboardShortcuts: PropTypes.bool,
120
+ onTab: PropTypes.func,
121
+ onShiftTab: PropTypes.func,
122
+
123
+ // internationalization
124
+ monthFormat: PropTypes.string,
125
+ weekDayFormat: PropTypes.string,
126
+ phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)),
127
+ dayAriaLabelFormat: PropTypes.string,
128
+ });
129
+
130
+ export const defaultProps = {
131
+ // calendar presentation props
132
+ enableOutsideDays: false,
133
+ numberOfMonths: 2,
134
+ orientation: HORIZONTAL_ORIENTATION,
135
+ withPortal: false,
136
+ onOutsideClick() {},
137
+ hidden: false,
138
+ initialVisibleMonth: () => moment(),
139
+ firstDayOfWeek: null,
140
+ renderCalendarInfo: null,
141
+ calendarInfoPosition: INFO_POSITION_BOTTOM,
142
+ hideKeyboardShortcutsPanel: false,
143
+ daySize: DAY_SIZE,
144
+ isRTL: false,
145
+ verticalHeight: null,
146
+ noBorder: false,
147
+ transitionDuration: undefined,
148
+ verticalBorderSpacing: undefined,
149
+ horizontalMonthPadding: 13,
150
+ renderKeyboardShortcutsButton: undefined,
151
+ renderKeyboardShortcutsPanel: undefined,
152
+
153
+ // navigation props
154
+ dayPickerNavigationInlineStyles: null,
155
+ disablePrev: false,
156
+ disableNext: false,
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
+ onPrevMonthClick() {},
166
+ onNextMonthClick() {},
167
+ onMonthChange() {},
168
+ onYearChange() {},
169
+ onGetNextScrollableMonths() {},
170
+ onGetPrevScrollableMonths() {},
171
+
172
+ // month props
173
+ renderMonthText: null,
174
+ renderMonthElement: null,
175
+ renderWeekHeaderElement: null,
176
+
177
+ // day props
178
+ modifiers: {},
179
+ renderCalendarDay: undefined,
180
+ renderDayContents: null,
181
+ onDayClick() {},
182
+ onDayMouseEnter() {},
183
+ onDayMouseLeave() {},
184
+
185
+ // accessibility props
186
+ isFocused: false,
187
+ getFirstFocusableDay: null,
188
+ onBlur() {},
189
+ showKeyboardShortcuts: false,
190
+ onTab() {},
191
+ onShiftTab() {},
192
+
193
+ // internationalization
194
+ monthFormat: 'MMMM YYYY',
195
+ weekDayFormat: 'dd',
196
+ phrases: DayPickerPhrases,
197
+ dayAriaLabelFormat: undefined,
198
+ };
199
+
200
+ class DayPicker extends React.PureComponent {
201
+ constructor(props) {
202
+ super(props);
203
+
204
+ const currentMonth = props.hidden ? moment() : props.initialVisibleMonth();
205
+
206
+ let focusedDate = currentMonth.clone().startOf('month').hour(12);
207
+ if (props.getFirstFocusableDay) {
208
+ focusedDate = props.getFirstFocusableDay(currentMonth);
209
+ }
210
+
211
+ const { horizontalMonthPadding } = props;
212
+
213
+ const translationValue = props.isRTL && this.isHorizontal()
214
+ ? -getCalendarMonthWidth(props.daySize, horizontalMonthPadding)
215
+ : 0;
216
+
217
+ this.hasSetInitialVisibleMonth = !props.hidden;
218
+ this.state = {
219
+ currentMonth,
220
+ monthTransition: null,
221
+ translationValue,
222
+ scrollableMonthMultiple: 1,
223
+ calendarMonthWidth: getCalendarMonthWidth(props.daySize, horizontalMonthPadding),
224
+ focusedDate: (!props.hidden || props.isFocused) ? focusedDate : null,
225
+ nextFocusedDate: null,
226
+ showKeyboardShortcuts: props.showKeyboardShortcuts,
227
+ onKeyboardShortcutsPanelClose() {},
228
+ isTouchDevice: isTouchDevice(),
229
+ withMouseInteractions: true,
230
+ calendarInfoWidth: 0,
231
+ monthTitleHeight: null,
232
+ hasSetHeight: false,
233
+ };
234
+
235
+ this.setCalendarMonthWeeks(currentMonth);
236
+
237
+ this.calendarMonthGridHeight = 0;
238
+ this.setCalendarInfoWidthTimeout = null;
239
+ this.setCalendarMonthGridHeightTimeout = null;
240
+
241
+ this.onKeyDown = this.onKeyDown.bind(this);
242
+ this.throttledKeyDown = throttle(this.onFinalKeyDown, 200, { trailing: false });
243
+ this.onPrevMonthClick = this.onPrevMonthClick.bind(this);
244
+ this.onPrevMonthTransition = this.onPrevMonthTransition.bind(this);
245
+ this.onNextMonthClick = this.onNextMonthClick.bind(this);
246
+ this.onNextMonthTransition = this.onNextMonthTransition.bind(this);
247
+ this.onMonthChange = this.onMonthChange.bind(this);
248
+ this.onYearChange = this.onYearChange.bind(this);
249
+
250
+ this.getNextScrollableMonths = this.getNextScrollableMonths.bind(this);
251
+ this.getPrevScrollableMonths = this.getPrevScrollableMonths.bind(this);
252
+ this.updateStateAfterMonthTransition = this.updateStateAfterMonthTransition.bind(this);
253
+
254
+ this.openKeyboardShortcutsPanel = this.openKeyboardShortcutsPanel.bind(this);
255
+ this.closeKeyboardShortcutsPanel = this.closeKeyboardShortcutsPanel.bind(this);
256
+
257
+ this.setCalendarInfoRef = this.setCalendarInfoRef.bind(this);
258
+ this.setContainerRef = this.setContainerRef.bind(this);
259
+ this.setTransitionContainerRef = this.setTransitionContainerRef.bind(this);
260
+ this.setMonthTitleHeight = this.setMonthTitleHeight.bind(this);
261
+ }
262
+
263
+ componentDidMount() {
264
+ const { currentMonth } = this.state;
265
+
266
+ const calendarInfoWidth = this.calendarInfo
267
+ ? calculateDimension(this.calendarInfo, 'width', true, true)
268
+ : 0;
269
+
270
+ this.setState({
271
+ isTouchDevice: isTouchDevice(),
272
+ calendarInfoWidth,
273
+ });
274
+
275
+ this.setCalendarMonthWeeks(currentMonth);
276
+ }
277
+
278
+ getSnapshotBeforeUpdate(prevProps, prevState) {
279
+ const { orientation } = this.props;
280
+ const { currentMonth } = this.state;
281
+
282
+ // Capture the scroll position before the DOM is updated so that, when previous
283
+ // months are rendered above the current month, we can restore scroll afterwards
284
+ // (in componentDidUpdate) and keep the previous current month in view. This used
285
+ // to live in componentWillReceiveProps; getSnapshotBeforeUpdate is the supported
286
+ // place to read layout right before a commit.
287
+ if (
288
+ orientation === VERTICAL_SCROLLABLE
289
+ && this.transitionContainer
290
+ && !isSameMonth(prevState.currentMonth, currentMonth)
291
+ ) {
292
+ return this.transitionContainer.scrollHeight - this.transitionContainer.scrollTop;
293
+ }
294
+
295
+ return null;
296
+ }
297
+
298
+ componentDidUpdate(prevProps, prevState, snapshot) {
299
+ const {
300
+ hidden,
301
+ isFocused,
302
+ showKeyboardShortcuts,
303
+ onBlur,
304
+ orientation,
305
+ renderMonthText,
306
+ horizontalMonthPadding,
307
+ daySize,
308
+ numberOfMonths,
309
+ transitionDuration,
310
+ initialVisibleMonth,
311
+ } = this.props;
312
+ const {
313
+ currentMonth,
314
+ focusedDate,
315
+ monthTitleHeight,
316
+ } = this.state;
317
+
318
+ // ----- migrated from componentWillReceiveProps -----
319
+ // Only re-sync the visible month in response to a props change (a new props
320
+ // object from the parent), never on our own setState-driven updates, otherwise
321
+ // internal state changes (e.g. hover) would call initialVisibleMonth() and could
322
+ // snap the calendar back to that month.
323
+ if (prevProps !== this.props && !hidden) {
324
+ if (!this.hasSetInitialVisibleMonth) {
325
+ this.hasSetInitialVisibleMonth = true;
326
+ this.setState({
327
+ currentMonth: initialVisibleMonth(),
328
+ });
329
+ } else {
330
+ const newDate = initialVisibleMonth();
331
+ if (!isDayVisible(newDate, currentMonth, numberOfMonths)) {
332
+ this.onMonthChange(newDate);
333
+ }
334
+ }
335
+ }
336
+
337
+ if (daySize !== prevProps.daySize) {
338
+ this.setState({
339
+ calendarMonthWidth: getCalendarMonthWidth(
340
+ daySize,
341
+ horizontalMonthPadding,
342
+ ),
343
+ });
344
+ }
345
+
346
+ // Track the focusedDate that this update produces so the container-focus check
347
+ // below sees the same value componentWillReceiveProps used to set before render.
348
+ let focusedDateAfterUpdate = focusedDate;
349
+ if (isFocused !== prevProps.isFocused) {
350
+ if (isFocused) {
351
+ const newFocusedDate = this.getFocusedDay(currentMonth);
352
+
353
+ let { onKeyboardShortcutsPanelClose } = this.state;
354
+ if (showKeyboardShortcuts) {
355
+ // the ? shortcut came from the input and we should return input there once it is close
356
+ onKeyboardShortcutsPanelClose = onBlur;
357
+ }
358
+
359
+ this.setState({
360
+ showKeyboardShortcuts,
361
+ onKeyboardShortcutsPanelClose,
362
+ focusedDate: newFocusedDate,
363
+ withMouseInteractions: false,
364
+ });
365
+ focusedDateAfterUpdate = newFocusedDate;
366
+ } else {
367
+ this.setState({ focusedDate: null });
368
+ focusedDateAfterUpdate = null;
369
+ }
370
+ }
371
+
372
+ if (renderMonthText !== null && prevProps.renderMonthText !== null
373
+ && renderMonthText(currentMonth) !== prevProps.renderMonthText(currentMonth)) {
374
+ this.setState({
375
+ monthTitleHeight: null,
376
+ });
377
+ }
378
+
379
+ // ----- migrated from componentWillUpdate -----
380
+ // Calculating the dimensions triggers a DOM repaint which breaks the CSS
381
+ // transition. The setTimeout waits until the transition ends.
382
+ if (this.calendarInfo) {
383
+ this.setCalendarInfoWidthTimeout = setTimeout(() => {
384
+ const { calendarInfoWidth } = this.state;
385
+ const calendarInfoPanelWidth = calculateDimension(this.calendarInfo, 'width', true, true);
386
+ if (calendarInfoWidth !== calendarInfoPanelWidth) {
387
+ this.setState({
388
+ calendarInfoWidth: calendarInfoPanelWidth,
389
+ });
390
+ }
391
+ }, transitionDuration);
392
+ }
393
+
394
+ // ----- existing componentDidUpdate behaviour -----
395
+ let shouldAdjustHeight = false;
396
+ if (numberOfMonths !== prevProps.numberOfMonths) {
397
+ this.setCalendarMonthWeeks(currentMonth);
398
+ shouldAdjustHeight = true;
399
+ }
400
+ if (
401
+ this.isHorizontal()
402
+ && (orientation !== prevProps.orientation || daySize !== prevProps.daySize)
403
+ ) {
404
+ shouldAdjustHeight = true;
405
+ }
406
+
407
+ if (shouldAdjustHeight) {
408
+ const visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1);
409
+ const calendarMonthWeeksHeight = Math.max(0, ...visibleCalendarWeeks) * (daySize - 1);
410
+ const newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1;
411
+ this.adjustDayPickerHeight(newMonthHeight);
412
+ }
413
+
414
+ if (!prevProps.isFocused && isFocused && !focusedDateAfterUpdate) {
415
+ this.container.focus();
416
+ }
417
+
418
+ // If orientation is VERTICAL_SCROLLABLE and currentMonth has changed adjust scrollTop so the
419
+ // new months rendered above the current month don't push the current month out of view.
420
+ if (
421
+ orientation === VERTICAL_SCROLLABLE
422
+ && snapshot != null
423
+ && this.transitionContainer
424
+ ) {
425
+ this.transitionContainer.scrollTop = this.transitionContainer.scrollHeight - snapshot;
426
+ }
427
+ }
428
+
429
+ componentWillUnmount() {
430
+ clearTimeout(this.setCalendarInfoWidthTimeout);
431
+ clearTimeout(this.setCalendarMonthGridHeightTimeout);
432
+ }
433
+
434
+ onKeyDown(e) {
435
+ e.stopPropagation();
436
+
437
+ if (!MODIFIER_KEY_NAMES.has(e.key)) {
438
+ this.throttledKeyDown(e);
439
+ }
440
+ }
441
+
442
+ onFinalKeyDown(e) {
443
+ this.setState({ withMouseInteractions: false });
444
+
445
+ const {
446
+ onBlur,
447
+ onTab,
448
+ onShiftTab,
449
+ isRTL,
450
+ } = this.props;
451
+ const { focusedDate, showKeyboardShortcuts } = this.state;
452
+ if (!focusedDate) return;
453
+
454
+ const newFocusedDate = focusedDate.clone();
455
+
456
+ let didTransitionMonth = false;
457
+
458
+ // focus might be anywhere when the keyboard shortcuts panel is opened so we want to
459
+ // return it to wherever it was before when the panel was opened
460
+ const activeElement = getActiveElement();
461
+ const onKeyboardShortcutsPanelClose = () => {
462
+ if (activeElement) activeElement.focus();
463
+ };
464
+
465
+ switch (e.key) {
466
+ case 'ArrowUp':
467
+ e.preventDefault();
468
+ newFocusedDate.subtract(1, 'week');
469
+ didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate);
470
+ break;
471
+ case 'ArrowLeft':
472
+ e.preventDefault();
473
+ if (isRTL) {
474
+ newFocusedDate.add(1, 'day');
475
+ didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate);
476
+ } else {
477
+ newFocusedDate.subtract(1, 'day');
478
+ didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate);
479
+ }
480
+ break;
481
+ case 'Home':
482
+ e.preventDefault();
483
+ newFocusedDate.startOf('week').hour(12);
484
+ didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate);
485
+ break;
486
+ case 'PageUp':
487
+ e.preventDefault();
488
+ newFocusedDate.subtract(1, 'month');
489
+ didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate);
490
+ break;
491
+
492
+ case 'ArrowDown':
493
+ e.preventDefault();
494
+ newFocusedDate.add(1, 'week');
495
+ didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate);
496
+ break;
497
+ case 'ArrowRight':
498
+ e.preventDefault();
499
+ if (isRTL) {
500
+ newFocusedDate.subtract(1, 'day');
501
+ didTransitionMonth = this.maybeTransitionPrevMonth(newFocusedDate);
502
+ } else {
503
+ newFocusedDate.add(1, 'day');
504
+ didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate);
505
+ }
506
+ break;
507
+ case 'End':
508
+ e.preventDefault();
509
+ newFocusedDate.endOf('week');
510
+ didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate);
511
+ break;
512
+ case 'PageDown':
513
+ e.preventDefault();
514
+ newFocusedDate.add(1, 'month');
515
+ didTransitionMonth = this.maybeTransitionNextMonth(newFocusedDate);
516
+ break;
517
+
518
+ case '?':
519
+ this.openKeyboardShortcutsPanel(onKeyboardShortcutsPanelClose);
520
+ break;
521
+
522
+ case 'Escape':
523
+ if (showKeyboardShortcuts) {
524
+ this.closeKeyboardShortcutsPanel();
525
+ } else {
526
+ onBlur(e);
527
+ }
528
+ break;
529
+
530
+ case 'Tab':
531
+ if (e.shiftKey) {
532
+ onShiftTab();
533
+ } else {
534
+ onTab(e);
535
+ }
536
+ break;
537
+
538
+ default:
539
+ break;
540
+ }
541
+
542
+ // If there was a month transition, do not update the focused date until the transition has
543
+ // completed. Otherwise, attempting to focus on a DOM node may interrupt the CSS animation. If
544
+ // didTransitionMonth is true, the focusedDate gets updated in #updateStateAfterMonthTransition
545
+ if (!didTransitionMonth) {
546
+ this.setState({
547
+ focusedDate: newFocusedDate,
548
+ });
549
+ }
550
+ }
551
+
552
+ onPrevMonthClick(e) {
553
+ if (e) e.preventDefault();
554
+ this.onPrevMonthTransition();
555
+ }
556
+
557
+ onPrevMonthTransition(nextFocusedDate) {
558
+ const { daySize, isRTL, numberOfMonths } = this.props;
559
+ const { calendarMonthWidth, monthTitleHeight } = this.state;
560
+
561
+ let translationValue;
562
+ if (this.isVertical()) {
563
+ const calendarMonthWeeksHeight = this.calendarMonthWeeks[0] * (daySize - 1);
564
+ translationValue = monthTitleHeight + calendarMonthWeeksHeight + 1;
565
+ } else if (this.isHorizontal()) {
566
+ translationValue = calendarMonthWidth;
567
+ if (isRTL) {
568
+ translationValue = -2 * calendarMonthWidth;
569
+ }
570
+
571
+ const visibleCalendarWeeks = this.calendarMonthWeeks.slice(0, numberOfMonths);
572
+ const calendarMonthWeeksHeight = Math.max(0, ...visibleCalendarWeeks) * (daySize - 1);
573
+ const newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1;
574
+ this.adjustDayPickerHeight(newMonthHeight);
575
+ }
576
+
577
+ this.setState({
578
+ monthTransition: PREV_TRANSITION,
579
+ translationValue,
580
+ focusedDate: null,
581
+ nextFocusedDate,
582
+ });
583
+ }
584
+
585
+ onMonthChange(currentMonth) {
586
+ this.setCalendarMonthWeeks(currentMonth);
587
+ this.calculateAndSetDayPickerHeight();
588
+
589
+ // Translation value is a hack to force an invisible transition that
590
+ // properly rerenders the CalendarMonthGrid
591
+ this.setState({
592
+ monthTransition: MONTH_SELECTION_TRANSITION,
593
+ translationValue: 0.00001,
594
+ focusedDate: null,
595
+ nextFocusedDate: currentMonth,
596
+ currentMonth,
597
+ });
598
+ }
599
+
600
+ onYearChange(currentMonth) {
601
+ this.setCalendarMonthWeeks(currentMonth);
602
+ this.calculateAndSetDayPickerHeight();
603
+
604
+ // Translation value is a hack to force an invisible transition that
605
+ // properly rerenders the CalendarMonthGrid
606
+ this.setState({
607
+ monthTransition: YEAR_SELECTION_TRANSITION,
608
+ translationValue: 0.0001,
609
+ focusedDate: null,
610
+ nextFocusedDate: currentMonth,
611
+ currentMonth,
612
+ });
613
+ }
614
+
615
+ onNextMonthClick(e) {
616
+ if (e) e.preventDefault();
617
+ this.onNextMonthTransition();
618
+ }
619
+
620
+ onNextMonthTransition(nextFocusedDate) {
621
+ const { isRTL, numberOfMonths, daySize } = this.props;
622
+ const { calendarMonthWidth, monthTitleHeight } = this.state;
623
+
624
+ let translationValue;
625
+
626
+ if (this.isVertical()) {
627
+ const firstVisibleMonthWeeks = this.calendarMonthWeeks[1];
628
+ const calendarMonthWeeksHeight = firstVisibleMonthWeeks * (daySize - 1);
629
+ translationValue = -(monthTitleHeight + calendarMonthWeeksHeight + 1);
630
+ }
631
+
632
+ if (this.isHorizontal()) {
633
+ translationValue = -calendarMonthWidth;
634
+ if (isRTL) {
635
+ translationValue = 0;
636
+ }
637
+
638
+ const visibleCalendarWeeks = this.calendarMonthWeeks.slice(2, numberOfMonths + 2);
639
+ const calendarMonthWeeksHeight = Math.max(0, ...visibleCalendarWeeks) * (daySize - 1);
640
+ const newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1;
641
+ this.adjustDayPickerHeight(newMonthHeight);
642
+ }
643
+
644
+ this.setState({
645
+ monthTransition: NEXT_TRANSITION,
646
+ translationValue,
647
+ focusedDate: null,
648
+ nextFocusedDate,
649
+ });
650
+ }
651
+
652
+ getFirstDayOfWeek() {
653
+ const { firstDayOfWeek } = this.props;
654
+ if (firstDayOfWeek == null) {
655
+ return moment.localeData().firstDayOfWeek();
656
+ }
657
+
658
+ return firstDayOfWeek;
659
+ }
660
+
661
+ getWeekHeaders() {
662
+ const { weekDayFormat } = this.props;
663
+ const { currentMonth } = this.state;
664
+ const firstDayOfWeek = this.getFirstDayOfWeek();
665
+
666
+ const weekHeaders = [];
667
+ for (let i = 0; i < 7; i += 1) {
668
+ weekHeaders.push(currentMonth.clone().day((i + firstDayOfWeek) % 7).format(weekDayFormat));
669
+ }
670
+
671
+ return weekHeaders;
672
+ }
673
+
674
+ getFirstVisibleIndex() {
675
+ const { orientation } = this.props;
676
+ const { monthTransition } = this.state;
677
+
678
+ if (orientation === VERTICAL_SCROLLABLE) return 0;
679
+
680
+ let firstVisibleMonthIndex = 1;
681
+ if (monthTransition === PREV_TRANSITION) {
682
+ firstVisibleMonthIndex -= 1;
683
+ } else if (monthTransition === NEXT_TRANSITION) {
684
+ firstVisibleMonthIndex += 1;
685
+ }
686
+
687
+ return firstVisibleMonthIndex;
688
+ }
689
+
690
+ getFocusedDay(newMonth) {
691
+ const { getFirstFocusableDay, numberOfMonths } = this.props;
692
+
693
+ let focusedDate;
694
+ if (getFirstFocusableDay) {
695
+ focusedDate = getFirstFocusableDay(newMonth);
696
+ }
697
+
698
+ if (newMonth && (!focusedDate || !isDayVisible(focusedDate, newMonth, numberOfMonths))) {
699
+ focusedDate = newMonth.clone().startOf('month').hour(12);
700
+ }
701
+
702
+ return focusedDate;
703
+ }
704
+
705
+ setMonthTitleHeight(monthTitleHeight) {
706
+ this.setState({
707
+ monthTitleHeight,
708
+ }, () => {
709
+ this.calculateAndSetDayPickerHeight();
710
+ });
711
+ }
712
+
713
+ setCalendarMonthWeeks(currentMonth) {
714
+ const { numberOfMonths } = this.props;
715
+
716
+ this.calendarMonthWeeks = [];
717
+ let month = currentMonth.clone().subtract(1, 'months');
718
+ const firstDayOfWeek = this.getFirstDayOfWeek();
719
+ for (let i = 0; i < numberOfMonths + 2; i += 1) {
720
+ const numberOfWeeks = getNumberOfCalendarMonthWeeks(month, firstDayOfWeek);
721
+ this.calendarMonthWeeks.push(numberOfWeeks);
722
+ month = month.add(1, 'months');
723
+ }
724
+ }
725
+
726
+ setContainerRef(ref) {
727
+ this.container = ref;
728
+ }
729
+
730
+ setCalendarInfoRef(ref) {
731
+ this.calendarInfo = ref;
732
+ }
733
+
734
+ setTransitionContainerRef(ref) {
735
+ this.transitionContainer = ref;
736
+ }
737
+
738
+ getNextScrollableMonths(e) {
739
+ const { onGetNextScrollableMonths } = this.props;
740
+ if (e) e.preventDefault();
741
+
742
+ if (onGetNextScrollableMonths) onGetNextScrollableMonths(e);
743
+
744
+ this.setState(({ scrollableMonthMultiple }) => ({
745
+ scrollableMonthMultiple: scrollableMonthMultiple + 1,
746
+ }));
747
+ }
748
+
749
+ getPrevScrollableMonths(e) {
750
+ const { numberOfMonths, onGetPrevScrollableMonths } = this.props;
751
+ if (e) e.preventDefault();
752
+
753
+ if (onGetPrevScrollableMonths) onGetPrevScrollableMonths(e);
754
+
755
+ this.setState(({ currentMonth, scrollableMonthMultiple }) => ({
756
+ currentMonth: currentMonth.clone().subtract(numberOfMonths, 'month'),
757
+ scrollableMonthMultiple: scrollableMonthMultiple + 1,
758
+ }));
759
+ }
760
+
761
+ maybeTransitionNextMonth(newFocusedDate) {
762
+ const { numberOfMonths } = this.props;
763
+ const { currentMonth, focusedDate } = this.state;
764
+
765
+ const newFocusedDateMonth = newFocusedDate.month();
766
+ const focusedDateMonth = focusedDate.month();
767
+ const isNewFocusedDateVisible = isDayVisible(newFocusedDate, currentMonth, numberOfMonths);
768
+ if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) {
769
+ this.onNextMonthTransition(newFocusedDate);
770
+ return true;
771
+ }
772
+
773
+ return false;
774
+ }
775
+
776
+ maybeTransitionPrevMonth(newFocusedDate) {
777
+ const { numberOfMonths } = this.props;
778
+ const { currentMonth, focusedDate } = this.state;
779
+
780
+ const newFocusedDateMonth = newFocusedDate.month();
781
+ const focusedDateMonth = focusedDate.month();
782
+ const isNewFocusedDateVisible = isDayVisible(newFocusedDate, currentMonth, numberOfMonths);
783
+ if (newFocusedDateMonth !== focusedDateMonth && !isNewFocusedDateVisible) {
784
+ this.onPrevMonthTransition(newFocusedDate);
785
+ return true;
786
+ }
787
+
788
+ return false;
789
+ }
790
+
791
+ isHorizontal() {
792
+ const { orientation } = this.props;
793
+ return orientation === HORIZONTAL_ORIENTATION;
794
+ }
795
+
796
+ isVertical() {
797
+ const { orientation } = this.props;
798
+ return orientation === VERTICAL_ORIENTATION || orientation === VERTICAL_SCROLLABLE;
799
+ }
800
+
801
+ updateStateAfterMonthTransition() {
802
+ const {
803
+ onPrevMonthClick,
804
+ onNextMonthClick,
805
+ numberOfMonths,
806
+ onMonthChange,
807
+ onYearChange,
808
+ isRTL,
809
+ } = this.props;
810
+
811
+ const {
812
+ currentMonth,
813
+ monthTransition,
814
+ focusedDate,
815
+ nextFocusedDate,
816
+ withMouseInteractions,
817
+ calendarMonthWidth,
818
+ } = this.state;
819
+
820
+ if (!monthTransition) return;
821
+
822
+ const newMonth = currentMonth.clone();
823
+ const firstDayOfWeek = this.getFirstDayOfWeek();
824
+ if (monthTransition === PREV_TRANSITION) {
825
+ newMonth.subtract(1, 'month');
826
+ if (onPrevMonthClick) onPrevMonthClick(newMonth);
827
+ const newInvisibleMonth = newMonth.clone().subtract(1, 'month');
828
+ const numberOfWeeks = getNumberOfCalendarMonthWeeks(newInvisibleMonth, firstDayOfWeek);
829
+ this.calendarMonthWeeks = [numberOfWeeks, ...this.calendarMonthWeeks.slice(0, -1)];
830
+ } else if (monthTransition === NEXT_TRANSITION) {
831
+ newMonth.add(1, 'month');
832
+ if (onNextMonthClick) onNextMonthClick(newMonth);
833
+ const newInvisibleMonth = newMonth.clone().add(numberOfMonths, 'month');
834
+ const numberOfWeeks = getNumberOfCalendarMonthWeeks(newInvisibleMonth, firstDayOfWeek);
835
+ this.calendarMonthWeeks = [...this.calendarMonthWeeks.slice(1), numberOfWeeks];
836
+ } else if (monthTransition === MONTH_SELECTION_TRANSITION) {
837
+ if (onMonthChange) onMonthChange(newMonth);
838
+ } else if (monthTransition === YEAR_SELECTION_TRANSITION) {
839
+ if (onYearChange) onYearChange(newMonth);
840
+ }
841
+
842
+ let newFocusedDate = null;
843
+ if (nextFocusedDate) {
844
+ newFocusedDate = nextFocusedDate;
845
+ } else if (!focusedDate && !withMouseInteractions) {
846
+ newFocusedDate = this.getFocusedDay(newMonth);
847
+ }
848
+
849
+ this.setState({
850
+ currentMonth: newMonth,
851
+ monthTransition: null,
852
+ translationValue: (isRTL && this.isHorizontal()) ? -calendarMonthWidth : 0,
853
+ nextFocusedDate: null,
854
+ focusedDate: newFocusedDate,
855
+ }, () => {
856
+ // we don't want to focus on the relevant calendar day after a month transition
857
+ // if the user is navigating around using a mouse
858
+ if (withMouseInteractions) {
859
+ const activeElement = getActiveElement();
860
+ if (
861
+ activeElement
862
+ && activeElement !== document.body
863
+ && this.container.contains(activeElement)
864
+ && activeElement.blur
865
+ ) {
866
+ activeElement.blur();
867
+ }
868
+ }
869
+ });
870
+ }
871
+
872
+ adjustDayPickerHeight(newMonthHeight) {
873
+ const monthHeight = newMonthHeight + MONTH_PADDING;
874
+ if (monthHeight !== this.calendarMonthGridHeight) {
875
+ this.transitionContainer.style.height = `${monthHeight}px`;
876
+ if (!this.calendarMonthGridHeight) {
877
+ this.setCalendarMonthGridHeightTimeout = setTimeout(() => {
878
+ this.setState({ hasSetHeight: true });
879
+ }, 0);
880
+ }
881
+ this.calendarMonthGridHeight = monthHeight;
882
+ }
883
+ }
884
+
885
+ calculateAndSetDayPickerHeight() {
886
+ const { daySize, numberOfMonths } = this.props;
887
+ const { monthTitleHeight } = this.state;
888
+
889
+ const visibleCalendarWeeks = this.calendarMonthWeeks.slice(1, numberOfMonths + 1);
890
+ const calendarMonthWeeksHeight = Math.max(0, ...visibleCalendarWeeks) * (daySize - 1);
891
+ const newMonthHeight = monthTitleHeight + calendarMonthWeeksHeight + 1;
892
+
893
+ if (this.isHorizontal()) {
894
+ this.adjustDayPickerHeight(newMonthHeight);
895
+ }
896
+ }
897
+
898
+ openKeyboardShortcutsPanel(onCloseCallBack) {
899
+ this.setState({
900
+ showKeyboardShortcuts: true,
901
+ onKeyboardShortcutsPanelClose: onCloseCallBack,
902
+ });
903
+ }
904
+
905
+ closeKeyboardShortcutsPanel() {
906
+ const { onKeyboardShortcutsPanelClose } = this.state;
907
+
908
+ if (onKeyboardShortcutsPanelClose) {
909
+ onKeyboardShortcutsPanelClose();
910
+ }
911
+
912
+ this.setState({
913
+ onKeyboardShortcutsPanelClose: null,
914
+ showKeyboardShortcuts: false,
915
+ });
916
+ }
917
+
918
+ renderNavigation(navDirection) {
919
+ const {
920
+ dayPickerNavigationInlineStyles,
921
+ disablePrev,
922
+ disableNext,
923
+ navPosition,
924
+ navPrev,
925
+ navNext,
926
+ noNavButtons,
927
+ noNavNextButton,
928
+ noNavPrevButton,
929
+ orientation,
930
+ phrases,
931
+ renderNavPrevButton,
932
+ renderNavNextButton,
933
+ isRTL,
934
+ } = this.props;
935
+
936
+ if (noNavButtons) {
937
+ return null;
938
+ }
939
+
940
+ const onPrevMonthClick = orientation === VERTICAL_SCROLLABLE
941
+ ? this.getPrevScrollableMonths
942
+ : this.onPrevMonthClick;
943
+
944
+ const onNextMonthClick = orientation === VERTICAL_SCROLLABLE
945
+ ? this.getNextScrollableMonths
946
+ : this.onNextMonthClick;
947
+
948
+ return (
949
+ <DayPickerNavigation
950
+ disablePrev={disablePrev}
951
+ disableNext={disableNext}
952
+ inlineStyles={dayPickerNavigationInlineStyles}
953
+ onPrevMonthClick={onPrevMonthClick}
954
+ onNextMonthClick={onNextMonthClick}
955
+ navPosition={navPosition}
956
+ navPrev={navPrev}
957
+ navNext={navNext}
958
+ renderNavPrevButton={renderNavPrevButton}
959
+ renderNavNextButton={renderNavNextButton}
960
+ orientation={orientation}
961
+ phrases={phrases}
962
+ isRTL={isRTL}
963
+ showNavNextButton={
964
+ !(noNavNextButton || (orientation === VERTICAL_SCROLLABLE && navDirection === PREV_NAV))
965
+ }
966
+ showNavPrevButton={
967
+ !(noNavPrevButton || (orientation === VERTICAL_SCROLLABLE && navDirection === NEXT_NAV))
968
+ }
969
+ />
970
+ );
971
+ }
972
+
973
+ renderWeekHeader(index) {
974
+ const {
975
+ daySize,
976
+ horizontalMonthPadding,
977
+ orientation,
978
+ renderWeekHeaderElement,
979
+ css,
980
+ styles,
981
+ } = this.props;
982
+
983
+ const { calendarMonthWidth } = this.state;
984
+
985
+ const verticalScrollable = orientation === VERTICAL_SCROLLABLE;
986
+
987
+ const horizontalStyle = {
988
+ left: index * calendarMonthWidth,
989
+ };
990
+ const verticalStyle = {
991
+ marginLeft: -calendarMonthWidth / 2,
992
+ };
993
+
994
+ let weekHeaderStyle = {}; // no styles applied to the vertical-scrollable orientation
995
+ if (this.isHorizontal()) {
996
+ weekHeaderStyle = horizontalStyle;
997
+ } else if (this.isVertical() && !verticalScrollable) {
998
+ weekHeaderStyle = verticalStyle;
999
+ }
1000
+
1001
+ const weekHeaders = this.getWeekHeaders();
1002
+ const header = weekHeaders.map((day) => (
1003
+ <li key={day} {...css(styles.DayPicker_weekHeader_li, { width: daySize })}>
1004
+ {renderWeekHeaderElement ? renderWeekHeaderElement(day) : <small>{day}</small>}
1005
+ </li>
1006
+ ));
1007
+
1008
+ return (
1009
+ <div
1010
+ {...css(
1011
+ styles.DayPicker_weekHeader,
1012
+ this.isVertical() && styles.DayPicker_weekHeader__vertical,
1013
+ verticalScrollable && styles.DayPicker_weekHeader__verticalScrollable,
1014
+ weekHeaderStyle,
1015
+ { padding: `0 ${horizontalMonthPadding}px` },
1016
+ )}
1017
+ key={`week-${index}`}
1018
+ >
1019
+ <ul {...css(styles.DayPicker_weekHeader_ul)}>
1020
+ {header}
1021
+ </ul>
1022
+ </div>
1023
+ );
1024
+ }
1025
+
1026
+ render() {
1027
+ const {
1028
+ calendarMonthWidth,
1029
+ currentMonth,
1030
+ monthTransition,
1031
+ translationValue,
1032
+ scrollableMonthMultiple,
1033
+ focusedDate,
1034
+ showKeyboardShortcuts,
1035
+ isTouchDevice: isTouch,
1036
+ hasSetHeight,
1037
+ calendarInfoWidth,
1038
+ monthTitleHeight,
1039
+ } = this.state;
1040
+
1041
+ const {
1042
+ enableOutsideDays,
1043
+ numberOfMonths,
1044
+ orientation,
1045
+ modifiers,
1046
+ withPortal,
1047
+ onDayClick,
1048
+ onDayMouseEnter,
1049
+ onDayMouseLeave,
1050
+ firstDayOfWeek,
1051
+ renderMonthText,
1052
+ renderCalendarDay,
1053
+ renderDayContents,
1054
+ renderCalendarInfo,
1055
+ renderMonthElement,
1056
+ renderKeyboardShortcutsButton,
1057
+ renderKeyboardShortcutsPanel,
1058
+ calendarInfoPosition,
1059
+ hideKeyboardShortcutsPanel,
1060
+ onOutsideClick,
1061
+ monthFormat,
1062
+ daySize,
1063
+ isFocused,
1064
+ isRTL,
1065
+ css,
1066
+ styles,
1067
+ theme,
1068
+ phrases,
1069
+ verticalHeight,
1070
+ dayAriaLabelFormat,
1071
+ noBorder,
1072
+ transitionDuration,
1073
+ verticalBorderSpacing,
1074
+ horizontalMonthPadding,
1075
+ navPosition,
1076
+ } = this.props;
1077
+
1078
+ const { reactDates: { spacing: { dayPickerHorizontalPadding } } } = theme;
1079
+
1080
+ const isHorizontal = this.isHorizontal();
1081
+
1082
+ const numOfWeekHeaders = this.isVertical() ? 1 : numberOfMonths;
1083
+ const weekHeaders = [];
1084
+ for (let i = 0; i < numOfWeekHeaders; i += 1) {
1085
+ weekHeaders.push(this.renderWeekHeader(i));
1086
+ }
1087
+
1088
+ const verticalScrollable = orientation === VERTICAL_SCROLLABLE;
1089
+ let height;
1090
+ if (isHorizontal) {
1091
+ height = this.calendarMonthGridHeight;
1092
+ } else if (this.isVertical() && !verticalScrollable && !withPortal) {
1093
+ // If the user doesn't set a desired height,
1094
+ // we default back to this kind of made-up value that generally looks good
1095
+ height = verticalHeight || 1.75 * calendarMonthWidth;
1096
+ }
1097
+
1098
+ const isCalendarMonthGridAnimating = monthTransition !== null;
1099
+
1100
+ const shouldFocusDate = !isCalendarMonthGridAnimating && isFocused;
1101
+
1102
+ let keyboardShortcutButtonLocation = BOTTOM_RIGHT;
1103
+ if (this.isVertical()) {
1104
+ keyboardShortcutButtonLocation = withPortal ? TOP_LEFT : TOP_RIGHT;
1105
+ }
1106
+
1107
+ const shouldAnimateHeight = isHorizontal && hasSetHeight;
1108
+
1109
+ const calendarInfoPositionTop = calendarInfoPosition === INFO_POSITION_TOP;
1110
+ const calendarInfoPositionBottom = calendarInfoPosition === INFO_POSITION_BOTTOM;
1111
+ const calendarInfoPositionBefore = calendarInfoPosition === INFO_POSITION_BEFORE;
1112
+ const calendarInfoPositionAfter = calendarInfoPosition === INFO_POSITION_AFTER;
1113
+ const calendarInfoIsInline = calendarInfoPositionBefore || calendarInfoPositionAfter;
1114
+
1115
+ const calendarInfo = renderCalendarInfo && (
1116
+ <div
1117
+ ref={this.setCalendarInfoRef}
1118
+ {...css((calendarInfoIsInline) && styles.DayPicker_calendarInfo__horizontal)}
1119
+ >
1120
+ {renderCalendarInfo()}
1121
+ </div>
1122
+ );
1123
+
1124
+ const calendarInfoPanelWidth = renderCalendarInfo && calendarInfoIsInline
1125
+ ? calendarInfoWidth
1126
+ : 0;
1127
+
1128
+ const firstVisibleMonthIndex = this.getFirstVisibleIndex();
1129
+ const wrapperHorizontalWidth = (calendarMonthWidth * numberOfMonths)
1130
+ + (2 * dayPickerHorizontalPadding);
1131
+ // Adding `1px` because of whitespace between 2 inline-block
1132
+ const fullHorizontalWidth = wrapperHorizontalWidth + calendarInfoPanelWidth + 1;
1133
+
1134
+ const transitionContainerStyle = {
1135
+ width: isHorizontal && wrapperHorizontalWidth,
1136
+ height,
1137
+ };
1138
+
1139
+ const dayPickerWrapperStyle = {
1140
+ width: isHorizontal && wrapperHorizontalWidth,
1141
+ };
1142
+
1143
+ const dayPickerStyle = {
1144
+ width: isHorizontal && fullHorizontalWidth,
1145
+
1146
+ // These values are to center the datepicker (approximately) on the page
1147
+ marginLeft: isHorizontal && withPortal ? -fullHorizontalWidth / 2 : null,
1148
+ marginTop: isHorizontal && withPortal ? -calendarMonthWidth / 2 : null,
1149
+ };
1150
+
1151
+ return (
1152
+ <div
1153
+ {...css(
1154
+ styles.DayPicker,
1155
+ isHorizontal && styles.DayPicker__horizontal,
1156
+ verticalScrollable && styles.DayPicker__verticalScrollable,
1157
+ isHorizontal && withPortal && styles.DayPicker_portal__horizontal,
1158
+ this.isVertical() && withPortal && styles.DayPicker_portal__vertical,
1159
+ dayPickerStyle,
1160
+ !monthTitleHeight && styles.DayPicker__hidden,
1161
+ !noBorder && styles.DayPicker__withBorder,
1162
+ )}
1163
+ >
1164
+ <OutsideClickHandler onOutsideClick={onOutsideClick}>
1165
+ {(calendarInfoPositionTop || calendarInfoPositionBefore) && calendarInfo}
1166
+
1167
+ <div
1168
+ {...css(
1169
+ dayPickerWrapperStyle,
1170
+ calendarInfoIsInline && isHorizontal && styles.DayPicker_wrapper__horizontal,
1171
+ )}
1172
+ >
1173
+
1174
+ <div
1175
+ {...css(
1176
+ styles.DayPicker_weekHeaders,
1177
+ isHorizontal && styles.DayPicker_weekHeaders__horizontal,
1178
+ )}
1179
+ aria-hidden="true"
1180
+ role="presentation"
1181
+ >
1182
+ {weekHeaders}
1183
+ </div>
1184
+
1185
+ <div // eslint-disable-line jsx-a11y/no-noninteractive-element-interactions
1186
+ {...css(styles.DayPicker_focusRegion)}
1187
+ ref={this.setContainerRef}
1188
+ onClick={(e) => { e.stopPropagation(); }}
1189
+ onKeyDown={this.onKeyDown}
1190
+ onMouseUp={() => { this.setState({ withMouseInteractions: true }); }}
1191
+ tabIndex={-1}
1192
+ role="application"
1193
+ aria-roledescription={phrases.roleDescription}
1194
+ aria-label={phrases.calendarLabel}
1195
+ >
1196
+ {!verticalScrollable && navPosition === NAV_POSITION_TOP && this.renderNavigation()}
1197
+
1198
+ <div
1199
+ {...css(
1200
+ styles.DayPicker_transitionContainer,
1201
+ shouldAnimateHeight && styles.DayPicker_transitionContainer__horizontal,
1202
+ this.isVertical() && styles.DayPicker_transitionContainer__vertical,
1203
+ verticalScrollable && styles.DayPicker_transitionContainer__verticalScrollable,
1204
+ transitionContainerStyle,
1205
+ )}
1206
+ ref={this.setTransitionContainerRef}
1207
+ >
1208
+ {verticalScrollable && this.renderNavigation(PREV_NAV)}
1209
+ <CalendarMonthGrid
1210
+ setMonthTitleHeight={!monthTitleHeight ? this.setMonthTitleHeight : undefined}
1211
+ translationValue={translationValue}
1212
+ enableOutsideDays={enableOutsideDays}
1213
+ firstVisibleMonthIndex={firstVisibleMonthIndex}
1214
+ initialMonth={currentMonth}
1215
+ isAnimating={isCalendarMonthGridAnimating}
1216
+ modifiers={modifiers}
1217
+ orientation={orientation}
1218
+ numberOfMonths={numberOfMonths * scrollableMonthMultiple}
1219
+ onDayClick={onDayClick}
1220
+ onDayMouseEnter={onDayMouseEnter}
1221
+ onDayMouseLeave={onDayMouseLeave}
1222
+ onMonthChange={this.onMonthChange}
1223
+ onYearChange={this.onYearChange}
1224
+ renderMonthText={renderMonthText}
1225
+ renderCalendarDay={renderCalendarDay}
1226
+ renderDayContents={renderDayContents}
1227
+ renderMonthElement={renderMonthElement}
1228
+ onMonthTransitionEnd={this.updateStateAfterMonthTransition}
1229
+ monthFormat={monthFormat}
1230
+ daySize={daySize}
1231
+ firstDayOfWeek={firstDayOfWeek}
1232
+ isFocused={shouldFocusDate}
1233
+ focusedDate={focusedDate}
1234
+ phrases={phrases}
1235
+ isRTL={isRTL}
1236
+ dayAriaLabelFormat={dayAriaLabelFormat}
1237
+ transitionDuration={transitionDuration}
1238
+ verticalBorderSpacing={verticalBorderSpacing}
1239
+ horizontalMonthPadding={horizontalMonthPadding}
1240
+ />
1241
+ {verticalScrollable && this.renderNavigation(NEXT_NAV)}
1242
+ </div>
1243
+
1244
+ {!verticalScrollable
1245
+ && navPosition === NAV_POSITION_BOTTOM
1246
+ && this.renderNavigation()}
1247
+
1248
+ {!isTouch && !hideKeyboardShortcutsPanel && (
1249
+ <DayPickerKeyboardShortcuts
1250
+ block={this.isVertical() && !withPortal}
1251
+ buttonLocation={keyboardShortcutButtonLocation}
1252
+ showKeyboardShortcutsPanel={showKeyboardShortcuts}
1253
+ openKeyboardShortcutsPanel={this.openKeyboardShortcutsPanel}
1254
+ closeKeyboardShortcutsPanel={this.closeKeyboardShortcutsPanel}
1255
+ phrases={phrases}
1256
+ renderKeyboardShortcutsButton={renderKeyboardShortcutsButton}
1257
+ renderKeyboardShortcutsPanel={renderKeyboardShortcutsPanel}
1258
+ />
1259
+ )}
1260
+ </div>
1261
+ </div>
1262
+
1263
+ {(calendarInfoPositionBottom || calendarInfoPositionAfter) && calendarInfo}
1264
+ </OutsideClickHandler>
1265
+ </div>
1266
+ );
1267
+ }
1268
+ }
1269
+
1270
+ DayPicker.propTypes = propTypes;
1271
+ DayPicker.defaultProps = defaultProps;
1272
+
1273
+ export { DayPicker as PureDayPicker };
1274
+
1275
+ export default withStyles(({
1276
+ reactDates: {
1277
+ color,
1278
+ font,
1279
+ noScrollBarOnVerticalScrollable,
1280
+ spacing,
1281
+ zIndex,
1282
+ },
1283
+ }) => ({
1284
+ DayPicker: {
1285
+ background: color.background,
1286
+ position: 'relative',
1287
+ textAlign: noflip('left'),
1288
+ },
1289
+
1290
+ DayPicker__horizontal: {
1291
+ background: color.background,
1292
+ },
1293
+
1294
+ DayPicker__verticalScrollable: {
1295
+ height: '100%',
1296
+ },
1297
+
1298
+ DayPicker__hidden: {
1299
+ visibility: 'hidden',
1300
+ },
1301
+
1302
+ DayPicker__withBorder: {
1303
+ boxShadow: noflip('0 2px 6px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.07)'),
1304
+ borderRadius: 3,
1305
+ },
1306
+
1307
+ DayPicker_portal__horizontal: {
1308
+ boxShadow: 'none',
1309
+ position: 'absolute',
1310
+ left: noflip('50%'),
1311
+ top: '50%',
1312
+ },
1313
+
1314
+ DayPicker_portal__vertical: {
1315
+ position: 'initial',
1316
+ },
1317
+
1318
+ DayPicker_focusRegion: {
1319
+ outline: 'none',
1320
+ },
1321
+
1322
+ DayPicker_calendarInfo__horizontal: {
1323
+ display: 'inline-block',
1324
+ verticalAlign: 'top',
1325
+ },
1326
+
1327
+ DayPicker_wrapper__horizontal: {
1328
+ display: 'inline-block',
1329
+ verticalAlign: 'top',
1330
+ },
1331
+
1332
+ DayPicker_weekHeaders: {
1333
+ position: 'relative',
1334
+ },
1335
+
1336
+ DayPicker_weekHeaders__horizontal: {
1337
+ marginLeft: noflip(spacing.dayPickerHorizontalPadding),
1338
+ },
1339
+
1340
+ DayPicker_weekHeader: {
1341
+ color: color.placeholderText,
1342
+ position: 'absolute',
1343
+ top: 62,
1344
+ zIndex: zIndex + 2,
1345
+ textAlign: noflip('left'),
1346
+ },
1347
+
1348
+ DayPicker_weekHeader__vertical: {
1349
+ left: noflip('50%'),
1350
+ },
1351
+
1352
+ DayPicker_weekHeader__verticalScrollable: {
1353
+ top: 0,
1354
+ display: 'table-row',
1355
+ borderBottom: `1px solid ${color.core.border}`,
1356
+ background: color.background,
1357
+ marginLeft: noflip(0),
1358
+ left: noflip(0),
1359
+ width: '100%',
1360
+ textAlign: 'center',
1361
+ },
1362
+
1363
+ DayPicker_weekHeader_ul: {
1364
+ listStyle: 'none',
1365
+ margin: '1px 0',
1366
+ paddingLeft: noflip(0),
1367
+ paddingRight: noflip(0),
1368
+ fontSize: font.size,
1369
+ },
1370
+
1371
+ DayPicker_weekHeader_li: {
1372
+ display: 'inline-block',
1373
+ textAlign: 'center',
1374
+ },
1375
+
1376
+ DayPicker_transitionContainer: {
1377
+ position: 'relative',
1378
+ overflow: 'hidden',
1379
+ borderRadius: 3,
1380
+ },
1381
+
1382
+ DayPicker_transitionContainer__horizontal: {
1383
+ transition: 'height 0.2s ease-in-out',
1384
+ },
1385
+
1386
+ DayPicker_transitionContainer__vertical: {
1387
+ width: '100%',
1388
+ },
1389
+
1390
+ DayPicker_transitionContainer__verticalScrollable: {
1391
+ paddingTop: 20,
1392
+ height: '100%',
1393
+ position: 'absolute',
1394
+ top: 0,
1395
+ bottom: 0,
1396
+ right: noflip(0),
1397
+ left: noflip(0),
1398
+ overflowY: 'scroll',
1399
+ ...(noScrollBarOnVerticalScrollable && {
1400
+ '-webkitOverflowScrolling': 'touch',
1401
+ '::-webkit-scrollbar': {
1402
+ '-webkit-appearance': 'none',
1403
+ display: 'none',
1404
+ },
1405
+ }),
1406
+ },
1407
+ }), { pureComponent: typeof React.PureComponent !== 'undefined' })(DayPicker);