@steroidsjs/core 3.0.81 → 3.0.83

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.
@@ -15,8 +15,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  };
16
16
  exports.__esModule = true;
17
17
  var react_1 = require("react");
18
- var kit_1 = require("@maskito/kit");
19
18
  var react_2 = require("@maskito/react");
19
+ var utils_1 = require("./utils");
20
20
  var useDateTime_1 = __importDefault(require("../DateField/useDateTime"));
21
21
  var useDateInputState_1 = __importDefault(require("../../form/DateField/useDateInputState"));
22
22
  var fieldWrapper_1 = __importDefault(require("../../form/Field/fieldWrapper"));
@@ -28,10 +28,18 @@ var DATE_TIME_SEPARATOR = ', ';
28
28
  * Поля ввода с выпадающими списками для выбора даты и времени
29
29
  */
30
30
  function DateTimeField(props) {
31
- var _a;
31
+ var _a, _b, _c, _d, _e, _f;
32
32
  var components = (0, hooks_1.useComponents)();
33
- var maskInputRef = (0, react_2.useMaskito)({ options: props.maskOptions });
34
- var _b = (0, useDateInputState_1["default"])({
33
+ var maskInputRef = (0, react_2.useMaskito)({
34
+ options: (0, utils_1.createDateTimeMask)({
35
+ from: (_a = props.availableTime) === null || _a === void 0 ? void 0 : _a.from,
36
+ to: (_b = props.availableTime) === null || _b === void 0 ? void 0 : _b.to,
37
+ minuteStep: props.minuteStep,
38
+ min: (_d = (_c = props.disabledDays) === null || _c === void 0 ? void 0 : _c.before) !== null && _d !== void 0 ? _d : null,
39
+ dateTimeSeparator: (_e = props.dateTimeSeparator) !== null && _e !== void 0 ? _e : DATE_TIME_SEPARATOR
40
+ })
41
+ });
42
+ var _g = (0, useDateInputState_1["default"])({
35
43
  input: props.input,
36
44
  disabled: props.disabled,
37
45
  onChange: props.onChange,
@@ -42,25 +50,31 @@ function DateTimeField(props) {
42
50
  displayFormat: props.displayFormat,
43
51
  useUTC: props.useUTC,
44
52
  dateInUTC: props.dateInUTC
45
- }), onClear = _b.onClear, onClose = _b.onClose, isOpened = _b.isOpened, inputProps = _b.inputProps;
46
- var _c = (0, useDateTime_1["default"])({
53
+ }), onClear = _g.onClear, onClose = _g.onClose, isOpened = _g.isOpened, inputProps = _g.inputProps;
54
+ var _h = (0, useDateTime_1["default"])({
47
55
  displayFormat: props.displayFormat,
48
- dateTimeSeparator: (_a = props.dateTimeSeparator) !== null && _a !== void 0 ? _a : DATE_TIME_SEPARATOR,
56
+ dateTimeSeparator: (_f = props.dateTimeSeparator) !== null && _f !== void 0 ? _f : DATE_TIME_SEPARATOR,
49
57
  input: props.input,
50
58
  valueFormat: props.valueFormat,
51
59
  useUTC: props.useUTC,
52
60
  dateInUTC: props.dateInUTC
53
- }), dateValueFormat = _c.dateValueFormat, dateValue = _c.dateValue, timeValue = _c.timeValue, onDateSelect = _c.onDateSelect, onTimeSelect = _c.onTimeSelect;
61
+ }), dateValueFormat = _h.dateValueFormat, dateValue = _h.dateValue, timeValue = _h.timeValue, onDateSelect = _h.onDateSelect, onTimeSelect = _h.onTimeSelect;
54
62
  // Calendar props
55
- var calendarProps = (0, react_1.useMemo)(function () { return (__assign({ value: dateValue, onChange: onDateSelect, valueFormat: dateValueFormat }, props.calendarProps)); }, [dateValue, dateValueFormat, onDateSelect, props.calendarProps]);
63
+ var calendarProps = (0, react_1.useMemo)(function () {
64
+ var _a;
65
+ return (__assign({ value: dateValue, onChange: onDateSelect, valueFormat: dateValueFormat }, ((props === null || props === void 0 ? void 0 : props.disabledDays)
66
+ ? __assign(__assign({}, props.calendarProps), { pickerProps: __assign(__assign({}, (_a = props.calendarProps) === null || _a === void 0 ? void 0 : _a.pickerProps), { disabledDays: props.disabledDays }) }) : props.calendarProps)));
67
+ }, [dateValue, dateValueFormat, onDateSelect, props.calendarProps, props.disabledDays]);
56
68
  // TimePanel props
57
69
  var timePanelViewProps = (0, react_1.useMemo)(function () { return ({
58
70
  onClose: onClose,
59
71
  showHeader: true,
60
72
  showNow: false,
61
73
  value: timeValue,
62
- onSelect: onTimeSelect
63
- }); }, [onClose, onTimeSelect, timeValue]);
74
+ onSelect: onTimeSelect,
75
+ availableTime: props.availableTime,
76
+ minuteStep: props.minuteStep
77
+ }); }, [onClose, onTimeSelect, props.availableTime, props.minuteStep, timeValue]);
64
78
  var viewProps = (0, react_1.useMemo)(function () { return ({
65
79
  isOpened: isOpened,
66
80
  onClear: onClear,
@@ -78,10 +92,7 @@ function DateTimeField(props) {
78
92
  disabled: props.disabled,
79
93
  style: props.style,
80
94
  id: props.id
81
- }); }, [
82
- calendarProps, inputProps, isOpened, maskInputRef, onClear, onClose, props.className, props.disabled, props.errors,
83
- props.icon, props.id, props.placeholder, props.showRemove, props.size, props.style, timePanelViewProps,
84
- ]);
95
+ }); }, [calendarProps, inputProps, isOpened, maskInputRef, onClear, onClose, props.className, props.disabled, props.errors, props.icon, props.id, props.placeholder, props.showRemove, props.size, props.style, timePanelViewProps]);
85
96
  return components.ui.renderView(props.view || 'form.DateTimeFieldView', viewProps);
