@zendeskgarden/react-datepickers 9.0.0-next.2 → 9.0.0-next.21

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 (47) hide show
  1. package/README.md +2 -2
  2. package/dist/esm/elements/DatePicker/DatePicker.js +169 -0
  3. package/dist/esm/elements/DatePicker/components/Calendar.js +125 -0
  4. package/dist/esm/elements/DatePicker/components/Input.js +75 -0
  5. package/dist/esm/elements/DatePicker/components/MonthSelector.js +61 -0
  6. package/dist/esm/elements/DatePicker/utils/date-picker-reducer.js +187 -0
  7. package/dist/esm/elements/DatePicker/utils/useDatePickerContext.js +14 -0
  8. package/dist/esm/elements/DatePickerRange/DatePickerRange.js +101 -0
  9. package/dist/esm/elements/DatePickerRange/components/Calendar.js +42 -0
  10. package/dist/esm/elements/DatePickerRange/components/End.js +79 -0
  11. package/dist/esm/elements/DatePickerRange/components/Month.js +270 -0
  12. package/dist/esm/elements/DatePickerRange/components/Start.js +79 -0
  13. package/dist/esm/elements/DatePickerRange/utils/date-picker-range-reducer.js +319 -0
  14. package/dist/esm/elements/DatePickerRange/utils/useDatePickerRangeContext.js +14 -0
  15. package/dist/esm/index.js +8 -0
  16. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/16/chevron-left-stroke.svg.js +25 -0
  17. package/dist/esm/node_modules/@zendeskgarden/svg-icons/src/16/chevron-right-stroke.svg.js +25 -0
  18. package/dist/esm/styled/StyledCalendar.js +22 -0
  19. package/dist/esm/styled/StyledCalendarItem.js +35 -0
  20. package/dist/esm/styled/StyledDatePicker.js +40 -0
  21. package/dist/esm/styled/StyledDay.js +95 -0
  22. package/dist/esm/styled/StyledDayLabel.js +22 -0
  23. package/dist/esm/styled/StyledHeader.js +22 -0
  24. package/dist/esm/styled/StyledHeaderLabel.js +22 -0
  25. package/dist/esm/styled/StyledHeaderPaddle.js +71 -0
  26. package/dist/esm/styled/StyledHighlight.js +56 -0
  27. package/dist/esm/styled/StyledMenu.js +22 -0
  28. package/dist/esm/styled/StyledMenuWrapper.js +29 -0
  29. package/dist/esm/styled/StyledRangeCalendar.js +23 -0
  30. package/dist/esm/types/index.js +12 -0
  31. package/dist/esm/utils/calendar-utils.js +88 -0
  32. package/dist/index.cjs.js +240 -156
  33. package/dist/typings/elements/DatePicker/utils/date-picker-reducer.d.ts +4 -4
  34. package/dist/typings/elements/DatePickerRange/utils/date-picker-range-reducer.d.ts +4 -4
  35. package/dist/typings/styled/StyledCalendar.d.ts +3 -2
  36. package/dist/typings/styled/StyledCalendarItem.d.ts +4 -3
  37. package/dist/typings/styled/StyledDatePicker.d.ts +3 -2
  38. package/dist/typings/styled/StyledDay.d.ts +5 -5
  39. package/dist/typings/styled/StyledDayLabel.d.ts +3 -2
  40. package/dist/typings/styled/StyledHeader.d.ts +3 -2
  41. package/dist/typings/styled/StyledHeaderLabel.d.ts +3 -2
  42. package/dist/typings/styled/StyledHeaderPaddle.d.ts +7 -4
  43. package/dist/typings/styled/StyledHighlight.d.ts +5 -4
  44. package/dist/typings/styled/StyledMenuWrapper.d.ts +4 -4
  45. package/dist/typings/styled/StyledRangeCalendar.d.ts +2 -1
  46. package/package.json +8 -8
  47. package/dist/index.esm.js +0 -1683
