1 | import React from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 | import momentPropTypes from 'react-moment-proptypes';
|
4 | import { forbidExtraProps, mutuallyExclusiveProps, nonNegativeInteger } from 'airbnb-prop-types';
|
5 | import moment from 'moment';
|
6 | import values from 'object.values';
|
7 | import isTouchDevice from 'is-touch-device';
|
8 |
|
9 | import { DayPickerPhrases } from '../defaultPhrases';
|
10 | import getPhrasePropTypes from '../utils/getPhrasePropTypes';
|
11 |
|
12 | import isSameDay from '../utils/isSameDay';
|
13 | import isAfterDay from '../utils/isAfterDay';
|
14 |
|
15 | import getVisibleDays from '../utils/getVisibleDays';
|
16 |
|
17 | import toISODateString from '../utils/toISODateString';
|
18 | import { addModifier, deleteModifier } from '../utils/modifiers';
|
19 |
|
20 | import ScrollableOrientationShape from '../shapes/ScrollableOrientationShape';
|
21 | import DayOfWeekShape from '../shapes/DayOfWeekShape';
|
22 | import CalendarInfoPositionShape from '../shapes/CalendarInfoPositionShape';
|
23 |
|
24 | import {
|
25 | HORIZONTAL_ORIENTATION,
|
26 | VERTICAL_SCROLLABLE,
|
27 | DAY_SIZE,
|
28 | INFO_POSITION_BOTTOM,
|
29 | } from '../constants';
|
30 |
|
31 | import DayPicker from './DayPicker';
|
32 | import getPooledMoment from '../utils/getPooledMoment';
|
33 |
|
34 | const propTypes = forbidExtraProps({
|
35 | date: momentPropTypes.momentObj,
|
36 | onDateChange: PropTypes.func,
|
37 |
|
38 | focused: PropTypes.bool,
|
39 | onFocusChange: PropTypes.func,
|
40 | onClose: PropTypes.func,
|
41 |
|
42 | keepOpenOnDateSelect: PropTypes.bool,
|
43 | isOutsideRange: PropTypes.func,
|
44 | isDayBlocked: PropTypes.func,
|
45 | isDayHighlighted: PropTypes.func,
|
46 |
|
47 |
|
48 | renderMonthText: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
|
49 | renderMonthElement: mutuallyExclusiveProps(PropTypes.func, 'renderMonthText', 'renderMonthElement'),
|
50 | renderWeekHeaderElement: PropTypes.func,
|
51 | enableOutsideDays: PropTypes.bool,
|
52 | numberOfMonths: PropTypes.number,
|
53 | orientation: ScrollableOrientationShape,
|
54 | withPortal: PropTypes.bool,
|
55 | initialVisibleMonth: PropTypes.func,
|
56 | firstDayOfWeek: DayOfWeekShape,
|
57 | hideKeyboardShortcutsPanel: PropTypes.bool,
|
58 | daySize: nonNegativeInteger,
|
59 | verticalHeight: nonNegativeInteger,
|
60 | noBorder: PropTypes.bool,
|
61 | verticalBorderSpacing: nonNegativeInteger,
|
62 | transitionDuration: nonNegativeInteger,
|
63 | horizontalMonthPadding: nonNegativeInteger,
|
64 |
|
65 | navPrev: PropTypes.node,
|
66 | navNext: PropTypes.node,
|
67 |
|
68 | onPrevMonthClick: PropTypes.func,
|
69 | onNextMonthClick: PropTypes.func,
|
70 | onOutsideClick: PropTypes.func,
|
71 | renderCalendarDay: PropTypes.func,
|
72 | renderDayContents: PropTypes.func,
|
73 | renderCalendarInfo: PropTypes.func,
|
74 | calendarInfoPosition: CalendarInfoPositionShape,
|
75 |
|
76 |
|
77 | onBlur: PropTypes.func,
|
78 | isFocused: PropTypes.bool,
|
79 | showKeyboardShortcuts: PropTypes.bool,
|
80 | onTab: PropTypes.func,
|
81 | onShiftTab: PropTypes.func,
|
82 |
|
83 |
|
84 | monthFormat: PropTypes.string,
|
85 | weekDayFormat: PropTypes.string,
|
86 | phrases: PropTypes.shape(getPhrasePropTypes(DayPickerPhrases)),
|
87 | dayAriaLabelFormat: PropTypes.string,
|
88 |
|
89 | isRTL: PropTypes.bool,
|
90 | });
|
91 |
|
92 | const defaultProps = {
|
93 | date: undefined,
|
94 | onDateChange() {},
|
95 |
|
96 | focused: false,
|
97 | onFocusChange() {},
|
98 | onClose() {},
|
99 |
|
100 | keepOpenOnDateSelect: false,
|
101 | isOutsideRange() {},
|
102 | isDayBlocked() {},
|
103 | isDayHighlighted() {},
|
104 |
|
105 |
|
106 | renderMonthText: null,
|
107 | renderWeekHeaderElement: null,
|
108 | enableOutsideDays: false,
|
109 | numberOfMonths: 1,
|
110 | orientation: HORIZONTAL_ORIENTATION,
|
111 | withPortal: false,
|
112 | hideKeyboardShortcutsPanel: false,
|
113 | initialVisibleMonth: null,
|
114 | firstDayOfWeek: null,
|
115 | daySize: DAY_SIZE,
|
116 | verticalHeight: null,
|
117 | noBorder: false,
|
118 | verticalBorderSpacing: undefined,
|
119 | transitionDuration: undefined,
|
120 | horizontalMonthPadding: 13,
|
121 |
|
122 | navPrev: null,
|
123 | navNext: null,
|
124 |
|
125 | onPrevMonthClick() {},
|
126 | onNextMonthClick() {},
|
127 | onOutsideClick() {},
|
128 |
|
129 | renderCalendarDay: undefined,
|
130 | renderDayContents: null,
|
131 | renderCalendarInfo: null,
|
132 | renderMonthElement: null,
|
133 | calendarInfoPosition: INFO_POSITION_BOTTOM,
|
134 |
|
135 |
|
136 | onBlur() {},
|
137 | isFocused: false,
|
138 | showKeyboardShortcuts: false,
|
139 | onTab() {},
|
140 | onShiftTab() {},
|
141 |
|
142 |
|
143 | monthFormat: 'MMMM YYYY',
|
144 | weekDayFormat: 'dd',
|
145 | phrases: DayPickerPhrases,
|
146 | dayAriaLabelFormat: undefined,
|
147 |
|
148 | isRTL: false,
|
149 | };
|
150 |
|
151 | export default class DayPickerSingleDateController extends React.PureComponent {
|
152 | constructor(props) {
|
153 | super(props);
|
154 |
|
155 | this.isTouchDevice = false;
|
156 | this.today = moment();
|
157 |
|
158 | this.modifiers = {
|
159 | today: (day) => this.isToday(day),
|
160 | blocked: (day) => this.isBlocked(day),
|
161 | 'blocked-calendar': (day) => props.isDayBlocked(day),
|
162 | 'blocked-out-of-range': (day) => props.isOutsideRange(day),
|
163 | 'highlighted-calendar': (day) => props.isDayHighlighted(day),
|
164 | valid: (day) => !this.isBlocked(day),
|
165 | hovered: (day) => this.isHovered(day),
|
166 | selected: (day) => this.isSelected(day),
|
167 | 'first-day-of-week': (day) => this.isFirstDayOfWeek(day),
|
168 | 'last-day-of-week': (day) => this.isLastDayOfWeek(day),
|
169 | };
|
170 |
|
171 | const { currentMonth, visibleDays } = this.getStateForNewMonth(props);
|
172 |
|
173 | this.state = {
|
174 | hoverDate: null,
|
175 | currentMonth,
|
176 | visibleDays,
|
177 | };
|
178 |
|
179 | this.onDayMouseEnter = this.onDayMouseEnter.bind(this);
|
180 | this.onDayMouseLeave = this.onDayMouseLeave.bind(this);
|
181 | this.onDayClick = this.onDayClick.bind(this);
|
182 |
|
183 | this.onPrevMonthClick = this.onPrevMonthClick.bind(this);
|
184 | this.onNextMonthClick = this.onNextMonthClick.bind(this);
|
185 | this.onMonthChange = this.onMonthChange.bind(this);
|
186 | this.onYearChange = this.onYearChange.bind(this);
|
187 | this.onMultiplyScrollableMonths = this.onMultiplyScrollableMonths.bind(this);
|
188 | this.getFirstFocusableDay = this.getFirstFocusableDay.bind(this);
|
189 | }
|
190 |
|
191 | componentDidMount() {
|
192 | this.isTouchDevice = isTouchDevice();
|
193 | }
|
194 |
|
195 | componentWillReceiveProps(nextProps) {
|
196 | const {
|
197 | date,
|
198 | focused,
|
199 | isOutsideRange,
|
200 | isDayBlocked,
|
201 | isDayHighlighted,
|
202 | initialVisibleMonth,
|
203 | numberOfMonths,
|
204 | enableOutsideDays,
|
205 | } = nextProps;
|
206 | const {
|
207 | isOutsideRange: prevIsOutsideRange,
|
208 | isDayBlocked: prevIsDayBlocked,
|
209 | isDayHighlighted: prevIsDayHighlighted,
|
210 | numberOfMonths: prevNumberOfMonths,
|
211 | enableOutsideDays: prevEnableOutsideDays,
|
212 | initialVisibleMonth: prevInitialVisibleMonth,
|
213 | focused: prevFocused,
|
214 | date: prevDate,
|
215 | } = this.props;
|
216 | let { visibleDays } = this.state;
|
217 |
|
218 | let recomputeOutsideRange = false;
|
219 | let recomputeDayBlocked = false;
|
220 | let recomputeDayHighlighted = false;
|
221 |
|
222 | if (isOutsideRange !== prevIsOutsideRange) {
|
223 | this.modifiers['blocked-out-of-range'] = (day) => isOutsideRange(day);
|
224 | recomputeOutsideRange = true;
|
225 | }
|
226 |
|
227 | if (isDayBlocked !== prevIsDayBlocked) {
|
228 | this.modifiers['blocked-calendar'] = (day) => isDayBlocked(day);
|
229 | recomputeDayBlocked = true;
|
230 | }
|
231 |
|
232 | if (isDayHighlighted !== prevIsDayHighlighted) {
|
233 | this.modifiers['highlighted-calendar'] = (day) => isDayHighlighted(day);
|
234 | recomputeDayHighlighted = true;
|
235 | }
|
236 |
|
237 | const recomputePropModifiers = (
|
238 | recomputeOutsideRange || recomputeDayBlocked || recomputeDayHighlighted
|
239 | );
|
240 |
|
241 | if (
|
242 | numberOfMonths !== prevNumberOfMonths
|
243 | || enableOutsideDays !== prevEnableOutsideDays
|
244 | || (
|
245 | initialVisibleMonth !== prevInitialVisibleMonth
|
246 | && !prevFocused
|
247 | && focused
|
248 | )
|
249 | ) {
|
250 | const newMonthState = this.getStateForNewMonth(nextProps);
|
251 | const { currentMonth } = newMonthState;
|
252 | ({ visibleDays } = newMonthState);
|
253 | this.setState({
|
254 | currentMonth,
|
255 | visibleDays,
|
256 | });
|
257 | }
|
258 |
|
259 | const didDateChange = date !== prevDate;
|
260 | const didFocusChange = focused !== prevFocused;
|
261 |
|
262 | let modifiers = {};
|
263 |
|
264 | if (didDateChange) {
|
265 | modifiers = this.deleteModifier(modifiers, prevDate, 'selected');
|
266 | modifiers = this.addModifier(modifiers, date, 'selected');
|
267 | }
|
268 |
|
269 | if (didFocusChange || recomputePropModifiers) {
|
270 | values(visibleDays).forEach((days) => {
|
271 | Object.keys(days).forEach((day) => {
|
272 | const momentObj = getPooledMoment(day);
|
273 | if (this.isBlocked(momentObj)) {
|
274 | modifiers = this.addModifier(modifiers, momentObj, 'blocked');
|
275 | } else {
|
276 | modifiers = this.deleteModifier(modifiers, momentObj, 'blocked');
|
277 | }
|
278 |
|
279 | if (didFocusChange || recomputeOutsideRange) {
|
280 | if (isOutsideRange(momentObj)) {
|
281 | modifiers = this.addModifier(modifiers, momentObj, 'blocked-out-of-range');
|
282 | } else {
|
283 | modifiers = this.deleteModifier(modifiers, momentObj, 'blocked-out-of-range');
|
284 | }
|
285 | }
|
286 |
|
287 | if (didFocusChange || recomputeDayBlocked) {
|
288 | if (isDayBlocked(momentObj)) {
|
289 | modifiers = this.addModifier(modifiers, momentObj, 'blocked-calendar');
|
290 | } else {
|
291 | modifiers = this.deleteModifier(modifiers, momentObj, 'blocked-calendar');
|
292 | }
|
293 | }
|
294 |
|
295 | if (didFocusChange || recomputeDayHighlighted) {
|
296 | if (isDayHighlighted(momentObj)) {
|
297 | modifiers = this.addModifier(modifiers, momentObj, 'highlighted-calendar');
|
298 | } else {
|
299 | modifiers = this.deleteModifier(modifiers, momentObj, 'highlighted-calendar');
|
300 | }
|
301 | }
|
302 | });
|
303 | });
|
304 | }
|
305 |
|
306 | const today = moment();
|
307 | if (!isSameDay(this.today, today)) {
|
308 | modifiers = this.deleteModifier(modifiers, this.today, 'today');
|
309 | modifiers = this.addModifier(modifiers, today, 'today');
|
310 | this.today = today;
|
311 | }
|
312 |
|
313 | if (Object.keys(modifiers).length > 0) {
|
314 | this.setState({
|
315 | visibleDays: {
|
316 | ...visibleDays,
|
317 | ...modifiers,
|
318 | },
|
319 | });
|
320 | }
|
321 | }
|
322 |
|
323 | componentWillUpdate() {
|
324 | this.today = moment();
|
325 | }
|
326 |
|
327 | onDayClick(day, e) {
|
328 | if (e) e.preventDefault();
|
329 | if (this.isBlocked(day)) return;
|
330 | const {
|
331 | onDateChange,
|
332 | keepOpenOnDateSelect,
|
333 | onFocusChange,
|
334 | onClose,
|
335 | } = this.props;
|
336 |
|
337 | onDateChange(day);
|
338 | if (!keepOpenOnDateSelect) {
|
339 | onFocusChange({ focused: false });
|
340 | onClose({ date: day });
|
341 | }
|
342 | }
|
343 |
|
344 | onDayMouseEnter(day) {
|
345 | if (this.isTouchDevice) return;
|
346 | const { hoverDate, visibleDays } = this.state;
|
347 |
|
348 | let modifiers = this.deleteModifier({}, hoverDate, 'hovered');
|
349 | modifiers = this.addModifier(modifiers, day, 'hovered');
|
350 |
|
351 | this.setState({
|
352 | hoverDate: day,
|
353 | visibleDays: {
|
354 | ...visibleDays,
|
355 | ...modifiers,
|
356 | },
|
357 | });
|
358 | }
|
359 |
|
360 | onDayMouseLeave() {
|
361 | const { hoverDate, visibleDays } = this.state;
|
362 | if (this.isTouchDevice || !hoverDate) return;
|
363 |
|
364 | const modifiers = this.deleteModifier({}, hoverDate, 'hovered');
|
365 |
|
366 | this.setState({
|
367 | hoverDate: null,
|
368 | visibleDays: {
|
369 | ...visibleDays,
|
370 | ...modifiers,
|
371 | },
|
372 | });
|
373 | }
|
374 |
|
375 | onPrevMonthClick() {
|
376 | const { onPrevMonthClick, numberOfMonths, enableOutsideDays } = this.props;
|
377 | const { currentMonth, visibleDays } = this.state;
|
378 |
|
379 | const newVisibleDays = {};
|
380 | Object.keys(visibleDays).sort().slice(0, numberOfMonths + 1).forEach((month) => {
|
381 | newVisibleDays[month] = visibleDays[month];
|
382 | });
|
383 |
|
384 | const prevMonth = currentMonth.clone().subtract(1, 'month');
|
385 | const prevMonthVisibleDays = getVisibleDays(prevMonth, 1, enableOutsideDays);
|
386 |
|
387 | this.setState({
|
388 | currentMonth: prevMonth,
|
389 | visibleDays: {
|
390 | ...newVisibleDays,
|
391 | ...this.getModifiers(prevMonthVisibleDays),
|
392 | },
|
393 | }, () => {
|
394 | onPrevMonthClick(prevMonth.clone());
|
395 | });
|
396 | }
|
397 |
|
398 | onNextMonthClick() {
|
399 | const { onNextMonthClick, numberOfMonths, enableOutsideDays } = this.props;
|
400 | const { currentMonth, visibleDays } = this.state;
|
401 |
|
402 | const newVisibleDays = {};
|
403 | Object.keys(visibleDays).sort().slice(1).forEach((month) => {
|
404 | newVisibleDays[month] = visibleDays[month];
|
405 | });
|
406 |
|
407 | const nextMonth = currentMonth.clone().add(numberOfMonths, 'month');
|
408 | const nextMonthVisibleDays = getVisibleDays(nextMonth, 1, enableOutsideDays);
|
409 |
|
410 | const newCurrentMonth = currentMonth.clone().add(1, 'month');
|
411 | this.setState({
|
412 | currentMonth: newCurrentMonth,
|
413 | visibleDays: {
|
414 | ...newVisibleDays,
|
415 | ...this.getModifiers(nextMonthVisibleDays),
|
416 | },
|
417 | }, () => {
|
418 | onNextMonthClick(newCurrentMonth.clone());
|
419 | });
|
420 | }
|
421 |
|
422 | onMonthChange(newMonth) {
|
423 | const { numberOfMonths, enableOutsideDays, orientation } = this.props;
|
424 | const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
|
425 | const newVisibleDays = getVisibleDays(
|
426 | newMonth,
|
427 | numberOfMonths,
|
428 | enableOutsideDays,
|
429 | withoutTransitionMonths,
|
430 | );
|
431 |
|
432 | this.setState({
|
433 | currentMonth: newMonth.clone(),
|
434 | visibleDays: this.getModifiers(newVisibleDays),
|
435 | });
|
436 | }
|
437 |
|
438 | onYearChange(newMonth) {
|
439 | const { numberOfMonths, enableOutsideDays, orientation } = this.props;
|
440 | const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
|
441 | const newVisibleDays = getVisibleDays(
|
442 | newMonth,
|
443 | numberOfMonths,
|
444 | enableOutsideDays,
|
445 | withoutTransitionMonths,
|
446 | );
|
447 |
|
448 | this.setState({
|
449 | currentMonth: newMonth.clone(),
|
450 | visibleDays: this.getModifiers(newVisibleDays),
|
451 | });
|
452 | }
|
453 |
|
454 | onMultiplyScrollableMonths() {
|
455 | const { numberOfMonths, enableOutsideDays } = this.props;
|
456 | const { currentMonth, visibleDays } = this.state;
|
457 |
|
458 | const numberOfVisibleMonths = Object.keys(visibleDays).length;
|
459 | const nextMonth = currentMonth.clone().add(numberOfVisibleMonths, 'month');
|
460 | const newVisibleDays = getVisibleDays(nextMonth, numberOfMonths, enableOutsideDays, true);
|
461 |
|
462 | this.setState({
|
463 | visibleDays: {
|
464 | ...visibleDays,
|
465 | ...this.getModifiers(newVisibleDays),
|
466 | },
|
467 | });
|
468 | }
|
469 |
|
470 | getFirstFocusableDay(newMonth) {
|
471 | const { date, numberOfMonths } = this.props;
|
472 |
|
473 | let focusedDate = newMonth.clone().startOf('month');
|
474 | if (date) {
|
475 | focusedDate = date.clone();
|
476 | }
|
477 |
|
478 | if (this.isBlocked(focusedDate)) {
|
479 | const days = [];
|
480 | const lastVisibleDay = newMonth.clone().add(numberOfMonths - 1, 'months').endOf('month');
|
481 | let currentDay = focusedDate.clone();
|
482 | while (!isAfterDay(currentDay, lastVisibleDay)) {
|
483 | currentDay = currentDay.clone().add(1, 'day');
|
484 | days.push(currentDay);
|
485 | }
|
486 |
|
487 | const viableDays = days.filter((day) => !this.isBlocked(day) && isAfterDay(day, focusedDate));
|
488 | if (viableDays.length > 0) {
|
489 | ([focusedDate] = viableDays);
|
490 | }
|
491 | }
|
492 |
|
493 | return focusedDate;
|
494 | }
|
495 |
|
496 | getModifiers(visibleDays) {
|
497 | const modifiers = {};
|
498 | Object.keys(visibleDays).forEach((month) => {
|
499 | modifiers[month] = {};
|
500 | visibleDays[month].forEach((day) => {
|
501 | modifiers[month][toISODateString(day)] = this.getModifiersForDay(day);
|
502 | });
|
503 | });
|
504 |
|
505 | return modifiers;
|
506 | }
|
507 |
|
508 | getModifiersForDay(day) {
|
509 | return new Set(Object.keys(this.modifiers).filter((modifier) => this.modifiers[modifier](day)));
|
510 | }
|
511 |
|
512 | getStateForNewMonth(nextProps) {
|
513 | const {
|
514 | initialVisibleMonth,
|
515 | date,
|
516 | numberOfMonths,
|
517 | orientation,
|
518 | enableOutsideDays,
|
519 | } = nextProps;
|
520 | const initialVisibleMonthThunk = initialVisibleMonth || (date ? () => date : () => this.today);
|
521 | const currentMonth = initialVisibleMonthThunk();
|
522 | const withoutTransitionMonths = orientation === VERTICAL_SCROLLABLE;
|
523 | const visibleDays = this.getModifiers(getVisibleDays(
|
524 | currentMonth,
|
525 | numberOfMonths,
|
526 | enableOutsideDays,
|
527 | withoutTransitionMonths,
|
528 | ));
|
529 | return { currentMonth, visibleDays };
|
530 | }
|
531 |
|
532 | addModifier(updatedDays, day, modifier) {
|
533 | return addModifier(updatedDays, day, modifier, this.props, this.state);
|
534 | }
|
535 |
|
536 | deleteModifier(updatedDays, day, modifier) {
|
537 | return deleteModifier(updatedDays, day, modifier, this.props, this.state);
|
538 | }
|
539 |
|
540 | isBlocked(day) {
|
541 | const { isDayBlocked, isOutsideRange } = this.props;
|
542 | return isDayBlocked(day) || isOutsideRange(day);
|
543 | }
|
544 |
|
545 | isHovered(day) {
|
546 | const { hoverDate } = this.state || {};
|
547 | return isSameDay(day, hoverDate);
|
548 | }
|
549 |
|
550 | isSelected(day) {
|
551 | const { date } = this.props;
|
552 | return isSameDay(day, date);
|
553 | }
|
554 |
|
555 | isToday(day) {
|
556 | return isSameDay(day, this.today);
|
557 | }
|
558 |
|
559 | isFirstDayOfWeek(day) {
|
560 | const { firstDayOfWeek } = this.props;
|
561 | return day.day() === (firstDayOfWeek || moment.localeData().firstDayOfWeek());
|
562 | }
|
563 |
|
564 | isLastDayOfWeek(day) {
|
565 | const { firstDayOfWeek } = this.props;
|
566 | return day.day() === ((firstDayOfWeek || moment.localeData().firstDayOfWeek()) + 6) % 7;
|
567 | }
|
568 |
|
569 | render() {
|
570 | const {
|
571 | numberOfMonths,
|
572 | orientation,
|
573 | monthFormat,
|
574 | renderMonthText,
|
575 | renderWeekHeaderElement,
|
576 | navPrev,
|
577 | navNext,
|
578 | onOutsideClick,
|
579 | onShiftTab,
|
580 | onTab,
|
581 | withPortal,
|
582 | focused,
|
583 | enableOutsideDays,
|
584 | hideKeyboardShortcutsPanel,
|
585 | daySize,
|
586 | firstDayOfWeek,
|
587 | renderCalendarDay,
|
588 | renderDayContents,
|
589 | renderCalendarInfo,
|
590 | renderMonthElement,
|
591 | calendarInfoPosition,
|
592 | isFocused,
|
593 | isRTL,
|
594 | phrases,
|
595 | dayAriaLabelFormat,
|
596 | onBlur,
|
597 | showKeyboardShortcuts,
|
598 | weekDayFormat,
|
599 | verticalHeight,
|
600 | noBorder,
|
601 | transitionDuration,
|
602 | verticalBorderSpacing,
|
603 | horizontalMonthPadding,
|
604 | } = this.props;
|
605 |
|
606 | const { currentMonth, visibleDays } = this.state;
|
607 |
|
608 | return (
|
609 | <DayPicker
|
610 | orientation={orientation}
|
611 | enableOutsideDays={enableOutsideDays}
|
612 | modifiers={visibleDays}
|
613 | numberOfMonths={numberOfMonths}
|
614 | onDayClick={this.onDayClick}
|
615 | onDayMouseEnter={this.onDayMouseEnter}
|
616 | onDayMouseLeave={this.onDayMouseLeave}
|
617 | onPrevMonthClick={this.onPrevMonthClick}
|
618 | onNextMonthClick={this.onNextMonthClick}
|
619 | onMonthChange={this.onMonthChange}
|
620 | onYearChange={this.onYearChange}
|
621 | onMultiplyScrollableMonths={this.onMultiplyScrollableMonths}
|
622 | monthFormat={monthFormat}
|
623 | withPortal={withPortal}
|
624 | hidden={!focused}
|
625 | hideKeyboardShortcutsPanel={hideKeyboardShortcutsPanel}
|
626 | initialVisibleMonth={() => currentMonth}
|
627 | firstDayOfWeek={firstDayOfWeek}
|
628 | onOutsideClick={onOutsideClick}
|
629 | navPrev={navPrev}
|
630 | navNext={navNext}
|
631 | renderMonthText={renderMonthText}
|
632 | renderWeekHeaderElement={renderWeekHeaderElement}
|
633 | renderCalendarDay={renderCalendarDay}
|
634 | renderDayContents={renderDayContents}
|
635 | renderCalendarInfo={renderCalendarInfo}
|
636 | renderMonthElement={renderMonthElement}
|
637 | calendarInfoPosition={calendarInfoPosition}
|
638 | isFocused={isFocused}
|
639 | getFirstFocusableDay={this.getFirstFocusableDay}
|
640 | onBlur={onBlur}
|
641 | onTab={onTab}
|
642 | onShiftTab={onShiftTab}
|
643 | phrases={phrases}
|
644 | daySize={daySize}
|
645 | isRTL={isRTL}
|
646 | showKeyboardShortcuts={showKeyboardShortcuts}
|
647 | weekDayFormat={weekDayFormat}
|
648 | dayAriaLabelFormat={dayAriaLabelFormat}
|
649 | verticalHeight={verticalHeight}
|
650 | noBorder={noBorder}
|
651 | transitionDuration={transitionDuration}
|
652 | verticalBorderSpacing={verticalBorderSpacing}
|
653 | horizontalMonthPadding={horizontalMonthPadding}
|
654 | />
|
655 | );
|
656 | }
|
657 | }
|
658 |
|
659 | DayPickerSingleDateController.propTypes = propTypes;
|
660 | DayPickerSingleDateController.defaultProps = defaultProps;
|