86
97
  }
87
98
  DateTimeField.defaultProps = {
@@ -93,11 +104,6 @@ DateTimeField.defaultProps = {
93
104
  useUTC: false,
94
105
  dateInUTC: false,
95
106
  icon: true,
96
- maskOptions: (0, kit_1.maskitoDateTimeOptionsGenerator)({
97
- dateMode: 'dd/mm/yyyy',
98
- timeMode: 'HH:MM',
99
- dateSeparator: '.',
100
- dateTimeSeparator: DATE_TIME_SEPARATOR
101
- })
107
+ minuteStep: 1
102
108
  };
103
109
  exports["default"] = (0, fieldWrapper_1["default"])(enums_1.FieldEnum.DATE_TIME_FIELD, DateTimeField);
@@ -0,0 +1,8 @@
1
+ import { MaskitoOptions } from '@maskito/core';
2
+ export declare const createDateTimeMask: (options?: {
3
+ from?: string;
4
+ to?: string;
5
+ minuteStep?: number;
6
+ min?: Date;
7
+ dateTimeSeparator?: string;
8
+ }) => MaskitoOptions;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
+ if (ar || !(i in from)) {
16
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
+ ar[i] = from[i];
18
+ }
19
+ }
20
+ return to.concat(ar || Array.prototype.slice.call(from));
21
+ };
22
+ exports.__esModule = true;
23
+ exports.createDateTimeMask = void 0;
24
+ var kit_1 = require("@maskito/kit");
25
+ var utils_1 = require("@steroidsjs/core/ui/form/TimeField/utils");
26
+ var TIME_REGEXP = /(\d{2}:\d{2})$/;
27
+ var clampTime = function (minutes, fromMin, toMin, step) {
28
+ // Жёсткие границы
29
+ if (minutes <= fromMin) {
30
+ return fromMin;
31
+ }
32
+ if (minutes >= toMin) {
33
+ return toMin;
34
+ }
35
+ if (!step || step <= 1) {
36
+ return minutes;
37
+ }
38
+ // Округление относительно from
39
+ var diff = minutes - fromMin;
40
+ return fromMin + Math.floor(diff / step) * step;
41
+ };
42
+ var createDateTimeMask = function (options) {
43
+ var _a;
44
+ var baseMask = (0, kit_1.maskitoDateTimeOptionsGenerator)({
45
+ dateMode: 'dd/mm/yyyy',
46
+ timeMode: 'HH:MM',
47
+ dateSeparator: '.',
48
+ min: options.min,
49
+ dateTimeSeparator: options.dateTimeSeparator
50
+ });
51
+ return __assign(__assign({}, baseMask), { postprocessors: __spreadArray(__spreadArray([], ((_a = baseMask.postprocessors) !== null && _a !== void 0 ? _a : []), true), [
52
+ function (_a) {
53
+ var value = _a.value, selection = _a.selection;
54
+ if (!value) {
55
+ return { value: value, selection: selection };
56
+ }
57
+ var match = value.match(TIME_REGEXP);
58
+ if (!match) {
59
+ return { value: value, selection: selection };
60
+ }
61
+ var time = match[1];
62
+ var minutes = (0, utils_1.timeToMinutes)(time);
63
+ var fromMin = (options === null || options === void 0 ? void 0 : options.from)
64
+ ? (0, utils_1.timeToMinutes)(options.from.padStart(5, '0'))
65
+ : 0;
66
+ var toMin = (options === null || options === void 0 ? void 0 : options.to)
67
+ ? (0, utils_1.timeToMinutes)(options.to.padStart(5, '0'))
68
+ : 24 * 60 - 1;
69
+ var clamped = clampTime(minutes, fromMin, toMin, options === null || options === void 0 ? void 0 : options.minuteStep);
70
+ var normalizedTime = (0, utils_1.minutesToTime)(clamped);
71
+ if (normalizedTime === time) {
72
+ return { value: value, selection: selection };
73
+ }
74
+ return {
75
+ value: value.replace(TIME_REGEXP, normalizedTime),
76
+ selection: selection
77
+ };
78
+ },
79
+ ], false) });
80
+ };
81
+ exports.createDateTimeMask = createDateTimeMask;
@@ -57,6 +57,29 @@ export interface IDateTimeRangeFieldProps extends Omit<IDateInputStateInput, 'in
57
57
  */
