@alfalab/core-components-calendar-range 9.0.14 → 9.1.0

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 (68) hide show
  1. package/Component.d.ts +4 -0
  2. package/Component.js.map +1 -1
  3. package/components/divider/index.css +8 -8
  4. package/components/divider/index.module.css.js +1 -1
  5. package/components/divider/index.module.css.js.map +1 -1
  6. package/cssm/Component.d.ts +4 -0
  7. package/cssm/Component.js.map +1 -1
  8. package/cssm/components/divider/index.module.css +1 -1
  9. package/cssm/hooks.d.ts +31 -0
  10. package/cssm/hooks.js +84 -0
  11. package/cssm/hooks.js.map +1 -1
  12. package/cssm/views/index.module.css +12 -0
  13. package/cssm/views/static.d.ts +13 -2
  14. package/cssm/views/static.js +93 -50
  15. package/cssm/views/static.js.map +1 -1
  16. package/esm/Component.d.ts +4 -0
  17. package/esm/Component.js.map +1 -1
  18. package/esm/components/divider/index.css +8 -8
  19. package/esm/components/divider/index.module.css.js +1 -1
  20. package/esm/components/divider/index.module.css.js.map +1 -1
  21. package/esm/hooks.d.ts +31 -0
  22. package/esm/hooks.js +84 -2
  23. package/esm/hooks.js.map +1 -1
  24. package/esm/views/index.css +19 -7
  25. package/esm/views/index.module.css.js +1 -1
  26. package/esm/views/index.module.css.js.map +1 -1
  27. package/esm/views/static.d.ts +13 -2
  28. package/esm/views/static.js +93 -50
  29. package/esm/views/static.js.map +1 -1
  30. package/hooks.d.ts +31 -0
  31. package/hooks.js +84 -0
  32. package/hooks.js.map +1 -1
  33. package/modern/Component.d.ts +4 -0
  34. package/modern/Component.js.map +1 -1
  35. package/modern/components/divider/index.css +8 -8
  36. package/modern/components/divider/index.module.css.js +1 -1
  37. package/modern/components/divider/index.module.css.js.map +1 -1
  38. package/modern/hooks.d.ts +31 -0
  39. package/modern/hooks.js +79 -2
  40. package/modern/hooks.js.map +1 -1
  41. package/modern/views/index.css +19 -7
  42. package/modern/views/index.module.css.js +1 -1
  43. package/modern/views/index.module.css.js.map +1 -1
  44. package/modern/views/static.d.ts +13 -2
  45. package/modern/views/static.js +88 -45
  46. package/modern/views/static.js.map +1 -1
  47. package/moderncssm/Component.d.ts +4 -0
  48. package/moderncssm/Component.js.map +1 -1
  49. package/moderncssm/components/divider/index.module.css +1 -1
  50. package/moderncssm/hooks.d.ts +31 -0
  51. package/moderncssm/hooks.js +79 -2
  52. package/moderncssm/hooks.js.map +1 -1
  53. package/moderncssm/views/index.module.css +13 -0
  54. package/moderncssm/views/static.d.ts +13 -2
  55. package/moderncssm/views/static.js +88 -45
  56. package/moderncssm/views/static.js.map +1 -1
  57. package/package.json +2 -1
  58. package/src/Component.tsx +5 -0
  59. package/src/components/divider/index.module.css +1 -1
  60. package/src/hooks.ts +150 -1
  61. package/src/views/index.module.css +11 -0
  62. package/src/views/static.tsx +188 -92
  63. package/views/index.css +19 -7
  64. package/views/index.module.css.js +1 -1
  65. package/views/index.module.css.js.map +1 -1
  66. package/views/static.d.ts +13 -2
  67. package/views/static.js +90 -47
  68. package/views/static.js.map +1 -1
@@ -1,9 +1,20 @@
1
1
  import { type FC } from 'react';
2
+ import { type CalendarInputProps } from '@alfalab/core-components-calendar-input/moderncssm';
2
3
  import { type CalendarRangeProps } from '../Component';
3
- export type CalendarRangeStaticProps = Omit<CalendarRangeProps, 'calendarPosition'> & {
4
+ type DateInputProps = Omit<CalendarInputProps, 'onCalendarOpen' | 'onCalendarClose' | 'onChange'>;
5
+ interface CalendarRangeStaticProps extends Omit<CalendarRangeProps, 'calendarPosition' | 'inputFromProps' | 'inputToProps'> {
4
6
  /**
5
7
  * Отображать начальный месяц слева или справа (влияет только на начальный рендер)
6
8
  */
7
9
  defaultMonthPosition?: 'left' | 'right';
8
- };
10
+ /**
11
+ * Пропсы для инпута начальной даты диапазона
12
+ */
13
+ inputFromProps?: DateInputProps;
14
+ /**
15
+ * Пропсы для инпута конечной даты диапазона
16
+ */
17
+ inputToProps?: DateInputProps;
18
+ }
9
19
  export declare const CalendarRangeStatic: FC<CalendarRangeStaticProps>;
