@zendeskgarden/react-datepickers 9.0.0-next.6 → 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,169 @@
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, useContext, useCallback, useReducer, useRef, useState, useMemo, useEffect } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { mergeRefs } from 'react-merge-refs';
10
+ import { ThemeContext } from 'styled-components';
11
+ import { useFloating, platform, autoPlacement, flip, autoUpdate } from '@floating-ui/react-dom';
12
+ import { WEEK_STARTS_ON, PLACEMENT } from '../../types/index.js';
13
+ import { Calendar } from './components/Calendar.js';
14
+ import { datepickerReducer, retrieveInitialState } from './utils/date-picker-reducer.js';
15
+ import { DatePickerContext } from './utils/useDatePickerContext.js';
16
+ import { StyledMenu } from '../../styled/StyledMenu.js';
17
+ import { StyledMenuWrapper } from '../../styled/StyledMenuWrapper.js';
18
+ import '../../styled/StyledDatePicker.js';
19
+ import '../../styled/StyledRangeCalendar.js';
20
+ import '../../styled/StyledHeader.js';
21
+ import '../../styled/StyledHeaderPaddle.js';
22
+ import '../../styled/StyledHeaderLabel.js';
23
+ import '../../styled/StyledCalendar.js';
24
+ import '../../styled/StyledCalendarItem.js';
25
+ import '../../styled/StyledDayLabel.js';
26
+ import '../../styled/StyledHighlight.js';
27
+ import '../../styled/StyledDay.js';
28
+ import { DEFAULT_THEME, getFloatingPlacements } from '@zendeskgarden/react-theming';
29
+ import { Input } from './components/Input.js';
30
+
31
+ const PLACEMENT_DEFAULT = 'bottom-start';
32
+ const DatePicker = forwardRef((props, calendarRef) => {
33
+ const {
34
+ children,
35
+ placement: _placement,
36
+ zIndex,
37
+ isAnimated,
38
+ refKey,
39
+ value,
40
+ isCompact,
41
+ onChange,
42
+ formatDate,
43
+ minValue,
44
+ maxValue,
45
+ locale,
46
+ weekStartsOn,
47
+ customParseDate,
48
+ ...menuProps
49
+ } = props;
50
+ const theme = useContext(ThemeContext) || DEFAULT_THEME;
51
+ const memoizedReducer = useCallback(datepickerReducer({
52
+ value,
53
+ formatDate,
54
+ locale,
55
+ customParseDate,
56
+ onChange
57
+ }), [value, formatDate, locale, onChange, customParseDate]);
58
+ const [state, dispatch] = useReducer(memoizedReducer, retrieveInitialState(props));
59
+ const triggerRef = useRef(null);
60
+ const floatingRef = useRef(null);
61
+ const [isVisible, setIsVisible] = useState(state.isOpen);
62
+ const contextValue = useMemo(() => ({
63
+ state,
64
+ dispatch
65
+ }), [state, dispatch]);
66
+ const [floatingPlacement] = getFloatingPlacements(theme, _placement === 'auto' ? PLACEMENT_DEFAULT : _placement);
67
+ const {
68
+ refs,
69
+ placement,
70
+ update,
71
+ floatingStyles: {
72
+ transform
73
+ }
74
+ } = useFloating({
75
+ platform: {
76
+ ...platform,
77
+ isRTL: () => theme.rtl
78
+ },
79
+ elements: {
80
+ reference: triggerRef?.current,
81
+ floating: floatingRef?.current
82
+ },
83
+ placement: floatingPlacement,
84
+ middleware: [_placement === 'auto' ? autoPlacement() : flip()]
85
+ });
86
+ const Child = React__default.Children.only(children);
87
+ useEffect(() => {
88
+ let cleanup;
89
+ if (state.isOpen && refs.reference.current && refs.floating.current) {
90
+ cleanup = autoUpdate(refs.reference.current, refs.floating.current, update, {
91
+ elementResize: typeof ResizeObserver === 'function'
92
+ });
93
+ }
94
+ return () => cleanup && cleanup();
95
+ }, [state.isOpen, refs.reference, refs.floating, update]);
96
+ useEffect(() => {
97
+ let timeout;
98
+ if (state.isOpen) {
99
+ setIsVisible(true);
100
+ } else if (isAnimated) {
101
+ timeout = setTimeout(() => setIsVisible(false), 200);
102
+ } else {
103
+ setIsVisible(false);
104
+ }
105
+ return () => clearTimeout(timeout);
106
+ }, [state.isOpen, isAnimated]);
107
+ useEffect(() => {
108
+ dispatch({
109
+ type: 'CONTROLLED_VALUE_CHANGE',
110
+ value
111
+ });
112
+ }, [value]);
113
+ useEffect(() => {
114
+ dispatch({
115
+ type: 'CONTROLLED_LOCALE_CHANGE'
116
+ });
117
+ }, [locale]);
118
+ return React__default.createElement(React__default.Fragment, null, React__default.createElement(Input, {
119
+ element: Child,
120
+ dispatch: dispatch,
121
+ state: state,
122
+ refKey: refKey,
123
+ ref: mergeRefs([triggerRef, Child.ref ? Child.ref : null])
124
+ }), React__default.createElement(DatePickerContext.Provider, {
125
+ value: contextValue
126
+ }, React__default.createElement(StyledMenuWrapper, {
127
+ ref: floatingRef,
128
+ style: {
129
+ transform
130
+ },
131
+ isHidden: !state.isOpen,
132
+ isAnimated: isAnimated && (state.isOpen || isVisible),
133
+ placement: placement,
134
+ zIndex: zIndex
135
+ }, (state.isOpen || isVisible) && React__default.createElement(StyledMenu, menuProps, React__default.createElement(Calendar, {
136
+ ref: calendarRef,
137
+ isCompact: isCompact,
138
+ value: value,
139
+ minValue: minValue,
140
+ maxValue: maxValue,
141
+ locale: locale,
142
+ weekStartsOn: weekStartsOn
143
+ })))));
144
+ });
145
+ DatePicker.displayName = 'DatePicker';
146
+ DatePicker.propTypes = {
147
+ value: PropTypes.any,
148
+ onChange: PropTypes.any,
149
+ formatDate: PropTypes.func,
150
+ locale: PropTypes.any,
151
+ weekStartsOn: PropTypes.oneOf(WEEK_STARTS_ON),
152
+ minValue: PropTypes.any,
153
+ maxValue: PropTypes.any,
154
+ isCompact: PropTypes.bool,
155
+ customParseDate: PropTypes.any,
156
+ refKey: PropTypes.string,
157
+ placement: PropTypes.oneOf(PLACEMENT),
158
+ isAnimated: PropTypes.bool,
159
+ zIndex: PropTypes.number
160
+ };
161
+ DatePicker.defaultProps = {
162
+ placement: PLACEMENT_DEFAULT,
163
+ refKey: 'ref',
164
+ isAnimated: true,
165
+ zIndex: 1000,
166
+ locale: 'en-US'
167
+ };
168
+
169
+ export { DatePicker };
@@ -0,0 +1,125 @@
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 { getDate } from 'date-fns/getDate';
20
+ import '../../../styled/StyledMenu.js';
21
+ import '../../../styled/StyledMenuWrapper.js';
22
+ import { StyledDatePicker } from '../../../styled/StyledDatePicker.js';
23
+ import '../../../styled/StyledRangeCalendar.js';
24
+ import '../../../styled/StyledHeader.js';
25
+ import '../../../styled/StyledHeaderPaddle.js';
26
+ import '../../../styled/StyledHeaderLabel.js';
27
+ import { StyledCalendar } from '../../../styled/StyledCalendar.js';
28
+ import { StyledCalendarItem } from '../../../styled/StyledCalendarItem.js';
29
+ import { StyledDayLabel } from '../../../styled/StyledDayLabel.js';
30
+ import '../../../styled/StyledHighlight.js';
31
+ import { StyledDay } from '../../../styled/StyledDay.js';
32
+ import useDatePickerContext from '../utils/useDatePickerContext.js';
33
+ import { getStartOfWeek } from '../../../utils/calendar-utils.js';
34
+ import { MonthSelector } from './MonthSelector.js';
35
+
36
+ const Calendar = forwardRef((_ref, ref) => {
37
+ let {
38
+ value,
39
+ minValue,
40
+ maxValue,
41
+ isCompact,
42
+ locale,
43
+ weekStartsOn
44
+ } = _ref;
45
+ const {
46
+ state,
47
+ dispatch
48
+ } = useDatePickerContext();
49
+ const preferredWeekStartsOn = weekStartsOn || getStartOfWeek(locale);
50
+ const monthStartDate = startOfMonth(state.previewDate);
51
+ const monthEndDate = endOfMonth(monthStartDate);
52
+ const startDate = startOfWeek(monthStartDate, {
53
+ weekStartsOn: preferredWeekStartsOn
54
+ });
55
+ const endDate = endOfWeek(monthEndDate, {
56
+ weekStartsOn: preferredWeekStartsOn
57
+ });
58
+ const dayLabelFormatter = useCallback(date => {
59
+ const formatter = new Intl.DateTimeFormat(locale, {
60
+ weekday: 'short'
61
+ });
62
+ return formatter.format(date);
63
+ }, [locale]);
64
+ const dayLabels = eachDayOfInterval({
65
+ start: startDate,
66
+ end: addDays(startDate, 6)
67
+ }).map(date => {
68
+ const formattedDayLabel = dayLabelFormatter(date);
69
+ return React__default.createElement(StyledCalendarItem, {
70
+ key: `day-label-${formattedDayLabel}`,
71
+ isCompact: isCompact
72
+ }, React__default.createElement(StyledDayLabel, {
73
+ isCompact: isCompact
74
+ }, formattedDayLabel));
75
+ });
76
+ const items = eachDayOfInterval({
77
+ start: startDate,
78
+ end: endDate
79
+ }).map((date, itemsIndex) => {
80
+ const formattedDayLabel = getDate(date);
81
+ const isCurrentDate = isToday(date);
82
+ const isPreviousMonth = !isSameMonth(date, state.previewDate);
83
+ const isSelected = value && isSameDay(date, value);
84
+ let isDisabled = false;
85
+ if (minValue !== undefined) {
86
+ isDisabled = isBefore(date, minValue) && !isSameDay(date, minValue);
87
+ }
88
+ if (maxValue !== undefined) {
89
+ isDisabled = isDisabled || isAfter(date, maxValue) && !isSameDay(date, maxValue);
90
+ }
91
+ return React__default.createElement(StyledCalendarItem, {
92
+ key: `day-${itemsIndex}`,
93
+ isCompact: isCompact
94
+ }, React__default.createElement(StyledDay, {
95
+ isToday: isCurrentDate,
96
+ isPreviousMonth: isPreviousMonth,
97
+ isSelected: isSelected,
98
+ isDisabled: isDisabled,
99
+ isCompact: isCompact,
100
+ onClick: () => {
101
+ if (!isDisabled) {
102
+ dispatch({
103
+ type: 'SELECT_DATE',
104
+ value: date
105
+ });
106
+ }
107
+ }
108
+ }, formattedDayLabel));
109
+ });
110
+ return React__default.createElement(StyledDatePicker, {
111
+ ref: ref,
112
+ isCompact: isCompact,
113
+ onMouseDown: e => {
114
+ e.preventDefault();
115
+ }
116
+ }, React__default.createElement(MonthSelector, {
117
+ locale: locale,
118
+ isCompact: isCompact
119
+ }), React__default.createElement(StyledCalendar, {
120
+ isCompact: isCompact
121
+ }, dayLabels, items));
122
+ });
123
+ Calendar.displayName = 'Calendar';
124
+
125
+ export { Calendar };
@@ -0,0 +1,75 @@
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 { forwardRef, useRef, cloneElement } from 'react';
8
+ import { composeEventHandlers, KEYS } from '@zendeskgarden/container-utilities';
9
+
10
+ const Input = forwardRef((_ref, ref) => {
11
+ let {
12
+ element,
13
+ dispatch,
14
+ state,
15
+ refKey
16
+ } = _ref;
17
+ const isInputMouseDownRef = useRef(false);
18
+ const handleBlur = () => {
19
+ dispatch({
20
+ type: 'CLOSE'
21
+ });
22
+ };
23
+ const handleChange = e => {
24
+ dispatch({
25
+ type: 'MANUALLY_UPDATE_INPUT',
26
+ value: e.target.value
27
+ });
28
+ };
29
+ const handleClick = () => {
30
+ if (isInputMouseDownRef.current && !state.isOpen) {
31
+ dispatch({
32
+ type: 'OPEN'
33
+ });
34
+ }
35
+ };
36
+ const handleKeyDown = e => {
37
+ switch (e.key) {
38
+ case KEYS.ESCAPE:
39
+ case KEYS.ENTER:
40
+ dispatch({
41
+ type: 'CLOSE'
42
+ });
43
+ break;
44
+ case KEYS.UP:
45
+ case KEYS.DOWN:
46
+ case KEYS.SPACE:
47
+ dispatch({
48
+ type: 'OPEN'
49
+ });
50
+ break;
51
+ }
52
+ };
53
+ const handleMouseDown = () => {
54
+ isInputMouseDownRef.current = true;
55
+ };
56
+ const handleMouseUp = () => {
57
+ setTimeout(() => {
58
+ isInputMouseDownRef.current = false;
59
+ }, 0);
60
+ };
61
+ return cloneElement(element, {
62
+ [refKey]: ref,
63
+ onMouseDown: composeEventHandlers(element.props.onMouseDown, handleMouseDown),
64
+ onMouseUp: composeEventHandlers(element.props.onMouseUp, handleMouseUp),
65
+ onClick: composeEventHandlers(element.props.onClick, handleClick),
66
+ onBlur: composeEventHandlers(element.props.onBlur, handleBlur),
67
+ onChange: composeEventHandlers(element.props.onChange, handleChange),
68
+ onKeyDown: composeEventHandlers(element.props.onKeyDown, handleKeyDown),
69
+ autoComplete: 'off',
70
+ value: state.inputValue
71
+ });
72
+ });
73
+ Input.displayName = 'Input';
74
+
75
+ export { Input };
@@ -0,0 +1,61 @@
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 '../../../styled/StyledMenu.js';
9
+ import '../../../styled/StyledMenuWrapper.js';
10
+ import '../../../styled/StyledDatePicker.js';
11
+ import '../../../styled/StyledRangeCalendar.js';
12
+ import { StyledHeader } from '../../../styled/StyledHeader.js';
13
+ import { StyledHeaderPaddle } from '../../../styled/StyledHeaderPaddle.js';
14
+ import { StyledHeaderLabel } from '../../../styled/StyledHeaderLabel.js';
15
+ import '../../../styled/StyledCalendar.js';
16
+ import '../../../styled/StyledCalendarItem.js';
17
+ import '../../../styled/StyledDayLabel.js';
18
+ import '../../../styled/StyledHighlight.js';
19
+ import '../../../styled/StyledDay.js';
20
+ import useDatePickerContext from '../utils/useDatePickerContext.js';
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
+
24
+ const MonthSelector = _ref => {
25
+ let {
26
+ locale,
27
+ isCompact
28
+ } = _ref;
29
+ const {
30
+ state,
31
+ dispatch
32
+ } = useDatePickerContext();
33
+ const headerLabelFormatter = useCallback(date => {
34
+ const formatter = new Intl.DateTimeFormat(locale, {
35
+ month: 'long',
36
+ year: 'numeric'
37
+ });
38
+ return formatter.format(date);
39
+ }, [locale]);
40
+ return React__default.createElement(StyledHeader, {
41
+ isCompact: isCompact
42
+ }, React__default.createElement(StyledHeaderPaddle, {
43
+ isCompact: isCompact,
44
+ onClick: () => {
45
+ dispatch({
46
+ type: 'PREVIEW_PREVIOUS_MONTH'
47
+ });
48
+ }
49
+ }, React__default.createElement(SvgChevronLeftStroke, null)), React__default.createElement(StyledHeaderLabel, {
50
+ isCompact: isCompact
51
+ }, headerLabelFormatter(state.previewDate)), React__default.createElement(StyledHeaderPaddle, {
52
+ isCompact: isCompact,
53
+ onClick: () => {
54
+ dispatch({
55
+ type: 'PREVIEW_NEXT_MONTH'
56
+ });
57
+ }
58
+ }, React__default.createElement(SvgChevronRightStroke, null)));
59
+ };
60
+
61
+ export { MonthSelector };
@@ -0,0 +1,187 @@
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 { addMonths } from 'date-fns/addMonths';
8
+ import { subMonths } from 'date-fns/subMonths';
9
+ import { isValid } from 'date-fns/isValid';
10
+ import { parse } from 'date-fns/parse';
11
+ import { isBefore } from 'date-fns/isBefore';
12
+ import { isSameDay } from 'date-fns/isSameDay';
13
+
14
+ function parseInputValue(_ref) {
15
+ let {
16
+ inputValue,
17
+ customParseDate
18
+ } = _ref;
19
+ if (customParseDate) {
20
+ return customParseDate(inputValue);
21
+ }
22
+ const MINIMUM_DATE = new Date(1001, 0, 0);
23
+ let tryParseDate = parse(inputValue, 'P', new Date());
24
+ if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
25
+ return tryParseDate;
26
+ }
27
+ tryParseDate = parse(inputValue, 'PP', new Date());
28
+ if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
29
+ return tryParseDate;
30
+ }
31
+ tryParseDate = parse(inputValue, 'PPP', new Date());
32
+ if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
33
+ return tryParseDate;
34
+ }
35
+ return new Date(NaN);
36
+ }
37
+ function formatInputValue(_ref2) {
38
+ let {
39
+ date,
40
+ locale,
41
+ formatDate
42
+ } = _ref2;
43
+ if (!date) {
44
+ return '';
45
+ }
46
+ if (formatDate) {
47
+ return formatDate(date);
48
+ }
49
+ return new Intl.DateTimeFormat(locale, {
50
+ month: 'long',
51
+ day: 'numeric',
52
+ year: 'numeric'
53
+ }).format(date);
54
+ }
55
+ const datepickerReducer = _ref3 => {
56
+ let {
57
+ value,
58
+ formatDate,
59
+ locale,
60
+ customParseDate,
61
+ onChange
62
+ } = _ref3;
63
+ return (state, action) => {
64
+ switch (action.type) {
65
+ case 'OPEN':
66
+ return {
67
+ ...state,
68
+ isOpen: true,
69
+ previewDate: value || new Date()
70
+ };
71
+ case 'CLOSE':
72
+ {
73
+ const inputValue = formatInputValue({
74
+ date: value,
75
+ locale,
76
+ formatDate
77
+ });
78
+ return {
79
+ ...state,
80
+ isOpen: false,
81
+ inputValue
82
+ };
83
+ }
84
+ case 'PREVIEW_NEXT_MONTH':
85
+ {
86
+ const previewDate = addMonths(state.previewDate, 1);
87
+ return {
88
+ ...state,
89
+ previewDate
90
+ };
91
+ }
92
+ case 'PREVIEW_PREVIOUS_MONTH':
93
+ {
94
+ const previewDate = subMonths(state.previewDate, 1);
95
+ return {
96
+ ...state,
97
+ previewDate
98
+ };
99
+ }
100
+ case 'MANUALLY_UPDATE_INPUT':
101
+ {
102
+ const inputValue = action.value;
103
+ const currentDate = parseInputValue({
104
+ inputValue,
105
+ customParseDate
106
+ });
107
+ if (onChange && currentDate && isValid(currentDate) && !isSameDay(value, currentDate)) {
108
+ onChange(currentDate);
109
+ }
110
+ return {
111
+ ...state,
112
+ isOpen: true,
113
+ inputValue
114
+ };
115
+ }
116
+ case 'CONTROLLED_VALUE_CHANGE':
117
+ {
118
+ const previewDate = action.value || new Date();
119
+ const inputValue = formatInputValue({
120
+ date: action.value,
121
+ locale,
122
+ formatDate
123
+ });
124
+ return {
125
+ ...state,
126
+ previewDate,
127
+ inputValue
128
+ };
129
+ }
130
+ case 'CONTROLLED_LOCALE_CHANGE':
131
+ {
132
+ const inputValue = formatInputValue({
133
+ date: value,
134
+ locale,
135
+ formatDate
136
+ });
137
+ return {
138
+ ...state,
139
+ inputValue
140
+ };
141
+ }
142
+ case 'SELECT_DATE':
143
+ {
144
+ const inputValue = formatInputValue({
145
+ date: action.value,
146
+ locale,
147
+ formatDate
148
+ });
149
+ if (onChange && action.value && isValid(action.value) && !isSameDay(value, action.value)) {
150
+ onChange(action.value);
151
+ }
152
+ return {
153
+ ...state,
154
+ isOpen: false,
155
+ inputValue
156
+ };
157
+ }
158
+ default:
159
+ throw new Error();
160
+ }
161
+ };
162
+ };
163
+ function retrieveInitialState(initialProps) {
164
+ let previewDate = initialProps.value;
165
+ if (previewDate === undefined || !isValid(previewDate)) {
166
+ previewDate = new Date();
167
+ }
168
+ let inputValue = '';
169
+ if (initialProps.value !== undefined) {
170
+ if (initialProps.formatDate) {
171
+ inputValue = initialProps.formatDate(initialProps.value);
172
+ } else {
173
+ inputValue = new Intl.DateTimeFormat(initialProps.locale, {
174
+ month: 'long',
175
+ day: 'numeric',
176
+ year: 'numeric'
177
+ }).format(previewDate);
178
+ }
179
+ }
180
+ return {
181
+ isOpen: false,
182
+ previewDate,
183
+ inputValue
184
+ };
185
+ }
186
+
187
+ export { datepickerReducer, retrieveInitialState };
@@ -0,0 +1,14 @@
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 { createContext, useContext } from 'react';
8
+
9
+ const DatePickerContext = createContext(undefined);
10
+ const useDatePickerContext = () => {
11
+ return useContext(DatePickerContext);
12
+ };
13
+
14
+ export { DatePickerContext, useDatePickerContext as default };