58
58
  to: MaskitoOptions;
59
59
  };
60
+ /**
61
+ * Ограничение доступных дат.
62
+ */
63
+ disabledDays?: {
64
+ after?: Date;
65
+ before?: Date;
66
+ };
67
+ /**
68
+ * Разделитель для даты и времени, не влияет на отображение
69
+ */
70
+ dateTimeSeparator?: string;
71
+ /**
72
+ * Ограничение доступного времени.
73
+ */
74
+ availableTime?: {
75
+ from: string;
76
+ to: string;
77
+ };
78
+ /**
79
+ * Шаг минут
80
+ * @example 15
81
+ */
82
+ minuteStep?: number;
60
83
  /**
61
84
  * Добавляет дополнительные кнопки к календарю
62
85
  * true - будут отображены кнопки по-умолчанию
@@ -10,36 +10,13 @@ var __assign = (this && this.__assign) || function () {
10
10
  };
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
- if (k2 === undefined) k2 = k;
15
- var desc = Object.getOwnPropertyDescriptor(m, k);
16
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
- desc = { enumerable: true, get: function() { return m[k]; } };
18
- }
19
- Object.defineProperty(o, k2, desc);
20
- }) : (function(o, m, k, k2) {
21
- if (k2 === undefined) k2 = k;
22
- o[k2] = m[k];
23
- }));
24
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
- Object.defineProperty(o, "default", { enumerable: true, value: v });
26
- }) : function(o, v) {
27
- o["default"] = v;
28
- });
29
- var __importStar = (this && this.__importStar) || function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
37
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
15
  };
39
16
  exports.__esModule = true;
40
- var react_1 = __importStar(require("react"));
41
- var kit_1 = require("@maskito/kit");
17
+ var react_1 = require("react");
42
18
  var react_2 = require("@maskito/react");
19
+ var utils_1 = require("@steroidsjs/core/ui/form/DateTimeField/utils");
43
20
  var useDateRange_1 = __importDefault(require("../../form/DateField/useDateRange"));
44
21
  var useDateTime_1 = __importDefault(require("../../form/DateField/useDateTime"));
45
22
  var useDateInputState_1 = __importDefault(require("../../form/DateField/useDateInputState"));
@@ -48,10 +25,26 @@ var hooks_1 = require("../../../hooks");
48
25
  var enums_1 = require("../../../enums");
49
26
  var DATE_TIME_SEPARATOR = ', ';
50
27
  function DateTimeRangeField(props) {
51
- var _a, _b;
28
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
52
29
  var components = (0, hooks_1.useComponents)();
53
- var maskInputFromRef = (0, react_2.useMaskito)({ options: (_a = props.maskOptions) === null || _a === void 0 ? void 0 : _a.from });
54
- var maskInputToRef = (0, react_2.useMaskito)({ options: (_b = props.maskOptions) === null || _b === void 0 ? void 0 : _b.to });
30
+ var maskInputFromRef = (0, react_2.useMaskito)({
31
+ options: (_b = (_a = props.maskOptions) === null || _a === void 0 ? void 0 : _a.from) !== null && _b !== void 0 ? _b : (0, utils_1.createDateTimeMask)({
32
+ from: (_c = props.availableTime) === null || _c === void 0 ? void 0 : _c.from,
33
+ to: (_d = props.availableTime) === null || _d === void 0 ? void 0 : _d.to,
34
+ minuteStep: props.minuteStep,
35
+ min: (_f = (_e = props.disabledDays) === null || _e === void 0 ? void 0 : _e.before) !== null && _f !== void 0 ? _f : null,
36
+ dateTimeSeparator: (_g = props.dateTimeSeparator) !== null && _g !== void 0 ? _g : DATE_TIME_SEPARATOR
37
+ })
38
+ });
39
+ var maskInputToRef = (0, react_2.useMaskito)({
40
+ options: (_j = (_h = props.maskOptions) === null || _h === void 0 ? void 0 : _h.to) !== null && _j !== void 0 ? _j : (0, utils_1.createDateTimeMask)({
41
+ from: (_k = props.availableTime) === null || _k === void 0 ? void 0 : _k.from,
42
+ to: (_l = props.availableTime) === null || _l === void 0 ? void 0 : _l.to,
43
+ minuteStep: props.minuteStep,
44
+ min: (_o = (_m = props.disabledDays) === null || _m === void 0 ? void 0 : _m.before) !== null && _o !== void 0 ? _o : null,
45
+ dateTimeSeparator: (_p = props.dateTimeSeparator) !== null && _p !== void 0 ? _p : DATE_TIME_SEPARATOR
46
+ })
47
+ });
55
48
  // Global onChange (from props)
56
49
  var onChange = (0, react_1.useCallback)(function () {
57
50
  var _a;
@@ -63,7 +56,7 @@ function DateTimeRangeField(props) {
63
56
  }
64
57
  }, [props.attributeFrom, props.attributeTo, props.inputFrom.value, props.inputTo.value, props.onChange]);
65
58
  // Input 'from'
66
- var _c = (0, useDateInputState_1["default"])({
59
+ var _q = (0, useDateInputState_1["default"])({
67
60
  displayFormat: props.displayFormat,
68
61
  valueFormat: props.valueFormat,
69
62
  input: props.inputFrom,
@@ -74,9 +67,9 @@ function DateTimeRangeField(props) {
74
67
  useUTC: props.useUTC,
75
68
  dateInUTC: props.dateInUTC,
76
69
  onChange: onChange
77
- }), isOpenedFrom = _c.isOpened, onCloseFrom = _c.onClose, inputPropsFrom = _c.inputProps, onClearFrom = _c.onClear, onNow = _c.onNow;
70
+ }), isOpenedFrom = _q.isOpened, onCloseFrom = _q.onClose, inputPropsFrom = _q.inputProps, onClearFrom = _q.onClear, onNow = _q.onNow;
78
71
  // Input 'to'
79
- var _d = (0, useDateInputState_1["default"])({
72
+ var _r = (0, useDateInputState_1["default"])({
80
73
  displayFormat: props.displayFormat,
81
74
  valueFormat: props.valueFormat,
82
75
  input: props.inputTo,
@@ -87,24 +80,24 @@ function DateTimeRangeField(props) {
87
80
  useUTC: props.useUTC,
88
81
  dateInUTC: props.dateInUTC,
89
82
  onChange: onChange
90
- }), isOpenedTo = _d.isOpened, onCloseTo = _d.onClose, inputPropsTo = _d.inputProps, onClearTo = _d.onClear;
91
- var _e = (0, useDateTime_1["default"])({
83
+ }), isOpenedTo = _r.isOpened, onCloseTo = _r.onClose, inputPropsTo = _r.inputProps, onClearTo = _r.onClear;
84
+ var _s = (0, useDateTime_1["default"])({
92
85
  displayFormat: props.displayFormat,
93
86
  valueFormat: props.valueFormat,
94
87
  dateTimeSeparator: DATE_TIME_SEPARATOR,
95
88
  useUTC: props.useUTC,
96
89
  dateInUTC: props.dateInUTC,
97
90
  input: props.inputFrom
98
- }), dateValueFormat = _e.dateValueFormat, dateValueFrom = _e.dateValue, timeValueFrom = _e.timeValue, onDateFromSelect = _e.onDateSelect, onTimeFromSelect = _e.onTimeSelect;
99
- var _f = (0, useDateTime_1["default"])({
91
+ }), dateValueFormat = _s.dateValueFormat, dateValueFrom = _s.dateValue, timeValueFrom = _s.timeValue, onDateFromSelect = _s.onDateSelect, onTimeFromSelect = _s.onTimeSelect;
92
+ var _t = (0, useDateTime_1["default"])({
100
93
  displayFormat: props.displayFormat,
101
94
  valueFormat: props.valueFormat,
102
95
  dateTimeSeparator: DATE_TIME_SEPARATOR,
103
96
  useUTC: props.useUTC,
104
97
  dateInUTC: props.dateInUTC,
105
98
  input: props.inputTo
106
- }), dateValueTo = _f.dateValue, timeValueTo = _f.timeValue, onDateToSelect = _f.onDateSelect, onTimeToSelect = _f.onTimeSelect;
107
- var _g = (0, useDateRange_1["default"])({
99
+ }), dateValueTo = _t.dateValue, timeValueTo = _t.timeValue, onDateToSelect = _t.onDateSelect, onTimeToSelect = _t.onTimeSelect;
100
+ var _u = (0, useDateRange_1["default"])({
108
101
  onClearFrom: onClearFrom,
109
102
  onCloseTo: onCloseTo,
110
103
  onCloseFrom: onCloseFrom,
@@ -117,8 +110,8 @@ function DateTimeRangeField(props) {
117
110
  hasInitialFocus: props.hasInitialFocus,
118
111
  displayFormat: props.displayFormat,
119
112
  valueFormat: props.valueFormat
120
- }), focus = _g.focus, onClose = _g.onClose, onClear = _g.onClear, extendedInputPropsFrom = _g.extendedInputPropsFrom, extendedInputPropsTo = _g.extendedInputPropsTo;
121
- react_1["default"].useEffect(function () {
113
+ }), focus = _u.focus, onClose = _u.onClose, onClear = _u.onClear, extendedInputPropsFrom = _u.extendedInputPropsFrom, extendedInputPropsTo = _u.extendedInputPropsTo;
114
+ (0, react_1.useEffect)(function () {
122
115
  if (extendedInputPropsFrom.ref && extendedInputPropsTo.ref) {
123
116
  maskInputFromRef(extendedInputPropsFrom.ref.current);
124
117
  maskInputToRef(extendedInputPropsTo.ref.current);
@@ -130,18 +123,13 @@ function DateTimeRangeField(props) {
130
123
  maskInputToRef,
131
124
  ]);
132
125
  // Calendar props
133
- var calendarProps = (0, react_1.useMemo)(function () { return (__assign({ value: [dateValueFrom, dateValueTo], onChange: focus === 'from' ? onDateFromSelect : onDateToSelect, valueFormat: dateValueFormat }, props.calendarProps)); }, [dateValueFormat, dateValueFrom, dateValueTo, focus, onDateFromSelect, onDateToSelect, props.calendarProps]);
126
+ var calendarProps = (0, react_1.useMemo)(function () {
127
+ var _a;
128
+ return (__assign({ value: [dateValueFrom, dateValueTo], onChange: focus === 'from' ? onDateFromSelect : onDateToSelect, valueFormat: dateValueFormat }, ((props === null || props === void 0 ? void 0 : props.disabledDays)
129
+ ? __assign(__assign({}, props.calendarProps), { pickerProps: __assign(__assign({}, (_a = props.calendarProps) === null || _a === void 0 ? void 0 : _a.pickerProps), { disabledDays: props.disabledDays }) }) : props.calendarProps)));
130
+ }, [dateValueFormat, dateValueFrom, dateValueTo, focus, onDateFromSelect, onDateToSelect, props.calendarProps, props.disabledDays]);
134
131
  // TimePanel props
135
- var timePanelViewProps = (0, react_1.useMemo)(function () { return (__assign({ value: focus === 'from' ? timeValueFrom : timeValueTo, onSelect: focus === 'from' ? onTimeFromSelect : onTimeToSelect, onNow: onNow, onClose: onClose, showNow: false, showHeader: true }, props.timePanelViewProps)); }, [
136
- focus,
137
- onClose,
138
- onNow,
139
- onTimeFromSelect,
140
- onTimeToSelect,
141
- props.timePanelViewProps,
142
- timeValueFrom,
143
- timeValueTo,
144
- ]);
132
+ var timePanelViewProps = (0, react_1.useMemo)(function () { return (__assign({ value: focus === 'from' ? timeValueFrom : timeValueTo, onSelect: focus === 'from' ? onTimeFromSelect : onTimeToSelect, onNow: onNow, onClose: onClose, showNow: false, showHeader: true, availableTime: props.availableTime, minuteStep: props.minuteStep }, props.timePanelViewProps)); }, [focus, onClose, onNow, onTimeFromSelect, onTimeToSelect, props.availableTime, props.minuteStep, props.timePanelViewProps, timeValueFrom, timeValueTo]);
145
133
  var viewProps = (0, react_1.useMemo)(function () { return ({
146
134
  onClear: onClear,
147
135
  onClose: onClose,
@@ -178,18 +166,7 @@ DateTimeRangeField.defaultProps = {
178
166
  useUTC: false,
179
167
  dateInUTC: false,
180
168
  icon: true,
181
- maskOptions: {
182
- from: (0, kit_1.maskitoDateTimeOptionsGenerator)({
183
- dateMode: 'dd/mm/yyyy',
184
- timeMode: 'HH:MM',
185
- dateSeparator: '.'
186
- }),
187
- to: (0, kit_1.maskitoDateTimeOptionsGenerator)({
188
- dateMode: 'dd/mm/yyyy',
189
- timeMode: 'HH:MM',
190
- dateSeparator: '.'
191
- })
192
- },
193
- rangeButtonsPosition: 'left-bottom'
169
+ rangeButtonsPosition: 'left-bottom',
170
+ minuteStep: 1
194
171
  };
195
172
  exports["default"] = (0, fieldWrapper_1["default"])(enums_1.FieldEnum.DATE_TIME_RANGE_FIELD, DateTimeRangeField, { attributeSuffixes: ['from', 'to'] });
@@ -20,6 +20,7 @@ export interface ITextFieldViewProps extends ITextFieldProps, IFieldWrapperOutpu
20
20
  value: string | number;
21
21
  placeholder: string;
22
22
  disabled: boolean;
23
+ required: boolean;
23
24
  };
24
25
  onClear: VoidFunction;
25
26
  }
@@ -1,5 +1,6 @@
1
+ import { MaskitoOptions } from '@maskito/core';
1
2
  import { IDateInputStateInput, IDateInputStateOutput } from '../../form/DateField/useDateInputState';
2
- export interface ITimePanelViewProps extends Pick<ITimeFieldViewProps, 'value' | 'onClose' | 'onNow' | 'onSelect' | 'className'> {
3
+ export interface ITimePanelViewProps extends Pick<ITimeFieldViewProps, 'value' | 'onClose' | 'onNow' | 'onSelect' | 'className' | 'availableTime' | 'minuteStep'> {
3
4
  showHeader?: boolean;
4
5
  showNow?: boolean;
5
6
  }
@@ -21,9 +22,25 @@ export interface ITimeFieldProps extends IDateInputStateInput, IUiComponent {
21
22
  * Свойства для компонента панели времени
22
23
  */