package/dist/index.esm.js DELETED
@@ -1,1683 +0,0 @@
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
-
8
- import * as React from 'react';
9
- import React__default, { createContext, useContext, useCallback, forwardRef, useRef, cloneElement, useReducer, useState, useMemo, useEffect } from 'react';
10
- import PropTypes from 'prop-types';
11
- import { mergeRefs } from 'react-merge-refs';
12
- import styled, { css, ThemeContext } from 'styled-components';
13
- import { useFloating, autoPlacement, flip, autoUpdate } from '@floating-ui/react-dom';
14
- import { PLACEMENT as PLACEMENT$1, retrieveComponentStyles, DEFAULT_THEME, menuStyles, getMenuPosition, getColor, getFloatingPlacements } from '@zendeskgarden/react-theming';
15
- import { startOfMonth } from 'date-fns/startOfMonth';
16
- import { endOfMonth } from 'date-fns/endOfMonth';
17
- import { startOfWeek } from 'date-fns/startOfWeek';
18
- import { endOfWeek } from 'date-fns/endOfWeek';
19
- import { eachDayOfInterval } from 'date-fns/eachDayOfInterval';
20
- import { addDays } from 'date-fns/addDays';
21
- import { isToday } from 'date-fns/isToday';
22
- import { isSameDay } from 'date-fns/isSameDay';
23
- import { isSameMonth } from 'date-fns/isSameMonth';
24
- import { isBefore } from 'date-fns/isBefore';
25
- import { isAfter } from 'date-fns/isAfter';
26
- import { getDate } from 'date-fns/getDate';
27
- import { addMonths } from 'date-fns/addMonths';
28
- import { subMonths } from 'date-fns/subMonths';
29
- import { isValid } from 'date-fns/isValid';
30
- import { parse } from 'date-fns/parse';
31
- import { composeEventHandlers, KEYS } from '@zendeskgarden/container-utilities';
32
- import { compareAsc } from 'date-fns/compareAsc';
33
- import { subDays } from 'date-fns/subDays';
34
-
35
- const WEEK_STARTS_ON = [0, 1, 2, 3, 4, 5, 6];
36
- const PLACEMENT = ['auto', ...PLACEMENT$1];
37
-
38
- const COMPONENT_ID$b = 'datepickers.menu';
39
- const StyledMenu = styled.div.attrs({
40
- 'data-garden-id': COMPONENT_ID$b,
41
- 'data-garden-version': '9.0.0-next.2'
42
- }).withConfig({
43
- displayName: "StyledMenu",
44
- componentId: "sc-1npbkk0-0"
45
- })(["", ";"], props => retrieveComponentStyles(COMPONENT_ID$b, props));
46
- StyledMenu.defaultProps = {
47
- theme: DEFAULT_THEME
48
- };
49
-
50
- const COMPONENT_ID$a = 'datepickers.menu_wrapper';
51
- const StyledMenuWrapper = styled.div.attrs(props => ({
52
- className: props.isAnimated && 'is-animated'
53
- })).withConfig({
54
- displayName: "StyledMenuWrapper",
55
- componentId: "sc-6fowoz-0"
56
- })(["top:0;left:0;", ";", ";"], props => menuStyles(getMenuPosition(props.placement), {
57
- theme: props.theme,
58
- hidden: props.isHidden,
59
- margin: `${props.theme.space.base}px`,
60
- zIndex: props.zIndex,
61
- animationModifier: props.isAnimated ? '.is-animated' : undefined
62
- }), props => retrieveComponentStyles(COMPONENT_ID$a, props));
63
- StyledMenuWrapper.defaultProps = {
64
- theme: DEFAULT_THEME
65
- };
66
-
67
- const COMPONENT_ID$9 = 'datepickers.datepicker';
68
- const retrievePadding = _ref => {
69
- let {
70
- isCompact,
71
- theme
72
- } = _ref;
73
- let value = theme.space.base * 5;
74
- if (isCompact) {
75
- value = theme.space.base * 4;
76
- }
77
- return `margin: ${value}px;`;
78
- };
79
- const StyledDatePicker = styled.div.attrs({
80
- 'data-garden-id': COMPONENT_ID$9
81
- }).withConfig({
82
- displayName: "StyledDatePicker",
83
- componentId: "sc-15hwqzh-0"
84
- })(["direction:", ";", " background-color:", ";color:", ";", ";"], props => props.theme.rtl && 'rtl', retrievePadding, props => props.theme.colors.background, props => props.theme.colors.foreground, props => retrieveComponentStyles(COMPONENT_ID$9, props));
85
- StyledDatePicker.defaultProps = {
86
- theme: DEFAULT_THEME
87
- };
88
-
89
- const COMPONENT_ID$8 = 'datepickers.range_calendar';
90
- const StyledRangeCalendar = styled.div.attrs({
91
- 'data-garden-id': COMPONENT_ID$8
92
- }).withConfig({
93
- displayName: "StyledRangeCalendar",
94
- componentId: "sc-1og46sy-0"
95
- })(["display:flex;overflow:auto;", "{margin:0;", "}", ";"], StyledDatePicker, props => props.theme.rtl ? `&:last-of-type {margin-right: ${props.theme.space.base * 5}px}` : `&:first-of-type {margin-right: ${props.theme.space.base * 5}px}`, props => retrieveComponentStyles(COMPONENT_ID$8, props));
96
- StyledRangeCalendar.defaultProps = {
97
- theme: DEFAULT_THEME
98
- };
99
-
100
- const COMPONENT_ID$7 = 'datepickers.header';
101
- const StyledHeader = styled.div.attrs({
102
- 'data-garden-id': COMPONENT_ID$7
103
- }).withConfig({
104
- displayName: "StyledHeader",
105
- componentId: "sc-upq318-0"
106
- })(["display:flex;width:", "px;", ";"], props => props.isCompact ? props.theme.space.base * 56 : props.theme.space.base * 70, props => retrieveComponentStyles(COMPONENT_ID$7, props));
107
- StyledHeader.defaultProps = {
108
- theme: DEFAULT_THEME
109
- };
110
-
111
- const retrieveSizing = _ref => {
112
- let {
113
- isCompact,
114
- theme
115
- } = _ref;
116
- let size = theme.space.base * 10;
117
- if (isCompact) {
118
- size = theme.space.base * 8;
119
- }
120
- return css(["width:", "px;height:", "px;"], size, size);
121
- };
122
- const retrieveColor$1 = _ref2 => {
123
- let {
124
- theme
125
- } = _ref2;
126
- return css([":hover{background-color:", ";color:", ";}:active{background-color:", ";color:", ";}color:", ";"], getColor('primaryHue', 600, theme, 0.08), theme.colors.foreground, getColor('primaryHue', 600, theme, 0.2), theme.colors.foreground, getColor('neutralHue', 600, theme));
127
- };
128
- const COMPONENT_ID$6 = 'datepickers.header_paddle';
129
- const StyledHeaderPaddle = styled.div.attrs({
130
- 'data-garden-id': COMPONENT_ID$6
131
- }).withConfig({
132
- displayName: "StyledHeaderPaddle",
133
- componentId: "sc-2oqh0g-0"
134
- })(["display:flex;align-items:center;justify-content:center;transform:", ";visibility:", ";border-radius:50%;cursor:pointer;", " ", " svg{width:", ";height:", ";}", ";"], props => props.theme.rtl && 'rotate(180deg)', props => props.isHidden && 'hidden', retrieveSizing, retrieveColor$1, props => `${props.theme.iconSizes.md}`, props => `${props.theme.iconSizes.md}`, props => retrieveComponentStyles(COMPONENT_ID$6, props));
135
- StyledHeaderPaddle.defaultProps = {
136
- theme: DEFAULT_THEME
137
- };
138
-
139
- const COMPONENT_ID$5 = 'datepickers.header_label';
140
- const StyledHeaderLabel = styled.div.attrs({
141
- 'data-garden-id': COMPONENT_ID$5
142
- }).withConfig({
143
- displayName: "StyledHeaderLabel",
144
- componentId: "sc-1ryf5ub-0"
145
- })(["display:flex;flex-grow:1;align-items:center;justify-content:center;font-size:", ";font-weight:", ";", ";"], props => props.isCompact ? props.theme.fontSizes.sm : props.theme.fontSizes.md, props => props.theme.fontWeights.semibold, props => retrieveComponentStyles(COMPONENT_ID$5, props));
146
- StyledHeaderLabel.defaultProps = {
147
- theme: DEFAULT_THEME
148
- };
149
-
150
- const COMPONENT_ID$4 = 'datepickers.calendar';
151
- const StyledCalendar = styled.div.attrs({
152
- 'data-garden-id': COMPONENT_ID$4
153
- }).withConfig({
154
- displayName: "StyledCalendar",
155
- componentId: "sc-g5hoe8-0"
156
- })(["width:", "px;", ";"], props => props.isCompact ? props.theme.space.base * 56 : props.theme.space.base * 70, props => retrieveComponentStyles(COMPONENT_ID$4, props));
157
- StyledCalendar.defaultProps = {
158
- theme: DEFAULT_THEME
159
- };
160
-
161
- const COMPONENT_ID$3 = 'datepickers.calendar_item';
162
- const retrieveSize = _ref => {
163
- let {
164
- isCompact,
165
- theme
166
- } = _ref;
167
- let size;
168
- if (isCompact) {
169
- size = `${theme.space.base * 8}px`;
170
- } else {
171
- size = `${theme.space.base * 10}px`;
172
- }
173
- return css(["width:", ";height:", ";"], size, size);
174
- };
175
- const StyledCalendarItem = styled.div.attrs({
176
- 'data-garden-id': COMPONENT_ID$3
177
- }).withConfig({
178
- displayName: "StyledCalendarItem",
179
- componentId: "sc-143w8wb-0"
180
- })(["display:inline-block;position:relative;vertical-align:top;", " ", ";"], retrieveSize, props => retrieveComponentStyles(COMPONENT_ID$3, props));
181
- StyledCalendarItem.defaultProps = {
182
- theme: DEFAULT_THEME
183
- };
184
-
185
- const COMPONENT_ID$2 = 'datepickers.day_label';
186
- const StyledDayLabel = styled.div.attrs({
187
- 'data-garden-id': COMPONENT_ID$2
188
- }).withConfig({
189
- displayName: "StyledDayLabel",
190
- componentId: "sc-9bh1p7-0"
191
- })(["display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:", ";font-weight:", ";", ";"], props => props.isCompact ? props.theme.fontSizes.sm : props.theme.fontSizes.md, props => props.theme.fontWeights.semibold, props => retrieveComponentStyles(COMPONENT_ID$2, props));
192
- StyledDayLabel.defaultProps = {
193
- theme: DEFAULT_THEME
194
- };
195
-
196
- const COMPONENT_ID$1 = 'datepickers.highlight';
197
- const retrieveBorderRadius = _ref => {
198
- let {
199
- theme,
200
- isEnd,
201
- isStart
202
- } = _ref;
203
- const startValue = 'border-radius: 0 50% 50% 0;';
204
- const endValue = 'border-radius: 50% 0 0 50%;';
205
- if (theme.rtl) {
206
- if (isStart) {
207
- return startValue;
208
- } else if (isEnd) {
209
- return endValue;
210
- }
211
- }
212
- if (isStart) {
213
- return endValue;
214
- } else if (isEnd) {
215
- return startValue;
216
- }
217
- return '';
218
- };
219
- const retrieveColor = _ref2 => {
220
- let {
221
- isHighlighted,
222
- theme
223
- } = _ref2;
224
- return css(["background-color:", ";"], isHighlighted && getColor('primaryHue', 600, theme, 0.08));
225
- };
226
- const StyledHighlight = styled.div.attrs({
227
- 'data-garden-id': COMPONENT_ID$1
228
- }).withConfig({
229
- displayName: "StyledHighlight",
230
- componentId: "sc-16vr32x-0"
231
- })(["position:absolute;top:0;left:0;width:100%;height:100%;", " ", " ", ";"], retrieveBorderRadius, retrieveColor, props => retrieveComponentStyles(COMPONENT_ID$1, props));
232
- StyledHighlight.defaultProps = {
233
- theme: DEFAULT_THEME
234
- };
235
-
236
- const retrieveStyledDayColors = _ref => {
237
- let {
238
- isSelected,
239
- isDisabled,
240
- isToday,
241
- isPreviousMonth,
242
- theme
243
- } = _ref;
244
- let backgroundColor = 'inherit';
245
- let color = getColor('primaryHue', 600, theme);
246
- if (isSelected && !isDisabled) {
247
- backgroundColor = getColor('primaryHue', 600, theme);
248
- color = theme.colors.background;
249
- } else if (isDisabled) {
250
- color = getColor('neutralHue', 400, theme);
251
- } else if (isToday) {
252
- color = 'inherit';
253
- } else if (isPreviousMonth) {
254
- color = getColor('neutralHue', 600, theme);
255
- }
256
- return css(["background-color:", ";color:", ";", ""], backgroundColor, color, !isSelected && !isDisabled && `
257
- :hover {
258
- background-color: ${getColor('primaryHue', 600, theme, 0.08)};
259
- color: ${getColor('primaryHue', 800, theme)};
260
- }
261
-
262
- :active {
263
- background-color: ${getColor('primaryHue', 600, theme, 0.2)};
264
- color: ${getColor('primaryHue', 800, theme)};
265
- }
266
- `);
267
- };
268
- const COMPONENT_ID = 'datepickers.day';
269
- const StyledDay = styled.div.attrs(props => ({
270
- 'data-garden-id': COMPONENT_ID,
271
- 'aria-disabled': props.isDisabled ? 'true' : 'false'
272
- })).withConfig({
273
- displayName: "StyledDay",
274
- componentId: "sc-v42uk5-0"
275
- })(["display:flex;position:absolute;align-items:center;justify-content:center;border-radius:50%;cursor:", ";width:100%;height:100%;font-size:", ";font-weight:", ";", " ", ";"], props => props.isDisabled ? 'inherit' : 'pointer', props => props.isCompact ? props.theme.fontSizes.sm : props.theme.fontSizes.md, props => props.isToday && !props.isDisabled ? props.theme.fontWeights.semibold : 'inherit', retrieveStyledDayColors, props => retrieveComponentStyles(COMPONENT_ID, props));
276
- StyledDay.defaultProps = {
277
- theme: DEFAULT_THEME
278
- };
279
-
280
- const DatePickerContext = createContext(undefined);
281
- const useDatePickerContext$1 = () => {
282
- return useContext(DatePickerContext);
283
- };
284
-
285
- const REGION_MAPPINGS = {
286
- 'ar-DZ': 0,
287
- 'ar-SA': 0,
288
- 'en-CA': 0,
289
- 'en-GB': 1,
290
- 'en-US': 0,
291
- 'fa-IR': 0,
292
- 'fr-CH': 1,
293
- 'nl-BE': 1,
294
- 'pt-BR': 0,
295
- 'zh-CN': 1,
296
- 'zh-TW': 1
297
- };
298
- const LANGUAGE_MAPPINGS = {
299
- af: 0,
300
- ar: 6,
301
- be: 1,
302
- bg: 1,
303
- bn: 0,
304
- ca: 1,
305
- cs: 1,
306
- da: 1,
307
- de: 1,
308
- el: 1,
309
- en: 0,
310
- eo: 1,
311
- es: 1,
312
- et: 1,
313
- fa: 0,
314
- fi: 1,
315
- fil: 0,
316
- fr: 1,
317
- gl: 1,
318
- he: 0,
319
- hr: 1,
320
- hu: 1,
321
- id: 1,
322
- is: 1,
323
- it: 1,
324
- ja: 1,
325
- ka: 1,
326
- ko: 0,
327
- lt: 1,
328
- lv: 1,
329
- mk: 1,
330
- ms: 1,
331
- nb: 1,
332
- nl: 1,
333
- nn: 1,
334
- pl: 1,
335
- pt: 0,
336
- ro: 1,
337
- ru: 1,
338
- sk: 1,
339
- sl: 1,
340
- sr: 1,
341
- sv: 1,
342
- th: 1,
343
- tr: 1,
344
- ug: 0,
345
- uk: 1,
346
- vi: 1,
347
- zh: 1
348
- };
349
- function getStartOfWeek(locale) {
350
- if (!locale) {
351
- return 0;
352
- }
353
- for (const region in REGION_MAPPINGS) {
354
- if (locale.startsWith(region)) {
355
- return REGION_MAPPINGS[region];
356
- }
357
- }
358
- for (const language in LANGUAGE_MAPPINGS) {
359
- if (locale.startsWith(language)) {
360
- return LANGUAGE_MAPPINGS[language];
361
- }
362
- }
363
- return 0;
364
- }
365
-
366
- var _path$1;
367
- function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
368
- var SvgChevronLeftStroke = function SvgChevronLeftStroke(props) {
369
- return /*#__PURE__*/React.createElement("svg", _extends$2({
370
- xmlns: "http://www.w3.org/2000/svg",
371
- width: 16,
372
- height: 16,
373
- focusable: "false",
374
- viewBox: "0 0 16 16",
375
- "aria-hidden": "true"
376
- }, props), _path$1 || (_path$1 = /*#__PURE__*/React.createElement("path", {
377
- fill: "currentColor",
378
- d: "M10.39 12.688a.5.5 0 01-.718.69l-.062-.066-4-5a.5.5 0 01-.054-.542l.054-.082 4-5a.5.5 0 01.83.55l-.05.074L6.641 8l3.75 4.688z"
379
- })));
380
- };
381
-
382
- var _path;
383
- function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
384
- var SvgChevronRightStroke = function SvgChevronRightStroke(props) {
385
- return /*#__PURE__*/React.createElement("svg", _extends$1({
386
- xmlns: "http://www.w3.org/2000/svg",
387
- width: 16,
388
- height: 16,
389
- focusable: "false",
390
- viewBox: "0 0 16 16",
391
- "aria-hidden": "true"
392
- }, props), _path || (_path = /*#__PURE__*/React.createElement("path", {
393
- fill: "currentColor",
394
- d: "M5.61 3.312a.5.5 0 01.718-.69l.062.066 4 5a.5.5 0 01.054.542l-.054.082-4 5a.5.5 0 01-.83-.55l.05-.074L9.359 8l-3.75-4.688z"
395
- })));
396
- };
397
-
398
- const MonthSelector = _ref => {
399
- let {
400
- locale,
401
- isCompact
402
- } = _ref;
403
- const {
404
- state,
405
- dispatch
406
- } = useDatePickerContext$1();
407
- const headerLabelFormatter = useCallback(date => {
408
- const formatter = new Intl.DateTimeFormat(locale, {
409
- month: 'long',
410
- year: 'numeric'
411
- });
412
- return formatter.format(date);
413
- }, [locale]);
414
- return React__default.createElement(StyledHeader, {
415
- isCompact: isCompact
416
- }, React__default.createElement(StyledHeaderPaddle, {
417
- isCompact: isCompact,
418
- onClick: () => {
419
- dispatch({
420
- type: 'PREVIEW_PREVIOUS_MONTH'
421
- });
422
- }
423
- }, React__default.createElement(SvgChevronLeftStroke, null)), React__default.createElement(StyledHeaderLabel, {
424
- isCompact: isCompact
425
- }, headerLabelFormatter(state.previewDate)), React__default.createElement(StyledHeaderPaddle, {
426
- isCompact: isCompact,
427
- onClick: () => {
428
- dispatch({
429
- type: 'PREVIEW_NEXT_MONTH'
430
- });
431
- }
432
- }, React__default.createElement(SvgChevronRightStroke, null)));
433
- };
434
-
435
- const Calendar$1 = forwardRef((_ref, ref) => {
436
- let {
437
- value,
438
- minValue,
439
- maxValue,
440
- isCompact,
441
- locale,
442
- weekStartsOn
443
- } = _ref;
444
- const {
445
- state,
446
- dispatch
447
- } = useDatePickerContext$1();
448
- const preferredWeekStartsOn = weekStartsOn || getStartOfWeek(locale);
449
- const monthStartDate = startOfMonth(state.previewDate);
450
- const monthEndDate = endOfMonth(monthStartDate);
451
- const startDate = startOfWeek(monthStartDate, {
452
- weekStartsOn: preferredWeekStartsOn
453
- });
454
- const endDate = endOfWeek(monthEndDate, {
455
- weekStartsOn: preferredWeekStartsOn
456
- });
457
- const dayLabelFormatter = useCallback(date => {
458
- const formatter = new Intl.DateTimeFormat(locale, {
459
- weekday: 'short'
460
- });
461
- return formatter.format(date);
462
- }, [locale]);
463
- const dayLabels = eachDayOfInterval({
464
- start: startDate,
465
- end: addDays(startDate, 6)
466
- }).map(date => {
467
- const formattedDayLabel = dayLabelFormatter(date);
468
- return React__default.createElement(StyledCalendarItem, {
469
- key: `day-label-${formattedDayLabel}`,
470
- isCompact: isCompact
471
- }, React__default.createElement(StyledDayLabel, {
472
- isCompact: isCompact
473
- }, formattedDayLabel));
474
- });
475
- const items = eachDayOfInterval({
476
- start: startDate,
477
- end: endDate
478
- }).map((date, itemsIndex) => {
479
- const formattedDayLabel = getDate(date);
480
- const isCurrentDate = isToday(date);
481
- const isPreviousMonth = !isSameMonth(date, state.previewDate);
482
- const isSelected = value && isSameDay(date, value);
483
- let isDisabled = false;
484
- if (minValue !== undefined) {
485
- isDisabled = isBefore(date, minValue) && !isSameDay(date, minValue);
486
- }
487
- if (maxValue !== undefined) {
488
- isDisabled = isDisabled || isAfter(date, maxValue) && !isSameDay(date, maxValue);
489
- }
490
- return React__default.createElement(StyledCalendarItem, {
491
- key: `day-${itemsIndex}`,
492
- isCompact: isCompact
493
- }, React__default.createElement(StyledDay, {
494
- isToday: isCurrentDate,
495
- isPreviousMonth: isPreviousMonth,
496
- isSelected: isSelected,
497
- isDisabled: isDisabled,
498
- isCompact: isCompact,
499
- onClick: () => {
500
- if (!isDisabled) {
501
- dispatch({
502
- type: 'SELECT_DATE',
503
- value: date
504
- });
505
- }
506
- }
507
- }, formattedDayLabel));
508
- });
509
- return React__default.createElement(StyledDatePicker, {
510
- ref: ref,
511
- isCompact: isCompact,
512
- onMouseDown: e => {
513
- e.preventDefault();
514
- }
515
- }, React__default.createElement(MonthSelector, {
516
- locale: locale,
517
- isCompact: isCompact
518
- }), React__default.createElement(StyledCalendar, {
519
- isCompact: isCompact
520
- }, dayLabels, items));
521
- });
522
- Calendar$1.displayName = 'Calendar';
523
-
524
- function parseInputValue$1(_ref) {
525
- let {
526
- inputValue,
527
- customParseDate
528
- } = _ref;
529
- if (customParseDate) {
530
- return customParseDate(inputValue);
531
- }
532
- const MINIMUM_DATE = new Date(1001, 0, 0);
533
- let tryParseDate = parse(inputValue, 'P', new Date());
534
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
535
- return tryParseDate;
536
- }
537
- tryParseDate = parse(inputValue, 'PP', new Date());
538
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
539
- return tryParseDate;
540
- }
541
- tryParseDate = parse(inputValue, 'PPP', new Date());
542
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
543
- return tryParseDate;
544
- }
545
- return new Date(NaN);
546
- }
547
- function formatInputValue(_ref2) {
548
- let {
549
- date,
550
- locale,
551
- formatDate
552
- } = _ref2;
553
- if (!date) {
554
- return '';
555
- }
556
- if (formatDate) {
557
- return formatDate(date);
558
- }
559
- return new Intl.DateTimeFormat(locale, {
560
- month: 'long',
561
- day: 'numeric',
562
- year: 'numeric'
563
- }).format(date);
564
- }
565
- const datepickerReducer = _ref3 => {
566
- let {
567
- value,
568
- formatDate,
569
- locale,
570
- customParseDate,
571
- onChange
572
- } = _ref3;
573
- return (state, action) => {
574
- switch (action.type) {
575
- case 'OPEN':
576
- return {
577
- ...state,
578
- isOpen: true,
579
- previewDate: value || new Date()
580
- };
581
- case 'CLOSE':
582
- {
583
- const inputValue = formatInputValue({
584
- date: value,
585
- locale,
586
- formatDate
587
- });
588
- return {
589
- ...state,
590
- isOpen: false,
591
- inputValue
592
- };
593
- }
594
- case 'PREVIEW_NEXT_MONTH':
595
- {
596
- const previewDate = addMonths(state.previewDate, 1);
597
- return {
598
- ...state,
599
- previewDate
600
- };
601
- }
602
- case 'PREVIEW_PREVIOUS_MONTH':
603
- {
604
- const previewDate = subMonths(state.previewDate, 1);
605
- return {
606
- ...state,
607
- previewDate
608
- };
609
- }
610
- case 'MANUALLY_UPDATE_INPUT':
611
- {
612
- const inputValue = action.value;
613
- const currentDate = parseInputValue$1({
614
- inputValue,
615
- customParseDate
616
- });
617
- if (onChange && currentDate && isValid(currentDate) && !isSameDay(value, currentDate)) {
618
- onChange(currentDate);
619
- }
620
- return {
621
- ...state,
622
- isOpen: true,
623
- inputValue
624
- };
625
- }
626
- case 'CONTROLLED_VALUE_CHANGE':
627
- {
628
- const previewDate = action.value || new Date();
629
- const inputValue = formatInputValue({
630
- date: action.value,
631
- locale,
632
- formatDate
633
- });
634
- return {
635
- ...state,
636
- previewDate,
637
- inputValue
638
- };
639
- }
640
- case 'CONTROLLED_LOCALE_CHANGE':
641
- {
642
- const inputValue = formatInputValue({
643
- date: value,
644
- locale,
645
- formatDate
646
- });
647
- return {
648
- ...state,
649
- inputValue
650
- };
651
- }
652
- case 'SELECT_DATE':
653
- {
654
- const inputValue = formatInputValue({
655
- date: action.value,
656
- locale,
657
- formatDate
658
- });
659
- if (onChange && action.value && isValid(action.value) && !isSameDay(value, action.value)) {
660
- onChange(action.value);
661
- }
662
- return {
663
- ...state,
664
- isOpen: false,
665
- inputValue
666
- };
667
- }
668
- default:
669
- throw new Error();
670
- }
671
- };
672
- };
673
- function retrieveInitialState$1(initialProps) {
674
- let previewDate = initialProps.value;
675
- if (previewDate === undefined || !isValid(previewDate)) {
676
- previewDate = new Date();
677
- }
678
- let inputValue = '';
679
- if (initialProps.value !== undefined) {
680
- if (initialProps.formatDate) {
681
- inputValue = initialProps.formatDate(initialProps.value);
682
- } else {
683
- inputValue = new Intl.DateTimeFormat(initialProps.locale, {
684
- month: 'long',
685
- day: 'numeric',
686
- year: 'numeric'
687
- }).format(previewDate);
688
- }
689
- }
690
- return {
691
- isOpen: false,
692
- previewDate,
693
- inputValue
694
- };
695
- }
696
-
697
- const Input = forwardRef((_ref, ref) => {
698
- let {
699
- element,
700
- dispatch,
701
- state,
702
- refKey
703
- } = _ref;
704
- const isInputMouseDownRef = useRef(false);
705
- const handleBlur = () => {
706
- dispatch({
707
- type: 'CLOSE'
708
- });
709
- };
710
- const handleChange = e => {
711
- dispatch({
712
- type: 'MANUALLY_UPDATE_INPUT',
713
- value: e.target.value
714
- });
715
- };
716
- const handleClick = () => {
717
- if (isInputMouseDownRef.current && !state.isOpen) {
718
- dispatch({
719
- type: 'OPEN'
720
- });
721
- }
722
- };
723
- const handleKeyDown = e => {
724
- switch (e.key) {
725
- case KEYS.ESCAPE:
726
- case KEYS.ENTER:
727
- dispatch({
728
- type: 'CLOSE'
729
- });
730
- break;
731
- case KEYS.UP:
732
- case KEYS.DOWN:
733
- case KEYS.SPACE:
734
- dispatch({
735
- type: 'OPEN'
736
- });
737
- break;
738
- }
739
- };
740
- const handleMouseDown = () => {
741
- isInputMouseDownRef.current = true;
742
- };
743
- const handleMouseUp = () => {
744
- setTimeout(() => {
745
- isInputMouseDownRef.current = false;
746
- }, 0);
747
- };
748
- return cloneElement(element, {
749
- [refKey]: ref,
750
- onMouseDown: composeEventHandlers(element.props.onMouseDown, handleMouseDown),
751
- onMouseUp: composeEventHandlers(element.props.onMouseUp, handleMouseUp),
752
- onClick: composeEventHandlers(element.props.onClick, handleClick),
753
- onBlur: composeEventHandlers(element.props.onBlur, handleBlur),
754
- onChange: composeEventHandlers(element.props.onChange, handleChange),
755
- onKeyDown: composeEventHandlers(element.props.onKeyDown, handleKeyDown),
756
- autoComplete: 'off',
757
- value: state.inputValue
758
- });
759
- });
760
- Input.displayName = 'Input';
761
-
762
- const PLACEMENT_DEFAULT = 'bottom-start';
763
- const DatePicker = forwardRef((props, calendarRef) => {
764
- const {
765
- children,
766
- placement: _placement,
767
- zIndex,
768
- isAnimated,
769
- refKey,
770
- value,
771
- isCompact,
772
- onChange,
773
- formatDate,
774
- minValue,
775
- maxValue,
776
- locale,
777
- weekStartsOn,
778
- customParseDate,
779
- ...menuProps
780
- } = props;
781
- const theme = useContext(ThemeContext) || DEFAULT_THEME;
782
- const memoizedReducer = useCallback(datepickerReducer({
783
- value,
784
- formatDate,
785
- locale,
786
- customParseDate,
787
- onChange
788
- }), [value, formatDate, locale, onChange, customParseDate]);
789
- const [state, dispatch] = useReducer(memoizedReducer, retrieveInitialState$1(props));
790
- const triggerRef = useRef(null);
791
- const floatingRef = useRef(null);
792
- const [isVisible, setIsVisible] = useState(state.isOpen);
793
- const contextValue = useMemo(() => ({
794
- state,
795
- dispatch
796
- }), [state, dispatch]);
797
- const [floatingPlacement] = getFloatingPlacements(theme, _placement === 'auto' ? PLACEMENT_DEFAULT : _placement);
798
- const {
799
- refs,
800
- placement,
801
- update,
802
- floatingStyles: {
803
- transform
804
- }
805
- } = useFloating({
806
- elements: {
807
- reference: triggerRef?.current,
808
- floating: floatingRef?.current
809
- },
810
- placement: floatingPlacement,
811
- middleware: [_placement === 'auto' ? autoPlacement() : flip()]
812
- });
813
- const Child = React__default.Children.only(children);
814
- useEffect(() => {
815
- let cleanup;
816
- if (state.isOpen && refs.reference.current && refs.floating.current) {
817
- cleanup = autoUpdate(refs.reference.current, refs.floating.current, update, {
818
- elementResize: typeof ResizeObserver === 'function'
819
- });
820
- }
821
- return () => cleanup && cleanup();
822
- }, [state.isOpen, refs.reference, refs.floating, update]);
823
- useEffect(() => {
824
- let timeout;
825
- if (state.isOpen) {
826
- setIsVisible(true);
827
- } else if (isAnimated) {
828
- timeout = setTimeout(() => setIsVisible(false), 200);
829
- } else {
830
- setIsVisible(false);
831
- }
832
- return () => clearTimeout(timeout);
833
- }, [state.isOpen, isAnimated]);
834
- useEffect(() => {
835
- dispatch({
836
- type: 'CONTROLLED_VALUE_CHANGE',
837
- value
838
- });
839
- }, [value]);
840
- useEffect(() => {
841
- dispatch({
842
- type: 'CONTROLLED_LOCALE_CHANGE'
843
- });
844
- }, [locale]);
845
- return React__default.createElement(React__default.Fragment, null, React__default.createElement(Input, {
846
- element: Child,
847
- dispatch: dispatch,
848
- state: state,
849
- refKey: refKey,
850
- ref: mergeRefs([triggerRef, Child.ref ? Child.ref : null])
851
- }), React__default.createElement(DatePickerContext.Provider, {
852
- value: contextValue
853
- }, React__default.createElement(StyledMenuWrapper, {
854
- ref: floatingRef,
855
- style: {
856
- transform
857
- },
858
- isHidden: !state.isOpen,
859
- isAnimated: isAnimated && (state.isOpen || isVisible),
860
- placement: placement,
861
- zIndex: zIndex
862
- }, (state.isOpen || isVisible) && React__default.createElement(StyledMenu, menuProps, React__default.createElement(Calendar$1, {
863
- ref: calendarRef,
864
- isCompact: isCompact,
865
- value: value,
866
- minValue: minValue,
867
- maxValue: maxValue,
868
- locale: locale,
869
- weekStartsOn: weekStartsOn
870
- })))));
871
- });
872
- DatePicker.displayName = 'DatePicker';
873
- DatePicker.propTypes = {
874
- value: PropTypes.any,
875
- onChange: PropTypes.any,
876
- formatDate: PropTypes.func,
877
- locale: PropTypes.any,
878
- weekStartsOn: PropTypes.oneOf(WEEK_STARTS_ON),
879
- minValue: PropTypes.any,
880
- maxValue: PropTypes.any,
881
- isCompact: PropTypes.bool,
882
- customParseDate: PropTypes.any,
883
- refKey: PropTypes.string,
884
- placement: PropTypes.oneOf(PLACEMENT),
885
- isAnimated: PropTypes.bool,
886
- zIndex: PropTypes.number
887
- };
888
- DatePicker.defaultProps = {
889
- placement: PLACEMENT_DEFAULT,
890
- refKey: 'ref',
891
- isAnimated: true,
892
- zIndex: 1000,
893
- locale: 'en-US'
894
- };
895
-
896
- function formatValue(_ref) {
897
- let {
898
- value,
899
- locale,
900
- formatDate
901
- } = _ref;
902
- let stringValue = '';
903
- if (value !== undefined && isValid(value)) {
904
- if (formatDate) {
905
- stringValue = formatDate(value);
906
- } else {
907
- stringValue = new Intl.DateTimeFormat(locale, {
908
- month: 'long',
909
- day: 'numeric',
910
- year: 'numeric'
911
- }).format(value);
912
- }
913
- }
914
- return stringValue;
915
- }
916
- function parseInputValue(_ref2) {
917
- let {
918
- inputValue
919
- } = _ref2;
920
- const MINIMUM_DATE = new Date(1001, 0, 0);
921
- let tryParseDate = parse(inputValue || '', 'P', new Date());
922
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
923
- return tryParseDate;
924
- }
925
- tryParseDate = parse(inputValue || '', 'PP', new Date());
926
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
927
- return tryParseDate;
928
- }
929
- tryParseDate = parse(inputValue || '', 'PPP', new Date());
930
- if (isValid(tryParseDate) && !isBefore(tryParseDate, MINIMUM_DATE)) {
931
- return tryParseDate;
932
- }
933
- return new Date(NaN);
934
- }
935
- const datepickerRangeReducer = _ref3 => {
936
- let {
937
- startValue,
938
- endValue,
939
- locale,
940
- formatDate,
941
- customParseDate
942
- } = _ref3;
943
- return (state, action) => {
944
- switch (action.type) {
945
- case 'START_FOCUS':
946
- {
947
- let previewDate = state.previewDate;
948
- if (startValue) {
949
- if (compareAsc(startValue, startOfMonth(state.previewDate)) === 1 && compareAsc(startValue, addMonths(endOfMonth(state.previewDate), 1)) === -1) {
950
- previewDate = state.previewDate;
951
- } else {
952
- previewDate = startOfMonth(startValue);
953
- }
954
- }
955
- return {
956
- ...state,
957
- previewDate,
958
- isStartFocused: true,
959
- isEndFocused: false
960
- };
961
- }
962
- case 'END_FOCUS':
963
- {
964
- let previewDate = state.previewDate;
965
- if (endValue) {
966
- if (compareAsc(endValue, startOfMonth(state.previewDate)) === 1 && compareAsc(endValue, addMonths(endOfMonth(state.previewDate), 1)) === -1) {
967
- previewDate = state.previewDate;
968
- } else {
969
- previewDate = startOfMonth(endValue);
970
- }
971
- }
972
- return {
973
- ...state,
974
- previewDate,
975
- isEndFocused: true,
976
- isStartFocused: false
977
- };
978
- }
979
- case 'START_BLUR':
980
- {
981
- let parsedDate;
982
- if (customParseDate) {
983
- parsedDate = customParseDate(state.startInputValue);
984
- } else {
985
- parsedDate = parseInputValue({
986
- inputValue: state.startInputValue
987
- });
988
- }
989
- const startInputValue = formatValue({
990
- value: parsedDate,
991
- locale,
992
- formatDate
993
- });
994
- return {
995
- ...state,
996
- startInputValue: startInputValue || formatValue({
997
- value: startValue,
998
- locale,
999
- formatDate
1000
- }),
1001
- isStartFocused: false
1002
- };
1003
- }
1004
- case 'END_BLUR':
1005
- {
1006
- let parsedDate;
1007
- if (customParseDate) {
1008
- parsedDate = customParseDate(state.endInputValue);
1009
- } else {
1010
- parsedDate = parseInputValue({
1011
- inputValue: state.endInputValue
1012
- });
1013
- }
1014
- const endInputValue = formatValue({
1015
- value: parsedDate,
1016
- locale,
1017
- formatDate
1018
- }) || formatValue({
1019
- value: endValue,
1020
- locale,
1021
- formatDate
1022
- });
1023
- return {
1024
- ...state,
1025
- endInputValue,
1026
- isEndFocused: false
1027
- };
1028
- }
1029
- case 'CONTROLLED_START_VALUE_CHANGE':
1030
- {
1031
- const startInputValue = formatValue({
1032
- value: action.value,
1033
- locale,
1034
- formatDate
1035
- });
1036
- let previewDate = state.previewDate;
1037
- if (action.value) {
1038
- if (compareAsc(action.value, startOfMonth(state.previewDate)) === 1 && compareAsc(action.value, addMonths(endOfMonth(state.previewDate), 1)) === -1) {
1039
- previewDate = state.previewDate;
1040
- } else {
1041
- previewDate = startOfMonth(action.value);
1042
- }
1043
- }
1044
- return {
1045
- ...state,
1046
- startInputValue,
1047
- hoverDate: undefined,
1048
- previewDate
1049
- };
1050
- }
1051
- case 'CONTROLLED_END_VALUE_CHANGE':
1052
- {
1053
- const endInputValue = formatValue({
1054
- value: action.value,
1055
- locale,
1056
- formatDate
1057
- });
1058
- let previewDate = state.previewDate;
1059
- if (action.value) {
1060
- if (compareAsc(action.value, startOfMonth(state.previewDate)) === 1 && compareAsc(action.value, addMonths(endOfMonth(state.previewDate), 1)) === -1) {
1061
- previewDate = state.previewDate;
1062
- } else {
1063
- previewDate = startOfMonth(action.value);
1064
- }
1065
- }
1066
- return {
1067
- ...state,
1068
- endInputValue,
1069
- hoverDate: undefined,
1070
- previewDate
1071
- };
1072
- }
1073
- case 'CLICK_DATE':
1074
- if (state.isStartFocused) {
1075
- if (endValue !== undefined && (isBefore(action.value, endValue) || isSameDay(action.value, endValue))) {
1076
- return {
1077
- ...state,
1078
- startInputValue: formatValue({
1079
- value: action.value
1080
- })
1081
- };
1082
- }
1083
- return {
1084
- ...state,
1085
- startInputValue: formatValue({
1086
- value: action.value
1087
- }),
1088
- endInputValue: undefined
1089
- };
1090
- } else if (state.isEndFocused) {
1091
- if (startValue !== undefined && (isAfter(action.value, startValue) || isSameDay(action.value, startValue))) {
1092
- return {
1093
- ...state,
1094
- endInputValue: formatValue({
1095
- value: action.value
1096
- })
1097
- };
1098
- }
1099
- return {
1100
- ...state,
1101
- startInputValue: formatValue({
1102
- value: action.value
1103
- })
1104
- };
1105
- } else if (startValue === undefined) {
1106
- return {
1107
- ...state,
1108
- startInputValue: formatValue({
1109
- value: action.value
1110
- }),
1111
- endInputValue: undefined
1112
- };
1113
- } else if (endValue === undefined) {
1114
- if (isBefore(action.value, startValue)) {
1115
- return {
1116
- ...state,
1117
- startInputValue: formatValue({
1118
- value: action.value
1119
- }),
1120
- endInputValue: undefined
1121
- };
1122
- }
1123
- return {
1124
- ...state,
1125
- endInputValue: formatValue({
1126
- value: action.value
1127
- })
1128
- };
1129
- }
1130
- return state;
1131
- case 'START_INPUT_ONCHANGE':
1132
- {
1133
- return {
1134
- ...state,
1135
- startInputValue: action.value
1136
- };
1137
- }
1138
- case 'END_INPUT_ONCHANGE':
1139
- {
1140
- return {
1141
- ...state,
1142
- endInputValue: action.value
1143
- };
1144
- }
1145
- case 'HOVER_DATE':
1146
- return {
1147
- ...state,
1148
- hoverDate: action.value
1149
- };
1150
- case 'PREVIEW_NEXT_MONTH':
1151
- {
1152
- const previewDate = addMonths(state.previewDate, 1);
1153
- return {
1154
- ...state,
1155
- previewDate,
1156
- hoverDate: undefined
1157
- };
1158
- }
1159
- case 'PREVIEW_PREVIOUS_MONTH':
1160
- {
1161
- const previewDate = subMonths(state.previewDate, 1);
1162
- return {
1163
- ...state,
1164
- previewDate,
1165
- hoverDate: undefined
1166
- };
1167
- }
1168
- default:
1169
- throw new Error();
1170
- }
1171
- };
1172
- };
1173
- function retrieveInitialState(initialProps) {
1174
- let previewDate = initialProps.startValue;
1175
- if (previewDate === undefined || !isValid(previewDate)) {
1176
- previewDate = new Date();
1177
- }
1178
- const startInputValue = formatValue({
1179
- value: initialProps.startValue,
1180
- locale: initialProps.locale,
1181
- formatDate: initialProps.formatDate
1182
- });
1183
- const endInputValue = formatValue({
1184
- value: initialProps.endValue,
1185
- locale: initialProps.locale,
1186
- formatDate: initialProps.formatDate
1187
- });
1188
- return {
1189
- previewDate,
1190
- startInputValue,
1191
- endInputValue,
1192
- isStartFocused: false,
1193
- isEndFocused: false
1194
- };
1195
- }
1196
-
1197
- const DatePickerRangeContext = createContext(undefined);
1198
- const useDatePickerContext = () => {
1199
- return useContext(DatePickerRangeContext);
1200
- };
1201
-
1202
- const Start = props => {
1203
- const {
1204
- state,
1205
- dispatch,
1206
- onChange,
1207
- startValue,
1208
- endValue,
1209
- startInputRef,
1210
- customParseDate
1211
- } = useDatePickerContext();
1212
- const onChangeCallback = useCallback(e => {
1213
- dispatch({
1214
- type: 'START_INPUT_ONCHANGE',
1215
- value: e.target.value
1216
- });
1217
- props.children.props.onChange && props.children.props.onChange(e);
1218
- }, [dispatch, props.children]);
1219
- const onFocusCallback = useCallback(e => {
1220
- dispatch({
1221
- type: 'START_FOCUS'
1222
- });
1223
- props.children.props.onFocus && props.children.props.onFocus(e);
1224
- }, [dispatch, props.children]);
1225
- const handleBlur = useCallback(() => {
1226
- let parsedDate;
1227
- if (customParseDate) {
1228
- parsedDate = customParseDate(state.startInputValue);
1229
- } else {
1230
- parsedDate = parseInputValue({
1231
- inputValue: state.startInputValue
1232
- });
1233
- }
1234
- dispatch({
1235
- type: 'START_BLUR'
1236
- });
1237
- if (parsedDate && isValid(parsedDate) && !isSameDay(parsedDate, startValue)) {
1238
- onChange && onChange({
1239
- startValue: parsedDate,
1240
- endValue
1241
- });
1242
- }
1243
- }, [dispatch, onChange, startValue, endValue, customParseDate, state.startInputValue]);
1244
- const onKeyDownCallback = useCallback(e => {
1245
- if (e.key === KEYS.ENTER) {
1246
- e.preventDefault();
1247
- handleBlur();
1248
- }
1249
- props.children.props.onKeyDown && props.children.props.onKeyDown(e);
1250
- }, [handleBlur, props.children]);
1251
- const onBlurCallback = useCallback(e => {
1252
- handleBlur();
1253
- props.children.props.onBlur && props.children.props.onBlur(e);
1254
- }, [handleBlur, props.children]);
1255
- const childElement = React__default.Children.only(props.children);
1256
- return React__default.cloneElement(childElement, {
1257
- value: state.startInputValue || '',
1258
- ref: startInputRef,
1259
- onChange: composeEventHandlers(childElement.props.onChange, onChangeCallback),
1260
- onFocus: composeEventHandlers(childElement.props.onFocus, onFocusCallback),
1261
- onKeyDown: composeEventHandlers(childElement.props.onKeyDown, onKeyDownCallback),
1262
- onBlur: composeEventHandlers(childElement.props.onBlur, onBlurCallback)
1263
- });
1264
- };
1265
- Start.displayName = 'DatePickerRange.Start';
1266
-
1267
- const End = props => {
1268
- const {
1269
- state,
1270
- dispatch,
1271
- onChange,
1272
- startValue,
1273
- endValue,
1274
- endInputRef,
1275
- customParseDate
1276
- } = useDatePickerContext();
1277
- const onChangeCallback = useCallback(e => {
1278
- dispatch({
1279
- type: 'END_INPUT_ONCHANGE',
1280
- value: e.target.value
1281
- });
1282
- props.children.props.onChange && props.children.props.onChange(e);
1283
- }, [dispatch, props.children]);
1284
- const onFocusCallback = useCallback(e => {
1285
- dispatch({
1286
- type: 'END_FOCUS'
1287
- });
1288
- props.children.props.onFocus && props.children.props.onFocus(e);
1289
- }, [dispatch, props.children]);
1290
- const handleBlur = useCallback(() => {
1291
- dispatch({
1292
- type: 'END_BLUR'
1293
- });
1294
- let parsedDate;
1295
- if (customParseDate) {
1296
- parsedDate = customParseDate(state.endInputValue);
1297
- } else {
1298
- parsedDate = parseInputValue({
1299
- inputValue: state.endInputValue
1300
- });
1301
- }
1302
- if (onChange && parsedDate && isValid(parsedDate) && !isSameDay(parsedDate, endValue)) {
1303
- onChange && onChange({
1304
- startValue,
1305
- endValue: parsedDate
1306
- });
1307
- }
1308
- }, [dispatch, onChange, startValue, endValue, customParseDate, state.endInputValue]);
1309
- const onKeydownCallback = useCallback(e => {
1310
- if (e.key === KEYS.ENTER) {
1311
- handleBlur();
1312
- e.preventDefault();
1313
- }
1314
- props.children.props.onKeyDown && props.children.props.onKeyDown(e);
1315
- }, [handleBlur, props.children]);
1316
- const onBlurCallback = useCallback(e => {
1317
- handleBlur();
1318
- props.children.props.onBlur && props.children.props.onBlur(e);
1319
- }, [handleBlur, props.children]);
1320
- const childElement = React__default.Children.only(props.children);
1321
- return React__default.cloneElement(childElement, {
1322
- value: state.endInputValue || '',
1323
- ref: endInputRef,
1324
- onChange: composeEventHandlers(childElement.props.onChange, onChangeCallback),
1325
- onFocus: composeEventHandlers(childElement.props.onFocus, onFocusCallback),
1326
- onKeyDown: composeEventHandlers(childElement.props.onKeyDown, onKeydownCallback),
1327
- onBlur: composeEventHandlers(childElement.props.onBlur, onBlurCallback)
1328
- });
1329
- };
1330
- End.displayName = 'DatePickerRange.End';
1331
-
1332
- function _extends() {
1333
- _extends = Object.assign ? Object.assign.bind() : function (target) {
1334
- for (var i = 1; i < arguments.length; i++) {
1335
- var source = arguments[i];
1336
- for (var key in source) {
1337
- if (Object.prototype.hasOwnProperty.call(source, key)) {
1338
- target[key] = source[key];
1339
- }
1340
- }
1341
- }
1342
- return target;
1343
- };
1344
- return _extends.apply(this, arguments);
1345
- }
1346
-
1347
- const Month = forwardRef((_ref, ref) => {
1348
- let {
1349
- displayDate,
1350
- isPreviousHidden,
1351
- isNextHidden
1352
- } = _ref;
1353
- const {
1354
- state,
1355
- dispatch,
1356
- locale,
1357
- weekStartsOn,
1358
- isCompact,
1359
- minValue,
1360
- maxValue,
1361
- startValue,
1362
- endValue,
1363
- onChange
1364
- } = useDatePickerContext();
1365
- const headerLabelFormatter = useCallback(date => {
1366
- const formatter = new Intl.DateTimeFormat(locale, {
1367
- month: 'long',
1368
- year: 'numeric'
1369
- });
1370
- return formatter.format(date);
1371
- }, [locale]);
1372
- const dayLabelFormatter = useCallback(date => {
1373
- const formatter = new Intl.DateTimeFormat(locale, {
1374
- weekday: 'short'
1375
- });
1376
- return formatter.format(date);
1377
- }, [locale]);
1378
- const dayFormatter = useCallback(date => {
1379
- const formatter = new Intl.DateTimeFormat(locale, {
1380
- day: 'numeric'
1381
- });
1382
- return formatter.format(date);
1383
- }, [locale]);
1384
- const preferredWeekStartsOn = weekStartsOn || getStartOfWeek(locale);
1385
- const monthStartDate = startOfMonth(displayDate);
1386
- const monthEndDate = endOfMonth(monthStartDate);
1387
- const startDate = startOfWeek(monthStartDate, {
1388
- weekStartsOn: preferredWeekStartsOn
1389
- });
1390
- const endDate = endOfWeek(monthEndDate, {
1391
- weekStartsOn: preferredWeekStartsOn
1392
- });
1393
- const dayLabels = eachDayOfInterval({
1394
- start: startDate,
1395
- end: addDays(startDate, 6)
1396
- }).map(date => {
1397
- const formattedDayLabel = dayLabelFormatter(date);
1398
- return React__default.createElement(StyledCalendarItem, {
1399
- key: `day-label-${formattedDayLabel}`,
1400
- isCompact: isCompact
1401
- }, React__default.createElement(StyledDayLabel, {
1402
- isCompact: isCompact
1403
- }, formattedDayLabel));
1404
- });
1405
- const items = eachDayOfInterval({
1406
- start: startDate,
1407
- end: endDate
1408
- }).map((date, itemsIndex) => {
1409
- const formattedDayLabel = dayFormatter(date);
1410
- const isCurrentDate = isToday(date);
1411
- const isPreviousMonth = !isSameMonth(date, displayDate);
1412
- if (isPreviousMonth) {
1413
- return React__default.createElement(StyledCalendarItem, {
1414
- key: `day-${itemsIndex}`,
1415
- isCompact: isCompact
1416
- }, React__default.createElement(StyledDay, {
1417
- isCompact: isCompact,
1418
- isPreviousMonth: true,
1419
- isDisabled: true
1420
- }, "\xA0"));
1421
- }
1422
- let isSelected = false;
1423
- if (startValue !== undefined) {
1424
- isSelected = isSameDay(date, startValue);
1425
- }
1426
- if (endValue !== undefined) {
1427
- isSelected = isSelected || isSameDay(date, endValue);
1428
- }
1429
- let isDisabled = false;
1430
- if (minValue !== undefined) {
1431
- isDisabled = isBefore(date, minValue) && !isSameDay(date, minValue);
1432
- }
1433
- if (maxValue !== undefined) {
1434
- isDisabled = isDisabled || isAfter(date, maxValue) && !isSameDay(date, maxValue);
1435
- }
1436
- let isHighlighted = false;
1437
- if (startValue !== undefined && endValue !== undefined) {
1438
- isHighlighted = (isAfter(date, startValue) || isSameDay(date, startValue)) && (isBefore(date, endValue) || isSameDay(date, endValue)) && !isSameDay(startValue, endValue);
1439
- } else if (startValue !== undefined && state.hoverDate !== undefined) {
1440
- isHighlighted = (isAfter(date, startValue) || isSameDay(date, startValue)) && (isBefore(date, state.hoverDate) || isSameDay(date, state.hoverDate));
1441
- }
1442
- const isHighlightStart = isHighlighted && startValue && isSameDay(date, startValue) || false;
1443
- const isHighlightEnd = isHighlighted && endValue && isSameDay(date, endValue) || state.hoverDate && isSameDay(date, state.hoverDate) && !isBefore(date, endValue) || false;
1444
- let isInvalidDateRange = endValue && startValue && compareAsc(endValue, startValue) === -1 || false;
1445
- if (minValue) {
1446
- if (startValue) {
1447
- isInvalidDateRange = isInvalidDateRange || compareAsc(startValue, subDays(minValue, 1)) === -1;
1448
- }
1449
- if (endValue) {
1450
- isInvalidDateRange = isInvalidDateRange || compareAsc(endValue, subDays(minValue, 1)) === -1;
1451
- }
1452
- }
1453
- if (maxValue) {
1454
- if (startValue) {
1455
- isInvalidDateRange = isInvalidDateRange || compareAsc(startValue, maxValue) === 1;
1456
- }
1457
- if (endValue) {
1458
- isInvalidDateRange = isInvalidDateRange || compareAsc(endValue, maxValue) === 1;
1459
- }
1460
- }
1461
- return React__default.createElement(StyledCalendarItem, {
1462
- key: `day-${itemsIndex}`,
1463
- isCompact: isCompact
1464
- }, React__default.createElement(StyledHighlight, {
1465
- isHighlighted: !isInvalidDateRange && isHighlighted && !isDisabled,
1466
- isStart: !isInvalidDateRange && isHighlightStart,
1467
- isEnd: !isInvalidDateRange && isHighlightEnd
1468
- }), React__default.createElement(StyledDay, {
1469
- isToday: isCurrentDate,
1470
- isPreviousMonth: isPreviousMonth,
1471
- isSelected: !isInvalidDateRange && isSelected,
1472
- isDisabled: isDisabled,
1473
- isCompact: isCompact,
1474
- onClick: () => {
1475
- if (!isDisabled) {
1476
- dispatch({
1477
- type: 'CLICK_DATE',
1478
- value: date
1479
- });
1480
- if (onChange) {
1481
- if (state.isStartFocused) {
1482
- if (endValue !== undefined && (isBefore(date, endValue) || isSameDay(date, endValue))) {
1483
- onChange({
1484
- startValue: date,
1485
- endValue
1486
- });
1487
- } else {
1488
- onChange({
1489
- startValue: date,
1490
- endValue: undefined
1491
- });
1492
- }
1493
- } else if (state.isEndFocused) {
1494
- if (startValue !== undefined && (isAfter(date, startValue) || isSameDay(date, startValue))) {
1495
- onChange({
1496
- startValue,
1497
- endValue: date
1498
- });
1499
- } else {
1500
- onChange({
1501
- startValue: date,
1502
- endValue: undefined
1503
- });
1504
- }
1505
- } else if (startValue === undefined) {
1506
- onChange({
1507
- startValue: date,
1508
- endValue: undefined
1509
- });
1510
- } else if (endValue === undefined) {
1511
- if (isBefore(date, startValue)) {
1512
- onChange({
1513
- startValue: date,
1514
- endValue: undefined
1515
- });
1516
- } else {
1517
- onChange({
1518
- startValue,
1519
- endValue: date
1520
- });
1521
- }
1522
- } else {
1523
- onChange({
1524
- startValue: date,
1525
- endValue: undefined
1526
- });
1527
- }
1528
- }
1529
- }
1530
- },
1531
- onMouseEnter: () => {
1532
- if (!isSelected) {
1533
- dispatch({
1534
- type: 'HOVER_DATE',
1535
- value: date
1536
- });
1537
- }
1538
- }
1539
- }, formattedDayLabel));
1540
- });
1541
- return React__default.createElement(StyledDatePicker, {
1542
- ref: ref,
1543
- isCompact: isCompact,
1544
- onMouseDown: e => {
1545
- e.preventDefault();
1546
- }
1547
- }, React__default.createElement(StyledHeader, {
1548
- isCompact: isCompact
1549
- }, React__default.createElement(StyledHeaderPaddle, {
1550
- isCompact: isCompact,
1551
- onClick: () => {
1552
- dispatch({
1553
- type: 'PREVIEW_PREVIOUS_MONTH'
1554
- });
1555
- },
1556
- isHidden: isPreviousHidden
1557
- }, React__default.createElement(SvgChevronLeftStroke, null)), React__default.createElement(StyledHeaderLabel, {
1558
- isCompact: isCompact
1559
- }, headerLabelFormatter(displayDate)), React__default.createElement(StyledHeaderPaddle, {
1560
- isCompact: isCompact,
1561
- isHidden: isNextHidden,
1562
- onClick: () => {
1563
- dispatch({
1564
- type: 'PREVIEW_NEXT_MONTH'
1565
- });
1566
- }
1567
- }, React__default.createElement(SvgChevronRightStroke, null))), React__default.createElement(StyledCalendar, {
1568
- isCompact: isCompact,
1569
- onMouseLeave: () => {
1570
- dispatch({
1571
- type: 'HOVER_DATE',
1572
- value: undefined
1573
- });
1574
- }
1575
- }, dayLabels, items));
1576
- });
1577
- Month.displayName = 'Month';
1578
-
1579
- const Calendar = forwardRef((props, ref) => {
1580
- const {
1581
- state
1582
- } = useDatePickerContext();
1583
- return React__default.createElement(StyledRangeCalendar, _extends({
1584
- ref: ref,
1585
- "data-garden-id": "datepickers.range",
1586
- "data-garden-version": '9.0.0-next.2'
1587
- }, props), React__default.createElement(Month, {
1588
- displayDate: state.previewDate,
1589
- isNextHidden: true
1590
- }), React__default.createElement(Month, {
1591
- displayDate: addMonths(state.previewDate, 1),
1592
- isPreviousHidden: true
1593
- }));
1594
- });
1595
- Calendar.displayName = 'DatePickerRange.Calendar';
1596
-
1597
- const DatePickerRangeComponent = props => {
1598
- const {
1599
- startValue,
1600
- locale,
1601
- weekStartsOn,
1602
- formatDate,
1603
- endValue,
1604
- onChange,
1605
- customParseDate,
1606
- isCompact,
1607
- minValue,
1608
- maxValue,
1609
- children
1610
- } = props;
1611
- const reducer = useCallback(datepickerRangeReducer({
1612
- startValue,
1613
- locale,
1614
- formatDate,
1615
- endValue,
1616
- customParseDate
1617
- }), [startValue, endValue, locale, formatDate, onChange, customParseDate]);
1618
- const [state, dispatch] = useReducer(reducer, retrieveInitialState(props));
1619
- const previousStartValue = useRef(startValue);
1620
- const previousEndValue = useRef(endValue);
1621
- const startInputRef = useRef();
1622
- const endInputRef = useRef();
1623
- useEffect(() => {
1624
- dispatch({
1625
- type: 'CONTROLLED_START_VALUE_CHANGE',
1626
- value: startValue
1627
- });
1628
- if (endInputRef.current && previousStartValue.current !== startValue && startValue !== undefined) {
1629
- endInputRef.current.focus();
1630
- }
1631
- previousStartValue.current = startValue;
1632
- }, [props, startValue]);
1633
- useEffect(() => {
1634
- dispatch({
1635
- type: 'CONTROLLED_END_VALUE_CHANGE',
1636
- value: endValue
1637
- });
1638
- if (startInputRef.current && previousEndValue.current !== endValue && endValue !== undefined) {
1639
- startInputRef.current.focus();
1640
- }
1641
- previousEndValue.current = endValue;
1642
- }, [props, endValue]);
1643
- const value = useMemo(() => ({
1644
- state,
1645
- dispatch,
1646
- isCompact,
1647
- locale,
1648
- weekStartsOn,
1649
- minValue,
1650
- maxValue,
1651
- startValue,
1652
- endValue,
1653
- onChange,
1654
- startInputRef,
1655
- endInputRef,
1656
- customParseDate
1657
- }), [state, dispatch, isCompact, locale, weekStartsOn, minValue, maxValue, startValue, endValue, onChange, startInputRef, endInputRef, customParseDate]);
1658
- return React__default.createElement(DatePickerRangeContext.Provider, {
1659
- value: value
1660
- }, children);
1661
- };
1662
- DatePickerRangeComponent.propTypes = {
1663
- locale: PropTypes.string,
1664
- weekStartsOn: PropTypes.number,
1665
- startValue: PropTypes.instanceOf(Date),
1666
- endValue: PropTypes.instanceOf(Date),
1667
- minValue: PropTypes.instanceOf(Date),
1668
- maxValue: PropTypes.instanceOf(Date),
1669
- onChange: PropTypes.func,
1670
- formatDate: PropTypes.func,
1671
- customParseDate: PropTypes.func,
1672
- isCompact: PropTypes.bool
1673
- };
1674
- DatePickerRangeComponent.defaultProps = {
1675
- locale: 'en-US',
1676
- isCompact: false
1677
- };
1678
- const DatePickerRange = DatePickerRangeComponent;
1679
- DatePickerRange.Calendar = Calendar;
1680
- DatePickerRange.End = End;
1681
- DatePickerRange.Start = Start;
1682
-
1683
- export { DatePicker, DatePickerRange };