@zendeskgarden/react-datepickers 9.0.0-next.7 → 9.0.0-next.8

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 (33) hide show
  1. package/dist/esm/elements/DatePicker/DatePicker.js +169 -0
  2. package/dist/esm/elements/DatePicker/components/Calendar.js +125 -0
  3. package/dist/esm/elements/DatePicker/components/Input.js +75 -0
  4. package/dist/esm/elements/DatePicker/components/MonthSelector.js +61 -0
  5. package/dist/esm/elements/DatePicker/utils/date-picker-reducer.js +187 -0
  6. package/dist/esm/elements/DatePicker/utils/useDatePickerContext.js +14 -0
  7. package/dist/esm/elements/DatePickerRange/DatePickerRange.js +101 -0
  8. package/dist/esm/elements/DatePickerRange/components/Calendar.js +42 -0
  9. package/dist/esm/elements/DatePickerRange/components/End.js +79 -0
  10. package/dist/esm/elements/DatePickerRange/components/Month.js +270 -0
  11. package/dist/esm/elements/DatePickerRange/components/Start.js +79 -0
  12. package/dist/esm/elements/DatePickerRange/utils/date-picker-range-reducer.js +319 -0
  13. package/dist/esm/elements/DatePickerRange/utils/useDatePickerRangeContext.js +14 -0
  14. package/dist/esm/index.js +8 -0
  15. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/16/chevron-left-stroke.svg.js +25 -0
  16. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/16/chevron-right-stroke.svg.js +25 -0
  17. package/dist/esm/styled/StyledCalendar.js +21 -0
  18. package/dist/esm/styled/StyledCalendarItem.js +34 -0
  19. package/dist/esm/styled/StyledDatePicker.js +32 -0
  20. package/dist/esm/styled/StyledDay.js +54 -0
  21. package/dist/esm/styled/StyledDayLabel.js +21 -0
  22. package/dist/esm/styled/StyledHeader.js +21 -0
  23. package/dist/esm/styled/StyledHeaderLabel.js +21 -0
  24. package/dist/esm/styled/StyledHeaderPaddle.js +38 -0
  25. package/dist/esm/styled/StyledHighlight.js +50 -0
  26. package/dist/esm/styled/StyledMenu.js +22 -0
  27. package/dist/esm/styled/StyledMenuWrapper.js +27 -0
  28. package/dist/esm/styled/StyledRangeCalendar.js +22 -0
  29. package/dist/esm/types/index.js +12 -0
  30. package/dist/esm/utils/calendar-utils.js +88 -0
  31. package/dist/index.cjs.js +12 -28
  32. package/package.json +5 -5
  33. package/dist/index.esm.js +0 -1687
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { useCallback, useReducer, useRef, useEffect, useMemo } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { datepickerRangeReducer, retrieveInitialState } from './utils/date-picker-range-reducer.js';
10
+ import { DatePickerRangeContext } from './utils/useDatePickerRangeContext.js';
11
+ import { Start } from './components/Start.js';
12
+ import { End } from './components/End.js';
13
+ import { Calendar } from './components/Calendar.js';
14
+
15
+ const DatePickerRangeComponent = props => {
16
+ const {
17
+ startValue,
18
+ locale,
19
+ weekStartsOn,
20
+ formatDate,
21
+ endValue,
22
+ onChange,
23
+ customParseDate,
24
+ isCompact,
25
+ minValue,
26
+ maxValue,
27
+ children
28
+ } = props;
29
+ const reducer = useCallback(datepickerRangeReducer({
30
+ startValue,
31
+ locale,
32
+ formatDate,
33
+ endValue,
34
+ customParseDate
35
+ }), [startValue, endValue, locale, formatDate, onChange, customParseDate]);
36
+ const [state, dispatch] = useReducer(reducer, retrieveInitialState(props));
37
+ const previousStartValue = useRef(startValue);
38
+ const previousEndValue = useRef(endValue);
39
+ const startInputRef = useRef();
40
+ const endInputRef = useRef();
41
+ useEffect(() => {
42
+ dispatch({
43
+ type: 'CONTROLLED_START_VALUE_CHANGE',
44
+ value: startValue
45
+ });
46
+ if (endInputRef.current && previousStartValue.current !== startValue && startValue !== undefined) {
47
+ endInputRef.current.focus();
48
+ }
49
+ previousStartValue.current = startValue;
50
+ }, [props, startValue]);
51
+ useEffect(() => {
52
+ dispatch({
53
+ type: 'CONTROLLED_END_VALUE_CHANGE',
54
+ value: endValue
55
+ });
56
+ if (startInputRef.current && previousEndValue.current !== endValue && endValue !== undefined) {
57
+ startInputRef.current.focus();
58
+ }
59
+ previousEndValue.current = endValue;
60
+ }, [props, endValue]);
61
+ const value = useMemo(() => ({
62
+ state,
63
+ dispatch,
64
+ isCompact,
65
+ locale,
66
+ weekStartsOn,
67
+ minValue,
68
+ maxValue,
69
+ startValue,
70
+ endValue,
71
+ onChange,
72
+ startInputRef,
73
+ endInputRef,
74
+ customParseDate
75
+ }), [state, dispatch, isCompact, locale, weekStartsOn, minValue, maxValue, startValue, endValue, onChange, startInputRef, endInputRef, customParseDate]);
76
+ return React__default.createElement(DatePickerRangeContext.Provider, {
77
+ value: value
78
+ }, children);
79
+ };
80
+ DatePickerRangeComponent.propTypes = {
81
+ locale: PropTypes.string,
82
+ weekStartsOn: PropTypes.number,
83
+ startValue: PropTypes.instanceOf(Date),
84
+ endValue: PropTypes.instanceOf(Date),
85
+ minValue: PropTypes.instanceOf(Date),
86
+ maxValue: PropTypes.instanceOf(Date),
87
+ onChange: PropTypes.func,
88
+ formatDate: PropTypes.func,
89
+ customParseDate: PropTypes.func,
90
+ isCompact: PropTypes.bool
91
+ };
92
+ DatePickerRangeComponent.defaultProps = {
93
+ locale: 'en-US',
94
+ isCompact: false
95
+ };
96
+ const DatePickerRange = DatePickerRangeComponent;
97
+ DatePickerRange.Calendar = Calendar;
98
+ DatePickerRange.End = End;
99
+ DatePickerRange.Start = Start;
100
+
101
+ export { DatePickerRange };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { forwardRef } from 'react';
8
+ import { addMonths } from 'date-fns/addMonths';
9
+ import '../../../styled/StyledMenu.js';
10
+ import '../../../styled/StyledMenuWrapper.js';
11
+ import '../../../styled/StyledDatePicker.js';
12
+ import { StyledRangeCalendar } from '../../../styled/StyledRangeCalendar.js';
13
+ import '../../../styled/StyledHeader.js';
14
+ import '../../../styled/StyledHeaderPaddle.js';
15
+ import '../../../styled/StyledHeaderLabel.js';
16
+ import '../../../styled/StyledCalendar.js';
17
+ import '../../../styled/StyledCalendarItem.js';
18
+ import '../../../styled/StyledDayLabel.js';
19
+ import '../../../styled/StyledHighlight.js';
20
+ import '../../../styled/StyledDay.js';
21
+ import useDatePickerContext from '../utils/useDatePickerRangeContext.js';
22
+ import { Month } from './Month.js';
23
+
24
+ const Calendar = forwardRef((props, ref) => {
25
+ const {
26
+ state
27
+ } = useDatePickerContext();
28
+ return React__default.createElement(StyledRangeCalendar, Object.assign({
29
+ ref: ref,
30
+ "data-garden-id": "datepickers.range",
31
+ "data-garden-version": '9.0.0-next.8'
32
+ }, props), React__default.createElement(Month, {
33
+ displayDate: state.previewDate,
34
+ isNextHidden: true
35
+ }), React__default.createElement(Month, {
36
+ displayDate: addMonths(state.previewDate, 1),
37
+ isPreviousHidden: true
38
+ }));
39
+ });
40
+ Calendar.displayName = 'DatePickerRange.Calendar';
41
+
42
+ export { Calendar };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { useCallback } from 'react';
8
+ import { KEYS, composeEventHandlers } from '@zendeskgarden/container-utilities';
9
+ import { isValid } from 'date-fns/isValid';
10
+ import { isSameDay } from 'date-fns/isSameDay';
11
+ import { parseInputValue } from '../utils/date-picker-range-reducer.js';
12
+ import useDatePickerContext from '../utils/useDatePickerRangeContext.js';
13
+
14
+ const End = props => {
15
+ const {
16
+ state,
17
+ dispatch,
18
+ onChange,
19
+ startValue,
20
+ endValue,
21
+ endInputRef,
22
+ customParseDate
23
+ } = useDatePickerContext();
24
+ const onChangeCallback = useCallback(e => {
25
+ dispatch({
26
+ type: 'END_INPUT_ONCHANGE',
27
+ value: e.target.value
28
+ });
29
+ props.children.props.onChange && props.children.props.onChange(e);
30
+ }, [dispatch, props.children]);
31
+ const onFocusCallback = useCallback(e => {
32
+ dispatch({
33
+ type: 'END_FOCUS'
34
+ });
35
+ props.children.props.onFocus && props.children.props.onFocus(e);
36
+ }, [dispatch, props.children]);
37
+ const handleBlur = useCallback(() => {
38
+ dispatch({
39
+ type: 'END_BLUR'
40
+ });
41
+ let parsedDate;
42
+ if (customParseDate) {
43
+ parsedDate = customParseDate(state.endInputValue);
44
+ } else {
45
+ parsedDate = parseInputValue({
46
+ inputValue: state.endInputValue
47
+ });
48
+ }
49
+ if (onChange && parsedDate && isValid(parsedDate) && !isSameDay(parsedDate, endValue)) {
50
+ onChange && onChange({
51
+ startValue,
52
+ endValue: parsedDate
53
+ });
54
+ }
55
+ }, [dispatch, onChange, startValue, endValue, customParseDate, state.endInputValue]);
56
+ const onKeydownCallback = useCallback(e => {
57
+ if (e.key === KEYS.ENTER) {
58
+ handleBlur();
59
+ e.preventDefault();
60
+ }
61
+ props.children.props.onKeyDown && props.children.props.onKeyDown(e);
62
+ }, [handleBlur, props.children]);
63
+ const onBlurCallback = useCallback(e => {
64
+ handleBlur();
65
+ props.children.props.onBlur && props.children.props.onBlur(e);
66
+ }, [handleBlur, props.children]);
67
+ const childElement = React__default.Children.only(props.children);
68
+ return React__default.cloneElement(childElement, {
69
+ value: state.endInputValue || '',
70
+ ref: endInputRef,
71
+ onChange: composeEventHandlers(childElement.props.onChange, onChangeCallback),
72
+ onFocus: composeEventHandlers(childElement.props.onFocus, onFocusCallback),
73
+ onKeyDown: composeEventHandlers(childElement.props.onKeyDown, onKeydownCallback),
74
+ onBlur: composeEventHandlers(childElement.props.onBlur, onBlurCallback)
75
+ });
76
+ };
77
+ End.displayName = 'DatePickerRange.End';
78
+
79
+ export { End };
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { forwardRef, useCallback } from 'react';
8
+ import { startOfMonth } from 'date-fns/startOfMonth';
9
+ import { endOfMonth } from 'date-fns/endOfMonth';
10
+ import { startOfWeek } from 'date-fns/startOfWeek';
11
+ import { endOfWeek } from 'date-fns/endOfWeek';
12
+ import { eachDayOfInterval } from 'date-fns/eachDayOfInterval';
13
+ import { addDays } from 'date-fns/addDays';
14
+ import { isToday } from 'date-fns/isToday';
15
+ import { isSameDay } from 'date-fns/isSameDay';
16
+ import { isSameMonth } from 'date-fns/isSameMonth';
17
+ import { isBefore } from 'date-fns/isBefore';
18
+ import { isAfter } from 'date-fns/isAfter';
19
+ import { subDays } from 'date-fns/subDays';
20
+ import { compareAsc } from 'date-fns/compareAsc';
21
+ import SvgChevronLeftStroke from '../../../node_modules/@zendeskgarden/svg-icons/src/16/chevron-left-stroke.svg.js';
22
+ import SvgChevronRightStroke from '../../../node_modules/@zendeskgarden/svg-icons/src/16/chevron-right-stroke.svg.js';
23
+ import '../../../styled/StyledMenu.js';
24
+ import '../../../styled/StyledMenuWrapper.js';
25
+ import { StyledDatePicker } from '../../../styled/StyledDatePicker.js';
26
+ import '../../../styled/StyledRangeCalendar.js';
27
+ import { StyledHeader } from '../../../styled/StyledHeader.js';
28
+ import { StyledHeaderPaddle } from '../../../styled/StyledHeaderPaddle.js';
29
+ import { StyledHeaderLabel } from '../../../styled/StyledHeaderLabel.js';
30
+ import { StyledCalendar } from '../../../styled/StyledCalendar.js';
31
+ import { StyledCalendarItem } from '../../../styled/StyledCalendarItem.js';
32
+ import { StyledDayLabel } from '../../../styled/StyledDayLabel.js';
33
+ import { StyledHighlight } from '../../../styled/StyledHighlight.js';
34
+ import { StyledDay } from '../../../styled/StyledDay.js';
35
+ import { getStartOfWeek } from '../../../utils/calendar-utils.js';
36
+ import useDatePickerContext from '../utils/useDatePickerRangeContext.js';
37
+
38
+ const Month = forwardRef((_ref, ref) => {
39
+ let {
40
+ displayDate,
41
+ isPreviousHidden,
42
+ isNextHidden
43
+ } = _ref;
44
+ const {
45
+ state,
46
+ dispatch,
47
+ locale,
48
+ weekStartsOn,
49
+ isCompact,
50
+ minValue,
51
+ maxValue,
52
+ startValue,
53
+ endValue,
54
+ onChange
55
+ } = useDatePickerContext();
56
+ const headerLabelFormatter = useCallback(date => {
57
+ const formatter = new Intl.DateTimeFormat(locale, {
58
+ month: 'long',
59
+ year: 'numeric'
60
+ });
61
+ return formatter.format(date);
62
+ }, [locale]);
63
+ const dayLabelFormatter = useCallback(date => {
64
+ const formatter = new Intl.DateTimeFormat(locale, {
65
+ weekday: 'short'
66
+ });
67
+ return formatter.format(date);
68
+ }, [locale]);
69
+ const dayFormatter = useCallback(date => {
70
+ const formatter = new Intl.DateTimeFormat(locale, {
71
+ day: 'numeric'
72
+ });
73
+ return formatter.format(date);
74
+ }, [locale]);
75
+ const preferredWeekStartsOn = weekStartsOn || getStartOfWeek(locale);
76
+ const monthStartDate = startOfMonth(displayDate);
77
+ const monthEndDate = endOfMonth(monthStartDate);
78
+ const startDate = startOfWeek(monthStartDate, {
79
+ weekStartsOn: preferredWeekStartsOn
80
+ });
81
+ const endDate = endOfWeek(monthEndDate, {
82
+ weekStartsOn: preferredWeekStartsOn
83
+ });
84
+ const dayLabels = eachDayOfInterval({
85
+ start: startDate,
86
+ end: addDays(startDate, 6)
87
+ }).map(date => {
88
+ const formattedDayLabel = dayLabelFormatter(date);
89
+ return React__default.createElement(StyledCalendarItem, {
90
+ key: `day-label-${formattedDayLabel}`,
91
+ isCompact: isCompact
92
+ }, React__default.createElement(StyledDayLabel, {
93
+ isCompact: isCompact
94
+ }, formattedDayLabel));
95
+ });
96
+ const items = eachDayOfInterval({
97
+ start: startDate,
98
+ end: endDate
99
+ }).map((date, itemsIndex) => {
100
+ const formattedDayLabel = dayFormatter(date);
101
+ const isCurrentDate = isToday(date);
102
+ const isPreviousMonth = !isSameMonth(date, displayDate);
103
+ if (isPreviousMonth) {
104
+ return React__default.createElement(StyledCalendarItem, {
105
+ key: `day-${itemsIndex}`,
106
+ isCompact: isCompact
107
+ }, React__default.createElement(StyledDay, {
108
+ isCompact: isCompact,
109
+ isPreviousMonth: true,
110
+ isDisabled: true
111
+ }, "\xA0"));
112
+ }
113
+ let isSelected = false;
114
+ if (startValue !== undefined) {
115
+ isSelected = isSameDay(date, startValue);
116
+ }
117
+ if (endValue !== undefined) {
118
+ isSelected = isSelected || isSameDay(date, endValue);
119
+ }
120
+ let isDisabled = false;
121
+ if (minValue !== undefined) {
122
+ isDisabled = isBefore(date, minValue) && !isSameDay(date, minValue);
123
+ }
124
+ if (maxValue !== undefined) {
125
+ isDisabled = isDisabled || isAfter(date, maxValue) && !isSameDay(date, maxValue);
126
+ }
127
+ let isHighlighted = false;
128
+ if (startValue !== undefined && endValue !== undefined) {
129
+ isHighlighted = (isAfter(date, startValue) || isSameDay(date, startValue)) && (isBefore(date, endValue) || isSameDay(date, endValue)) && !isSameDay(startValue, endValue);
130
+ } else if (startValue !== undefined && state.hoverDate !== undefined) {
131
+ isHighlighted = (isAfter(date, startValue) || isSameDay(date, startValue)) && (isBefore(date, state.hoverDate) || isSameDay(date, state.hoverDate));
132
+ }
133
+ const isHighlightStart = isHighlighted && startValue && isSameDay(date, startValue) || false;
134
+ const isHighlightEnd = isHighlighted && endValue && isSameDay(date, endValue) || state.hoverDate && isSameDay(date, state.hoverDate) && !isBefore(date, endValue) || false;
135
+ let isInvalidDateRange = endValue && startValue && compareAsc(endValue, startValue) === -1 || false;
136
+ if (minValue) {
137
+ if (startValue) {
138
+ isInvalidDateRange = isInvalidDateRange || compareAsc(startValue, subDays(minValue, 1)) === -1;
139
+ }
140
+ if (endValue) {
141
+ isInvalidDateRange = isInvalidDateRange || compareAsc(endValue, subDays(minValue, 1)) === -1;
142
+ }
143
+ }
144
+ if (maxValue) {
145
+ if (startValue) {
146
+ isInvalidDateRange = isInvalidDateRange || compareAsc(startValue, maxValue) === 1;
147
+ }
148
+ if (endValue) {
149
+ isInvalidDateRange = isInvalidDateRange || compareAsc(endValue, maxValue) === 1;
150
+ }
151
+ }
152
+ return React__default.createElement(StyledCalendarItem, {
153
+ key: `day-${itemsIndex}`,
154
+ isCompact: isCompact
155
+ }, React__default.createElement(StyledHighlight, {
156
+ isHighlighted: !isInvalidDateRange && isHighlighted && !isDisabled,
157
+ isStart: !isInvalidDateRange && isHighlightStart,
158
+ isEnd: !isInvalidDateRange && isHighlightEnd
159
+ }), React__default.createElement(StyledDay, {
160
+ isToday: isCurrentDate,
161
+ isPreviousMonth: isPreviousMonth,
162
+ isSelected: !isInvalidDateRange && isSelected,
163
+ isDisabled: isDisabled,
164
+ isCompact: isCompact,
165
+ onClick: () => {
166
+ if (!isDisabled) {
167
+ dispatch({
168
+ type: 'CLICK_DATE',
169
+ value: date
170
+ });
171
+ if (onChange) {
172
+ if (state.isStartFocused) {
173
+ if (endValue !== undefined && (isBefore(date, endValue) || isSameDay(date, endValue))) {
174
+ onChange({
175
+ startValue: date,
176
+ endValue
177
+ });
178
+ } else {
179
+ onChange({
180
+ startValue: date,
181
+ endValue: undefined
182
+ });
183
+ }
184
+ } else if (state.isEndFocused) {
185
+ if (startValue !== undefined && (isAfter(date, startValue) || isSameDay(date, startValue))) {
186
+ onChange({
187
+ startValue,
188
+ endValue: date
189
+ });
190
+ } else {
191
+ onChange({
192
+ startValue: date,
193
+ endValue: undefined
194
+ });
195
+ }
196
+ } else if (startValue === undefined) {
197
+ onChange({
198
+ startValue: date,
199
+ endValue: undefined
200
+ });
201
+ } else if (endValue === undefined) {
202
+ if (isBefore(date, startValue)) {
203
+ onChange({
204
+ startValue: date,
205
+ endValue: undefined
206
+ });
207
+ } else {
208
+ onChange({
209
+ startValue,
210
+ endValue: date
211
+ });
212
+ }
213
+ } else {
214
+ onChange({
215
+ startValue: date,
216
+ endValue: undefined
217
+ });
218
+ }
219
+ }
220
+ }
221
+ },
222
+ onMouseEnter: () => {
223
+ if (!isSelected) {
224
+ dispatch({
225
+ type: 'HOVER_DATE',
226
+ value: date
227
+ });
228
+ }
229
+ }
230
+ }, formattedDayLabel));
231
+ });
232
+ return React__default.createElement(StyledDatePicker, {
233
+ ref: ref,
234
+ isCompact: isCompact,
235
+ onMouseDown: e => {
236
+ e.preventDefault();
237
+ }
238
+ }, React__default.createElement(StyledHeader, {
239
+ isCompact: isCompact
240
+ }, React__default.createElement(StyledHeaderPaddle, {
241
+ isCompact: isCompact,
242
+ onClick: () => {
243
+ dispatch({
244
+ type: 'PREVIEW_PREVIOUS_MONTH'
245
+ });
246
+ },
247
+ isHidden: isPreviousHidden
248
+ }, React__default.createElement(SvgChevronLeftStroke, null)), React__default.createElement(StyledHeaderLabel, {
249
+ isCompact: isCompact
250
+ }, headerLabelFormatter(displayDate)), React__default.createElement(StyledHeaderPaddle, {
251
+ isCompact: isCompact,
252
+ isHidden: isNextHidden,
253
+ onClick: () => {
254
+ dispatch({
255
+ type: 'PREVIEW_NEXT_MONTH'
256
+ });
257
+ }
258
+ }, React__default.createElement(SvgChevronRightStroke, null))), React__default.createElement(StyledCalendar, {
259
+ isCompact: isCompact,
260
+ onMouseLeave: () => {
261
+ dispatch({
262
+ type: 'HOVER_DATE',
263
+ value: undefined
264
+ });
265
+ }
266
+ }, dayLabels, items));
267
+ });
268
+ Month.displayName = 'Month';
269
+
270
+ export { Month };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright Zendesk, Inc.
3
+ *
4
+ * Use of this source code is governed under the Apache License, Version 2.0
5
+ * found at http://www.apache.org/licenses/LICENSE-2.0.
6
+ */
7
+ import React__default, { useCallback } from 'react';
8
+ import useDatePickerContext from '../utils/useDatePickerRangeContext.js';
9
+ import { KEYS, composeEventHandlers } from '@zendeskgarden/container-utilities';
10
+ import { isValid } from 'date-fns/isValid';
11
+ import { isSameDay } from 'date-fns/isSameDay';
12
+ import { parseInputValue } from '../utils/date-picker-range-reducer.js';
13
+
14
+ const Start = props => {
15
+ const {
16
+ state,
17
+ dispatch,
18
+ onChange,
19
+ startValue,
20
+ endValue,
21
+ startInputRef,
22
+ customParseDate
23
+ } = useDatePickerContext();
24
+ const onChangeCallback = useCallback(e => {
25
+ dispatch({
26
+ type: 'START_INPUT_ONCHANGE',
27
+ value: e.target.value
28
+ });
29
+ props.children.props.onChange && props.children.props.onChange(e);
30
+ }, [dispatch, props.children]);
31
+ const onFocusCallback = useCallback(e => {
32
+ dispatch({
33
+ type: 'START_FOCUS'
34
+ });
35
+ props.children.props.onFocus && props.children.props.onFocus(e);
36
+ }, [dispatch, props.children]);
37
+ const handleBlur = useCallback(() => {
38
+ let parsedDate;
39
+ if (customParseDate) {
40
+ parsedDate = customParseDate(state.startInputValue);
41
+ } else {
42
+ parsedDate = parseInputValue({
43
+ inputValue: state.startInputValue
44
+ });
45
+ }
46
+ dispatch({
47
+ type: 'START_BLUR'
48
+ });
49
+ if (parsedDate && isValid(parsedDate) && !isSameDay(parsedDate, startValue)) {
50
+ onChange && onChange({
51
+ startValue: parsedDate,
52
+ endValue
53
+ });
54
+ }
55
+ }, [dispatch, onChange, startValue, endValue, customParseDate, state.startInputValue]);
56
+ const onKeyDownCallback = useCallback(e => {
57
+ if (e.key === KEYS.ENTER) {
58
+ e.preventDefault();
59
+ handleBlur();
60
+ }
61
+ props.children.props.onKeyDown && props.children.props.onKeyDown(e);
62
+ }, [handleBlur, props.children]);
63
+ const onBlurCallback = useCallback(e => {
64
+ handleBlur();
65
+ props.children.props.onBlur && props.children.props.onBlur(e);
66
+ }, [handleBlur, props.children]);
67
+ const childElement = React__default.Children.only(props.children);
68
+ return React__default.cloneElement(childElement, {
69
+ value: state.startInputValue || '',
70
+ ref: startInputRef,
71
+ onChange: composeEventHandlers(childElement.props.onChange, onChangeCallback),
72
+ onFocus: composeEventHandlers(childElement.props.onFocus, onFocusCallback),
73
+ onKeyDown: composeEventHandlers(childElement.props.onKeyDown, onKeyDownCallback),
74
+ onBlur: composeEventHandlers(childElement.props.onBlur, onBlurCallback)
75
+ });
76
+ };
77
+ Start.displayName = 'DatePickerRange.Start';
78
+
79
+ export { Start };