@alfalab/core-components-calendar-input 5.3.0 → 6.0.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,62 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [6.0.0](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-calendar-input@5.3.0...@alfalab/core-components-calendar-input@6.0.0) (2022-02-17)
7
+
8
+
9
+ * refactor/calendar-range (#984) ([714f615](https://github.com/alfa-laboratory/core-components/commit/714f61590586bafe1060e652943e95c133ed002a)), closes [#984](https://github.com/alfa-laboratory/core-components/issues/984)
10
+
11
+
12
+ ### BREAKING CHANGES
13
+
14
+ * Большое обновление CalendarRange
15
+
16
+ * feat(date-input): add some improvements
17
+
18
+ * feat(date-input): some updates
19
+
20
+ * feat(date-input): validation
21
+
22
+ * feat(calendar): change period selection logic
23
+
24
+ * fix(calendar): range styles
25
+
26
+ * fix(calendar): fix styles, add rangeComplete flag
27
+
28
+ * refactor(calendar-range): temporary
29
+
30
+ * fix(calendar-range): fix hook
31
+
32
+ * fix(calendar-range): fix period
33
+
34
+ * fix(calendar-range): fix tests, fix max date
35
+
36
+ * fix: update exports
37
+
38
+ * feat(calendar): allow empty values for PeriodSlider, update today
39
+
40
+ * fix(calendar-range): hide error icon
41
+
42
+ * chore(calendar-range): demo
43
+
44
+ * feat(calendar): use IconButton
45
+
46
+ * feat(calendar-range): add onChange, update demo
47
+
48
+ * fix(calendar-range): update width
49
+
50
+ * test(calendar-range): update snapshot
51
+
52
+ * fix: import date-fns separately
53
+
54
+ * fix(calendar-range): fix rest props
55
+
56
+ Co-authored-by: dmitrsavk <dmitrsavk@yandex.ru>
57
+
58
+
59
+
60
+
61
+
6
62
  # [5.3.0](https://github.com/alfa-laboratory/core-components/compare/@alfalab/core-components-calendar-input@5.2.7...@alfalab/core-components-calendar-input@5.3.0) (2022-02-17)
7
63
 
8
64
 
@@ -45,6 +45,10 @@ type CalendarInputProps = Omit<DateInputProps, 'onChange' | 'mobileMode'> & {
45
45
  * Максимальная дата, доступная для выбора (timestamp)
46
46
  */
47
47
  maxDate?: number;
48
+ /**
49
+ * Список событий
50
+ */
51
+ events?: Array<Date | number>;
48
52
  /**
49
53
  * Список выходных
50
54
  */
@@ -138,6 +142,10 @@ declare const CalendarInput: React.ForwardRefExoticComponent<Pick<DateInputProps
138
142
  * Максимальная дата, доступная для выбора (timestamp)
139
143
  */
140
144
  maxDate?: number | undefined;
145
+ /**
146
+ * Список событий
147
+ */
148
+ events?: (number | Date)[] | undefined;
141
149
  /**
142
150
  * Список выходных
143
151
  */
package/dist/Component.js CHANGED
@@ -6,10 +6,12 @@ var React = require('react');
6
6
  var cn = require('classnames');
7
7
  var mergeRefs = require('react-merge-refs');
8
8
  var coreComponentsPopover = require('@alfalab/core-components-popover');
9
+ var CalendarMIcon = require('@alfalab/icons-glyph/CalendarMIcon');
9
10
  var coreComponentsDateInput = require('@alfalab/core-components-date-input');
10
11
  var coreComponentsCalendar = require('@alfalab/core-components-calendar');
11
- var CalendarMIcon = require('@alfalab/icons-glyph/CalendarMIcon');
12
- require('date-fns');
12
+ require('date-fns/parse');
13
+ require('date-fns/format');
14
+ require('date-fns/isSameDay');
13
15
  var utils = require('./utils.js');
14
16
 
15
17
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -57,24 +59,28 @@ function __rest(s, e) {
57
59
  return t;
58
60
  }
59
61
 
60
- var styles = {"component":"calendar-input__component_1vge6","block":"calendar-input__block_1vge6","calendarContainer":"calendar-input__calendarContainer_1vge6","calendarIcon":"calendar-input__calendarIcon_1vge6","nativeInput":"calendar-input__nativeInput_1vge6"};
62
+ var styles = {"component":"calendar-input__component_1ksty","block":"calendar-input__block_1ksty","calendarContainer":"calendar-input__calendarContainer_1ksty","calendarIcon":"calendar-input__calendarIcon_1ksty","nativeInput":"calendar-input__nativeInput_1ksty"};
61
63
  require('./index.css')
62
64
 
63
65
  var CalendarInput = React.forwardRef(function (_a, ref) {
64
66
  var _b;
65
- var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, preventFlip = _a.preventFlip, _l = _a.mobileMode, mobileMode = _l === void 0 ? 'popover' : _l, _m = _a.wrapperRef, wrapperRef = _m === void 0 ? null : _m, disabled = _a.disabled, onChange = _a.onChange, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _o = _a.Calendar, Calendar = _o === void 0 ? coreComponentsCalendar.Calendar : _o, _p = _a.popoverPosition, popoverPosition = _p === void 0 ? 'bottom-start' : _p, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons"]);
66
- var uncontrolled = value === undefined;
67
+ var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, _l = _a.events, events = _l === void 0 ? calendarProps.events || [] : _l, preventFlip = _a.preventFlip, _m = _a.mobileMode, mobileMode = _m === void 0 ? 'popover' : _m, _o = _a.wrapperRef, wrapperRef = _o === void 0 ? null : _o, disabled = _a.disabled, _p = _a.onChange, onChange = _p === void 0 ? function () { return null; } : _p, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _q = _a.Calendar, Calendar = _q === void 0 ? coreComponentsCalendar.Calendar : _q, _r = _a.popoverPosition, popoverPosition = _r === void 0 ? 'bottom-start' : _r, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, error = _a.error, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "events", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons", "error"]);
67
68
  var shouldRenderNative = utils.SUPPORTS_INPUT_TYPE_DATE && mobileMode === 'native';
68
69
  var shouldRenderOnlyInput = mobileMode === 'input';
69
70
  var shouldRenderStatic = calendarPosition === 'static' && !shouldRenderOnlyInput;
70
71
  var shouldRenderPopover = calendarPosition === 'popover' && !shouldRenderNative && !shouldRenderOnlyInput;
71
- var _q = React.useState(false), open = _q[0], setOpen = _q[1];
72
- var _r = React.useState(defaultValue), stateValue = _r[0], setStateValue = _r[1];
73
- var inputValue = uncontrolled ? stateValue : value;
72
+ var _s = React.useState(false), open = _s[0], setOpen = _s[1];
73
+ var _t = React.useState(value || defaultValue), inputValue = _t[0], setInputValue = _t[1];
74
74
  var calendarValue = inputValue ? coreComponentsDateInput.parseDateString(inputValue).getTime() : undefined;
75
- var isCalendarValueValid = calendarValue &&
76
- coreComponentsCalendar.dateInLimits(calendarValue, minDate, maxDate) &&
77
- !offDays.includes(calendarValue);
75
+ var checkInputValueIsValid = React.useCallback(function (newInputValue) {
76
+ if (!newInputValue || error)
77
+ return false;
78
+ var dateValue = coreComponentsDateInput.parseDateString(newInputValue).getTime();
79
+ return (dateValue &&
80
+ coreComponentsDateInput.isCompleteDateInput(newInputValue) &&
81
+ coreComponentsCalendar.dateInLimits(dateValue, minDate, maxDate) &&
82
+ !offDays.includes(dateValue));
83
+ }, [error, maxDate, minDate, offDays]);
78
84
  var inputDisabled = disabled || readOnly;
79
85
  var inputWrapperRef = React.useRef(null);
80
86
  var calendarRef = React.useRef(null);
@@ -119,18 +125,14 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
119
125
  if (initiator === 'calendar' && onCalendarChange) {
120
126
  onCalendarChange(newDate.getTime());
121
127
  }
128
+ setInputValue(newValue);
122
129
  if (shouldChange) {
123
- if (uncontrolled) {
124
- setStateValue(newValue);
125
- }
126
- if (onChange) {
127
- onChange(event, { date: newDate, value: newValue });
128
- }
130
+ onChange(event, { date: newDate, value: newValue });
129
131
  }
130
- }, [onCalendarChange, onChange, onInputChange, uncontrolled]);
132
+ }, [onCalendarChange, onChange, onInputChange]);
131
133
  var handleInputChange = React.useCallback(function (event, payload) {
132
- changeHandler(event, payload.value, payload.date, 'input', !payload.value || coreComponentsDateInput.isCompleteDateInput(payload.value));
133
- }, [changeHandler]);
134
+ changeHandler(event, payload.value, payload.date, 'input', !payload.value || checkInputValueIsValid(payload.value));
135
+ }, [changeHandler, checkInputValueIsValid]);
134
136
  var handleCalendarChange = React.useCallback(function (date) {
135
137
  changeHandler(null, coreComponentsDateInput.formatDate(date), new Date(date), 'calendar');
136
138
  setOpen(false);
@@ -142,16 +144,23 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
142
144
  React.useEffect(function () {
143
145
  setOpen(defaultOpen);
144
146
  }, [defaultOpen]);
147
+ React.useEffect(function () {
148
+ if (typeof value !== 'undefined') {
149
+ setInputValue(value);
150
+ }
151
+ }, [value]);
145
152
  var renderCalendar = React.useCallback(function () { return (
146
153
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
147
154
  React__default['default'].createElement("div", { onMouseDown: handleCalendarWrapperMouseDown },
148
- React__default['default'].createElement(Calendar, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: isCalendarValueValid ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays })))); }, [
155
+ React__default['default'].createElement(Calendar, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: checkInputValueIsValid(inputValue) ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays, events: events })))); }, [
149
156
  calendarProps,
150
157
  calendarValue,
158
+ checkInputValueIsValid,
151
159
  defaultMonth,
160
+ events,
152
161
  handleCalendarChange,
153
162
  handleCalendarWrapperMouseDown,
154
- isCalendarValueValid,
163
+ inputValue,
155
164
  maxDate,
156
165
  minDate,
157
166
  offDays,
@@ -161,9 +170,9 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
161
170
  React__default['default'].createElement("div", { className: cn__default['default'](styles.component, className, (_b = {},
162
171
  _b[styles.block] = block,
163
172
  _b)), tabIndex: -1, onKeyDown: inputDisabled ? undefined : handleKeyDown, onClick: inputDisabled ? undefined : handleClick, onFocus: inputDisabled ? undefined : handleFocus, onBlur: handleBlur, "data-test-id": dataTestId },
164
- React__default['default'].createElement(coreComponentsDateInput.DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs__default['default']([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', rightAddons: React__default['default'].createElement(React__default['default'].Fragment, null,
173
+ React__default['default'].createElement(coreComponentsDateInput.DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs__default['default']([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', error: error, rightAddons: React__default['default'].createElement(React__default['default'].Fragment, null,
165
174
  rightAddons,
166
- React__default['default'].createElement(CalendarMIcon.CalendarMIcon, { className: styles.calendarIcon })), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
175
+ shouldRenderPopover && (React__default['default'].createElement(CalendarMIcon.CalendarMIcon, { className: styles.calendarIcon }))), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
167
176
  shouldRenderStatic && renderCalendar(),
168
177
  shouldRenderPopover && (React__default['default'].createElement(coreComponentsPopover.Popover, { open: open, useAnchorWidth: useAnchorWidth, anchorElement: inputWrapperRef.current, popperClassName: styles.calendarContainer, className: popoverClassName, position: popoverPosition, offset: [0, 8], withTransition: false, preventFlip: preventFlip, zIndex: zIndexPopover }, renderCalendar()))));
169
178
  });
@@ -45,6 +45,10 @@ type CalendarInputProps = Omit<DateInputProps, 'onChange' | 'mobileMode'> & {
45
45
  * Максимальная дата, доступная для выбора (timestamp)
46
46
  */
47
47
  maxDate?: number;
48
+ /**
49
+ * Список событий
50
+ */
51
+ events?: Array<Date | number>;
48
52
  /**
49
53
  * Список выходных
50
54
  */
@@ -138,6 +142,10 @@ declare const CalendarInput: React.ForwardRefExoticComponent<Pick<DateInputProps
138
142
  * Максимальная дата, доступная для выбора (timestamp)
139
143
  */
140
144
  maxDate?: number | undefined;
145
+ /**
146
+ * Список событий
147
+ */
148
+ events?: (number | Date)[] | undefined;
141
149
  /**
142
150
  * Список выходных
143
151
  */
@@ -6,12 +6,14 @@ var React = require('react');
6
6
  var cn = require('classnames');
7
7
  var mergeRefs = require('react-merge-refs');
8
8
  var coreComponentsPopover = require('@alfalab/core-components-popover/dist/cssm');
9
+ var CalendarMIcon = require('@alfalab/icons-glyph/CalendarMIcon');
9
10
  var coreComponentsDateInput = require('@alfalab/core-components-date-input/dist/cssm');
10
11
  var coreComponentsCalendar = require('@alfalab/core-components-calendar/dist/cssm');
11
- var CalendarMIcon = require('@alfalab/icons-glyph/CalendarMIcon');
12
- var styles = require('./index.module.css');
13
- require('date-fns');
12
+ require('date-fns/parse');
13
+ require('date-fns/format');
14
+ require('date-fns/isSameDay');
14
15
  var utils = require('./utils.js');
16
+ var styles = require('./index.module.css');
15
17
 
16
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
19
 
@@ -61,19 +63,23 @@ function __rest(s, e) {
61
63
 
62
64
  var CalendarInput = React.forwardRef(function (_a, ref) {
63
65
  var _b;
64
- var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, preventFlip = _a.preventFlip, _l = _a.mobileMode, mobileMode = _l === void 0 ? 'popover' : _l, _m = _a.wrapperRef, wrapperRef = _m === void 0 ? null : _m, disabled = _a.disabled, onChange = _a.onChange, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _o = _a.Calendar, Calendar = _o === void 0 ? coreComponentsCalendar.Calendar : _o, _p = _a.popoverPosition, popoverPosition = _p === void 0 ? 'bottom-start' : _p, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons"]);
65
- var uncontrolled = value === undefined;
66
+ var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, _l = _a.events, events = _l === void 0 ? calendarProps.events || [] : _l, preventFlip = _a.preventFlip, _m = _a.mobileMode, mobileMode = _m === void 0 ? 'popover' : _m, _o = _a.wrapperRef, wrapperRef = _o === void 0 ? null : _o, disabled = _a.disabled, _p = _a.onChange, onChange = _p === void 0 ? function () { return null; } : _p, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _q = _a.Calendar, Calendar = _q === void 0 ? coreComponentsCalendar.Calendar : _q, _r = _a.popoverPosition, popoverPosition = _r === void 0 ? 'bottom-start' : _r, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, error = _a.error, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "events", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons", "error"]);
66
67
  var shouldRenderNative = utils.SUPPORTS_INPUT_TYPE_DATE && mobileMode === 'native';
67
68
  var shouldRenderOnlyInput = mobileMode === 'input';
68
69
  var shouldRenderStatic = calendarPosition === 'static' && !shouldRenderOnlyInput;
69
70
  var shouldRenderPopover = calendarPosition === 'popover' && !shouldRenderNative && !shouldRenderOnlyInput;
70
- var _q = React.useState(false), open = _q[0], setOpen = _q[1];
71
- var _r = React.useState(defaultValue), stateValue = _r[0], setStateValue = _r[1];
72
- var inputValue = uncontrolled ? stateValue : value;
71
+ var _s = React.useState(false), open = _s[0], setOpen = _s[1];
72
+ var _t = React.useState(value || defaultValue), inputValue = _t[0], setInputValue = _t[1];
73
73
  var calendarValue = inputValue ? coreComponentsDateInput.parseDateString(inputValue).getTime() : undefined;
74
- var isCalendarValueValid = calendarValue &&
75
- coreComponentsCalendar.dateInLimits(calendarValue, minDate, maxDate) &&
76
- !offDays.includes(calendarValue);
74
+ var checkInputValueIsValid = React.useCallback(function (newInputValue) {
75
+ if (!newInputValue || error)
76
+ return false;
77
+ var dateValue = coreComponentsDateInput.parseDateString(newInputValue).getTime();
78
+ return (dateValue &&
79
+ coreComponentsDateInput.isCompleteDateInput(newInputValue) &&
80
+ coreComponentsCalendar.dateInLimits(dateValue, minDate, maxDate) &&
81
+ !offDays.includes(dateValue));
82
+ }, [error, maxDate, minDate, offDays]);
77
83
  var inputDisabled = disabled || readOnly;
78
84
  var inputWrapperRef = React.useRef(null);
79
85
  var calendarRef = React.useRef(null);
@@ -118,18 +124,14 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
118
124
  if (initiator === 'calendar' && onCalendarChange) {
119
125
  onCalendarChange(newDate.getTime());
120
126
  }
127
+ setInputValue(newValue);
121
128
  if (shouldChange) {
122
- if (uncontrolled) {
123
- setStateValue(newValue);
124
- }
125
- if (onChange) {
126
- onChange(event, { date: newDate, value: newValue });
127
- }
129
+ onChange(event, { date: newDate, value: newValue });
128
130
  }
129
- }, [onCalendarChange, onChange, onInputChange, uncontrolled]);
131
+ }, [onCalendarChange, onChange, onInputChange]);
130
132
  var handleInputChange = React.useCallback(function (event, payload) {
131
- changeHandler(event, payload.value, payload.date, 'input', !payload.value || coreComponentsDateInput.isCompleteDateInput(payload.value));
132
- }, [changeHandler]);
133
+ changeHandler(event, payload.value, payload.date, 'input', !payload.value || checkInputValueIsValid(payload.value));
134
+ }, [changeHandler, checkInputValueIsValid]);
133
135
  var handleCalendarChange = React.useCallback(function (date) {
134
136
  changeHandler(null, coreComponentsDateInput.formatDate(date), new Date(date), 'calendar');
135
137
  setOpen(false);
@@ -141,16 +143,23 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
141
143
  React.useEffect(function () {
142
144
  setOpen(defaultOpen);
143
145
  }, [defaultOpen]);
146
+ React.useEffect(function () {
147
+ if (typeof value !== 'undefined') {
148
+ setInputValue(value);
149
+ }
150
+ }, [value]);
144
151
  var renderCalendar = React.useCallback(function () { return (
145
152
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
146
153
  React__default['default'].createElement("div", { onMouseDown: handleCalendarWrapperMouseDown },
147
- React__default['default'].createElement(Calendar, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: isCalendarValueValid ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays })))); }, [
154
+ React__default['default'].createElement(Calendar, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: checkInputValueIsValid(inputValue) ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays, events: events })))); }, [
148
155
  calendarProps,
149
156
  calendarValue,
157
+ checkInputValueIsValid,
150
158
  defaultMonth,
159
+ events,
151
160
  handleCalendarChange,
152
161
  handleCalendarWrapperMouseDown,
153
- isCalendarValueValid,
162
+ inputValue,
154
163
  maxDate,
155
164
  minDate,
156
165
  offDays,
@@ -160,9 +169,9 @@ var CalendarInput = React.forwardRef(function (_a, ref) {
160
169
  React__default['default'].createElement("div", { className: cn__default['default'](styles__default['default'].component, className, (_b = {},
161
170
  _b[styles__default['default'].block] = block,
162
171
  _b)), tabIndex: -1, onKeyDown: inputDisabled ? undefined : handleKeyDown, onClick: inputDisabled ? undefined : handleClick, onFocus: inputDisabled ? undefined : handleFocus, onBlur: handleBlur, "data-test-id": dataTestId },
163
- React__default['default'].createElement(coreComponentsDateInput.DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs__default['default']([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', rightAddons: React__default['default'].createElement(React__default['default'].Fragment, null,
172
+ React__default['default'].createElement(coreComponentsDateInput.DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs__default['default']([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', error: error, rightAddons: React__default['default'].createElement(React__default['default'].Fragment, null,
164
173
  rightAddons,
165
- React__default['default'].createElement(CalendarMIcon.CalendarMIcon, { className: styles__default['default'].calendarIcon })), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
174
+ shouldRenderPopover && (React__default['default'].createElement(CalendarMIcon.CalendarMIcon, { className: styles__default['default'].calendarIcon }))), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
166
175
  shouldRenderStatic && renderCalendar(),
167
176
  shouldRenderPopover && (React__default['default'].createElement(coreComponentsPopover.Popover, { open: open, useAnchorWidth: useAnchorWidth, anchorElement: inputWrapperRef.current, popperClassName: styles__default['default'].calendarContainer, className: popoverClassName, position: popoverPosition, offset: [0, 8], withTransition: false, preventFlip: preventFlip, zIndex: zIndexPopover }, renderCalendar()))));
168
177
  });
@@ -7,12 +7,14 @@ require('react');
7
7
  require('classnames');
8
8
  require('react-merge-refs');
9
9
  require('@alfalab/core-components-popover/dist/cssm');
10
+ require('@alfalab/icons-glyph/CalendarMIcon');
10
11
  require('@alfalab/core-components-date-input/dist/cssm');
11
12
  require('@alfalab/core-components-calendar/dist/cssm');
12
- require('@alfalab/icons-glyph/CalendarMIcon');
13
- require('./index.module.css');
14
- require('date-fns');
13
+ require('date-fns/parse');
14
+ require('date-fns/format');
15
+ require('date-fns/isSameDay');
15
16
  var utils = require('./utils.js');
17
+ require('./index.module.css');
16
18
 
17
19
 
18
20
 
@@ -23,6 +25,6 @@ exports.IS_BROWSER = utils.IS_BROWSER;
23
25
  exports.NATIVE_DATE_FORMAT = utils.NATIVE_DATE_FORMAT;
24
26
  exports.SUPPORTS_INPUT_TYPE_DATE = utils.SUPPORTS_INPUT_TYPE_DATE;
25
27
  exports.formatDate = utils.formatDate;
26
- exports.isCompleteDateInput = utils.isCompleteDateInput;
27
28
  exports.isInputDateSupported = utils.isInputDateSupported;
29
+ exports.isValidInputValue = utils.isValidInputValue;
28
30
  exports.parseDateString = utils.parseDateString;
@@ -3,11 +3,11 @@ declare const NATIVE_DATE_FORMAT = "yyyy-MM-dd";
3
3
  declare const DATE_MASK: (string | RegExp)[];
4
4
  declare const IS_BROWSER: boolean;
5
5
  declare const SUPPORTS_INPUT_TYPE_DATE: boolean;
6
- declare const isCompleteDateInput: (input: string) => boolean;
7
6
  declare const formatDate: (date: number | Date, dateFormat?: string) => string;
8
7
  declare const parseDateString: (value: string, dateFormat?: string) => Date;
9
8
  /**
10
9
  * Возвращает `true`, если поддерживается `input[type="date"]`
11
10
  */
12
11
  declare function isInputDateSupported(): boolean;
13
- export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, isCompleteDateInput, formatDate, parseDateString, isInputDateSupported };
12
+ declare const isValidInputValue: (newInputValue: string | undefined, minDate: number | undefined, maxDate: number | undefined, offDays?: (number | Date)[]) => boolean;
13
+ export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, formatDate, parseDateString, isInputDateSupported, isValidInputValue };
@@ -2,21 +2,30 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dateFns = require('date-fns');
5
+ var coreComponentsDateInput = require('@alfalab/core-components-date-input/dist/cssm');
6
+ var coreComponentsCalendar = require('@alfalab/core-components-calendar/dist/cssm');
7
+ var parse = require('date-fns/parse');
8
+ var format = require('date-fns/format');
9
+ var isSameDay = require('date-fns/isSameDay');
10
+
11
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+
13
+ var parse__default = /*#__PURE__*/_interopDefaultLegacy(parse);
14
+ var format__default = /*#__PURE__*/_interopDefaultLegacy(format);
15
+ var isSameDay__default = /*#__PURE__*/_interopDefaultLegacy(isSameDay);
6
16
 
7
17
  var DATE_FORMAT = 'dd.MM.yyyy';
8
18
  var NATIVE_DATE_FORMAT = 'yyyy-MM-dd';
9
19
  var DATE_MASK = [/\d/, /\d/, '.', /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/];
10
20
  var IS_BROWSER = typeof window !== 'undefined';
11
21
  var SUPPORTS_INPUT_TYPE_DATE = IS_BROWSER && isInputDateSupported();
12
- var isCompleteDateInput = function (input) { return input.length === DATE_MASK.length; };
13
22
  var formatDate = function (date, dateFormat) {
14
23
  if (dateFormat === void 0) { dateFormat = DATE_FORMAT; }
15
- return dateFns.format(date, dateFormat);
24
+ return format__default['default'](date, dateFormat);
16
25
  };
17
26
  var parseDateString = function (value, dateFormat) {
18
27
  if (dateFormat === void 0) { dateFormat = DATE_FORMAT; }
19
- return dateFns.parse(value, dateFormat, new Date());
28
+ return parse__default['default'](value, dateFormat, new Date());
20
29
  };
21
30
  /**
22
31
  * Возвращает `true`, если поддерживается `input[type="date"]`
@@ -28,6 +37,16 @@ function isInputDateSupported() {
28
37
  input.setAttribute('value', value);
29
38
  return input.value !== value;
30
39
  }
40
+ var isValidInputValue = function (newInputValue, minDate, maxDate, offDays) {
41
+ if (offDays === void 0) { offDays = []; }
42
+ if (!newInputValue)
43
+ return false;
44
+ var dateValue = parseDateString(newInputValue).getTime();
45
+ return Boolean(dateValue &&
46
+ coreComponentsDateInput.isCompleteDateInput(newInputValue) &&
47
+ coreComponentsCalendar.dateInLimits(dateValue, minDate, maxDate) &&
48
+ !offDays.some(function (offDay) { return isSameDay__default['default'](offDay, dateValue); }));
49
+ };
31
50
 
32
51
  exports.DATE_FORMAT = DATE_FORMAT;
33
52
  exports.DATE_MASK = DATE_MASK;
@@ -35,6 +54,6 @@ exports.IS_BROWSER = IS_BROWSER;
35
54
  exports.NATIVE_DATE_FORMAT = NATIVE_DATE_FORMAT;
36
55
  exports.SUPPORTS_INPUT_TYPE_DATE = SUPPORTS_INPUT_TYPE_DATE;
37
56
  exports.formatDate = formatDate;
38
- exports.isCompleteDateInput = isCompleteDateInput;
39
57
  exports.isInputDateSupported = isInputDateSupported;
58
+ exports.isValidInputValue = isValidInputValue;
40
59
  exports.parseDateString = parseDateString;
@@ -45,6 +45,10 @@ type CalendarInputProps = Omit<DateInputProps, 'onChange' | 'mobileMode'> & {
45
45
  * Максимальная дата, доступная для выбора (timestamp)
46
46
  */
47
47
  maxDate?: number;
48
+ /**
49
+ * Список событий
50
+ */
51
+ events?: Array<Date | number>;
48
52
  /**
49
53
  * Список выходных
50
54
  */
@@ -138,6 +142,10 @@ declare const CalendarInput: React.ForwardRefExoticComponent<Pick<DateInputProps
138
142
  * Максимальная дата, доступная для выбора (timestamp)
139
143
  */
140
144
  maxDate?: number | undefined;
145
+ /**
146
+ * Список событий
147
+ */
148
+ events?: (number | Date)[] | undefined;
141
149
  /**
142
150
  * Список выходных
143
151
  */
@@ -1,11 +1,13 @@
1
- import React, { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
1
+ import React, { forwardRef, useState, useCallback, useRef, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import mergeRefs from 'react-merge-refs';
4
4
  import { Popover } from '@alfalab/core-components-popover/dist/esm';
5
+ import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
5
6
  import { parseDateString, isCompleteDateInput, formatDate, DateInput } from '@alfalab/core-components-date-input/dist/esm';
6
7
  import { dateInLimits, Calendar } from '@alfalab/core-components-calendar/dist/esm';
7
- import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
8
- import 'date-fns';
8
+ import 'date-fns/parse';
9
+ import 'date-fns/format';
10
+ import 'date-fns/isSameDay';
9
11
  import { SUPPORTS_INPUT_TYPE_DATE } from './utils.js';
10
12
 
11
13
  /*! *****************************************************************************
@@ -47,24 +49,28 @@ function __rest(s, e) {
47
49
  return t;
48
50
  }
49
51
 
50
- var styles = {"component":"calendar-input__component_1vge6","block":"calendar-input__block_1vge6","calendarContainer":"calendar-input__calendarContainer_1vge6","calendarIcon":"calendar-input__calendarIcon_1vge6","nativeInput":"calendar-input__nativeInput_1vge6"};
52
+ var styles = {"component":"calendar-input__component_1ksty","block":"calendar-input__block_1ksty","calendarContainer":"calendar-input__calendarContainer_1ksty","calendarIcon":"calendar-input__calendarIcon_1ksty","nativeInput":"calendar-input__nativeInput_1ksty"};
51
53
  require('./index.css')
52
54
 
53
55
  var CalendarInput = forwardRef(function (_a, ref) {
54
56
  var _b;
55
- var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, preventFlip = _a.preventFlip, _l = _a.mobileMode, mobileMode = _l === void 0 ? 'popover' : _l, _m = _a.wrapperRef, wrapperRef = _m === void 0 ? null : _m, disabled = _a.disabled, onChange = _a.onChange, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _o = _a.Calendar, Calendar$1 = _o === void 0 ? Calendar : _o, _p = _a.popoverPosition, popoverPosition = _p === void 0 ? 'bottom-start' : _p, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons"]);
56
- var uncontrolled = value === undefined;
57
+ var _c = _a.block, block = _c === void 0 ? false : _c, className = _a.className, inputClassName = _a.inputClassName, popoverClassName = _a.popoverClassName, _d = _a.defaultOpen, defaultOpen = _d === void 0 ? false : _d, defaultMonth = _a.defaultMonth, _e = _a.defaultValue, defaultValue = _e === void 0 ? '' : _e, _f = _a.calendarPosition, calendarPosition = _f === void 0 ? 'popover' : _f, value = _a.value, dataTestId = _a.dataTestId, _g = _a.calendarProps, calendarProps = _g === void 0 ? {} : _g, _h = _a.minDate, minDate = _h === void 0 ? calendarProps.minDate : _h, _j = _a.maxDate, maxDate = _j === void 0 ? calendarProps.maxDate : _j, _k = _a.offDays, offDays = _k === void 0 ? calendarProps.offDays || [] : _k, _l = _a.events, events = _l === void 0 ? calendarProps.events || [] : _l, preventFlip = _a.preventFlip, _m = _a.mobileMode, mobileMode = _m === void 0 ? 'popover' : _m, _o = _a.wrapperRef, wrapperRef = _o === void 0 ? null : _o, disabled = _a.disabled, _p = _a.onChange, onChange = _p === void 0 ? function () { return null; } : _p, onInputChange = _a.onInputChange, onCalendarChange = _a.onCalendarChange, onKeyDown = _a.onKeyDown, readOnly = _a.readOnly, _q = _a.Calendar, Calendar$1 = _q === void 0 ? Calendar : _q, _r = _a.popoverPosition, popoverPosition = _r === void 0 ? 'bottom-start' : _r, zIndexPopover = _a.zIndexPopover, useAnchorWidth = _a.useAnchorWidth, rightAddons = _a.rightAddons, error = _a.error, restProps = __rest(_a, ["block", "className", "inputClassName", "popoverClassName", "defaultOpen", "defaultMonth", "defaultValue", "calendarPosition", "value", "dataTestId", "calendarProps", "minDate", "maxDate", "offDays", "events", "preventFlip", "mobileMode", "wrapperRef", "disabled", "onChange", "onInputChange", "onCalendarChange", "onKeyDown", "readOnly", "Calendar", "popoverPosition", "zIndexPopover", "useAnchorWidth", "rightAddons", "error"]);
57
58
  var shouldRenderNative = SUPPORTS_INPUT_TYPE_DATE && mobileMode === 'native';
58
59
  var shouldRenderOnlyInput = mobileMode === 'input';
59
60
  var shouldRenderStatic = calendarPosition === 'static' && !shouldRenderOnlyInput;
60
61
  var shouldRenderPopover = calendarPosition === 'popover' && !shouldRenderNative && !shouldRenderOnlyInput;
61
- var _q = useState(false), open = _q[0], setOpen = _q[1];
62
- var _r = useState(defaultValue), stateValue = _r[0], setStateValue = _r[1];
63
- var inputValue = uncontrolled ? stateValue : value;
62
+ var _s = useState(false), open = _s[0], setOpen = _s[1];
63
+ var _t = useState(value || defaultValue), inputValue = _t[0], setInputValue = _t[1];
64
64
  var calendarValue = inputValue ? parseDateString(inputValue).getTime() : undefined;
65
- var isCalendarValueValid = calendarValue &&
66
- dateInLimits(calendarValue, minDate, maxDate) &&
67
- !offDays.includes(calendarValue);
65
+ var checkInputValueIsValid = useCallback(function (newInputValue) {
66
+ if (!newInputValue || error)
67
+ return false;
68
+ var dateValue = parseDateString(newInputValue).getTime();
69
+ return (dateValue &&
70
+ isCompleteDateInput(newInputValue) &&
71
+ dateInLimits(dateValue, minDate, maxDate) &&
72
+ !offDays.includes(dateValue));
73
+ }, [error, maxDate, minDate, offDays]);
68
74
  var inputDisabled = disabled || readOnly;
69
75
  var inputWrapperRef = useRef(null);
70
76
  var calendarRef = useRef(null);
@@ -109,18 +115,14 @@ var CalendarInput = forwardRef(function (_a, ref) {
109
115
  if (initiator === 'calendar' && onCalendarChange) {
110
116
  onCalendarChange(newDate.getTime());
111
117
  }
118
+ setInputValue(newValue);
112
119
  if (shouldChange) {
113
- if (uncontrolled) {
114
- setStateValue(newValue);
115
- }
116
- if (onChange) {
117
- onChange(event, { date: newDate, value: newValue });
118
- }
120
+ onChange(event, { date: newDate, value: newValue });
119
121
  }
120
- }, [onCalendarChange, onChange, onInputChange, uncontrolled]);
122
+ }, [onCalendarChange, onChange, onInputChange]);
121
123
  var handleInputChange = useCallback(function (event, payload) {
122
- changeHandler(event, payload.value, payload.date, 'input', !payload.value || isCompleteDateInput(payload.value));
123
- }, [changeHandler]);
124
+ changeHandler(event, payload.value, payload.date, 'input', !payload.value || checkInputValueIsValid(payload.value));
125
+ }, [changeHandler, checkInputValueIsValid]);
124
126
  var handleCalendarChange = useCallback(function (date) {
125
127
  changeHandler(null, formatDate(date), new Date(date), 'calendar');
126
128
  setOpen(false);
@@ -132,16 +134,23 @@ var CalendarInput = forwardRef(function (_a, ref) {
132
134
  useEffect(function () {
133
135
  setOpen(defaultOpen);
134
136
  }, [defaultOpen]);
137
+ useEffect(function () {
138
+ if (typeof value !== 'undefined') {
139
+ setInputValue(value);
140
+ }
141
+ }, [value]);
135
142
  var renderCalendar = useCallback(function () { return (
136
143
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
137
144
  React.createElement("div", { onMouseDown: handleCalendarWrapperMouseDown },
138
- React.createElement(Calendar$1, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: isCalendarValueValid ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays })))); }, [
145
+ React.createElement(Calendar$1, __assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: checkInputValueIsValid(inputValue) ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays, events: events })))); }, [
139
146
  calendarProps,
140
147
  calendarValue,
148
+ checkInputValueIsValid,
141
149
  defaultMonth,
150
+ events,
142
151
  handleCalendarChange,
143
152
  handleCalendarWrapperMouseDown,
144
- isCalendarValueValid,
153
+ inputValue,
145
154
  maxDate,
146
155
  minDate,
147
156
  offDays,
@@ -151,9 +160,9 @@ var CalendarInput = forwardRef(function (_a, ref) {
151
160
  React.createElement("div", { className: cn(styles.component, className, (_b = {},
152
161
  _b[styles.block] = block,
153
162
  _b)), tabIndex: -1, onKeyDown: inputDisabled ? undefined : handleKeyDown, onClick: inputDisabled ? undefined : handleClick, onFocus: inputDisabled ? undefined : handleFocus, onBlur: handleBlur, "data-test-id": dataTestId },
154
- React.createElement(DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', rightAddons: React.createElement(React.Fragment, null,
163
+ React.createElement(DateInput, __assign({}, restProps, { ref: ref, wrapperRef: mergeRefs([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', error: error, rightAddons: React.createElement(React.Fragment, null,
155
164
  rightAddons,
156
- React.createElement(CalendarMIcon, { className: styles.calendarIcon })), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
165
+ shouldRenderPopover && (React.createElement(CalendarMIcon, { className: styles.calendarIcon }))), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
157
166
  shouldRenderStatic && renderCalendar(),
158
167
  shouldRenderPopover && (React.createElement(Popover, { open: open, useAnchorWidth: useAnchorWidth, anchorElement: inputWrapperRef.current, popperClassName: styles.calendarContainer, className: popoverClassName, position: popoverPosition, offset: [0, 8], withTransition: false, preventFlip: preventFlip, zIndex: zIndexPopover }, renderCalendar()))));
159
168
  });
@@ -1,4 +1,4 @@
1
- /* hash: 1saz8 */
1
+ /* hash: codnr */
2
2
  :root {
3
3
  --color-light-graphic-primary: #0b1f35;
4
4
  }
@@ -41,36 +41,36 @@
41
41
  --calendar-input-icon-color: var(--color-light-graphic-primary);
42
42
  --calendar-input-popover-border-radius: 0 0 var(--border-radius-s) var(--border-radius-s);
43
43
  }
44
- .calendar-input__component_1vge6 {
44
+ .calendar-input__component_1ksty {
45
45
  display: inline-block;
46
46
  outline: none;
47
47
  position: relative;
48
48
  }
49
- .calendar-input__block_1vge6 {
49
+ .calendar-input__block_1ksty {
50
50
  width: 100%;
51
51
  }
52
- .calendar-input__calendarContainer_1vge6 {
52
+ .calendar-input__calendarContainer_1ksty {
53
53
  display: inline-block;
54
54
  box-sizing: border-box;
55
55
  box-shadow: var(--shadow-s);
56
56
  border-radius: var(--calendar-input-popover-border-radius)
57
57
  }
58
58
  @media (max-width: 374px) {
59
- .calendar-input__calendarContainer_1vge6 {
59
+ .calendar-input__calendarContainer_1ksty {
60
60
  width: 100%;
61
61
  min-width: 288px
62
62
  }
63
63
  }
64
- .calendar-input__calendarIcon_1vge6 {
64
+ .calendar-input__calendarIcon_1ksty {
65
65
  width: 24px;
66
66
  height: 24px;
67
67
  display: block;
68
68
  color: var(--calendar-input-icon-color)
69
69
  }
70
- .calendar-input__calendarIcon_1vge6:not(:only-child) {
70
+ .calendar-input__calendarIcon_1ksty:not(:only-child) {
71
71
  margin-right: var(--gap-2xs);
72
72
  }
73
- .calendar-input__nativeInput_1vge6 {
73
+ .calendar-input__nativeInput_1ksty {
74
74
  opacity: 0;
75
75
  position: absolute;
76
76
  top: 0;
@@ -81,9 +81,9 @@
81
81
  appearance: none;
82
82
  z-index: 1
83
83
  }
84
- .calendar-input__nativeInput_1vge6::-webkit-calendar-picker-indicator {
84
+ .calendar-input__nativeInput_1ksty::-webkit-calendar-picker-indicator {
85
85
  display: none;
86
86
  }
87
- .calendar-input__nativeInput_1vge6::-webkit-inner-spin-button {
87
+ .calendar-input__nativeInput_1ksty::-webkit-inner-spin-button {
88
88
  display: none;
89
89
  }
package/dist/esm/index.js CHANGED
@@ -3,8 +3,10 @@ import 'react';
3
3
  import 'classnames';
4
4
  import 'react-merge-refs';
5
5
  import '@alfalab/core-components-popover/dist/esm';
6
+ import '@alfalab/icons-glyph/CalendarMIcon';
6
7
  import '@alfalab/core-components-date-input/dist/esm';
7
8
  import '@alfalab/core-components-calendar/dist/esm';
8
- import '@alfalab/icons-glyph/CalendarMIcon';
9
- import 'date-fns';
10
- export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isCompleteDateInput, isInputDateSupported, parseDateString } from './utils.js';
9
+ import 'date-fns/parse';
10
+ import 'date-fns/format';
11
+ import 'date-fns/isSameDay';
12
+ export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString } from './utils.js';
@@ -3,11 +3,11 @@ declare const NATIVE_DATE_FORMAT = "yyyy-MM-dd";
3
3
  declare const DATE_MASK: (string | RegExp)[];
4
4
  declare const IS_BROWSER: boolean;
5
5
  declare const SUPPORTS_INPUT_TYPE_DATE: boolean;
6
- declare const isCompleteDateInput: (input: string) => boolean;
7
6
  declare const formatDate: (date: number | Date, dateFormat?: string) => string;
8
7
  declare const parseDateString: (value: string, dateFormat?: string) => Date;
9
8
  /**
10
9
  * Возвращает `true`, если поддерживается `input[type="date"]`
11
10
  */
12
11
  declare function isInputDateSupported(): boolean;
13
- export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, isCompleteDateInput, formatDate, parseDateString, isInputDateSupported };
12
+ declare const isValidInputValue: (newInputValue: string | undefined, minDate: number | undefined, maxDate: number | undefined, offDays?: (number | Date)[]) => boolean;
13
+ export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, formatDate, parseDateString, isInputDateSupported, isValidInputValue };
package/dist/esm/utils.js CHANGED
@@ -1,11 +1,14 @@
1
- import { format, parse } from 'date-fns';
1
+ import { isCompleteDateInput } from '@alfalab/core-components-date-input/dist/esm';
2
+ import { dateInLimits } from '@alfalab/core-components-calendar/dist/esm';
3
+ import parse from 'date-fns/parse';
4
+ import format from 'date-fns/format';
5
+ import isSameDay from 'date-fns/isSameDay';
2
6
 
3
7
  var DATE_FORMAT = 'dd.MM.yyyy';
4
8
  var NATIVE_DATE_FORMAT = 'yyyy-MM-dd';
5
9
  var DATE_MASK = [/\d/, /\d/, '.', /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/];
6
10
  var IS_BROWSER = typeof window !== 'undefined';
7
11
  var SUPPORTS_INPUT_TYPE_DATE = IS_BROWSER && isInputDateSupported();
8
- var isCompleteDateInput = function (input) { return input.length === DATE_MASK.length; };
9
12
  var formatDate = function (date, dateFormat) {
10
13
  if (dateFormat === void 0) { dateFormat = DATE_FORMAT; }
11
14
  return format(date, dateFormat);
@@ -24,5 +27,15 @@ function isInputDateSupported() {
24
27
  input.setAttribute('value', value);
25
28
  return input.value !== value;
26
29
  }
30
+ var isValidInputValue = function (newInputValue, minDate, maxDate, offDays) {
31
+ if (offDays === void 0) { offDays = []; }
32
+ if (!newInputValue)
33
+ return false;
34
+ var dateValue = parseDateString(newInputValue).getTime();
35
+ return Boolean(dateValue &&
36
+ isCompleteDateInput(newInputValue) &&
37
+ dateInLimits(dateValue, minDate, maxDate) &&
38
+ !offDays.some(function (offDay) { return isSameDay(offDay, dateValue); }));
39
+ };
27
40
 
28
- export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isCompleteDateInput, isInputDateSupported, parseDateString };
41
+ export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString };
package/dist/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: 1saz8 */
1
+ /* hash: codnr */
2
2
  :root {
3
3
  --color-light-graphic-primary: #0b1f35;
4
4
  }
@@ -41,36 +41,36 @@
41
41
  --calendar-input-icon-color: var(--color-light-graphic-primary);
42
42
  --calendar-input-popover-border-radius: 0 0 var(--border-radius-s) var(--border-radius-s);
43
43
  }
44
- .calendar-input__component_1vge6 {
44
+ .calendar-input__component_1ksty {
45
45
  display: inline-block;
46
46
  outline: none;
47
47
  position: relative;
48
48
  }
49
- .calendar-input__block_1vge6 {
49
+ .calendar-input__block_1ksty {
50
50
  width: 100%;
51
51
  }
52
- .calendar-input__calendarContainer_1vge6 {
52
+ .calendar-input__calendarContainer_1ksty {
53
53
  display: inline-block;
54
54
  box-sizing: border-box;
55
55
  box-shadow: var(--shadow-s);
56
56
  border-radius: var(--calendar-input-popover-border-radius)
57
57
  }
58
58
  @media (max-width: 374px) {
59
- .calendar-input__calendarContainer_1vge6 {
59
+ .calendar-input__calendarContainer_1ksty {
60
60
  width: 100%;
61
61
  min-width: 288px
62
62
  }
63
63
  }
64
- .calendar-input__calendarIcon_1vge6 {
64
+ .calendar-input__calendarIcon_1ksty {
65
65
  width: 24px;
66
66
  height: 24px;
67
67
  display: block;
68
68
  color: var(--calendar-input-icon-color)
69
69
  }
70
- .calendar-input__calendarIcon_1vge6:not(:only-child) {
70
+ .calendar-input__calendarIcon_1ksty:not(:only-child) {
71
71
  margin-right: var(--gap-2xs);
72
72
  }
73
- .calendar-input__nativeInput_1vge6 {
73
+ .calendar-input__nativeInput_1ksty {
74
74
  opacity: 0;
75
75
  position: absolute;
76
76
  top: 0;
@@ -81,9 +81,9 @@
81
81
  appearance: none;
82
82
  z-index: 1
83
83
  }
84
- .calendar-input__nativeInput_1vge6::-webkit-calendar-picker-indicator {
84
+ .calendar-input__nativeInput_1ksty::-webkit-calendar-picker-indicator {
85
85
  display: none;
86
86
  }
87
- .calendar-input__nativeInput_1vge6::-webkit-inner-spin-button {
87
+ .calendar-input__nativeInput_1ksty::-webkit-inner-spin-button {
88
88
  display: none;
89
89
  }
package/dist/index.js CHANGED
@@ -7,10 +7,12 @@ require('react');
7
7
  require('classnames');
8
8
  require('react-merge-refs');
9
9
  require('@alfalab/core-components-popover');
10
+ require('@alfalab/icons-glyph/CalendarMIcon');
10
11
  require('@alfalab/core-components-date-input');
11
12
  require('@alfalab/core-components-calendar');
12
- require('@alfalab/icons-glyph/CalendarMIcon');
13
- require('date-fns');
13
+ require('date-fns/parse');
14
+ require('date-fns/format');
15
+ require('date-fns/isSameDay');
14
16
  var utils = require('./utils.js');
15
17
 
16
18
 
@@ -22,6 +24,6 @@ exports.IS_BROWSER = utils.IS_BROWSER;
22
24
  exports.NATIVE_DATE_FORMAT = utils.NATIVE_DATE_FORMAT;
23
25
  exports.SUPPORTS_INPUT_TYPE_DATE = utils.SUPPORTS_INPUT_TYPE_DATE;
24
26
  exports.formatDate = utils.formatDate;
25
- exports.isCompleteDateInput = utils.isCompleteDateInput;
26
27
  exports.isInputDateSupported = utils.isInputDateSupported;
28
+ exports.isValidInputValue = utils.isValidInputValue;
27
29
  exports.parseDateString = utils.parseDateString;
@@ -45,6 +45,10 @@ type CalendarInputProps = Omit<DateInputProps, 'onChange' | 'mobileMode'> & {
45
45
  * Максимальная дата, доступная для выбора (timestamp)
46
46
  */
47
47
  maxDate?: number;
48
+ /**
49
+ * Список событий
50
+ */
51
+ events?: Array<Date | number>;
48
52
  /**
49
53
  * Список выходных
50
54
  */
@@ -138,6 +142,10 @@ declare const CalendarInput: React.ForwardRefExoticComponent<Pick<DateInputProps
138
142
  * Максимальная дата, доступная для выбора (timestamp)
139
143
  */
140
144
  maxDate?: number | undefined;
145
+ /**
146
+ * Список событий
147
+ */
148
+ events?: (number | Date)[] | undefined;
141
149
  /**
142
150
  * Список выходных
143
151
  */
@@ -1,29 +1,35 @@
1
- import React, { forwardRef, useState, useRef, useCallback, useEffect } from 'react';
1
+ import React, { forwardRef, useState, useCallback, useRef, useEffect } from 'react';
2
2
  import cn from 'classnames';
3
3
  import mergeRefs from 'react-merge-refs';
4
4
  import { Popover } from '@alfalab/core-components-popover/dist/modern';
5
+ import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
5
6
  import { parseDateString, isCompleteDateInput, formatDate, DateInput } from '@alfalab/core-components-date-input/dist/modern';
6
7
  import { Calendar, dateInLimits } from '@alfalab/core-components-calendar/dist/modern';
7
- import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
8
- import 'date-fns';
8
+ import 'date-fns/parse';
9
+ import 'date-fns/format';
10
+ import 'date-fns/isSameDay';
9
11
  import { SUPPORTS_INPUT_TYPE_DATE } from './utils.js';
10
12
 
11
- var styles = {"component":"calendar-input__component_1vge6","block":"calendar-input__block_1vge6","calendarContainer":"calendar-input__calendarContainer_1vge6","calendarIcon":"calendar-input__calendarIcon_1vge6","nativeInput":"calendar-input__nativeInput_1vge6"};
13
+ var styles = {"component":"calendar-input__component_1ksty","block":"calendar-input__block_1ksty","calendarContainer":"calendar-input__calendarContainer_1ksty","calendarIcon":"calendar-input__calendarIcon_1ksty","nativeInput":"calendar-input__nativeInput_1ksty"};
12
14
  require('./index.css')
13
15
 
14
- const CalendarInput = forwardRef(({ block = false, className, inputClassName, popoverClassName, defaultOpen = false, defaultMonth, defaultValue = '', calendarPosition = 'popover', value, dataTestId, calendarProps = {}, minDate = calendarProps.minDate, maxDate = calendarProps.maxDate, offDays = calendarProps.offDays || [], preventFlip, mobileMode = 'popover', wrapperRef = null, disabled, onChange, onInputChange, onCalendarChange, onKeyDown, readOnly, Calendar: Calendar$1 = Calendar, popoverPosition = 'bottom-start', zIndexPopover, useAnchorWidth, rightAddons, ...restProps }, ref) => {
15
- const uncontrolled = value === undefined;
16
+ const CalendarInput = forwardRef(({ block = false, className, inputClassName, popoverClassName, defaultOpen = false, defaultMonth, defaultValue = '', calendarPosition = 'popover', value, dataTestId, calendarProps = {}, minDate = calendarProps.minDate, maxDate = calendarProps.maxDate, offDays = calendarProps.offDays || [], events = calendarProps.events || [], preventFlip, mobileMode = 'popover', wrapperRef = null, disabled, onChange = () => null, onInputChange, onCalendarChange, onKeyDown, readOnly, Calendar: Calendar$1 = Calendar, popoverPosition = 'bottom-start', zIndexPopover, useAnchorWidth, rightAddons, error, ...restProps }, ref) => {
16
17
  const shouldRenderNative = SUPPORTS_INPUT_TYPE_DATE && mobileMode === 'native';
17
18
  const shouldRenderOnlyInput = mobileMode === 'input';
18
19
  const shouldRenderStatic = calendarPosition === 'static' && !shouldRenderOnlyInput;
19
20
  const shouldRenderPopover = calendarPosition === 'popover' && !shouldRenderNative && !shouldRenderOnlyInput;
20
21
  const [open, setOpen] = useState(false);
21
- const [stateValue, setStateValue] = useState(defaultValue);
22
- const inputValue = uncontrolled ? stateValue : value;
22
+ const [inputValue, setInputValue] = useState(value || defaultValue);
23
23
  const calendarValue = inputValue ? parseDateString(inputValue).getTime() : undefined;
24
- const isCalendarValueValid = calendarValue &&
25
- dateInLimits(calendarValue, minDate, maxDate) &&
26
- !offDays.includes(calendarValue);
24
+ const checkInputValueIsValid = useCallback((newInputValue) => {
25
+ if (!newInputValue || error)
26
+ return false;
27
+ const dateValue = parseDateString(newInputValue).getTime();
28
+ return (dateValue &&
29
+ isCompleteDateInput(newInputValue) &&
30
+ dateInLimits(dateValue, minDate, maxDate) &&
31
+ !offDays.includes(dateValue));
32
+ }, [error, maxDate, minDate, offDays]);
27
33
  const inputDisabled = disabled || readOnly;
28
34
  const inputWrapperRef = useRef(null);
29
35
  const calendarRef = useRef(null);
@@ -66,18 +72,14 @@ const CalendarInput = forwardRef(({ block = false, className, inputClassName, po
66
72
  if (initiator === 'calendar' && onCalendarChange) {
67
73
  onCalendarChange(newDate.getTime());
68
74
  }
75
+ setInputValue(newValue);
69
76
  if (shouldChange) {
70
- if (uncontrolled) {
71
- setStateValue(newValue);
72
- }
73
- if (onChange) {
74
- onChange(event, { date: newDate, value: newValue });
75
- }
77
+ onChange(event, { date: newDate, value: newValue });
76
78
  }
77
- }, [onCalendarChange, onChange, onInputChange, uncontrolled]);
79
+ }, [onCalendarChange, onChange, onInputChange]);
78
80
  const handleInputChange = useCallback((event, payload) => {
79
- changeHandler(event, payload.value, payload.date, 'input', !payload.value || isCompleteDateInput(payload.value));
80
- }, [changeHandler]);
81
+ changeHandler(event, payload.value, payload.date, 'input', !payload.value || checkInputValueIsValid(payload.value));
82
+ }, [changeHandler, checkInputValueIsValid]);
81
83
  const handleCalendarChange = useCallback(date => {
82
84
  changeHandler(null, formatDate(date), new Date(date), 'calendar');
83
85
  setOpen(false);
@@ -89,16 +91,23 @@ const CalendarInput = forwardRef(({ block = false, className, inputClassName, po
89
91
  useEffect(() => {
90
92
  setOpen(defaultOpen);
91
93
  }, [defaultOpen]);
94
+ useEffect(() => {
95
+ if (typeof value !== 'undefined') {
96
+ setInputValue(value);
97
+ }
98
+ }, [value]);
92
99
  const renderCalendar = useCallback(() => (
93
100
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
94
101
  React.createElement("div", { onMouseDown: handleCalendarWrapperMouseDown },
95
- React.createElement(Calendar$1, Object.assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: isCalendarValueValid ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays })))), [
102
+ React.createElement(Calendar$1, Object.assign({}, calendarProps, { ref: calendarRef, defaultMonth: defaultMonth, value: checkInputValueIsValid(inputValue) ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays, events: events })))), [
96
103
  calendarProps,
97
104
  calendarValue,
105
+ checkInputValueIsValid,
98
106
  defaultMonth,
107
+ events,
99
108
  handleCalendarChange,
100
109
  handleCalendarWrapperMouseDown,
101
- isCalendarValueValid,
110
+ inputValue,
102
111
  maxDate,
103
112
  minDate,
104
113
  offDays,
@@ -108,9 +117,9 @@ const CalendarInput = forwardRef(({ block = false, className, inputClassName, po
108
117
  React.createElement("div", { className: cn(styles.component, className, {
109
118
  [styles.block]: block,
110
119
  }), tabIndex: -1, onKeyDown: inputDisabled ? undefined : handleKeyDown, onClick: inputDisabled ? undefined : handleClick, onFocus: inputDisabled ? undefined : handleFocus, onBlur: handleBlur, "data-test-id": dataTestId },
111
- React.createElement(DateInput, Object.assign({}, restProps, { ref: ref, wrapperRef: mergeRefs([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', rightAddons: React.createElement(React.Fragment, null,
120
+ React.createElement(DateInput, Object.assign({}, restProps, { ref: ref, wrapperRef: mergeRefs([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', error: error, rightAddons: React.createElement(React.Fragment, null,
112
121
  rightAddons,
113
- React.createElement(CalendarMIcon, { className: styles.calendarIcon })), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
122
+ shouldRenderPopover && (React.createElement(CalendarMIcon, { className: styles.calendarIcon }))), onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true })),
114
123
  shouldRenderStatic && renderCalendar(),
115
124
  shouldRenderPopover && (React.createElement(Popover, { open: open, useAnchorWidth: useAnchorWidth, anchorElement: inputWrapperRef.current, popperClassName: styles.calendarContainer, className: popoverClassName, position: popoverPosition, offset: [0, 8], withTransition: false, preventFlip: preventFlip, zIndex: zIndexPopover }, renderCalendar()))));
116
125
  });
@@ -1,4 +1,4 @@
1
- /* hash: 1saz8 */
1
+ /* hash: codnr */
2
2
  :root {
3
3
  --color-light-graphic-primary: #0b1f35;
4
4
  }
@@ -41,36 +41,36 @@
41
41
  --calendar-input-icon-color: var(--color-light-graphic-primary);
42
42
  --calendar-input-popover-border-radius: 0 0 var(--border-radius-s) var(--border-radius-s);
43
43
  }
44
- .calendar-input__component_1vge6 {
44
+ .calendar-input__component_1ksty {
45
45
  display: inline-block;
46
46
  outline: none;
47
47
  position: relative;
48
48
  }
49
- .calendar-input__block_1vge6 {
49
+ .calendar-input__block_1ksty {
50
50
  width: 100%;
51
51
  }
52
- .calendar-input__calendarContainer_1vge6 {
52
+ .calendar-input__calendarContainer_1ksty {
53
53
  display: inline-block;
54
54
  box-sizing: border-box;
55
55
  box-shadow: var(--shadow-s);
56
56
  border-radius: var(--calendar-input-popover-border-radius)
57
57
  }
58
58
  @media (max-width: 374px) {
59
- .calendar-input__calendarContainer_1vge6 {
59
+ .calendar-input__calendarContainer_1ksty {
60
60
  width: 100%;
61
61
  min-width: 288px
62
62
  }
63
63
  }
64
- .calendar-input__calendarIcon_1vge6 {
64
+ .calendar-input__calendarIcon_1ksty {
65
65
  width: 24px;
66
66
  height: 24px;
67
67
  display: block;
68
68
  color: var(--calendar-input-icon-color)
69
69
  }
70
- .calendar-input__calendarIcon_1vge6:not(:only-child) {
70
+ .calendar-input__calendarIcon_1ksty:not(:only-child) {
71
71
  margin-right: var(--gap-2xs);
72
72
  }
73
- .calendar-input__nativeInput_1vge6 {
73
+ .calendar-input__nativeInput_1ksty {
74
74
  opacity: 0;
75
75
  position: absolute;
76
76
  top: 0;
@@ -81,9 +81,9 @@
81
81
  appearance: none;
82
82
  z-index: 1
83
83
  }
84
- .calendar-input__nativeInput_1vge6::-webkit-calendar-picker-indicator {
84
+ .calendar-input__nativeInput_1ksty::-webkit-calendar-picker-indicator {
85
85
  display: none;
86
86
  }
87
- .calendar-input__nativeInput_1vge6::-webkit-inner-spin-button {
87
+ .calendar-input__nativeInput_1ksty::-webkit-inner-spin-button {
88
88
  display: none;
89
89
  }
@@ -2,9 +2,11 @@ import 'react';
2
2
  import 'classnames';
3
3
  import 'react-merge-refs';
4
4
  import '@alfalab/core-components-popover/dist/modern';
5
+ import '@alfalab/icons-glyph/CalendarMIcon';
5
6
  import '@alfalab/core-components-date-input/dist/modern';
6
7
  import '@alfalab/core-components-calendar/dist/modern';
7
- import '@alfalab/icons-glyph/CalendarMIcon';
8
+ import 'date-fns/parse';
9
+ import 'date-fns/format';
10
+ import 'date-fns/isSameDay';
11
+ export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString } from './utils.js';
8
12
  export { CalendarInput } from './Component.js';
9
- import 'date-fns';
10
- export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isCompleteDateInput, isInputDateSupported, parseDateString } from './utils.js';
@@ -3,11 +3,11 @@ declare const NATIVE_DATE_FORMAT = "yyyy-MM-dd";
3
3
  declare const DATE_MASK: (string | RegExp)[];
4
4
  declare const IS_BROWSER: boolean;
5
5
  declare const SUPPORTS_INPUT_TYPE_DATE: boolean;
6
- declare const isCompleteDateInput: (input: string) => boolean;
7
6
  declare const formatDate: (date: number | Date, dateFormat?: string) => string;
8
7
  declare const parseDateString: (value: string, dateFormat?: string) => Date;
9
8
  /**
10
9
  * Возвращает `true`, если поддерживается `input[type="date"]`
11
10
  */
12
11
  declare function isInputDateSupported(): boolean;
13
- export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, isCompleteDateInput, formatDate, parseDateString, isInputDateSupported };
12
+ declare const isValidInputValue: (newInputValue: string | undefined, minDate: number | undefined, maxDate: number | undefined, offDays?: (number | Date)[]) => boolean;
13
+ export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, formatDate, parseDateString, isInputDateSupported, isValidInputValue };
@@ -1,11 +1,14 @@
1
- import { format, parse } from 'date-fns';
1
+ import { isCompleteDateInput } from '@alfalab/core-components-date-input/dist/modern';
2
+ import { dateInLimits } from '@alfalab/core-components-calendar/dist/modern';
3
+ import parse from 'date-fns/parse';
4
+ import format from 'date-fns/format';
5
+ import isSameDay from 'date-fns/isSameDay';
2
6
 
3
7
  const DATE_FORMAT = 'dd.MM.yyyy';
4
8
  const NATIVE_DATE_FORMAT = 'yyyy-MM-dd';
5
9
  const DATE_MASK = [/\d/, /\d/, '.', /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/];
6
10
  const IS_BROWSER = typeof window !== 'undefined';
7
11
  const SUPPORTS_INPUT_TYPE_DATE = IS_BROWSER && isInputDateSupported();
8
- const isCompleteDateInput = (input) => input.length === DATE_MASK.length;
9
12
  const formatDate = (date, dateFormat = DATE_FORMAT) => format(date, dateFormat);
10
13
  const parseDateString = (value, dateFormat = DATE_FORMAT) => parse(value, dateFormat, new Date());
11
14
  /**
@@ -18,5 +21,14 @@ function isInputDateSupported() {
18
21
  input.setAttribute('value', value);
19
22
  return input.value !== value;
20
23
  }
24
+ const isValidInputValue = (newInputValue, minDate, maxDate, offDays = []) => {
25
+ if (!newInputValue)
26
+ return false;
27
+ const dateValue = parseDateString(newInputValue).getTime();
28
+ return Boolean(dateValue &&
29
+ isCompleteDateInput(newInputValue) &&
30
+ dateInLimits(dateValue, minDate, maxDate) &&
31
+ !offDays.some(offDay => isSameDay(offDay, dateValue)));
32
+ };
21
33
 
22
- export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isCompleteDateInput, isInputDateSupported, parseDateString };
34
+ export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString };
package/dist/utils.d.ts CHANGED
@@ -3,11 +3,11 @@ declare const NATIVE_DATE_FORMAT = "yyyy-MM-dd";
3
3
  declare const DATE_MASK: (string | RegExp)[];
4
4
  declare const IS_BROWSER: boolean;
5
5
  declare const SUPPORTS_INPUT_TYPE_DATE: boolean;
6
- declare const isCompleteDateInput: (input: string) => boolean;
7
6
  declare const formatDate: (date: number | Date, dateFormat?: string) => string;
8
7
  declare const parseDateString: (value: string, dateFormat?: string) => Date;
9
8
  /**
10
9
  * Возвращает `true`, если поддерживается `input[type="date"]`
11
10
  */
12
11
  declare function isInputDateSupported(): boolean;
13
- export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, isCompleteDateInput, formatDate, parseDateString, isInputDateSupported };
12
+ declare const isValidInputValue: (newInputValue: string | undefined, minDate: number | undefined, maxDate: number | undefined, offDays?: (number | Date)[]) => boolean;
13
+ export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, formatDate, parseDateString, isInputDateSupported, isValidInputValue };
package/dist/utils.js CHANGED
@@ -2,21 +2,30 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dateFns = require('date-fns');
5
+ var coreComponentsDateInput = require('@alfalab/core-components-date-input');
6
+ var coreComponentsCalendar = require('@alfalab/core-components-calendar');
7
+ var parse = require('date-fns/parse');
8
+ var format = require('date-fns/format');
9
+ var isSameDay = require('date-fns/isSameDay');
10
+
11
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+
13
+ var parse__default = /*#__PURE__*/_interopDefaultLegacy(parse);
14
+ var format__default = /*#__PURE__*/_interopDefaultLegacy(format);
15
+ var isSameDay__default = /*#__PURE__*/_interopDefaultLegacy(isSameDay);
6
16
 
7
17
  var DATE_FORMAT = 'dd.MM.yyyy';
8
18
  var NATIVE_DATE_FORMAT = 'yyyy-MM-dd';
9
19
  var DATE_MASK = [/\d/, /\d/, '.', /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/];
10
20
  var IS_BROWSER = typeof window !== 'undefined';
11
21
  var SUPPORTS_INPUT_TYPE_DATE = IS_BROWSER && isInputDateSupported();
12
- var isCompleteDateInput = function (input) { return input.length === DATE_MASK.length; };
13
22
  var formatDate = function (date, dateFormat) {
14
23
  if (dateFormat === void 0) { dateFormat = DATE_FORMAT; }
15
- return dateFns.format(date, dateFormat);
24
+ return format__default['default'](date, dateFormat);
16
25
  };
17
26
  var parseDateString = function (value, dateFormat) {
18
27
  if (dateFormat === void 0) { dateFormat = DATE_FORMAT; }
19
- return dateFns.parse(value, dateFormat, new Date());
28
+ return parse__default['default'](value, dateFormat, new Date());
20
29
  };
21
30
  /**
22
31
  * Возвращает `true`, если поддерживается `input[type="date"]`
@@ -28,6 +37,16 @@ function isInputDateSupported() {
28
37
  input.setAttribute('value', value);
29
38
  return input.value !== value;
30
39
  }
40
+ var isValidInputValue = function (newInputValue, minDate, maxDate, offDays) {
41
+ if (offDays === void 0) { offDays = []; }
42
+ if (!newInputValue)
43
+ return false;
44
+ var dateValue = parseDateString(newInputValue).getTime();
45
+ return Boolean(dateValue &&
46
+ coreComponentsDateInput.isCompleteDateInput(newInputValue) &&
47
+ coreComponentsCalendar.dateInLimits(dateValue, minDate, maxDate) &&
48
+ !offDays.some(function (offDay) { return isSameDay__default['default'](offDay, dateValue); }));
49
+ };
31
50
 
32
51
  exports.DATE_FORMAT = DATE_FORMAT;
33
52
  exports.DATE_MASK = DATE_MASK;
@@ -35,6 +54,6 @@ exports.IS_BROWSER = IS_BROWSER;
35
54
  exports.NATIVE_DATE_FORMAT = NATIVE_DATE_FORMAT;
36
55
  exports.SUPPORTS_INPUT_TYPE_DATE = SUPPORTS_INPUT_TYPE_DATE;
37
56
  exports.formatDate = formatDate;
38
- exports.isCompleteDateInput = isCompleteDateInput;
39
57
  exports.isInputDateSupported = isInputDateSupported;
58
+ exports.isValidInputValue = isValidInputValue;
40
59
  exports.parseDateString = parseDateString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-calendar-input",
3
- "version": "5.3.0",
3
+ "version": "6.0.0",
4
4
  "description": "Calendar input component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -19,12 +19,12 @@
19
19
  "react-dom": "^16.9.0 || ^17.0.1"
20
20
  },
21
21
  "dependencies": {
22
- "@alfalab/core-components-calendar": "^4.3.0",
23
- "@alfalab/core-components-date-input": "^1.3.0",
22
+ "@alfalab/core-components-calendar": "^5.0.0",
23
+ "@alfalab/core-components-date-input": "^2.0.0",
24
24
  "@alfalab/core-components-popover": "^5.6.1",
25
25
  "classnames": "^2.2.6",
26
26
  "date-fns": "^2.16.1",
27
27
  "react-merge-refs": "^1.1.0"
28
28
  },
29
- "gitHead": "45ff10d1efc81a4a1afb82c6b6eca1b428c7c459"
29
+ "gitHead": "c807c08f187316e93147175be6feffc3492989c8"
30
30
  }