23
24
  timePanelViewProps?: any;
25
+ /**
26
+ * Опции маски для поля ввода
27
+ */
28
+ maskOptions?: MaskitoOptions;
29
+ /**
30
+ * Ограничение доступного времени.
31
+ */
32
+ availableTime?: {
33
+ from: string;
34
+ to: string;
35
+ };
36
+ /**
37
+ * Шаг минут
38
+ * @example 15
39
+ */
40
+ minuteStep?: number;
24
41
  [key: string]: any;
25
42
  }
26
- export interface ITimeFieldViewProps extends IDateInputStateOutput, Pick<ITimeFieldProps, 'size' | 'errors' | 'showRemove' | 'noBorder' | 'className' | 'timePanelViewProps' | 'style'> {
43
+ export interface ITimeFieldViewProps extends IDateInputStateOutput, Pick<ITimeFieldProps, 'size' | 'errors' | 'showRemove' | 'noBorder' | 'className' | 'timePanelViewProps' | 'style' | 'availableTime' | 'minuteStep'> {
27
44
  [key: string]: any;
28
45
  }
29
46
  declare const _default: import("../Field/fieldWrapper").FieldWrapperComponent<ITimeFieldProps>;
@@ -15,13 +15,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  };
16
16
  exports.__esModule = true;
