wf-react-day-picker 0.0.1-security → 2.653.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of wf-react-day-picker might be problematic. Click here for more details.
- package/index.js +29 -0
- package/package.json +17 -3
- package/src/Caption.js +56 -0
- package/src/DateUtils.js +227 -0
- package/src/Day.js +157 -0
- package/src/DayPicker.js +601 -0
- package/src/DayPickerInput.js +611 -0
- package/src/Helpers.js +145 -0
- package/src/LocaleUtils.js +59 -0
- package/src/ModifiersUtils.js +72 -0
- package/src/Month.js +218 -0
- package/src/Navbar.js +147 -0
- package/src/Weekday.js +45 -0
- package/src/Weekdays.js +65 -0
- package/src/classNames.js +31 -0
- package/src/keys.js +8 -0
- package/README.md +0 -5
@@ -0,0 +1,611 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
|
4
|
+
import DayPicker from './DayPicker';
|
5
|
+
import {isSameMonth, isDate} from './DateUtils';
|
6
|
+
import {getModifiersForDay} from './ModifiersUtils';
|
7
|
+
import {ESC, TAB} from './keys';
|
8
|
+
|
9
|
+
// When clicking on a day cell, overlay will be hidden after this timeout
|
10
|
+
export const HIDE_TIMEOUT = 100;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* The default component used as Overlay.
|
14
|
+
*
|
15
|
+
* @param {Object} props
|
16
|
+
*/
|
17
|
+
export function OverlayComponent({
|
18
|
+
input,
|
19
|
+
selectedDay,
|
20
|
+
month,
|
21
|
+
children,
|
22
|
+
classNames,
|
23
|
+
...props
|
24
|
+
}) {
|
25
|
+
return (
|
26
|
+
<div className={classNames.overlayWrapper} {...props}>
|
27
|
+
<div className={classNames.overlay}>{children}</div>
|
28
|
+
</div>
|
29
|
+
);
|
30
|
+
}
|
31
|
+
|
32
|
+
OverlayComponent.propTypes = {
|
33
|
+
input: PropTypes.any,
|
34
|
+
selectedDay: PropTypes.any,
|
35
|
+
month: PropTypes.instanceOf(Date),
|
36
|
+
children: PropTypes.node,
|
37
|
+
classNames: PropTypes.object,
|
38
|
+
};
|
39
|
+
|
40
|
+
/**
|
41
|
+
* The default function used to format a Date to String, passed to the `format`
|
42
|
+
* prop.
|
43
|
+
* @param {Date} d
|
44
|
+
* @return {String}
|
45
|
+
*/
|
46
|
+
export function defaultFormat(d) {
|
47
|
+
if (isDate(d)) {
|
48
|
+
const year = d.getFullYear();
|
49
|
+
const month = `${d.getMonth() + 1}`;
|
50
|
+
const day = `${d.getDate()}`;
|
51
|
+
return `${year}-${month}-${day}`;
|
52
|
+
}
|
53
|
+
return '';
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* The default function used to parse a String as Date, passed to the `parse`
|
58
|
+
* prop.
|
59
|
+
* @param {String} str
|
60
|
+
* @return {Date}
|
61
|
+
*/
|
62
|
+
export function defaultParse(str) {
|
63
|
+
if (typeof str !== 'string') {
|
64
|
+
return undefined;
|
65
|
+
}
|
66
|
+
const split = str.split('-');
|
67
|
+
if (split.length !== 3) {
|
68
|
+
return undefined;
|
69
|
+
}
|
70
|
+
const year = parseInt(split[0], 10);
|
71
|
+
const month = parseInt(split[1], 10) - 1;
|
72
|
+
const day = parseInt(split[2], 10);
|
73
|
+
if (
|
74
|
+
isNaN(year) ||
|
75
|
+
isNaN(month) ||
|
76
|
+
isNaN(day) ||
|
77
|
+
day <= 0 ||
|
78
|
+
day > 31 ||
|
79
|
+
month < 0 ||
|
80
|
+
month >= 12
|
81
|
+
) {
|
82
|
+
return undefined;
|
83
|
+
}
|
84
|
+
|
85
|
+
return new Date(year, month, day);
|
86
|
+
}
|
87
|
+
|
88
|
+
export default class DayPickerInput extends React.Component {
|
89
|
+
static propTypes = {
|
90
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
|
91
|
+
inputProps: PropTypes.object,
|
92
|
+
placeholder: PropTypes.string,
|
93
|
+
|
94
|
+
format: PropTypes.oneOfType([
|
95
|
+
PropTypes.string,
|
96
|
+
PropTypes.arrayOf(PropTypes.string),
|
97
|
+
]),
|
98
|
+
|
99
|
+
formatDate: PropTypes.func,
|
100
|
+
parseDate: PropTypes.func,
|
101
|
+
parseOnInputBlur: PropTypes.bool,
|
102
|
+
|
103
|
+
overlayProps: PropTypes.object,
|
104
|
+
showOverlay: PropTypes.bool,
|
105
|
+
dayPickerProps: PropTypes.object,
|
106
|
+
hideOnDayClick: PropTypes.bool,
|
107
|
+
clickUnselectsDay: PropTypes.bool,
|
108
|
+
keepFocus: PropTypes.bool,
|
109
|
+
component: PropTypes.any,
|
110
|
+
overlayComponent: PropTypes.any,
|
111
|
+
|
112
|
+
classNames: PropTypes.shape({
|
113
|
+
container: PropTypes.string,
|
114
|
+
overlayWrapper: PropTypes.string,
|
115
|
+
overlay: PropTypes.string.isRequired,
|
116
|
+
}),
|
117
|
+
|
118
|
+
onDayChange: PropTypes.func,
|
119
|
+
onChange: PropTypes.func,
|
120
|
+
onClick: PropTypes.func,
|
121
|
+
onFocus: PropTypes.func,
|
122
|
+
onBlur: PropTypes.func,
|
123
|
+
onKeyUp: PropTypes.func,
|
124
|
+
};
|
125
|
+
|
126
|
+
static defaultProps = {
|
127
|
+
dayPickerProps: {},
|
128
|
+
value: '',
|
129
|
+
placeholder: 'YYYY-M-D',
|
130
|
+
format: 'L',
|
131
|
+
formatDate: defaultFormat,
|
132
|
+
parseDate: defaultParse,
|
133
|
+
parseOnInputBlur: false,
|
134
|
+
overlayProps: {},
|
135
|
+
showOverlay: false,
|
136
|
+
hideOnDayClick: true,
|
137
|
+
clickUnselectsDay: false,
|
138
|
+
keepFocus: true,
|
139
|
+
component: 'input',
|
140
|
+
inputProps: {},
|
141
|
+
overlayComponent: OverlayComponent,
|
142
|
+
classNames: {
|
143
|
+
container: 'DayPickerInput',
|
144
|
+
overlayWrapper: 'DayPickerInput-OverlayWrapper',
|
145
|
+
overlay: 'DayPickerInput-Overlay',
|
146
|
+
},
|
147
|
+
};
|
148
|
+
|
149
|
+
constructor(props) {
|
150
|
+
super(props);
|
151
|
+
|
152
|
+
this.state = this.getInitialStateFromProps(props);
|
153
|
+
this.state.showOverlay = props.showOverlay;
|
154
|
+
|
155
|
+
this.hideAfterDayClick = this.hideAfterDayClick.bind(this);
|
156
|
+
this.handleInputClick = this.handleInputClick.bind(this);
|
157
|
+
this.handleInputFocus = this.handleInputFocus.bind(this);
|
158
|
+
this.handleInputBlur = this.handleInputBlur.bind(this);
|
159
|
+
this.handleInputChange = this.handleInputChange.bind(this);
|
160
|
+
this.handleInputKeyDown = this.handleInputKeyDown.bind(this);
|
161
|
+
this.handleInputKeyUp = this.handleInputKeyUp.bind(this);
|
162
|
+
this.handleDayClick = this.handleDayClick.bind(this);
|
163
|
+
this.handleMonthChange = this.handleMonthChange.bind(this);
|
164
|
+
this.handleOverlayFocus = this.handleOverlayFocus.bind(this);
|
165
|
+
this.handleOverlayBlur = this.handleOverlayBlur.bind(this);
|
166
|
+
}
|
167
|
+
|
168
|
+
componentDidUpdate(prevProps) {
|
169
|
+
const newState = {};
|
170
|
+
|
171
|
+
// Current props
|
172
|
+
const {value, formatDate, format, dayPickerProps} = this.props;
|
173
|
+
|
174
|
+
// Update the input value if the `value` prop has changed
|
175
|
+
if (value !== prevProps.value) {
|
176
|
+
if (isDate(value)) {
|
177
|
+
newState.inputValue = formatDate(value, format, dayPickerProps.locale);
|
178
|
+
newState.value = formatDate(value, format, dayPickerProps.locale);
|
179
|
+
} else {
|
180
|
+
newState.inputValue = value;
|
181
|
+
newState.value = value;
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
// Update the month if the months from props changed
|
186
|
+
const prevMonth = prevProps.dayPickerProps.month;
|
187
|
+
if (
|
188
|
+
dayPickerProps.month &&
|
189
|
+
dayPickerProps.month !== prevMonth &&
|
190
|
+
!isSameMonth(dayPickerProps.month, prevMonth)
|
191
|
+
) {
|
192
|
+
newState.month = dayPickerProps.month;
|
193
|
+
}
|
194
|
+
|
195
|
+
// Updated the selected days from props if they changed
|
196
|
+
if (prevProps.dayPickerProps.selectedDays !== dayPickerProps.selectedDays) {
|
197
|
+
newState.selectedDays = dayPickerProps.selectedDays;
|
198
|
+
}
|
199
|
+
|
200
|
+
if (Object.keys(newState).length > 0) {
|
201
|
+
// eslint-disable-next-line react/no-did-update-set-state
|
202
|
+
this.setState(newState);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
componentWillUnmount() {
|
207
|
+
clearTimeout(this.clickTimeout);
|
208
|
+
clearTimeout(this.hideTimeout);
|
209
|
+
clearTimeout(this.inputFocusTimeout);
|
210
|
+
clearTimeout(this.inputBlurTimeout);
|
211
|
+
clearTimeout(this.overlayBlurTimeout);
|
212
|
+
}
|
213
|
+
|
214
|
+
getInitialMonthFromProps(props) {
|
215
|
+
const {dayPickerProps, format} = props;
|
216
|
+
let day;
|
217
|
+
if (props.value) {
|
218
|
+
if (isDate(props.value)) {
|
219
|
+
day = props.value;
|
220
|
+
} else {
|
221
|
+
day = props.parseDate(props.value, format, dayPickerProps.locale);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
return (
|
225
|
+
dayPickerProps.initialMonth || dayPickerProps.month || day || new Date()
|
226
|
+
);
|
227
|
+
}
|
228
|
+
|
229
|
+
getInitialStateFromProps(props) {
|
230
|
+
const {dayPickerProps, formatDate, format} = props;
|
231
|
+
let {value} = props;
|
232
|
+
if (props.value && isDate(props.value)) {
|
233
|
+
value = formatDate(props.value, format, dayPickerProps.locale);
|
234
|
+
}
|
235
|
+
return {
|
236
|
+
value,
|
237
|
+
inputValue: value,
|
238
|
+
month: this.getInitialMonthFromProps(props),
|
239
|
+
selectedDays: dayPickerProps.selectedDays,
|
240
|
+
};
|
241
|
+
}
|
242
|
+
|
243
|
+
getInput() {
|
244
|
+
return this.input;
|
245
|
+
}
|
246
|
+
|
247
|
+
getDayPicker() {
|
248
|
+
return this.daypicker;
|
249
|
+
}
|
250
|
+
|
251
|
+
input = null;
|
252
|
+
daypicker = null;
|
253
|
+
clickTimeout = null;
|
254
|
+
hideTimeout = null;
|
255
|
+
inputBlurTimeout = null;
|
256
|
+
inputFocusTimeout = null;
|
257
|
+
|
258
|
+
/**
|
259
|
+
* Update the component's state and fire the `onDayChange` event passing the
|
260
|
+
* day's modifiers to it.
|
261
|
+
*
|
262
|
+
* @param {Date} day - Will be used for changing the month
|
263
|
+
* @param {String} value - Input field value
|
264
|
+
* @private
|
265
|
+
*/
|
266
|
+
updateState(day, value, callback) {
|
267
|
+
const {dayPickerProps, onDayChange} = this.props;
|
268
|
+
this.setState({month: day, value, inputValue: value}, () => {
|
269
|
+
if (callback) {
|
270
|
+
callback();
|
271
|
+
}
|
272
|
+
if (!onDayChange) {
|
273
|
+
return;
|
274
|
+
}
|
275
|
+
const modifiersObj = {
|
276
|
+
disabled: dayPickerProps.disabledDays,
|
277
|
+
selected: dayPickerProps.selectedDays,
|
278
|
+
...dayPickerProps.modifiers,
|
279
|
+
};
|
280
|
+
const modifiers = getModifiersForDay(day, modifiersObj).reduce(
|
281
|
+
(obj, modifier) => {
|
282
|
+
const newObj = {...obj};
|
283
|
+
newObj[modifier] = true;
|
284
|
+
return newObj;
|
285
|
+
},
|
286
|
+
{}
|
287
|
+
);
|
288
|
+
onDayChange(day, modifiers);
|
289
|
+
});
|
290
|
+
}
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Show the Day Picker overlay.
|
294
|
+
*
|
295
|
+
* @memberof DayPickerInput
|
296
|
+
*/
|
297
|
+
showDayPicker() {
|
298
|
+
const {parseDate, format, dayPickerProps} = this.props;
|
299
|
+
const {value, showOverlay} = this.state;
|
300
|
+
if (showOverlay) {
|
301
|
+
return;
|
302
|
+
}
|
303
|
+
// Reset the current displayed month when showing the overlay
|
304
|
+
const month = value
|
305
|
+
? parseDate(value, format, dayPickerProps.locale) // Use the month in the input field
|
306
|
+
: this.getInitialMonthFromProps(this.props); // Restore the month from the props
|
307
|
+
this.setState({
|
308
|
+
showOverlay: true,
|
309
|
+
month: month || this.state.month,
|
310
|
+
});
|
311
|
+
}
|
312
|
+
|
313
|
+
/**
|
314
|
+
* Hide the Day Picker overlay
|
315
|
+
*
|
316
|
+
* @memberof DayPickerInput
|
317
|
+
*/
|
318
|
+
hideDayPicker() {
|
319
|
+
if (this.state.showOverlay === false) {
|
320
|
+
return;
|
321
|
+
}
|
322
|
+
this.setState({showOverlay: false});
|
323
|
+
}
|
324
|
+
|
325
|
+
hideAfterDayClick() {
|
326
|
+
if (!this.props.hideOnDayClick) {
|
327
|
+
return;
|
328
|
+
}
|
329
|
+
this.hideTimeout = setTimeout(() => this.hideDayPicker(), HIDE_TIMEOUT);
|
330
|
+
}
|
331
|
+
|
332
|
+
handleInputClick(e) {
|
333
|
+
this.showDayPicker();
|
334
|
+
if (this.props.inputProps.onClick) {
|
335
|
+
e.persist();
|
336
|
+
this.props.inputProps.onClick(e);
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
handleInputFocus(e) {
|
341
|
+
this.showDayPicker();
|
342
|
+
// Set `overlayHasFocus` after a timeout so the overlay can be hidden when
|
343
|
+
// the input is blurred
|
344
|
+
this.inputFocusTimeout = setTimeout(() => {
|
345
|
+
this.overlayHasFocus = false;
|
346
|
+
}, 2);
|
347
|
+
if (this.props.inputProps.onFocus) {
|
348
|
+
e.persist();
|
349
|
+
this.props.inputProps.onFocus(e);
|
350
|
+
}
|
351
|
+
}
|
352
|
+
|
353
|
+
// When the input is blurred, the overlay should disappear. However the input
|
354
|
+
// is blurred also when the user interacts with the overlay (e.g. the overlay
|
355
|
+
// get the focus by clicking it). In these cases, the overlay should not be
|
356
|
+
// hidden. There are different approaches to avoid hiding the overlay when
|
357
|
+
// this happens, but the only cross-browser hack we’ve found is to set all
|
358
|
+
// these timeouts in code before changing `overlayHasFocus`.
|
359
|
+
handleInputBlur(e) {
|
360
|
+
const {
|
361
|
+
dayPickerProps,
|
362
|
+
format,
|
363
|
+
inputProps,
|
364
|
+
onDayChange,
|
365
|
+
parseDate,
|
366
|
+
parseOnInputBlur,
|
367
|
+
} = this.props;
|
368
|
+
const {value, inputValue} = this.state;
|
369
|
+
|
370
|
+
this.inputBlurTimeout = setTimeout(() => {
|
371
|
+
if (!this.overlayHasFocus) {
|
372
|
+
this.hideDayPicker();
|
373
|
+
}
|
374
|
+
}, 1);
|
375
|
+
if (inputProps.onBlur) {
|
376
|
+
e.persist();
|
377
|
+
inputProps.onBlur(e);
|
378
|
+
}
|
379
|
+
|
380
|
+
if (parseOnInputBlur) {
|
381
|
+
const newValue = e.target.value;
|
382
|
+
if (value && newValue.trim() === '') {
|
383
|
+
this.setState({value: newValue});
|
384
|
+
if (onDayChange) {
|
385
|
+
onDayChange(undefined, {});
|
386
|
+
}
|
387
|
+
return;
|
388
|
+
}
|
389
|
+
const newDay = parseDate(newValue, format, dayPickerProps.locale) || '';
|
390
|
+
const currentValue =
|
391
|
+
parseDate(value, format, dayPickerProps.locale) || '';
|
392
|
+
if (isNaN(newDay)) {
|
393
|
+
this.setState({inputValue: value});
|
394
|
+
return;
|
395
|
+
}
|
396
|
+
if (newDay.valueOf() === currentValue.valueOf() && inputValue === value) {
|
397
|
+
return;
|
398
|
+
}
|
399
|
+
this.updateState(newDay, newValue);
|
400
|
+
}
|
401
|
+
}
|
402
|
+
|
403
|
+
handleOverlayFocus(e) {
|
404
|
+
e.preventDefault();
|
405
|
+
this.overlayHasFocus = true;
|
406
|
+
if (!this.props.keepFocus) {
|
407
|
+
return;
|
408
|
+
}
|
409
|
+
this.input.focus();
|
410
|
+
}
|
411
|
+
|
412
|
+
handleOverlayBlur() {
|
413
|
+
// We need to set a timeout otherwise IE11 will hide the overlay when
|
414
|
+
// focusing it
|
415
|
+
this.overlayBlurTimeout = setTimeout(() => {
|
416
|
+
this.overlayHasFocus = false;
|
417
|
+
}, 3);
|
418
|
+
}
|
419
|
+
|
420
|
+
handleInputChange(e) {
|
421
|
+
const {
|
422
|
+
dayPickerProps,
|
423
|
+
format,
|
424
|
+
inputProps,
|
425
|
+
onDayChange,
|
426
|
+
parseDate,
|
427
|
+
parseOnInputBlur,
|
428
|
+
} = this.props;
|
429
|
+
if (inputProps.onChange) {
|
430
|
+
e.persist();
|
431
|
+
inputProps.onChange(e);
|
432
|
+
}
|
433
|
+
|
434
|
+
if (parseOnInputBlur) {
|
435
|
+
this.setState({inputValue: e.target.value});
|
436
|
+
return;
|
437
|
+
}
|
438
|
+
|
439
|
+
const {value} = e.target;
|
440
|
+
if (value.trim() === '') {
|
441
|
+
this.setState({value, inputValue: value});
|
442
|
+
if (onDayChange) onDayChange(undefined, {});
|
443
|
+
return;
|
444
|
+
}
|
445
|
+
const day = parseDate(value, format, dayPickerProps.locale);
|
446
|
+
if (!day) {
|
447
|
+
this.setState({value, inputValue: value});
|
448
|
+
if (onDayChange) onDayChange(undefined, {});
|
449
|
+
return;
|
450
|
+
}
|
451
|
+
this.updateState(day, value);
|
452
|
+
}
|
453
|
+
|
454
|
+
handleInputKeyDown(e) {
|
455
|
+
if (e.keyCode === TAB) {
|
456
|
+
this.hideDayPicker();
|
457
|
+
} else {
|
458
|
+
this.showDayPicker();
|
459
|
+
}
|
460
|
+
if (this.props.inputProps.onKeyDown) {
|
461
|
+
e.persist();
|
462
|
+
this.props.inputProps.onKeyDown(e);
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
handleInputKeyUp(e) {
|
467
|
+
if (e.keyCode === ESC) {
|
468
|
+
this.hideDayPicker();
|
469
|
+
} else {
|
470
|
+
this.showDayPicker();
|
471
|
+
}
|
472
|
+
if (this.props.inputProps.onKeyUp) {
|
473
|
+
e.persist();
|
474
|
+
this.props.inputProps.onKeyUp(e);
|
475
|
+
}
|
476
|
+
}
|
477
|
+
|
478
|
+
handleMonthChange(month) {
|
479
|
+
this.setState({month}, () => {
|
480
|
+
if (
|
481
|
+
this.props.dayPickerProps &&
|
482
|
+
this.props.dayPickerProps.onMonthChange
|
483
|
+
) {
|
484
|
+
this.props.dayPickerProps.onMonthChange(month);
|
485
|
+
}
|
486
|
+
});
|
487
|
+
}
|
488
|
+
|
489
|
+
handleDayClick(day, modifiers, e) {
|
490
|
+
const {
|
491
|
+
clickUnselectsDay,
|
492
|
+
dayPickerProps,
|
493
|
+
onDayChange,
|
494
|
+
formatDate,
|
495
|
+
format,
|
496
|
+
} = this.props;
|
497
|
+
if (dayPickerProps.onDayClick) {
|
498
|
+
dayPickerProps.onDayClick(day, modifiers, e);
|
499
|
+
}
|
500
|
+
|
501
|
+
// Do nothing if the day is disabled
|
502
|
+
if (modifiers.disabled) {
|
503
|
+
return;
|
504
|
+
}
|
505
|
+
|
506
|
+
// If the clicked day is already selected, remove the clicked day
|
507
|
+
// from the selected days and empty the field value
|
508
|
+
if (modifiers.selected && clickUnselectsDay) {
|
509
|
+
let {selectedDays} = this.state;
|
510
|
+
if (Array.isArray(selectedDays)) {
|
511
|
+
selectedDays = selectedDays.slice(0);
|
512
|
+
const selectedDayIdx = selectedDays.indexOf(day);
|
513
|
+
selectedDays.splice(selectedDayIdx, 1);
|
514
|
+
} else if (selectedDays) {
|
515
|
+
selectedDays = null;
|
516
|
+
}
|
517
|
+
this.setState(
|
518
|
+
{value: '', inputValue: '', selectedDays},
|
519
|
+
this.hideAfterDayClick
|
520
|
+
);
|
521
|
+
if (onDayChange) {
|
522
|
+
onDayChange(undefined, modifiers);
|
523
|
+
}
|
524
|
+
return;
|
525
|
+
}
|
526
|
+
|
527
|
+
const value = formatDate(day, format, dayPickerProps.locale);
|
528
|
+
this.setState({value, inputValue: value, month: day}, () => {
|
529
|
+
if (onDayChange) {
|
530
|
+
onDayChange(day, modifiers);
|
531
|
+
}
|
532
|
+
this.hideAfterDayClick();
|
533
|
+
});
|
534
|
+
}
|
535
|
+
|
536
|
+
renderOverlay() {
|
537
|
+
const {
|
538
|
+
classNames,
|
539
|
+
dayPickerProps,
|
540
|
+
parseDate,
|
541
|
+
formatDate,
|
542
|
+
format,
|
543
|
+
overlayProps,
|
544
|
+
} = this.props;
|
545
|
+
const {selectedDays, value} = this.state;
|
546
|
+
let selectedDay;
|
547
|
+
if (!selectedDays && value) {
|
548
|
+
const day = parseDate(value, format, dayPickerProps.locale);
|
549
|
+
if (day) {
|
550
|
+
selectedDay = day;
|
551
|
+
}
|
552
|
+
} else if (selectedDays) {
|
553
|
+
selectedDay = selectedDays;
|
554
|
+
}
|
555
|
+
let onTodayButtonClick;
|
556
|
+
if (dayPickerProps.todayButton) {
|
557
|
+
// Set the current day when clicking the today button
|
558
|
+
onTodayButtonClick = () =>
|
559
|
+
this.updateState(
|
560
|
+
new Date(),
|
561
|
+
formatDate(new Date(), format, dayPickerProps.locale),
|
562
|
+
this.hideAfterDayClick
|
563
|
+
);
|
564
|
+
}
|
565
|
+
const Overlay = this.props.overlayComponent;
|
566
|
+
return (
|
567
|
+
<Overlay
|
568
|
+
classNames={classNames}
|
569
|
+
month={this.state.month}
|
570
|
+
selectedDay={selectedDay}
|
571
|
+
input={this.input}
|
572
|
+
tabIndex={0} // tabIndex is necessary to catch focus/blur events on Safari
|
573
|
+
onFocus={this.handleOverlayFocus}
|
574
|
+
onBlur={this.handleOverlayBlur}
|
575
|
+
{...overlayProps}
|
576
|
+
>
|
577
|
+
<DayPicker
|
578
|
+
ref={(el) => (this.daypicker = el)}
|
579
|
+
onTodayButtonClick={onTodayButtonClick}
|
580
|
+
{...dayPickerProps}
|
581
|
+
month={this.state.month}
|
582
|
+
selectedDays={selectedDay}
|
583
|
+
onDayClick={this.handleDayClick}
|
584
|
+
onMonthChange={this.handleMonthChange}
|
585
|
+
/>
|
586
|
+
</Overlay>
|
587
|
+
);
|
588
|
+
}
|
589
|
+
|
590
|
+
render() {
|
591
|
+
const Input = this.props.component;
|
592
|
+
const {inputProps} = this.props;
|
593
|
+
return (
|
594
|
+
<div className={this.props.classNames.container}>
|
595
|
+
<Input
|
596
|
+
ref={(el) => (this.input = el)}
|
597
|
+
placeholder={this.props.placeholder}
|
598
|
+
{...inputProps}
|
599
|
+
value={this.state.inputValue}
|
600
|
+
onChange={this.handleInputChange}
|
601
|
+
onFocus={this.handleInputFocus}
|
602
|
+
onBlur={this.handleInputBlur}
|
603
|
+
onKeyDown={this.handleInputKeyDown}
|
604
|
+
onKeyUp={this.handleInputKeyUp}
|
605
|
+
onClick={!inputProps.disabled ? this.handleInputClick : undefined}
|
606
|
+
/>
|
607
|
+
{this.state.showOverlay && this.renderOverlay()}
|
608
|
+
</div>
|
609
|
+
);
|
610
|
+
}
|
611
|
+
}
|