20
+ export {};
@@ -1,20 +1,37 @@
1
- import React, { useState, useCallback, useEffect } from 'react';
1
+ import React, { useState, useRef, useCallback, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import { startOfMonth, isSameMonth, max, endOfMonth, subMonths, addMonths } from 'date-fns';
4
4
  import { CalendarDesktop } from '@alfalab/core-components-calendar/moderncssm/desktop';
5
5
  import { usePeriodWithReset } from '@alfalab/core-components-calendar/moderncssm/shared';
6
6
  import { isValidInputValue, parseDateString, formatDate } from '@alfalab/core-components-calendar-input/moderncssm/shared';
7
- import { isCompleteDateInput, DateInput } from '@alfalab/core-components-date-input/moderncssm';
7
+ import { isCompleteDateInput } from '@alfalab/core-components-date-input/moderncssm';
8
8
  import { getDataTestId } from '@alfalab/core-components-shared/moderncssm';
9
+ import { UniversalDateInput } from '@alfalab/core-components-universal-date-input/moderncssm';
9
10
  import { Divider } from '../components/divider/Component.js';
10
- import { useStaticViewMonthes, useSelectionProps } from '../hooks.js';
11
+ import { useStaticRangeAutoSwap, useStaticViewMonthes, useSelectionProps } from '../hooks.js';
11
12
  import { isDayButton } from '../utils.js';
12
13
  import styles from './index.module.css';
13
14
 
14
15
  /* eslint-disable complexity */
15
- const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()).getTime(), defaultMonthPosition = 'left', minDate, maxDate, valueFrom = '', valueTo = '', onDateFromChange = () => null, onDateToChange = () => null, onChange = () => null, onError, inputFromProps = {}, inputToProps = {}, offDays, events, returnInvalidDates = false, dataTestId, calendarContainerClassName, }) => {
16
+ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()).getTime(), defaultMonthPosition = 'left', minDate, maxDate, valueFrom = '', valueTo = '', onDateFromChange = () => null, onDateToChange = () => null, onChange = () => null, inputFromProps = {}, inputToProps = {}, offDays, events, returnInvalidDates = false, dataTestId, calendarContainerClassName, autoSwap = false, onError, }) => {
16
17
  const [inputFromValue, setInputFromValue] = useState(valueFrom);
17
18
  const [inputToValue, setInputToValue] = useState(valueTo);
19
+ const [inputFromError, setInputFromError] = useState(false);
20
+ const [inputToError, setInputToError] = useState(false);
21
+ const toggleCorrectionFromRef = useRef(null);
22
+ const toggleCorrectionToRef = useRef(null);
23
+ const inputToRef = useRef(null);
24
+ const inputFromRef = useRef(null);
25
+ const { swapDates, isInternalUpdate } = useStaticRangeAutoSwap({
26
+ autoSwap,
27
+ setInputFromValue,
28
+ setInputToValue,
29
+ toggleCorrectionFromRef,
30
+ toggleCorrectionToRef,
31
+ inputFromRef,
32
+ inputToRef,
33
+ });
34
+ const [rangeValidationError, setRangeValidationError] = useState(false);
18
35
  let dateFrom = isValidInputValue(inputFromValue, minDate, maxDate, offDays)
19
36
  ? parseDateString(inputFromValue).getTime()
20
37
  : null;
@@ -24,19 +41,11 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
24
41
  if (isCompleteDateInput(inputToValue) && !dateTo && !returnInvalidDates) {
25
42
  dateFrom = null;
26
43
  }
27
- const bothInvalid = isCompleteDateInput(inputFromValue) &&
28
- isCompleteDateInput(inputToValue) &&
29
- parseDateString(inputFromValue).getTime() > parseDateString(inputToValue).getTime();
30
44
  const [highlightedDate, setHighlightedDate] = useState(undefined);
31
45
  const period = usePeriodWithReset({
32
46
  initialSelectedFrom: dateFrom ? parseDateString(inputFromValue).getTime() : undefined,
33
47
  initialSelectedTo: dateTo ? parseDateString(inputToValue).getTime() : undefined,
34
48
  });
35
- const validateInputFromValue = useCallback((value) => isValidInputValue(value, minDate, dateFrom || maxDate, offDays), [dateFrom, maxDate, minDate, offDays]);
36
- const validateInputToValue = useCallback((value) => isValidInputValue(value, dateFrom || minDate, maxDate, offDays), [dateFrom, minDate, maxDate, offDays]);
37
- const [inputFromInvalid, setInputFromInvalid] = useState(isCompleteDateInput(inputFromValue) && dateFrom === null);
38
- const [inputToInvalid, setInputToInvalid] = useState(isCompleteDateInput(inputToValue) && dateTo === null);
39
- const hasValidateError = bothInvalid || inputFromInvalid || inputToInvalid;
40
49
  const { calendarProps: calendarFromProps, onInputChange: onInputChangeFrom, ...dateInputFromProps } = inputFromProps;
41
50
  const { calendarProps: calendarToProps, onInputChange: onInputChangeTo, ...dateInputToProps } = inputToProps;
42
51
  const { monthFrom, monthTo, handleMonthFromChange, handleMonthToChange } = useStaticViewMonthes({
@@ -45,19 +54,27 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
45
54
  defaultMonth,
46
55
  defaultMonthPosition,
47
56
  });
48
- const handleValidInputFrom = useCallback(() => {
49
- setInputFromInvalid(inputFromValue !== '' && !validateInputFromValue(inputFromValue));
50
- }, [inputFromValue, validateInputFromValue]);
51
- const handleValidInputTo = useCallback(() => {
52
- setInputToInvalid(inputToValue !== '' && !validateInputToValue(inputToValue));
53
- }, [inputToValue, validateInputToValue]);
54
57
  const handleInputFromChange = (event, payload) => {
55
- setInputFromValue(payload.value);
56
- onInputChangeFrom?.(event, payload);
58
+ const newValue = payload.value;
59
+ setInputFromValue(newValue);
60
+ if (isValidInputValue(newValue, minDate, maxDate, offDays)) {
61
+ swapDates(newValue, inputFromValue, inputToValue);
62
+ }
63
+ const payloadWithDate = { date: parseDateString(payload.value), value: payload.value };
64
+ if (onInputChangeFrom) {
65
+ onInputChangeFrom(event === null ? {} : event, payloadWithDate);
66
+ }
57
67
  };
58
68
  const handleInputToChange = (event, payload) => {
59
- setInputToValue(payload.value);
60
- onInputChangeTo?.(event, payload);
69
+ const newValue = payload.value;
70
+ setInputToValue(newValue);
71
+ if (isValidInputValue(newValue, minDate, maxDate, offDays)) {
72
+ swapDates(newValue, inputFromValue, inputToValue);
73
+ }
74
+ const payloadWithDate = { date: parseDateString(payload.value), value: payload.value };
75
+ if (onInputChangeTo) {
76
+ onInputChangeTo(event === null ? {} : event, payloadWithDate);
77
+ }
61
78
  };
62
79
  const handleMouseOver = useCallback((event) => {
63
80
  const target = event.target;
@@ -90,19 +107,20 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
90
107
  setInputToValue(valueTo);
91
108
  }, [valueTo]);
92
109
  useEffect(() => {
93
- if (!inputFromValue || isCompleteDateInput(inputFromValue)) {
94
- handleValidInputFrom();
95
- }
96
110
  period.setStart(dateFrom || undefined);
97
111
  if (dateTo) {
98
112
  period.setEnd(dateTo);
99
113
  }
114
+ if (isInternalUpdate.current) {
115
+ isInternalUpdate.current = false;
116
+ return;
117
+ }
100
118
  if (inputFromValue !== valueFrom) {
101
- onDateFromChange({
119
+ onDateFromChange?.({
102
120
  value: inputFromValue,
103
121
  date: dateFrom,
104
122
  });
105
- onChange({
123
+ onChange?.({
106
124
  valueFrom: inputFromValue,
107
125
  valueTo: inputToValue,
108
126
  dateFrom,
@@ -112,13 +130,14 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
112
130
  // eslint-disable-next-line react-hooks/exhaustive-deps
113
131
  }, [inputFromValue]);
114
132
  useEffect(() => {
115
- if (!inputToValue || isCompleteDateInput(inputToValue)) {
116
- handleValidInputTo();
117
- }
118
133
  period.setEnd(dateTo || undefined);
119
134
  if (dateFrom) {
120
135
  period.setStart(dateFrom);
121
136
  }
137
+ if (isInternalUpdate.current) {
138
+ isInternalUpdate.current = false;
139
+ return;
140
+ }
122
141
  if (inputToValue !== valueTo) {
123
142
  // eslint-disable-next-line no-nested-ternary
124
143
  const inputDateTo = returnInvalidDates
@@ -126,11 +145,11 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
126
145
  ? parseDateString(inputToValue).getTime()
127
146
  : null
128
147
  : dateTo;
129
- onDateToChange({
148
+ onDateToChange?.({
130
149
  value: inputToValue,
131
150
  date: inputDateTo,
132
151
  });
133
- onChange({
152
+ onChange?.({
134
153
  valueFrom: inputFromValue,
135
154
  valueTo: inputToValue,
136
155
  dateFrom,
@@ -139,12 +158,36 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
139
158
  }
140
159
  // eslint-disable-next-line react-hooks/exhaustive-deps
141
160
  }, [inputToValue]);
161
+ useEffect(() => {
162
+ const isInputFromValueComplete = isCompleteDateInput(inputFromValue);
163
+ const isInputToValueComplete = isCompleteDateInput(inputToValue);
164
+ let individualInputFromError = false;
165
+ let individualInputToError = false;
166
+ if (isInputFromValueComplete) {
167
+ individualInputFromError = !isValidInputValue(inputFromValue, minDate, maxDate, offDays);
168
+ }
169
+ if (isInputToValueComplete) {
170
+ individualInputToError = !isValidInputValue(inputToValue, minDate, maxDate, offDays);
171
+ }
172
+ let isRangeError = false;
173
+ const isValidInputFromValueStandalone = isInputFromValueComplete && individualInputFromError === false;
174
+ const isValidInputToValueStandalone = isInputToValueComplete && individualInputToError === false;
175
+ if (isValidInputFromValueStandalone && isValidInputToValueStandalone) {
176
+ const parsedDateFrom = parseDateString(inputFromValue).getTime();
177
+ const parsedDateTo = parseDateString(inputToValue).getTime();
178
+ if (parsedDateFrom > parsedDateTo) {
179
+ isRangeError = true;
180
+ }
181
+ }
182
+ setInputFromError(individualInputFromError || isRangeError);
183
+ setInputToError(individualInputToError || isRangeError);
184
+ setRangeValidationError(isRangeError);
185
+ }, [inputFromValue, inputToValue, minDate, maxDate, offDays]);
142
186
  useEffect(() => {
143
187
  if (onError) {
144
- onError(hasValidateError);
188
+ onError(rangeValidationError);
145
189
  }
146
- // eslint-disable-next-line react-hooks/exhaustive-deps
147
- }, [hasValidateError]);
190
+ }, [onError, rangeValidationError]);
148
191
  const rangeProps = useSelectionProps(period.selectedFrom, period.selectedTo, highlightedDate);
149
192
  const CalendarFromComponent = dateInputFromProps.Calendar || CalendarDesktop;
150
193
  const CalendarToComponent = dateInputToProps.Calendar || CalendarDesktop;
@@ -154,20 +197,20 @@ const CalendarRangeStatic = ({ className, defaultMonth = startOfMonth(new Date()
154
197
  React.createElement("div", { className: cn(styles.component, styles.static, className),
155
198
  // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
156
199
  onMouseOver: handleMouseOver, "data-test-id": dataTestId },
157
- React.createElement("div", null,
158
- React.createElement(DateInput, { ...dateInputFromProps, mobileMode: dateInputFromProps.mobileMode === 'popover'
159
- ? 'input'
160
- : dateInputFromProps.mobileMode, value: inputFromValue, onChange: handleInputFromChange, onClear: handleClearFrom, onBlur: handleValidInputFrom, error: bothInvalid || inputFromInvalid || dateInputFromProps.error, clear: true, block: true }),
200
+ React.createElement("div", { className: cn(styles.inputsContainer) },
201
+ React.createElement(UniversalDateInput, { ...dateInputFromProps, Calendar: undefined, view: 'date', picker: false, value: inputFromValue, onInputChange: handleInputFromChange, onClear: handleClearFrom, correctionRef: toggleCorrectionFromRef, error: inputFromError ? 'Укажите корректную дату' : dateInputFromProps.error, clear: true, block: true, minDate: minDate, autoCorrection: false, maxDate: minMaxInSameMonth
202
+ ? maxDate
203
+ : maxDate && max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime(), ref: inputFromRef }),
204
+ React.createElement(Divider, { inputFromProps: inputFromProps, inputToProps: inputToProps }),
205
+ React.createElement(UniversalDateInput, { ...dateInputToProps, Calendar: undefined, view: 'date', picker: false, value: inputToValue, onInputChange: handleInputToChange, onClear: handleClearTo, error: inputToError ? 'Укажите корректную дату' : dateInputToProps.error, correctionRef: toggleCorrectionToRef, clear: true, block: true, autoCorrection: false, minDate: minMaxInSameMonth
206
+ ? minDate
207
+ : minDate && startOfMonth(addMonths(minDate, 1)).getTime(), maxDate: maxDate, ref: inputToRef })),
208
+ React.createElement("div", { className: cn(styles.calendarContainers) },
161
209
  React.createElement("div", { className: cn(styles.calendarContainer, calendarContainerClassName), "data-test-id": getDataTestId(dataTestId, 'container-from') },
162
210
  React.createElement(CalendarFromComponent, { ...calendarFromProps, className: cn(styles.calendar, calendarFromProps?.className), month: monthFrom, selectorView: 'month-only', offDays: offDays, events: events, onChange: period.updatePeriod, onMonthChange: handleMonthFromChange, minDate: minDate, maxDate: minMaxInSameMonth
163
211
  ? maxDate
164
212
  : maxDate &&
165
- max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime(), ...rangeProps }))),
166
- React.createElement(Divider, { inputFromProps: inputFromProps, inputToProps: inputToProps }),
167
- React.createElement("div", null,
168
- React.createElement(DateInput, { ...dateInputToProps, mobileMode: dateInputToProps.mobileMode === 'popover'
169
- ? 'input'
170
- : dateInputToProps.mobileMode, value: inputToValue, onChange: handleInputToChange, onClear: handleClearTo, onBlur: handleValidInputTo, error: bothInvalid || inputToInvalid || dateInputToProps.error, clear: true, block: true }),
213
+ max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime(), ...rangeProps })),
171
214
  React.createElement("div", { "data-test-id": getDataTestId(dataTestId, 'container-to') },
172
215
  React.createElement(CalendarToComponent, { ...calendarToProps, className: cn(styles.calendar, calendarToProps?.className), month: monthTo, selectorView: 'month-only', offDays: offDays, events: events, onChange: period.updatePeriod, onMonthChange: handleMonthToChange, minDate: minMaxInSameMonth
173
216
  ? minDate
@@ -1 +1 @@
1
- {"version":3,"file":"static.js","sources":["../../src/views/static.tsx"],"sourcesContent":["/* eslint-disable complexity */\nimport React, { type FC, type MouseEvent, useCallback, useEffect, useState } from 'react';\nimport cn from 'classnames';\nimport { addMonths, endOfMonth, isSameMonth, max, startOfMonth, subMonths } from 'date-fns';\n\nimport { CalendarDesktop } from '@alfalab/core-components-calendar/desktop';\nimport { usePeriodWithReset } from '@alfalab/core-components-calendar/shared';\nimport {\n formatDate,\n isValidInputValue,\n parseDateString,\n} from '@alfalab/core-components-calendar-input/shared';\nimport {\n DateInput,\n type DateInputProps,\n isCompleteDateInput,\n} from '@alfalab/core-components-date-input';\nimport { getDataTestId } from '@alfalab/core-components-shared';\n\nimport { type CalendarRangeProps } from '../Component';\nimport { Divider } from '../components/divider';\nimport { useSelectionProps, useStaticViewMonthes } from '../hooks';\nimport { isDayButton } from '../utils';\n\nimport styles from './index.module.css';\n\nexport type CalendarRangeStaticProps = Omit<CalendarRangeProps, 'calendarPosition'> & {\n /**\n * Отображать начальный месяц слева или справа (влияет только на начальный рендер)\n */\n defaultMonthPosition?: 'left' | 'right';\n};\n\nexport const CalendarRangeStatic: FC<CalendarRangeStaticProps> = ({\n className,\n defaultMonth = startOfMonth(new Date()).getTime(),\n defaultMonthPosition = 'left',\n minDate,\n maxDate,\n valueFrom = '',\n valueTo = '',\n onDateFromChange = () => null,\n onDateToChange = () => null,\n onChange = () => null,\n onError,\n inputFromProps = {},\n inputToProps = {},\n offDays,\n events,\n returnInvalidDates = false,\n dataTestId,\n calendarContainerClassName,\n}) => {\n const [inputFromValue, setInputFromValue] = useState<string>(valueFrom);\n const [inputToValue, setInputToValue] = useState<string>(valueTo);\n\n let dateFrom = isValidInputValue(inputFromValue, minDate, maxDate, offDays)\n ? parseDateString(inputFromValue).getTime()\n : null;\n\n const dateTo = isValidInputValue(inputToValue, dateFrom || minDate, maxDate, offDays)\n ? parseDateString(inputToValue).getTime()\n : null;\n\n if (isCompleteDateInput(inputToValue) && !dateTo && !returnInvalidDates) {\n dateFrom = null;\n }\n\n const bothInvalid =\n isCompleteDateInput(inputFromValue) &&\n isCompleteDateInput(inputToValue) &&\n parseDateString(inputFromValue).getTime() > parseDateString(inputToValue).getTime();\n\n const [highlightedDate, setHighlightedDate] = useState<number | undefined>(undefined);\n\n const period = usePeriodWithReset({\n initialSelectedFrom: dateFrom ? parseDateString(inputFromValue).getTime() : undefined,\n initialSelectedTo: dateTo ? parseDateString(inputToValue).getTime() : undefined,\n });\n\n const validateInputFromValue = useCallback(\n (value: string) => isValidInputValue(value, minDate, dateFrom || maxDate, offDays),\n [dateFrom, maxDate, minDate, offDays],\n );\n\n const validateInputToValue = useCallback(\n (value: string) => isValidInputValue(value, dateFrom || minDate, maxDate, offDays),\n\n [dateFrom, minDate, maxDate, offDays],\n );\n\n const [inputFromInvalid, setInputFromInvalid] = useState<boolean>(\n isCompleteDateInput(inputFromValue) && dateFrom === null,\n );\n\n const [inputToInvalid, setInputToInvalid] = useState<boolean>(\n isCompleteDateInput(inputToValue) && dateTo === null,\n );\n\n const hasValidateError = bothInvalid || inputFromInvalid || inputToInvalid;\n const {\n calendarProps: calendarFromProps,\n onInputChange: onInputChangeFrom,\n ...dateInputFromProps\n } = inputFromProps;\n const {\n calendarProps: calendarToProps,\n onInputChange: onInputChangeTo,\n ...dateInputToProps\n } = inputToProps;\n\n const { monthFrom, monthTo, handleMonthFromChange, handleMonthToChange } = useStaticViewMonthes(\n {\n selectedFrom: period.selectedFrom,\n selectedTo: period.selectedTo,\n defaultMonth,\n defaultMonthPosition,\n },\n );\n\n const handleValidInputFrom = useCallback(() => {\n setInputFromInvalid(inputFromValue !== '' && !validateInputFromValue(inputFromValue));\n }, [inputFromValue, validateInputFromValue]);\n\n const handleValidInputTo = useCallback(() => {\n setInputToInvalid(inputToValue !== '' && !validateInputToValue(inputToValue));\n }, [inputToValue, validateInputToValue]);\n\n const handleInputFromChange: Required<DateInputProps>['onChange'] = (event, payload) => {\n setInputFromValue(payload.value);\n onInputChangeFrom?.(event, payload);\n };\n\n const handleInputToChange: Required<DateInputProps>['onChange'] = (event, payload) => {\n setInputToValue(payload.value);\n onInputChangeTo?.(event, payload);\n };\n\n const handleMouseOver = useCallback((event: MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n\n const mouseOverDayButton = isDayButton(target) || isDayButton(target.parentElement);\n\n let date;\n\n if (mouseOverDayButton) {\n const button =\n target.tagName === 'BUTTON' ? target : (target.parentElement as HTMLButtonElement);\n\n if (button.dataset.date) {\n date = +button.dataset.date;\n }\n }\n\n setHighlightedDate(date);\n }, []);\n\n const handleClearFrom = useCallback(() => {\n setInputFromValue('');\n }, []);\n\n const handleClearTo = useCallback(() => {\n setInputToValue('');\n }, []);\n\n useEffect(() => {\n setInputFromValue(period.selectedFrom ? formatDate(period.selectedFrom) : '');\n }, [period.selectedFrom]);\n\n useEffect(() => {\n setInputToValue(period.selectedTo ? formatDate(period.selectedTo) : '');\n }, [period.selectedTo]);\n\n useEffect(() => {\n setInputFromValue(valueFrom);\n }, [valueFrom]);\n\n useEffect(() => {\n setInputToValue(valueTo);\n }, [valueTo]);\n\n useEffect(() => {\n if (!inputFromValue || isCompleteDateInput(inputFromValue)) {\n handleValidInputFrom();\n }\n\n period.setStart(dateFrom || undefined);\n if (dateTo) {\n period.setEnd(dateTo);\n }\n\n if (inputFromValue !== valueFrom) {\n onDateFromChange({\n value: inputFromValue,\n date: dateFrom,\n });\n\n onChange({\n valueFrom: inputFromValue,\n valueTo: inputToValue,\n dateFrom,\n dateTo,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputFromValue]);\n\n useEffect(() => {\n if (!inputToValue || isCompleteDateInput(inputToValue)) {\n handleValidInputTo();\n }\n\n period.setEnd(dateTo || undefined);\n if (dateFrom) {\n period.setStart(dateFrom);\n }\n\n if (inputToValue !== valueTo) {\n // eslint-disable-next-line no-nested-ternary\n const inputDateTo = returnInvalidDates\n ? isCompleteDateInput(inputToValue)\n ? parseDateString(inputToValue).getTime()\n : null\n : dateTo;\n\n onDateToChange({\n value: inputToValue,\n date: inputDateTo,\n });\n\n onChange({\n valueFrom: inputFromValue,\n valueTo: inputToValue,\n dateFrom,\n dateTo: inputDateTo,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputToValue]);\n\n useEffect(() => {\n if (onError) {\n onError(hasValidateError);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hasValidateError]);\n\n const rangeProps = useSelectionProps(period.selectedFrom, period.selectedTo, highlightedDate);\n\n const CalendarFromComponent = dateInputFromProps.Calendar || CalendarDesktop;\n const CalendarToComponent = dateInputToProps.Calendar || CalendarDesktop;\n\n const minMaxInSameMonth = minDate && maxDate && isSameMonth(minDate, maxDate);\n\n return (\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n <div\n className={cn(styles.component, styles.static, className)}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={handleMouseOver}\n data-test-id={dataTestId}\n >\n <div>\n <DateInput\n {...dateInputFromProps}\n mobileMode={\n dateInputFromProps.mobileMode === 'popover'\n ? 'input'\n : dateInputFromProps.mobileMode\n }\n value={inputFromValue}\n onChange={handleInputFromChange}\n onClear={handleClearFrom}\n onBlur={handleValidInputFrom}\n error={bothInvalid || inputFromInvalid || dateInputFromProps.error}\n clear={true}\n block={true}\n />\n <div\n className={cn(styles.calendarContainer, calendarContainerClassName)}\n data-test-id={getDataTestId(dataTestId, 'container-from')}\n >\n <CalendarFromComponent\n {...calendarFromProps}\n className={cn(styles.calendar, calendarFromProps?.className)}\n month={monthFrom}\n selectorView='month-only'\n offDays={offDays}\n events={events}\n onChange={period.updatePeriod}\n onMonthChange={handleMonthFromChange}\n minDate={minDate}\n maxDate={\n minMaxInSameMonth\n ? maxDate\n : maxDate &&\n max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime()\n }\n {...rangeProps}\n />\n </div>\n </div>\n\n <Divider inputFromProps={inputFromProps} inputToProps={inputToProps} />\n\n <div>\n <DateInput\n {...dateInputToProps}\n mobileMode={\n dateInputToProps.mobileMode === 'popover'\n ? 'input'\n : dateInputToProps.mobileMode\n }\n value={inputToValue}\n onChange={handleInputToChange}\n onClear={handleClearTo}\n onBlur={handleValidInputTo}\n error={bothInvalid || inputToInvalid || dateInputToProps.error}\n clear={true}\n block={true}\n />\n <div data-test-id={getDataTestId(dataTestId, 'container-to')}>\n <CalendarToComponent\n {...calendarToProps}\n className={cn(styles.calendar, calendarToProps?.className)}\n month={monthTo}\n selectorView='month-only'\n offDays={offDays}\n events={events}\n onChange={period.updatePeriod}\n onMonthChange={handleMonthToChange}\n minDate={\n minMaxInSameMonth\n ? minDate\n : minDate && startOfMonth(addMonths(minDate, 1)).getTime()\n }\n maxDate={maxDate}\n {...rangeProps}\n />\n </div>\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;AAAA;AAiCa,MAAA,mBAAmB,GAAiC,CAAC,EAC9D,SAAS,EACT,YAAY,GAAG,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,EACjD,oBAAoB,GAAG,MAAM,EAC7B,OAAO,EACP,OAAO,EACP,SAAS,GAAG,EAAE,EACd,OAAO,GAAG,EAAE,EACZ,gBAAgB,GAAG,MAAM,IAAI,EAC7B,cAAc,GAAG,MAAM,IAAI,EAC3B,QAAQ,GAAG,MAAM,IAAI,EACrB,OAAO,EACP,cAAc,GAAG,EAAE,EACnB,YAAY,GAAG,EAAE,EACjB,OAAO,EACP,MAAM,EACN,kBAAkB,GAAG,KAAK,EAC1B,UAAU,EACV,0BAA0B,GAC7B,KAAI;IACD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAS,SAAS,CAAC;IACvE,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,OAAO,CAAC;IAEjE,IAAI,QAAQ,GAAG,iBAAiB,CAAC,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;AACtE,UAAE,eAAe,CAAC,cAAc,CAAC,CAAC,OAAO;UACvC,IAAI;AAEV,IAAA,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,EAAE,QAAQ,IAAI,OAAO,EAAE,OAAO,EAAE,OAAO;AAChF,UAAE,eAAe,CAAC,YAAY,CAAC,CAAC,OAAO;UACrC,IAAI;IAEV,IAAI,mBAAmB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,kBAAkB,EAAE;QACrE,QAAQ,GAAG,IAAI;;AAGnB,IAAA,MAAM,WAAW,GACb,mBAAmB,CAAC,cAAc,CAAC;QACnC,mBAAmB,CAAC,YAAY,CAAC;AACjC,QAAA,eAAe,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;IAEvF,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAqB,SAAS,CAAC;IAErF,MAAM,MAAM,GAAG,kBAAkB,CAAC;AAC9B,QAAA,mBAAmB,EAAE,QAAQ,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS;AACrF,QAAA,iBAAiB,EAAE,MAAM,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS;AAClF,KAAA,CAAC;AAEF,IAAA,MAAM,sBAAsB,GAAG,WAAW,CACtC,CAAC,KAAa,KAAK,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,OAAO,CAAC,EAClF,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CACxC;AAED,IAAA,MAAM,oBAAoB,GAAG,WAAW,CACpC,CAAC,KAAa,KAAK,iBAAiB,CAAC,KAAK,EAAE,QAAQ,IAAI,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAElF,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CACxC;AAED,IAAA,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CACpD,mBAAmB,CAAC,cAAc,CAAC,IAAI,QAAQ,KAAK,IAAI,CAC3D;AAED,IAAA,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAChD,mBAAmB,CAAC,YAAY,CAAC,IAAI,MAAM,KAAK,IAAI,CACvD;AAED,IAAA,MAAM,gBAAgB,GAAG,WAAW,IAAI,gBAAgB,IAAI,cAAc;AAC1E,IAAA,MAAM,EACF,aAAa,EAAE,iBAAiB,EAChC,aAAa,EAAE,iBAAiB,EAChC,GAAG,kBAAkB,EACxB,GAAG,cAAc;AAClB,IAAA,MAAM,EACF,aAAa,EAAE,eAAe,EAC9B,aAAa,EAAE,eAAe,EAC9B,GAAG,gBAAgB,EACtB,GAAG,YAAY;IAEhB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,GAAG,oBAAoB,CAC3F;QACI,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY;QACZ,oBAAoB;AACvB,KAAA,CACJ;AAED,IAAA,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAK;QAC1C,mBAAmB,CAAC,cAAc,KAAK,EAAE,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,CAAC;AACzF,KAAC,EAAE,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC;AAE5C,IAAA,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAK;QACxC,iBAAiB,CAAC,YAAY,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;AACjF,KAAC,EAAE,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;AAExC,IAAA,MAAM,qBAAqB,GAAyC,CAAC,KAAK,EAAE,OAAO,KAAI;AACnF,QAAA,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC;AAChC,QAAA,iBAAiB,GAAG,KAAK,EAAE,OAAO,CAAC;AACvC,KAAC;AAED,IAAA,MAAM,mBAAmB,GAAyC,CAAC,KAAK,EAAE,OAAO,KAAI;AACjF,QAAA,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC;AAC9B,QAAA,eAAe,GAAG,KAAK,EAAE,OAAO,CAAC;AACrC,KAAC;AAED,IAAA,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,KAAiC,KAAI;AACtE,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;AAE1C,QAAA,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC;AAEnF,QAAA,IAAI,IAAI;QAER,IAAI,kBAAkB,EAAE;AACpB,YAAA,MAAM,MAAM,GACR,MAAM,CAAC,OAAO,KAAK,QAAQ,GAAG,MAAM,GAAI,MAAM,CAAC,aAAmC;AAEtF,YAAA,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;AACrB,gBAAA,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;;;QAInC,kBAAkB,CAAC,IAAI,CAAC;KAC3B,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,eAAe,GAAG,WAAW,CAAC,MAAK;QACrC,iBAAiB,CAAC,EAAE,CAAC;KACxB,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,MAAK;QACnC,eAAe,CAAC,EAAE,CAAC;KACtB,EAAE,EAAE,CAAC;IAEN,SAAS,CAAC,MAAK;AACX,QAAA,iBAAiB,CAAC,MAAM,CAAC,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;AACjF,KAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAEzB,SAAS,CAAC,MAAK;AACX,QAAA,eAAe,CAAC,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;AAC3E,KAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEvB,SAAS,CAAC,MAAK;QACX,iBAAiB,CAAC,SAAS,CAAC;AAChC,KAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAEf,SAAS,CAAC,MAAK;QACX,eAAe,CAAC,OAAO,CAAC;AAC5B,KAAC,EAAE,CAAC,OAAO,CAAC,CAAC;IAEb,SAAS,CAAC,MAAK;QACX,IAAI,CAAC,cAAc,IAAI,mBAAmB,CAAC,cAAc,CAAC,EAAE;AACxD,YAAA,oBAAoB,EAAE;;AAG1B,QAAA,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,SAAS,CAAC;QACtC,IAAI,MAAM,EAAE;AACR,YAAA,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;;AAGzB,QAAA,IAAI,cAAc,KAAK,SAAS,EAAE;AAC9B,YAAA,gBAAgB,CAAC;AACb,gBAAA,KAAK,EAAE,cAAc;AACrB,gBAAA,IAAI,EAAE,QAAQ;AACjB,aAAA,CAAC;AAEF,YAAA,QAAQ,CAAC;AACL,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,OAAO,EAAE,YAAY;gBACrB,QAAQ;gBACR,MAAM;AACT,aAAA,CAAC;;;AAGV,KAAC,EAAE,CAAC,cAAc,CAAC,CAAC;IAEpB,SAAS,CAAC,MAAK;QACX,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC,YAAY,CAAC,EAAE;AACpD,YAAA,kBAAkB,EAAE;;AAGxB,QAAA,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC;QAClC,IAAI,QAAQ,EAAE;AACV,YAAA,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;;AAG7B,QAAA,IAAI,YAAY,KAAK,OAAO,EAAE;;YAE1B,MAAM,WAAW,GAAG;AAChB,kBAAE,mBAAmB,CAAC,YAAY;AAC9B,sBAAE,eAAe,CAAC,YAAY,CAAC,CAAC,OAAO;AACvC,sBAAE;kBACJ,MAAM;AAEZ,YAAA,cAAc,CAAC;AACX,gBAAA,KAAK,EAAE,YAAY;AACnB,gBAAA,IAAI,EAAE,WAAW;AACpB,aAAA,CAAC;AAEF,YAAA,QAAQ,CAAC;AACL,gBAAA,SAAS,EAAE,cAAc;AACzB,gBAAA,OAAO,EAAE,YAAY;gBACrB,QAAQ;AACR,gBAAA,MAAM,EAAE,WAAW;AACtB,aAAA,CAAC;;;AAGV,KAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IAElB,SAAS,CAAC,MAAK;QACX,IAAI,OAAO,EAAE;YACT,OAAO,CAAC,gBAAgB,CAAC;;;AAGjC,KAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAEtB,IAAA,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC;AAE7F,IAAA,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,QAAQ,IAAI,eAAe;AAC5E,IAAA,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,QAAQ,IAAI,eAAe;AAExE,IAAA,MAAM,iBAAiB,GAAG,OAAO,IAAI,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC;IAE7E;;AAEI,IAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;;QAEzD,WAAW,EAAE,eAAe,EAAA,cAAA,EACd,UAAU,EAAA;AAExB,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;YACI,KAAC,CAAA,aAAA,CAAA,SAAS,EACF,EAAA,GAAA,kBAAkB,EACtB,UAAU,EACN,kBAAkB,CAAC,UAAU,KAAK;AAC9B,sBAAE;AACF,sBAAE,kBAAkB,CAAC,UAAU,EAEvC,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,WAAW,IAAI,gBAAgB,IAAI,kBAAkB,CAAC,KAAK,EAClE,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACb,CAAA;AACF,YAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,kBACrD,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAA;gBAEzD,KAAC,CAAA,aAAA,CAAA,qBAAqB,OACd,iBAAiB,EACrB,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,EAAE,SAAS,CAAC,EAC5D,KAAK,EAAE,SAAS,EAChB,YAAY,EAAC,YAAY,EACzB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,CAAC,YAAY,EAC7B,aAAa,EAAE,qBAAqB,EACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EACH;AACI,0BAAE;AACF,0BAAE,OAAO;4BACP,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAEjE,GAAA,UAAU,EAChB,CAAA,CACA,CACJ;QAEN,KAAC,CAAA,aAAA,CAAA,OAAO,IAAC,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAI,CAAA;AAEvE,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,IAAA;YACI,KAAC,CAAA,aAAA,CAAA,SAAS,EACF,EAAA,GAAA,gBAAgB,EACpB,UAAU,EACN,gBAAgB,CAAC,UAAU,KAAK;AAC5B,sBAAE;AACF,sBAAE,gBAAgB,CAAC,UAAU,EAErC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,WAAW,IAAI,cAAc,IAAI,gBAAgB,CAAC,KAAK,EAC9D,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACb,CAAA;AACF,YAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,cAAA,EAAmB,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,EAAA;gBACxD,KAAC,CAAA,aAAA,CAAA,mBAAmB,OACZ,eAAe,EACnB,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,CAAC,EAC1D,KAAK,EAAE,OAAO,EACd,YAAY,EAAC,YAAY,EACzB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,CAAC,YAAY,EAC7B,aAAa,EAAE,mBAAmB,EAClC,OAAO,EACH;AACI,0BAAE;0BACA,OAAO,IAAI,YAAY,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,EAElE,OAAO,EAAE,OAAO,EAAA,GACZ,UAAU,EAAA,CAChB,CACA,CACJ,CACJ;AAEd;;;;"}
1
+ {"version":3,"file":"static.js","sources":["../../src/views/static.tsx"],"sourcesContent":["/* eslint-disable complexity */\nimport React, { type FC, type MouseEvent, useCallback, useEffect, useRef, useState } from 'react';\nimport cn from 'classnames';\nimport { addMonths, endOfMonth, isSameMonth, max, startOfMonth, subMonths } from 'date-fns';\n\nimport { CalendarDesktop } from '@alfalab/core-components-calendar/desktop';\nimport { usePeriodWithReset } from '@alfalab/core-components-calendar/shared';\nimport { type CalendarInputProps } from '@alfalab/core-components-calendar-input';\nimport {\n formatDate,\n isValidInputValue,\n parseDateString,\n} from '@alfalab/core-components-calendar-input/shared';\nimport { isCompleteDateInput } from '@alfalab/core-components-date-input';\nimport { getDataTestId } from '@alfalab/core-components-shared';\nimport {\n UniversalDateInput,\n type UniversalDateInputProps,\n} from '@alfalab/core-components-universal-date-input';\n\nimport { type CalendarRangeProps } from '../Component';\nimport { Divider } from '../components/divider';\nimport { useSelectionProps, useStaticRangeAutoSwap, useStaticViewMonthes } from '../hooks';\nimport { isDayButton } from '../utils';\n\nimport styles from './index.module.css';\n\ntype DateInputProps = Omit<CalendarInputProps, 'onCalendarOpen' | 'onCalendarClose' | 'onChange'>;\n\ninterface CalendarRangeStaticProps\n extends Omit<CalendarRangeProps, 'calendarPosition' | 'inputFromProps' | 'inputToProps'> {\n /**\n * Отображать начальный месяц слева или справа (влияет только на начальный рендер)\n */\n defaultMonthPosition?: 'left' | 'right';\n\n /**\n * Пропсы для инпута начальной даты диапазона\n */\n inputFromProps?: DateInputProps;\n\n /**\n * Пропсы для инпута конечной даты диапазона\n */\n inputToProps?: DateInputProps;\n}\n\ntype CorrectionToggleRef = { handleCorrection: () => void };\n\nexport const CalendarRangeStatic: FC<CalendarRangeStaticProps> = ({\n className,\n defaultMonth = startOfMonth(new Date()).getTime(),\n defaultMonthPosition = 'left',\n minDate,\n maxDate,\n valueFrom = '',\n valueTo = '',\n onDateFromChange = () => null,\n onDateToChange = () => null,\n onChange = () => null,\n inputFromProps = {},\n inputToProps = {},\n offDays,\n events,\n returnInvalidDates = false,\n dataTestId,\n calendarContainerClassName,\n autoSwap = false,\n onError,\n}) => {\n const [inputFromValue, setInputFromValue] = useState<string>(valueFrom);\n const [inputToValue, setInputToValue] = useState<string>(valueTo);\n\n const [inputFromError, setInputFromError] = useState(false);\n const [inputToError, setInputToError] = useState(false);\n\n const toggleCorrectionFromRef = useRef<CorrectionToggleRef>(null);\n const toggleCorrectionToRef = useRef<CorrectionToggleRef>(null);\n\n const inputToRef = useRef<HTMLInputElement>(null);\n const inputFromRef = useRef<HTMLInputElement>(null);\n\n const { swapDates, isInternalUpdate } = useStaticRangeAutoSwap({\n autoSwap,\n setInputFromValue,\n setInputToValue,\n toggleCorrectionFromRef,\n toggleCorrectionToRef,\n inputFromRef,\n inputToRef,\n });\n\n const [rangeValidationError, setRangeValidationError] = useState(false);\n\n let dateFrom = isValidInputValue(inputFromValue, minDate, maxDate, offDays)\n ? parseDateString(inputFromValue).getTime()\n : null;\n\n const dateTo = isValidInputValue(inputToValue, dateFrom || minDate, maxDate, offDays)\n ? parseDateString(inputToValue).getTime()\n : null;\n\n if (isCompleteDateInput(inputToValue) && !dateTo && !returnInvalidDates) {\n dateFrom = null;\n }\n\n const [highlightedDate, setHighlightedDate] = useState<number | undefined>(undefined);\n\n const period = usePeriodWithReset({\n initialSelectedFrom: dateFrom ? parseDateString(inputFromValue).getTime() : undefined,\n initialSelectedTo: dateTo ? parseDateString(inputToValue).getTime() : undefined,\n });\n\n const {\n calendarProps: calendarFromProps,\n onInputChange: onInputChangeFrom,\n ...dateInputFromProps\n } = inputFromProps;\n const {\n calendarProps: calendarToProps,\n onInputChange: onInputChangeTo,\n ...dateInputToProps\n } = inputToProps;\n\n const { monthFrom, monthTo, handleMonthFromChange, handleMonthToChange } = useStaticViewMonthes(\n {\n selectedFrom: period.selectedFrom,\n selectedTo: period.selectedTo,\n defaultMonth,\n defaultMonthPosition,\n },\n );\n\n const handleInputFromChange: Required<UniversalDateInputProps>['onInputChange'] = (\n event,\n payload,\n ) => {\n const newValue = payload.value;\n\n setInputFromValue(newValue);\n\n if (isValidInputValue(newValue, minDate, maxDate, offDays)) {\n swapDates(newValue, inputFromValue, inputToValue);\n }\n\n const payloadWithDate = { date: parseDateString(payload.value), value: payload.value };\n\n if (onInputChangeFrom) {\n onInputChangeFrom(\n event === null ? ({} as React.ChangeEvent<HTMLInputElement>) : event,\n payloadWithDate,\n );\n }\n };\n\n const handleInputToChange: Required<UniversalDateInputProps>['onInputChange'] = (\n event,\n payload,\n ) => {\n const newValue = payload.value;\n\n setInputToValue(newValue);\n\n if (isValidInputValue(newValue, minDate, maxDate, offDays)) {\n swapDates(newValue, inputFromValue, inputToValue);\n }\n\n const payloadWithDate = { date: parseDateString(payload.value), value: payload.value };\n\n if (onInputChangeTo) {\n onInputChangeTo(\n event === null ? ({} as React.ChangeEvent<HTMLInputElement>) : event,\n payloadWithDate,\n );\n }\n };\n\n const handleMouseOver = useCallback((event: MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n\n const mouseOverDayButton = isDayButton(target) || isDayButton(target.parentElement);\n\n let date;\n\n if (mouseOverDayButton) {\n const button =\n target.tagName === 'BUTTON' ? target : (target.parentElement as HTMLButtonElement);\n\n if (button.dataset.date) {\n date = +button.dataset.date;\n }\n }\n\n setHighlightedDate(date);\n }, []);\n\n const handleClearFrom = useCallback(() => {\n setInputFromValue('');\n }, []);\n\n const handleClearTo = useCallback(() => {\n setInputToValue('');\n }, []);\n\n useEffect(() => {\n setInputFromValue(period.selectedFrom ? formatDate(period.selectedFrom) : '');\n }, [period.selectedFrom]);\n\n useEffect(() => {\n setInputToValue(period.selectedTo ? formatDate(period.selectedTo) : '');\n }, [period.selectedTo]);\n\n useEffect(() => {\n setInputFromValue(valueFrom);\n }, [valueFrom]);\n\n useEffect(() => {\n setInputToValue(valueTo);\n }, [valueTo]);\n\n useEffect(() => {\n period.setStart(dateFrom || undefined);\n if (dateTo) {\n period.setEnd(dateTo);\n }\n\n if (isInternalUpdate.current) {\n isInternalUpdate.current = false;\n\n return;\n }\n\n if (inputFromValue !== valueFrom) {\n onDateFromChange?.({\n value: inputFromValue,\n date: dateFrom,\n });\n\n onChange?.({\n valueFrom: inputFromValue,\n valueTo: inputToValue,\n dateFrom,\n dateTo,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputFromValue]);\n\n useEffect(() => {\n period.setEnd(dateTo || undefined);\n if (dateFrom) {\n period.setStart(dateFrom);\n }\n\n if (isInternalUpdate.current) {\n isInternalUpdate.current = false;\n\n return;\n }\n\n if (inputToValue !== valueTo) {\n // eslint-disable-next-line no-nested-ternary\n const inputDateTo = returnInvalidDates\n ? isCompleteDateInput(inputToValue)\n ? parseDateString(inputToValue).getTime()\n : null\n : dateTo;\n\n onDateToChange?.({\n value: inputToValue,\n date: inputDateTo,\n });\n\n onChange?.({\n valueFrom: inputFromValue,\n valueTo: inputToValue,\n dateFrom,\n dateTo: inputDateTo,\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [inputToValue]);\n\n useEffect(() => {\n const isInputFromValueComplete = isCompleteDateInput(inputFromValue);\n const isInputToValueComplete = isCompleteDateInput(inputToValue);\n\n let individualInputFromError = false;\n let individualInputToError = false;\n\n if (isInputFromValueComplete) {\n individualInputFromError = !isValidInputValue(\n inputFromValue,\n minDate,\n maxDate,\n offDays,\n );\n }\n\n if (isInputToValueComplete) {\n individualInputToError = !isValidInputValue(inputToValue, minDate, maxDate, offDays);\n }\n\n let isRangeError = false;\n\n const isValidInputFromValueStandalone =\n isInputFromValueComplete && individualInputFromError === false;\n const isValidInputToValueStandalone =\n isInputToValueComplete && individualInputToError === false;\n\n if (isValidInputFromValueStandalone && isValidInputToValueStandalone) {\n const parsedDateFrom = parseDateString(inputFromValue).getTime();\n const parsedDateTo = parseDateString(inputToValue).getTime();\n\n if (parsedDateFrom > parsedDateTo) {\n isRangeError = true;\n }\n }\n\n setInputFromError(individualInputFromError || isRangeError);\n setInputToError(individualInputToError || isRangeError);\n\n setRangeValidationError(isRangeError);\n }, [inputFromValue, inputToValue, minDate, maxDate, offDays]);\n\n useEffect(() => {\n if (onError) {\n onError(rangeValidationError);\n }\n }, [onError, rangeValidationError]);\n\n const rangeProps = useSelectionProps(period.selectedFrom, period.selectedTo, highlightedDate);\n\n const CalendarFromComponent = dateInputFromProps.Calendar || CalendarDesktop;\n const CalendarToComponent = dateInputToProps.Calendar || CalendarDesktop;\n\n const minMaxInSameMonth = minDate && maxDate && isSameMonth(minDate, maxDate);\n\n return (\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n <div\n className={cn(styles.component, styles.static, className)}\n // eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n onMouseOver={handleMouseOver}\n data-test-id={dataTestId}\n >\n <div className={cn(styles.inputsContainer)}>\n <UniversalDateInput\n {...dateInputFromProps}\n Calendar={undefined}\n view='date'\n picker={false}\n value={inputFromValue}\n onInputChange={handleInputFromChange}\n onClear={handleClearFrom}\n correctionRef={toggleCorrectionFromRef}\n error={inputFromError ? 'Укажите корректную дату' : dateInputFromProps.error}\n clear={true}\n block={true}\n minDate={minDate}\n autoCorrection={false}\n maxDate={\n minMaxInSameMonth\n ? maxDate\n : maxDate && max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime()\n }\n ref={inputFromRef}\n />\n\n <Divider inputFromProps={inputFromProps} inputToProps={inputToProps} />\n\n <UniversalDateInput\n {...dateInputToProps}\n Calendar={undefined}\n view='date'\n picker={false}\n value={inputToValue}\n onInputChange={handleInputToChange}\n onClear={handleClearTo}\n error={inputToError ? 'Укажите корректную дату' : dateInputToProps.error}\n correctionRef={toggleCorrectionToRef}\n clear={true}\n block={true}\n autoCorrection={false}\n minDate={\n minMaxInSameMonth\n ? minDate\n : minDate && startOfMonth(addMonths(minDate, 1)).getTime()\n }\n maxDate={maxDate}\n ref={inputToRef}\n />\n </div>\n <div className={cn(styles.calendarContainers)}>\n <div\n className={cn(styles.calendarContainer, calendarContainerClassName)}\n data-test-id={getDataTestId(dataTestId, 'container-from')}\n >\n <CalendarFromComponent\n {...calendarFromProps}\n className={cn(styles.calendar, calendarFromProps?.className)}\n month={monthFrom}\n selectorView='month-only'\n offDays={offDays}\n events={events}\n onChange={period.updatePeriod}\n onMonthChange={handleMonthFromChange}\n minDate={minDate}\n maxDate={\n minMaxInSameMonth\n ? maxDate\n : maxDate &&\n max([maxDate, endOfMonth(subMonths(maxDate, 1))]).getTime()\n }\n {...rangeProps}\n />\n </div>\n <div data-test-id={getDataTestId(dataTestId, 'container-to')}>\n <CalendarToComponent\n {...calendarToProps}\n className={cn(styles.calendar, calendarToProps?.className)}\n month={monthTo}\n selectorView='month-only'\n offDays={offDays}\n events={events}\n onChange={period.updatePeriod}\n onMonthChange={handleMonthToChange}\n minDate={\n minMaxInSameMonth\n ? minDate\n : minDate && startOfMonth(addMonths(minDate, 1)).getTime()\n }\n maxDate={maxDate}\n {...rangeProps}\n />\n </div>\n </div>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-calendar-range",
3
- "version": "9.0.14",
3
+ "version": "9.1.0",
4
4
  "description": "Calendar range component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -17,6 +17,7 @@
17
17
  "@alfalab/core-components-calendar-input": "^12.0.14",
18
18
  "@alfalab/core-components-date-input": "^6.0.10",
19
19
  "@alfalab/core-components-shared": "^2.2.1",
20
+ "@alfalab/core-components-universal-date-input": "^4.0.14",
20
21
  "@alfalab/hooks": "^1.17.0",
21
22
  "classnames": "^2.5.1",
22
23
  "date-fns": "^4.1.0",
package/src/Component.tsx CHANGED
@@ -106,6 +106,11 @@ export type CalendarRangeProps = {
106
106
  * Дополнительный класс для контейнера календаря
107
107
  */
108
108
  calendarContainerClassName?: string;
109
+
110
+ /**
111
+ * Автоподмена дат
112
+ */
113
+ autoSwap?: boolean;
109
114
  };
110
115
 
111
116
  export const CalendarRange: FC<CalendarRangeProps> = ({
@@ -5,7 +5,7 @@
5
5
  display: flex;
6
6
  align-items: center;
7
7
  justify-content: center;
8
- width: 16px;
8
+ min-width: 16px;
9
9
  margin: var(--gap-0) var(--gap-8);
10
10
 
11
11
  &:after {
package/src/hooks.ts CHANGED
@@ -1,6 +1,9 @@
1
- import { useCallback, useEffect, useMemo, useState } from 'react';
1
+ import { type RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { addMonths, isEqual, max, min, startOfMonth, subMonths } from 'date-fns';
3
3
 
4
+ import { isValidInputValue, parseDateString } from '@alfalab/core-components-calendar-input/shared';
5
+ import { isCompleteDateInput } from '@alfalab/core-components-date-input';
6
+
4
7
  export function usePopoverViewMonthes({
5
8
  dateFrom,
6
9
  dateTo,
@@ -194,3 +197,149 @@ export function useSelectionProps(from?: number, to?: number, highlighted?: numb
194
197
  };
195
198
  }, [from, highlighted, to]);
196
199
  }
200
+
201
+ interface UseStaticRangeAutoSwapParams {
202
+ autoSwap: boolean;
203
+ setInputFromValue: React.Dispatch<React.SetStateAction<string>>;
204
+ setInputToValue: React.Dispatch<React.SetStateAction<string>>;
205
+ toggleCorrectionFromRef: RefObject<CorrectionToggleRef>;
206
+ toggleCorrectionToRef: RefObject<CorrectionToggleRef>;
207
+ inputFromRef: RefObject<HTMLInputElement>;
208
+ inputToRef: RefObject<HTMLInputElement>;
209
+ }
210
+
211
+ type CorrectionToggleRef = { handleCorrection: () => void };
212
+
213
+ export const useStaticRangeAutoSwap = ({
214
+ autoSwap,
215
+ setInputFromValue,
216
+ setInputToValue,
217
+ toggleCorrectionFromRef,
218
+ toggleCorrectionToRef,
219
+ inputFromRef,
220
+ inputToRef,
221
+ }: UseStaticRangeAutoSwapParams) => {
222
+ const isInternalUpdate = useRef(false);
223
+
224
+ const swapDates = (newValue: string, inputFromValue: string, inputToValue: string) => {
225
+ if (!autoSwap) return;
226
+
227
+ if (
228
+ isCompleteDateInput(newValue) &&
229
+ isCompleteDateInput(inputToValue) &&
230
+ parseDateString(newValue).getTime() > parseDateString(inputToValue).getTime()
231
+ ) {
232
+ if (inputFromValue !== inputToValue) {
233
+ isInternalUpdate.current = true;
234
+ setInputFromValue(inputToValue);
235
+ setInputToValue(newValue);
236
+
237
+ toggleCorrectionFromRef.current?.handleCorrection();
238
+ toggleCorrectionToRef.current?.handleCorrection();
239
+
240
+ setTimeout(() => {
241
+ inputToRef.current?.focus();
242
+ }, 0);
243
+ }
244
+ }
245
+ if (
246
+ isCompleteDateInput(newValue) &&
247
+ isCompleteDateInput(inputFromValue) &&
248
+ parseDateString(newValue).getTime() < parseDateString(inputFromValue).getTime()
249
+ ) {
250
+ if (inputToValue !== inputFromValue) {
251
+ isInternalUpdate.current = true;
252
+ setInputToValue(inputFromValue);
253
+ setInputFromValue(newValue);
254
+
255
+ toggleCorrectionFromRef.current?.handleCorrection();
256
+ toggleCorrectionToRef.current?.handleCorrection();
257
+
258
+ setTimeout(() => {
259
+ inputFromRef.current?.focus();
260
+ }, 0);
261
+ }
262
+ }
263
+ };
264
+
265
+ return { swapDates, isInternalUpdate };
266
+ };
267
+
268
+ interface UseInputValidationParams {
269
+ inputFromValue: string;
270
+ inputToValue: string;
271
+ minDate: number;
272
+ maxDate: number;
273
+ offDays: Array<number | Date>;
274
+ }
275
+
276
+ interface InputValidationResult {
277
+ inputFromError: boolean;
278
+ inputToError: boolean;
279
+ rangeError: boolean;
280
+ }
281
+
282
+ export const useInputValidation = ({
283
+ inputFromValue,
284
+ inputToValue,
285
+ minDate,
286
+ maxDate,
287
+ offDays,
288
+ }: UseInputValidationParams): InputValidationResult => {
289
+ const [validationResult, setValidationResult] = useState<InputValidationResult>({
290
+ inputFromError: false,
291
+ inputToError: false,
292
+ rangeError: false,
293
+ });
294
+
295
+ useEffect(() => {
296
+ const isInputFromValueComplete = isCompleteDateInput(inputFromValue);
297
+ const isInputToValueComplete = isCompleteDateInput(inputToValue);
298
+
299
+ let individualInputFromError = false;
300
+ let individualInputToError = false;
301
+
302
+ if (isInputFromValueComplete) {
303
+ individualInputFromError = !isValidInputValue(
304
+ inputFromValue,
305
+ minDate,
306
+ maxDate,
307
+ offDays,
308
+ );
309
+ }
310
+
311
+ if (isInputToValueComplete) {
312
+ individualInputToError = !isValidInputValue(inputToValue, minDate, maxDate, offDays);
313
+ }
314
+
315
+ let rangeError = false;
316
+
317
+ const parsedDateFrom = isInputFromValueComplete ? parseDateString(inputFromValue) : null;
318
+ const parsedDateTo = isInputToValueComplete ? parseDateString(inputToValue) : null;
319
+
320
+ const isParsedDateFromValid =
321
+ parsedDateFrom &&
322
+ !Number.isNaN(parsedDateFrom.getTime()) &&
323
+ isValidInputValue(inputFromValue, minDate, maxDate, offDays);
324
+ const isParsedDateToValid =
325
+ parsedDateTo &&
326
+ !Number.isNaN(parsedDateTo.getTime()) &&
327
+ isValidInputValue(inputToValue, minDate, maxDate, offDays);
328
+
329
+ if (
330
+ isParsedDateFromValid &&
331
+ isParsedDateToValid &&
332
+ parsedDateFrom.getTime() > parsedDateTo.getTime()
333
+ ) {
334
+ rangeError = true;
335
+ }
336
+
337
+ setValidationResult({
338
+ inputFromError: individualInputFromError || rangeError,
339
+ inputToError: individualInputToError || rangeError,
340
+ rangeError,
341
+ });
342
+ }, [inputFromValue, inputToValue, minDate, maxDate, offDays]);
343
+
344
+ return validationResult;
345
+ };
@@ -18,6 +18,8 @@
18
18
  }
19
19
 
20
20
  .static {
21
+ flex-direction: column;
22
+
21
23
  & .calendar {
22
24
  width: var(--calendar-inner-width);
23
25
 
@@ -27,6 +29,15 @@
27
29
  }
28
30
  }
29
31
 
32
+ .inputsContainer {
33
+ display: flex;
34
+ }
35
+
36
+ .calendarContainers {
37
+ display: flex;
38
+ gap: var(--gap-32);
39
+ }
40
+
30
41
  .calendarContainer {
31
42
  width: var(--calendar-inner-width);
32
43
  display: flex;