17
17
  var react_1 = require("react");
18
+ var react_2 = require("@maskito/react");
18
19
  var useDateInputState_1 = __importDefault(require("../../form/DateField/useDateInputState"));
19
20
  var hooks_1 = require("../../../hooks");
20
21
  var fieldWrapper_1 = __importDefault(require("../Field/fieldWrapper"));
21
22
  var enums_1 = require("../../../enums");
23
+ var utils_1 = require("./utils");
22
24
  function TimeField(props) {
25
+ var _a, _b, _c;
23
26
  var components = (0, hooks_1.useComponents)();
24
- var _a = (0, useDateInputState_1["default"])({
27
+ var maskRef = (0, react_2.useMaskito)({
28
+ options: (_a = props.maskOptions) !== null && _a !== void 0 ? _a : (0, utils_1.createTimeMask)({
29
+ from: (_b = props.availableTime) === null || _b === void 0 ? void 0 : _b.from,
30
+ to: (_c = props.availableTime) === null || _c === void 0 ? void 0 : _c.to,
31
+ minuteStep: props.minuteStep
32
+ })
33
+ });
34
+ var _d = (0, useDateInputState_1["default"])({
25
35
  input: props.input,
26
36
  disabled: props.disabled,
27
37
  onChange: props.onChange,
@@ -32,10 +42,9 @@ function TimeField(props) {
32
42
  displayFormat: props.displayFormat,
33
43
  useUTC: props.useUTC,
34
44
  dateInUTC: props.dateInUTC
35
- }), onNow = _a.onNow, onClear = _a.onClear, onClose = _a.onClose, isOpened = _a.isOpened, inputProps = _a.inputProps;
36
- var timePanelViewProps = (0, react_1.useMemo)(function () { return (__assign({ onNow: onNow, onClose: onClose, value: inputProps.value, onSelect: inputProps.onChange }, props.timePanelViewProps)); }, [inputProps.onChange, inputProps.value, onClose, onNow, props.timePanelViewProps]);
37
- var viewProps = (0, react_1.useMemo)(function () { return (__assign(__assign({}, props.viewProps), { onNow: onNow, onClear: onClear, onClose: onClose, isOpened: isOpened, inputProps: inputProps, timePanelViewProps: timePanelViewProps, size: props.size, icon: props.icon, errors: props.errors, noBorder: props.noBorder, disabled: props.disabled, className: props.className, style: props.style, showRemove: props.showRemove, id: props.id })); }, [inputProps, isOpened, onClear, onClose, onNow, props.className, props.disabled, props.errors, props.icon, props.id, props.noBorder,
38
- props.showRemove, props.size, props.style, props.viewProps, timePanelViewProps]);
45
+ }), onNow = _d.onNow, onClear = _d.onClear, onClose = _d.onClose, isOpened = _d.isOpened, inputProps = _d.inputProps;
46
+ var timePanelViewProps = (0, react_1.useMemo)(function () { return (__assign({ onNow: onNow, onClose: onClose, value: inputProps.value, onSelect: inputProps.onChange, availableTime: props.availableTime, minuteStep: props.minuteStep }, props.timePanelViewProps)); }, [inputProps.onChange, inputProps.value, onClose, onNow, props.availableTime, props.minuteStep, props.timePanelViewProps]);
47
+ var viewProps = (0, react_1.useMemo)(function () { return (__assign(__assign({}, props.viewProps), { onNow: onNow, onClear: onClear, onClose: onClose, isOpened: isOpened, inputProps: inputProps, timePanelViewProps: timePanelViewProps, size: props.size, icon: props.icon, errors: props.errors, noBorder: props.noBorder, disabled: props.disabled, className: props.className, style: props.style, showRemove: props.showRemove, id: props.id, maskRef: maskRef })); }, [inputProps, isOpened, maskRef, onClear, onClose, onNow, props.className, props.disabled, props.errors, props.icon, props.id, props.noBorder, props.showRemove, props.size, props.style, props.viewProps, timePanelViewProps]);
39
48
  return components.ui.renderView(props.view || 'form.TimeFieldView', viewProps);
40
49
  }
41
50
  TimeField.defaultProps = {
@@ -48,6 +57,7 @@ TimeField.defaultProps = {
48
57
  valueFormat: 'HH:mm',
49
58
  useUTC: false,
50
59
  dateInUTC: false,
51
- icon: true
60
+ icon: true,
61
+ minuteStep: 1
52
62
  };
53
63
  exports["default"] = (0, fieldWrapper_1["default"])(enums_1.FieldEnum.TIME_FIELD, TimeField);
@@ -0,0 +1,9 @@
1
+ import { MaskitoOptions, MaskitoPlugin } from '@maskito/core';
2
+ export declare const timeToMinutes: (value: string) => number;
3
+ export declare const minutesToTime: (minutes: number) => string;
4
+ export declare const createTimeRangePlugin: (from?: string, to?: string) => MaskitoPlugin;
5
+ export declare const createTimeMask: (options?: {
6
+ from?: string;
7
+ to?: string;
8
+ minuteStep?: number;
9
+ }) => MaskitoOptions;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ exports.__esModule = true;
14
+ exports.createTimeMask = exports.createTimeRangePlugin = exports.minutesToTime = exports.timeToMinutes = void 0;
15
+ var timeToMinutes = function (value) {
16
+ var _a = value.split(':').map(Number), h = _a[0], m = _a[1];
17
+ return h * 60 + m;
18
+ };
19
+ exports.timeToMinutes = timeToMinutes;
20
+ var isCompleteTime = function (value) { return /^\d{2}:\d{2}$/.test(value); };
21
+ var minutesToTime = function (minutes) {
22
+ var h = Math.floor(minutes / 60);
23
+ var m = minutes % 60;
24
+ return "".concat(String(h).padStart(2, '0'), ":").concat(String(m).padStart(2, '0'));
25
+ };
26
+ exports.minutesToTime = minutesToTime;
27
+ var createTimeRangePlugin = function (from, to) {
28
+ var fromMin = from ? (0, exports.timeToMinutes)(/^\d:\d{2}$/.test(from) ? "0".concat(from) : from) : 0;
29
+ var toMin = to ? (0, exports.timeToMinutes)(/^\d:\d{2}$/.test(to) ? "0".concat(to) : to) : 24 * 60 - 1;
30
+ return function (element) {
31
+ element.addEventListener('input', function () {
32
+ var value = element.value;
33
+ if (!isCompleteTime(value)) {
34
+ return;
35
+ }
36
+ var minutes = (0, exports.timeToMinutes)(value);
37
+ if (minutes < fromMin) {
38
+ minutes = fromMin;
39
+ }
40
+ if (minutes > toMin) {
41
+ minutes = toMin;
42
+ }
43
+ var normalized = (0, exports.minutesToTime)(minutes);
44
+ if (normalized !== value) {
45
+ element.value = normalized;
46
+ }
47
+ });
48
+ };
49
+ };
50
+ exports.createTimeRangePlugin = createTimeRangePlugin;
51
+ var createTimeMask = function (options) { return ({
52
+ mask: [/\d/, /\d/, ':', /\d/, /\d/],
53
+ preprocessors: [
54
+ function (_a) {
55
+ var elementState = _a.elementState;
56
+ var value = elementState.value;
57
+ // авто-добавление ведущего нуля
58
+ if (/^\d:\d\d$/.test(value)) {
59
+ value = "0".concat(value);
60
+ }
61
+ return {
62
+ elementState: __assign(__assign({}, elementState), { value: value })
63
+ };
64
+ },
65
+ ],
66
+ postprocessors: [
67
+ function (_a) {
68
+ var value = _a.value, selection = _a.selection;
69
+ if (!/^\d{2}:\d{2}$/.test(value)) {
70
+ return { value: value, selection: selection };
71
+ }
72
+ var _b = value.split(':').map(Number), h = _b[0], m = _b[1];
73
+ if (Number.isNaN(h) || Number.isNaN(m)) {
74
+ return { value: value, selection: selection };
75
+ }
76
+ // Ограничение часов
77
+ if (h > 23) {
78
+ h = 23;
79
+ }
80
+ // Ограничение минут
81
+ if (m > 59) {
82
+ m = 59;
83
+ }
84
+ // Шаг минут
85
+ if ((options === null || options === void 0 ? void 0 : options.minuteStep) && options.minuteStep > 1) {
86
+ m = Math.floor(m / options.minuteStep)
87
+ * options.minuteStep;
88
+ }
89
+ var nextValue = "".concat(String(h).padStart(2, '0'), ":").concat(String(m).padStart(2, '0'));
90
+ return {
91
+ value: nextValue,
92
+ selection: selection
93
+ };
94
+ },
95
+ ],
96
+ plugins: [
97
+ (0, exports.createTimeRangePlugin)(options === null || options === void 0 ? void 0 : options.from, options === null || options === void 0 ? void 0 : options.to),
98
+ ]
99
+ }); };
100
+ exports.createTimeMask = createTimeMask;
@@ -1,3 +1,4 @@
1
+ import { MaskitoOptions } from '@maskito/core';
1
2
  import { IDateInputStateInput, IDateInputStateOutput } from '../DateField/useDateInputState';
2
3
  import { IFieldWrapperInputProps, IFieldWrapperOutputProps } from '../Field/fieldWrapper';
3
4
  import { ITimePanelViewProps } from '../TimeField/TimeField';
@@ -52,6 +53,31 @@ export interface ITimeRangeFieldProps extends IDateInputStateInput, Omit<IFieldW
52
53
  * @example true
53
54
  */
54
55
  hasInitialFocus?: boolean;
56
+ /**
57
+ * Опции маски для полей
58
+ */
59
+ maskOptions?: {
60
+ /**
61
+ * Опции маски для поля from
62
+ */
63
+ from: MaskitoOptions;
64
+ /**
65
+ * Опции маски для поля to
66
+ */
67
+ to: MaskitoOptions;
68
+ };
69
+ /**
70
+ * Ограничение доступного времени.
71
+ */
72
+ availableTime?: {
73
+ from: string;
74
+ to: string;
75
+ };
76
+ /**
77
+ * Шаг минут
78
+ * @example 15
79
+ */
80
+ minuteStep?: number;
55
81
  [key: string]: any;
56
82
  }
57
83
  export interface ITimeRangeFieldViewProps extends IDateInputStateOutput, Pick<ITimeRangeFieldProps, 'size' | 'errors' | 'showRemove' | 'className' | 'timePanelViewProps' | 'disabled' | 'style' | 'icon'>, Omit<IFieldWrapperOutputProps, 'input'> {