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