@astral/ui 1.47.0 → 1.47.2
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/DatePicker/DatePicker.d.ts +3 -3
- package/DatePicker/DatePicker.js +8 -7
- package/DatePicker/DatePicker.test.js +15 -0
- package/DatePicker/hooks/useMaskedValue/useMaskedValue.js +7 -1
- package/esm/DatePicker/DatePicker.d.ts +3 -3
- package/esm/DatePicker/DatePicker.js +9 -8
- package/esm/DatePicker/DatePicker.test.js +15 -0
- package/esm/DatePicker/hooks/useMaskedValue/useMaskedValue.js +7 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyntheticEvent } from 'react';
|
|
2
2
|
import { TextFieldProps } from '../TextField';
|
|
3
3
|
import { DateMask } from '../utils/date';
|
|
4
4
|
import { Reason } from '../types';
|
|
@@ -14,7 +14,7 @@ export type DatePickerProps = MondayFirst & Partial<MinMaxDate> & {
|
|
|
14
14
|
* @description Обработчик изменения состояния. Передает только Date object, если дата невалидна, то будет Invalid date
|
|
15
15
|
* */
|
|
16
16
|
onChange?: (date?: Date) => void;
|
|
17
|
-
onBlur?: (
|
|
17
|
+
onBlur?: () => void;
|
|
18
18
|
onOpen?: () => void;
|
|
19
19
|
onClose?: (event?: SyntheticEvent<Element, Event> | Event, reason?: Reason) => void;
|
|
20
20
|
inputProps?: Omit<TextFieldProps, 'ref' | 'value' | 'onChange'>;
|
|
@@ -34,7 +34,7 @@ export declare const DatePicker: import("react").ForwardRefExoticComponent<Monda
|
|
|
34
34
|
* @description Обработчик изменения состояния. Передает только Date object, если дата невалидна, то будет Invalid date
|
|
35
35
|
* */
|
|
36
36
|
onChange?: ((date?: Date) => void) | undefined;
|
|
37
|
-
onBlur?: ((
|
|
37
|
+
onBlur?: (() => void) | undefined;
|
|
38
38
|
onOpen?: (() => void) | undefined;
|
|
39
39
|
onClose?: ((event?: SyntheticEvent<Element, Event> | Event, reason?: Reason) => void) | undefined;
|
|
40
40
|
inputProps?: Omit<TextFieldProps, "ref" | "value" | "onChange"> | undefined;
|
package/DatePicker/DatePicker.js
CHANGED
|
@@ -24,10 +24,15 @@ const hooks_2 = require("./hooks");
|
|
|
24
24
|
const DatePickerInner = (0, react_1.forwardRef)(({ onChange, onOpen, onBlur, onClose, mask = 'DD.MM.YYYY', isMondayFirst, inputProps, disabled, value, }, forwardedRef) => {
|
|
25
25
|
const { maxDate, minDate } = (0, react_1.useContext)(MinMaxDateContext_1.MinMaxDateContext);
|
|
26
26
|
const ref = (0, hooks_1.useForwardedRef)(forwardedRef);
|
|
27
|
-
const [
|
|
27
|
+
const [isOpenPopper, openPopper, closePopper] = (0, hooks_1.useToggle)({
|
|
28
28
|
onActive: onOpen,
|
|
29
29
|
onInactive: onClose,
|
|
30
30
|
});
|
|
31
|
+
const handleClosePopper = () => {
|
|
32
|
+
// для данного компонента onBlur должен срабатывать после закрытия popover, а не во время выбора даты
|
|
33
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
|
34
|
+
closePopper(undefined, 'selectOption');
|
|
35
|
+
};
|
|
31
36
|
const { maskedValue, onChangeMaskedValue, onChangeMaskedDate } = (0, hooks_2.useMaskedValue)({
|
|
32
37
|
currentValue: value,
|
|
33
38
|
mask,
|
|
@@ -37,16 +42,12 @@ const DatePickerInner = (0, react_1.forwardRef)(({ onChange, onOpen, onBlur, onC
|
|
|
37
42
|
const selectedBaseDate = (0, hooks_2.useSelectedBaseDate)(value);
|
|
38
43
|
const handleDayPick = (date) => {
|
|
39
44
|
onChangeMaskedDate(date);
|
|
40
|
-
|
|
41
|
-
};
|
|
42
|
-
const handleBlurMaskInput = (e) => {
|
|
43
|
-
onChangeMaskedValue(e.target.value);
|
|
44
|
-
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
45
|
+
handleClosePopper();
|
|
45
46
|
};
|
|
46
47
|
const handleChangeMaskInput = (e) => {
|
|
47
48
|
onChangeMaskedValue(e.target.value);
|
|
48
49
|
};
|
|
49
|
-
return ((0, jsx_runtime_1.jsxs)(DatePickerClickAwayListener_1.DatePickerClickAwayListener, Object.assign({ onClickAway:
|
|
50
|
+
return ((0, jsx_runtime_1.jsxs)(DatePickerClickAwayListener_1.DatePickerClickAwayListener, Object.assign({ onClickAway: handleClosePopper }, { children: [(0, jsx_runtime_1.jsx)(DatePickerInput_1.DatePickerInput, Object.assign({}, inputProps, { mask: mask, onNativeChange: handleChangeMaskInput, disabled: disabled, value: maskedValue, ref: ref, onFocus: openPopper })), (0, jsx_runtime_1.jsx)(DatePickerPopper_1.DatePickerPopper, Object.assign({ open: isOpenPopper, onClose: handleClosePopper, anchorEl: ref === null || ref === void 0 ? void 0 : ref.current }, { children: (0, jsx_runtime_1.jsx)(YearMonthDayPicker_1.YearMonthDayPicker, { isMondayFirst: isMondayFirst, selectedDate: selectedBaseDate, onChange: handleDayPick, date: selectedBaseDate || baseDate }) }))] })));
|
|
50
51
|
});
|
|
51
52
|
exports.DatePicker = (0, react_1.forwardRef)((_a, forwardedRef) => {
|
|
52
53
|
var { minDate, maxDate } = _a, props = __rest(_a, ["minDate", "maxDate"]);
|
|
@@ -74,4 +74,19 @@ describe('DatePicker', () => {
|
|
|
74
74
|
const selected = tests_1.screen.getAllByText('9')[0].getAttribute('aria-selected');
|
|
75
75
|
expect(selected).toBeTruthy();
|
|
76
76
|
}));
|
|
77
|
+
it('Props:onBlur: вызывается при закрытии popover', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
const onBlur = vitest_1.vi.fn();
|
|
79
|
+
(0, tests_1.renderWithTheme)((0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, { onBlur: onBlur }));
|
|
80
|
+
tests_1.fireEvent.focus(tests_1.screen.getByRole('textbox'));
|
|
81
|
+
// клик вне инпута с поповером
|
|
82
|
+
yield tests_1.userEvents.click(document.body);
|
|
83
|
+
expect(onBlur).toBeCalled();
|
|
84
|
+
}));
|
|
85
|
+
it('Props:onBlur: не вызывается при потере фокуса на инпуте', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
+
const onBlur = vitest_1.vi.fn();
|
|
87
|
+
(0, tests_1.renderWithTheme)((0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, { onBlur: onBlur }));
|
|
88
|
+
tests_1.fireEvent.focus(tests_1.screen.getByRole('textbox'));
|
|
89
|
+
yield tests_1.userEvents.tab();
|
|
90
|
+
expect(onBlur).not.toBeCalled();
|
|
91
|
+
}));
|
|
77
92
|
});
|
|
@@ -10,7 +10,13 @@ const useMaskedValue = ({ currentValue, mask, onChangeValue, }) => {
|
|
|
10
10
|
const [maskedValue, setMaskedValue] = (0, react_1.useState)(() => currentValue ? (0, date_1.formatDate)(currentValue, mask) : '');
|
|
11
11
|
const handleChangeMaskedValue = (value) => {
|
|
12
12
|
setMaskedValue(value);
|
|
13
|
-
|
|
13
|
+
// parseDate вернет Invalid Date при undefined. А нам надо undefined
|
|
14
|
+
if (!value) {
|
|
15
|
+
onChangeValue === null || onChangeValue === void 0 ? void 0 : onChangeValue(undefined);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
onChangeValue === null || onChangeValue === void 0 ? void 0 : onChangeValue((0, date_1.parseDate)(value, mask));
|
|
19
|
+
}
|
|
14
20
|
};
|
|
15
21
|
const handleChangeMaskedDate = (date) => {
|
|
16
22
|
setMaskedValue((0, date_1.formatDate)(date, mask));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyntheticEvent } from 'react';
|
|
2
2
|
import { TextFieldProps } from '../TextField';
|
|
3
3
|
import { DateMask } from '../utils/date';
|
|
4
4
|
import { Reason } from '../types';
|
|
@@ -14,7 +14,7 @@ export type DatePickerProps = MondayFirst & Partial<MinMaxDate> & {
|
|
|
14
14
|
* @description Обработчик изменения состояния. Передает только Date object, если дата невалидна, то будет Invalid date
|
|
15
15
|
* */
|
|
16
16
|
onChange?: (date?: Date) => void;
|
|
17
|
-
onBlur?: (
|
|
17
|
+
onBlur?: () => void;
|
|
18
18
|
onOpen?: () => void;
|
|
19
19
|
onClose?: (event?: SyntheticEvent<Element, Event> | Event, reason?: Reason) => void;
|
|
20
20
|
inputProps?: Omit<TextFieldProps, 'ref' | 'value' | 'onChange'>;
|
|
@@ -34,7 +34,7 @@ export declare const DatePicker: import("react").ForwardRefExoticComponent<Monda
|
|
|
34
34
|
* @description Обработчик изменения состояния. Передает только Date object, если дата невалидна, то будет Invalid date
|
|
35
35
|
* */
|
|
36
36
|
onChange?: ((date?: Date) => void) | undefined;
|
|
37
|
-
onBlur?: ((
|
|
37
|
+
onBlur?: (() => void) | undefined;
|
|
38
38
|
onOpen?: (() => void) | undefined;
|
|
39
39
|
onClose?: ((event?: SyntheticEvent<Element, Event> | Event, reason?: Reason) => void) | undefined;
|
|
40
40
|
inputProps?: Omit<TextFieldProps, "ref" | "value" | "onChange"> | undefined;
|
|
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { forwardRef, useContext
|
|
13
|
+
import { forwardRef, useContext } from 'react';
|
|
14
14
|
import { useForwardedRef, useToggle } from '../hooks';
|
|
15
15
|
import { DatePickerClickAwayListener } from './DatePickerClickAwayListener';
|
|
16
16
|
import { DatePickerInput } from './DatePickerInput';
|
|
@@ -21,10 +21,15 @@ import { useBaseDateInRange, useMaskedValue, useSelectedBaseDate, } from './hook
|
|
|
21
21
|
const DatePickerInner = forwardRef(({ onChange, onOpen, onBlur, onClose, mask = 'DD.MM.YYYY', isMondayFirst, inputProps, disabled, value, }, forwardedRef) => {
|
|
22
22
|
const { maxDate, minDate } = useContext(MinMaxDateContext);
|
|
23
23
|
const ref = useForwardedRef(forwardedRef);
|
|
24
|
-
const [
|
|
24
|
+
const [isOpenPopper, openPopper, closePopper] = useToggle({
|
|
25
25
|
onActive: onOpen,
|
|
26
26
|
onInactive: onClose,
|
|
27
27
|
});
|
|
28
|
+
const handleClosePopper = () => {
|
|
29
|
+
// для данного компонента onBlur должен срабатывать после закрытия popover, а не во время выбора даты
|
|
30
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
|
|
31
|
+
closePopper(undefined, 'selectOption');
|
|
32
|
+
};
|
|
28
33
|
const { maskedValue, onChangeMaskedValue, onChangeMaskedDate } = useMaskedValue({
|
|
29
34
|
currentValue: value,
|
|
30
35
|
mask,
|
|
@@ -34,16 +39,12 @@ const DatePickerInner = forwardRef(({ onChange, onOpen, onBlur, onClose, mask =
|
|
|
34
39
|
const selectedBaseDate = useSelectedBaseDate(value);
|
|
35
40
|
const handleDayPick = (date) => {
|
|
36
41
|
onChangeMaskedDate(date);
|
|
37
|
-
|
|
38
|
-
};
|
|
39
|
-
const handleBlurMaskInput = (e) => {
|
|
40
|
-
onChangeMaskedValue(e.target.value);
|
|
41
|
-
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
42
|
+
handleClosePopper();
|
|
42
43
|
};
|
|
43
44
|
const handleChangeMaskInput = (e) => {
|
|
44
45
|
onChangeMaskedValue(e.target.value);
|
|
45
46
|
};
|
|
46
|
-
return (_jsxs(DatePickerClickAwayListener, Object.assign({ onClickAway:
|
|
47
|
+
return (_jsxs(DatePickerClickAwayListener, Object.assign({ onClickAway: handleClosePopper }, { children: [_jsx(DatePickerInput, Object.assign({}, inputProps, { mask: mask, onNativeChange: handleChangeMaskInput, disabled: disabled, value: maskedValue, ref: ref, onFocus: openPopper })), _jsx(DatePickerPopper, Object.assign({ open: isOpenPopper, onClose: handleClosePopper, anchorEl: ref === null || ref === void 0 ? void 0 : ref.current }, { children: _jsx(YearMonthDayPicker, { isMondayFirst: isMondayFirst, selectedDate: selectedBaseDate, onChange: handleDayPick, date: selectedBaseDate || baseDate }) }))] })));
|
|
47
48
|
});
|
|
48
49
|
export const DatePicker = forwardRef((_a, forwardedRef) => {
|
|
49
50
|
var { minDate, maxDate } = _a, props = __rest(_a, ["minDate", "maxDate"]);
|
|
@@ -72,4 +72,19 @@ describe('DatePicker', () => {
|
|
|
72
72
|
const selected = screen.getAllByText('9')[0].getAttribute('aria-selected');
|
|
73
73
|
expect(selected).toBeTruthy();
|
|
74
74
|
}));
|
|
75
|
+
it('Props:onBlur: вызывается при закрытии popover', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
+
const onBlur = vi.fn();
|
|
77
|
+
renderWithTheme(_jsx(DatePicker, { onBlur: onBlur }));
|
|
78
|
+
fireEvent.focus(screen.getByRole('textbox'));
|
|
79
|
+
// клик вне инпута с поповером
|
|
80
|
+
yield userEvents.click(document.body);
|
|
81
|
+
expect(onBlur).toBeCalled();
|
|
82
|
+
}));
|
|
83
|
+
it('Props:onBlur: не вызывается при потере фокуса на инпуте', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
const onBlur = vi.fn();
|
|
85
|
+
renderWithTheme(_jsx(DatePicker, { onBlur: onBlur }));
|
|
86
|
+
fireEvent.focus(screen.getByRole('textbox'));
|
|
87
|
+
yield userEvents.tab();
|
|
88
|
+
expect(onBlur).not.toBeCalled();
|
|
89
|
+
}));
|
|
75
90
|
});
|
|
@@ -7,7 +7,13 @@ export const useMaskedValue = ({ currentValue, mask, onChangeValue, }) => {
|
|
|
7
7
|
const [maskedValue, setMaskedValue] = useState(() => currentValue ? formatDate(currentValue, mask) : '');
|
|
8
8
|
const handleChangeMaskedValue = (value) => {
|
|
9
9
|
setMaskedValue(value);
|
|
10
|
-
|
|
10
|
+
// parseDate вернет Invalid Date при undefined. А нам надо undefined
|
|
11
|
+
if (!value) {
|
|
12
|
+
onChangeValue === null || onChangeValue === void 0 ? void 0 : onChangeValue(undefined);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
onChangeValue === null || onChangeValue === void 0 ? void 0 : onChangeValue(parseDate(value, mask));
|
|
16
|
+
}
|
|
11
17
|
};
|
|
12
18
|
const handleChangeMaskedDate = (date) => {
|
|
13
19
|
setMaskedValue(formatDate(date, mask));
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astral/ui",
|
|
3
|
-
"version": "1.47.
|
|
3
|
+
"version": "1.47.2",
|
|
4
4
|
"browser": "./esm/index.js",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@astral/icons": "^1.47.
|
|
7
|
+
"@astral/icons": "^1.47.2",
|
|
8
8
|
"@emotion/cache": "11.7.1",
|
|
9
9
|
"@emotion/react": "11.9.0",
|
|
10
10
|
"@emotion/server": "11.4.0",
|