@skbkontur/react-ui 4.25.2 → 4.26.0-MaskedInput-2nd.7
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 +19 -0
- package/LICENSE +21 -21
- package/README.md +41 -13
- package/cjs/components/Autocomplete/Autocomplete.md +76 -3
- package/cjs/components/Button/Button.md +38 -11
- package/cjs/components/Calendar/Calendar.md +40 -0
- package/cjs/components/DropdownMenu/DropdownMenu.md +39 -0
- package/cjs/components/FileUploader/FileUploader.d.ts +2 -0
- package/cjs/components/FileUploader/FileUploader.js +32 -9
- package/cjs/components/FileUploader/FileUploader.js.map +1 -1
- package/cjs/components/FileUploader/FileUploader.md +29 -0
- package/cjs/components/Gapped/Gapped.md +43 -43
- package/cjs/components/Input/Input.d.ts +3 -2
- package/cjs/components/Input/Input.js +7 -4
- package/cjs/components/Input/Input.js.map +1 -1
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.d.ts +10 -0
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.js +158 -0
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.js.map +1 -0
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles.d.ts +3 -0
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles.js +8 -0
- package/cjs/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles.js.map +1 -0
- package/cjs/components/MaskedInput/ColorableInputElement/index.d.ts +1 -0
- package/cjs/components/MaskedInput/ColorableInputElement/index.js +1 -0
- package/cjs/components/MaskedInput/ColorableInputElement/index.js.map +1 -0
- package/cjs/components/MaskedInput/FixedIMaskInput.d.ts +9 -0
- package/cjs/components/MaskedInput/FixedIMaskInput.js +215 -0
- package/cjs/components/MaskedInput/FixedIMaskInput.js.map +1 -0
- package/cjs/components/MaskedInput/MaskedInput.d.ts +43 -4
- package/cjs/components/MaskedInput/MaskedInput.helpers.d.ts +10 -0
- package/cjs/components/MaskedInput/MaskedInput.helpers.js +30 -0
- package/cjs/components/MaskedInput/MaskedInput.helpers.js.map +1 -0
- package/cjs/components/MaskedInput/MaskedInput.js +172 -23
- package/cjs/components/MaskedInput/MaskedInput.js.map +1 -1
- package/cjs/components/MaskedInput/MaskedInput.md +100 -9
- package/cjs/components/MaskedInput/MaskedInput.styles.d.ts +3 -0
- package/cjs/components/MaskedInput/MaskedInput.styles.js +4 -0
- package/cjs/components/MaskedInput/MaskedInput.styles.js.map +1 -0
- package/cjs/components/RadioGroup/RadioGroup.md +43 -43
- package/cjs/components/ScrollContainer/ScrollContainer.d.ts +1 -0
- package/cjs/components/ScrollContainer/ScrollContainer.js +6 -0
- package/cjs/components/ScrollContainer/ScrollContainer.js.map +1 -1
- package/cjs/hooks/useDrop.d.ts +1 -1
- package/cjs/hooks/useDrop.js.map +1 -1
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +1 -0
- package/cjs/index.js.map +1 -1
- package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.d.ts +5 -2
- package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.js +16 -3
- package/cjs/internal/FileUploaderControl/FileUploaderControlProvider.js.map +1 -1
- package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.d.ts +1 -0
- package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.js +4 -2
- package/cjs/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.js.map +1 -1
- package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.d.ts +1 -0
- package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.js +3 -2
- package/cjs/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.js.map +1 -1
- package/cjs/internal/RenderContainer/RenderContainer.d.ts +2 -0
- package/cjs/internal/RenderContainer/RenderContainer.js +6 -3
- package/cjs/internal/RenderContainer/RenderContainer.js.map +1 -1
- package/cjs/internal/RenderContainer/RenderInnerContainer.js +3 -2
- package/cjs/internal/RenderContainer/RenderInnerContainer.js.map +1 -1
- package/cjs/internal/ThemeShowcase/ThemeShowcase.md +13 -13
- package/cjs/internal/ZIndex/ZIndex.d.ts +7 -3
- package/cjs/internal/ZIndex/ZIndex.js +41 -3
- package/cjs/internal/ZIndex/ZIndex.js.map +1 -1
- package/cjs/internal/themes/Theme2022Dark.js +1 -1
- package/cjs/internal/themes/Theme2022Dark.js.map +1 -1
- package/cjs/lib/events/MouseDrag.d.ts +1 -1
- package/cjs/lib/events/MouseDrag.js.map +1 -1
- package/cjs/lib/events/keyboard/identifiers.d.ts +3 -0
- package/cjs/lib/events/keyboard/identifiers.js +5 -1
- package/cjs/lib/events/keyboard/identifiers.js.map +1 -1
- package/cjs/lib/listenFocusOutside.js +4 -2
- package/cjs/lib/listenFocusOutside.js.map +1 -1
- package/cjs/lib/styles/HoldSelectionColor.js +1 -1
- package/cjs/lib/styles/HoldSelectionColor.js.map +1 -1
- package/cjs/lib/styles/UiFont.d.ts +4 -0
- package/cjs/lib/styles/UiFont.js +61 -0
- package/cjs/lib/styles/UiFont.js.map +1 -0
- package/components/Autocomplete/Autocomplete.md +76 -3
- package/components/Button/Button.md +38 -11
- package/components/Calendar/Calendar.md +40 -0
- package/components/DropdownMenu/DropdownMenu.md +39 -0
- package/components/FileUploader/FileUploader/FileUploader.js +30 -8
- package/components/FileUploader/FileUploader/FileUploader.js.map +1 -1
- package/components/FileUploader/FileUploader.d.ts +2 -0
- package/components/FileUploader/FileUploader.md +29 -0
- package/components/Gapped/Gapped.md +43 -43
- package/components/Input/Input/Input.js +8 -4
- package/components/Input/Input/Input.js.map +1 -1
- package/components/Input/Input.d.ts +3 -2
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement/ColorableInputElement.js +152 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement/ColorableInputElement.js.map +1 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement/package.json +6 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement.d.ts +10 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles/ColorableInputElement.styles.js +9 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles/ColorableInputElement.styles.js.map +1 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles/package.json +6 -0
- package/components/MaskedInput/ColorableInputElement/ColorableInputElement.styles.d.ts +3 -0
- package/components/MaskedInput/ColorableInputElement/index/index.js +1 -0
- package/components/MaskedInput/ColorableInputElement/index/index.js.map +1 -0
- package/components/MaskedInput/ColorableInputElement/index/package.json +6 -0
- package/components/MaskedInput/ColorableInputElement/index.d.ts +1 -0
- package/components/MaskedInput/ColorableInputElement/package.json +6 -0
- package/components/MaskedInput/FixedIMaskInput/FixedIMaskInput.js +231 -0
- package/components/MaskedInput/FixedIMaskInput/FixedIMaskInput.js.map +1 -0
- package/components/MaskedInput/FixedIMaskInput/package.json +6 -0
- package/components/MaskedInput/FixedIMaskInput.d.ts +9 -0
- package/components/MaskedInput/MaskedInput/MaskedInput.js +134 -26
- package/components/MaskedInput/MaskedInput/MaskedInput.js.map +1 -1
- package/components/MaskedInput/MaskedInput.d.ts +43 -4
- package/components/MaskedInput/MaskedInput.helpers/MaskedInput.helpers.js +27 -0
- package/components/MaskedInput/MaskedInput.helpers/MaskedInput.helpers.js.map +1 -0
- package/components/MaskedInput/MaskedInput.helpers/package.json +6 -0
- package/components/MaskedInput/MaskedInput.helpers.d.ts +10 -0
- package/components/MaskedInput/MaskedInput.md +100 -9
- package/components/MaskedInput/MaskedInput.styles/MaskedInput.styles.js +4 -0
- package/components/MaskedInput/MaskedInput.styles/MaskedInput.styles.js.map +1 -0
- package/components/MaskedInput/MaskedInput.styles/package.json +6 -0
- package/components/MaskedInput/MaskedInput.styles.d.ts +3 -0
- package/components/RadioGroup/RadioGroup.md +43 -43
- package/components/ScrollContainer/ScrollContainer/ScrollContainer.js +5 -0
- package/components/ScrollContainer/ScrollContainer/ScrollContainer.js.map +1 -1
- package/components/ScrollContainer/ScrollContainer.d.ts +1 -0
- package/hooks/useDrop/useDrop.js.map +1 -1
- package/hooks/useDrop.d.ts +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/internal/FileUploaderControl/FileUploaderControlProvider/FileUploaderControlProvider.js +12 -3
- package/internal/FileUploaderControl/FileUploaderControlProvider/FileUploaderControlProvider.js.map +1 -1
- package/internal/FileUploaderControl/FileUploaderControlProvider.d.ts +5 -2
- package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile/FileUploaderFile.js +4 -2
- package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile/FileUploaderFile.js.map +1 -1
- package/internal/FileUploaderControl/FileUploaderFile/FileUploaderFile.d.ts +1 -0
- package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList/FileUploaderFileList.js +4 -2
- package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList/FileUploaderFileList.js.map +1 -1
- package/internal/FileUploaderControl/FileUploaderFileList/FileUploaderFileList.d.ts +1 -0
- package/internal/RenderContainer/RenderContainer/RenderContainer.js +3 -1
- package/internal/RenderContainer/RenderContainer/RenderContainer.js.map +1 -1
- package/internal/RenderContainer/RenderContainer.d.ts +2 -0
- package/internal/RenderContainer/RenderInnerContainer/RenderInnerContainer.js +5 -4
- package/internal/RenderContainer/RenderInnerContainer/RenderInnerContainer.js.map +1 -1
- package/internal/ThemeShowcase/ThemeShowcase.md +13 -13
- package/internal/ZIndex/ZIndex/ZIndex.js +55 -7
- package/internal/ZIndex/ZIndex/ZIndex.js.map +1 -1
- package/internal/ZIndex/ZIndex.d.ts +7 -3
- package/internal/themes/Theme2022Dark/Theme2022Dark.js +1 -1
- package/internal/themes/Theme2022Dark/Theme2022Dark.js.map +1 -1
- package/lib/events/MouseDrag/MouseDrag.js.map +1 -1
- package/lib/events/MouseDrag.d.ts +1 -1
- package/lib/events/keyboard/identifiers/identifiers.js +13 -0
- package/lib/events/keyboard/identifiers/identifiers.js.map +1 -1
- package/lib/events/keyboard/identifiers.d.ts +3 -0
- package/lib/listenFocusOutside/listenFocusOutside.js +3 -2
- package/lib/listenFocusOutside/listenFocusOutside.js.map +1 -1
- package/lib/styles/HoldSelectionColor/HoldSelectionColor.js +1 -1
- package/lib/styles/HoldSelectionColor/HoldSelectionColor.js.map +1 -1
- package/lib/styles/UiFont/UiFont.js +27 -0
- package/lib/styles/UiFont/UiFont.js.map +1 -0
- package/lib/styles/UiFont/package.json +6 -0
- package/lib/styles/UiFont.d.ts +4 -0
- package/package.json +2 -5
- package/cjs/internal/MaskedInputElement/MaskedInputElement.d.ts +0 -14
- package/cjs/internal/MaskedInputElement/MaskedInputElement.helpers.d.ts +0 -16
- package/cjs/internal/MaskedInputElement/MaskedInputElement.helpers.js +0 -52
- package/cjs/internal/MaskedInputElement/MaskedInputElement.helpers.js.map +0 -1
- package/cjs/internal/MaskedInputElement/MaskedInputElement.js +0 -196
- package/cjs/internal/MaskedInputElement/MaskedInputElement.js.map +0 -1
- package/cjs/internal/MaskedInputElement/MaskedInputElement.styles.d.ts +0 -6
- package/cjs/internal/MaskedInputElement/MaskedInputElement.styles.js +0 -29
- package/cjs/internal/MaskedInputElement/MaskedInputElement.styles.js.map +0 -1
- package/cjs/internal/MaskedInputElement/index.d.ts +0 -1
- package/cjs/internal/MaskedInputElement/index.js +0 -1
- package/cjs/internal/MaskedInputElement/index.js.map +0 -1
- package/internal/MaskedInputElement/MaskedInputElement/MaskedInputElement.js +0 -206
- package/internal/MaskedInputElement/MaskedInputElement/MaskedInputElement.js.map +0 -1
- package/internal/MaskedInputElement/MaskedInputElement/package.json +0 -6
- package/internal/MaskedInputElement/MaskedInputElement.d.ts +0 -14
- package/internal/MaskedInputElement/MaskedInputElement.helpers/MaskedInputElement.helpers.js +0 -43
- package/internal/MaskedInputElement/MaskedInputElement.helpers/MaskedInputElement.helpers.js.map +0 -1
- package/internal/MaskedInputElement/MaskedInputElement.helpers/package.json +0 -6
- package/internal/MaskedInputElement/MaskedInputElement.helpers.d.ts +0 -16
- package/internal/MaskedInputElement/MaskedInputElement.styles/MaskedInputElement.styles.js +0 -16
- package/internal/MaskedInputElement/MaskedInputElement.styles/MaskedInputElement.styles.js.map +0 -1
- package/internal/MaskedInputElement/MaskedInputElement.styles/package.json +0 -6
- package/internal/MaskedInputElement/MaskedInputElement.styles.d.ts +0 -6
- package/internal/MaskedInputElement/index/index.js +0 -1
- package/internal/MaskedInputElement/index/index.js.map +0 -1
- package/internal/MaskedInputElement/index/package.json +0 -6
- package/internal/MaskedInputElement/index.d.ts +0 -1
- package/internal/MaskedInputElement/package.json +0 -6
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
3
|
-
var _excluded = ["mask", "maskChar", "formatChars", "alwaysShowMask", "
|
|
4
|
-
import React, { useImperativeHandle, useRef, useState } from 'react';
|
|
5
|
-
import { Input } from "../../Input";
|
|
6
|
-
import { MaskedInputElement } from "../../../internal/MaskedInputElement";
|
|
3
|
+
var _excluded = ["mask", "maskChar", "formatChars", "alwaysShowMask", "colored", "imaskProps", "unmask", "onValueChange", "onUnexpectedInput", "onChange", "element", "className"];
|
|
4
|
+
import React, { useImperativeHandle, useRef, useState, useEffect } from 'react';
|
|
7
5
|
import { forwardRefAndName } from "../../../lib/forwardRefAndName";
|
|
6
|
+
import { cx } from "../../../lib/theming/Emotion";
|
|
7
|
+
import { uiFontGlobalClasses } from "../../../lib/styles/UiFont";
|
|
8
|
+
import { Input } from "../../Input";
|
|
9
|
+
import { isKeyBackspace, isKeyDelete } from "../../../lib/events/keyboard/identifiers";
|
|
10
|
+
import { globalClasses } from "../MaskedInput.styles";
|
|
11
|
+
import { getDefinitions, getMaskChar } from "../MaskedInput.helpers";
|
|
12
|
+
import { ColorableInputElement } from "../ColorableInputElement";
|
|
13
|
+
import { FixedIMaskInput } from "../FixedIMaskInput";
|
|
8
14
|
/**
|
|
9
15
|
* Интерфейс пропсов наследуется от `Input`.
|
|
10
16
|
* Из пропсов `Input` исключены некоторые не применимые к полю с маской пропсы и сокращен список возможных значений в type.
|
|
@@ -14,49 +20,151 @@ export var MaskedInput = forwardRefAndName('MaskedInput', function MaskedInput(p
|
|
|
14
20
|
var mask = props.mask,
|
|
15
21
|
maskChar = props.maskChar,
|
|
16
22
|
formatChars = props.formatChars,
|
|
17
|
-
alwaysShowMask = props.alwaysShowMask,
|
|
18
|
-
|
|
23
|
+
_props$alwaysShowMask = props.alwaysShowMask,
|
|
24
|
+
alwaysShowMask = _props$alwaysShowMask === void 0 ? false : _props$alwaysShowMask,
|
|
25
|
+
_props$colored = props.colored,
|
|
26
|
+
colored = _props$colored === void 0 ? true : _props$colored,
|
|
27
|
+
_props$imaskProps = props.imaskProps,
|
|
28
|
+
customIMaskProps = _props$imaskProps === void 0 ? {} : _props$imaskProps,
|
|
29
|
+
_props$unmask = props.unmask,
|
|
30
|
+
unmask = _props$unmask === void 0 ? false : _props$unmask,
|
|
31
|
+
onValueChange = props.onValueChange,
|
|
32
|
+
onUnexpectedInput = props.onUnexpectedInput,
|
|
33
|
+
onChange = props.onChange,
|
|
34
|
+
element = props.element,
|
|
35
|
+
className = props.className,
|
|
19
36
|
inputProps = _objectWithoutPropertiesLoose(props, _excluded);
|
|
20
37
|
|
|
38
|
+
var inputRef = useRef(null);
|
|
39
|
+
|
|
21
40
|
var _useState = useState(false),
|
|
22
41
|
focused = _useState[0],
|
|
23
42
|
setFocused = _useState[1];
|
|
24
43
|
|
|
25
|
-
var
|
|
26
|
-
var
|
|
44
|
+
var prevValue = useRef(props.value || String(props.defaultValue) || '');
|
|
45
|
+
var prevSelectionStart = useRef(null);
|
|
27
46
|
useImperativeHandle(ref, function () {
|
|
28
|
-
return
|
|
29
|
-
|
|
47
|
+
return inputRef.current && Object.assign(inputRef.current, {
|
|
48
|
+
selectAll: inputRef.current.delaySelectAll
|
|
49
|
+
});
|
|
50
|
+
}, []);
|
|
51
|
+
useEffect(function () {
|
|
52
|
+
var _inputRef$current; // Для корректной работы onUnexpectedInput надо знать предыдущий value,
|
|
53
|
+
// но imask при монтировании не вызывает onAccept, если value невалиден или laze=false.
|
|
54
|
+
// Поэтому актуальный value при монтировании надо получать вручную
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if ((_inputRef$current = inputRef.current) != null && _inputRef$current.input) {
|
|
58
|
+
prevValue.current = inputRef.current.input.value;
|
|
59
|
+
prevSelectionStart.current = inputRef.current.input.selectionStart;
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
var imaskProps = getCompatibleIMaskProps();
|
|
30
63
|
return /*#__PURE__*/React.createElement(Input, _extends({
|
|
31
|
-
ref:
|
|
64
|
+
ref: inputRef
|
|
32
65
|
}, inputProps, {
|
|
33
|
-
placeholder: showPlaceholder ? placeholder : undefined,
|
|
34
66
|
onFocus: handleFocus,
|
|
35
67
|
onBlur: handleBlur,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
68
|
+
onInput: handleInput,
|
|
69
|
+
onKeyDown: handleKeyDown,
|
|
70
|
+
className: cx(globalClasses.root, uiFontGlobalClasses.root, className),
|
|
71
|
+
element: colored ? /*#__PURE__*/React.createElement(ColorableInputElement, {
|
|
72
|
+
showOnFocus: false
|
|
73
|
+
}, /*#__PURE__*/React.createElement(FixedIMaskInput, _extends({}, imaskProps, {
|
|
74
|
+
onAccept: handleAccept
|
|
75
|
+
}))) : /*#__PURE__*/React.createElement(FixedIMaskInput, _extends({}, imaskProps, {
|
|
76
|
+
onAccept: handleAccept
|
|
77
|
+
}))
|
|
43
78
|
}));
|
|
44
79
|
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
80
|
+
function getCompatibleIMaskProps() {
|
|
81
|
+
return _extends({
|
|
82
|
+
mask: mask.replace(/0/g, '{\\0}'),
|
|
83
|
+
placeholderChar: getMaskChar(maskChar),
|
|
84
|
+
definitions: getDefinitions(formatChars),
|
|
85
|
+
// FIXME: Должно быть eager=true, но в imask ломается удаление по delete
|
|
86
|
+
eager: 'append',
|
|
87
|
+
overwrite: 'shift',
|
|
88
|
+
lazy: !alwaysShowMask && (props.disabled || !focused),
|
|
89
|
+
unmask: unmask
|
|
90
|
+
}, customIMaskProps);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function handleAccept() {
|
|
94
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
95
|
+
args[_key] = arguments[_key];
|
|
50
96
|
}
|
|
97
|
+
|
|
98
|
+
var value = args[0],
|
|
99
|
+
e = args[2]; // Метод onAccept может вызываться при монтировании, если не задан проп defaultValue.
|
|
100
|
+
// Но нативный input никогда не вызывает onChange при монтировании.
|
|
101
|
+
// Наше событие onValueChange в Input вывается в тех же случаях, что и нативный onChange,
|
|
102
|
+
// поэтому чтобы сохранить консинстентность будем ориентироваться на наличие аргумента e.
|
|
103
|
+
// Он содержит нативное событие, вызвавшее изменение.
|
|
104
|
+
|
|
105
|
+
e && (onValueChange == null ? void 0 : onValueChange(value));
|
|
106
|
+
!e && (prevValue.current = value);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Отслеживаем неожиданные нажатия
|
|
110
|
+
* handleAccept не вызывается когда значение с маской не меняется
|
|
111
|
+
* Сначала вызывается handleAccept, затем handleInput
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
function handleInput(e) {
|
|
116
|
+
var _e$currentTarget = e.currentTarget,
|
|
117
|
+
value = _e$currentTarget.value,
|
|
118
|
+
selectionStart = _e$currentTarget.selectionStart; // При вводе неожиданных символов или удалении каретка может перепрыгивать фиксированные символы.
|
|
119
|
+
// Такие случаи не расцениваем как неожиданный ввод, т.к. пользователь может намеренно их вводить.
|
|
120
|
+
|
|
121
|
+
if (prevValue.current === value && selectionStart === prevSelectionStart.current) {
|
|
122
|
+
handleUnexpectedInput(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
prevValue.current = value;
|
|
126
|
+
prevSelectionStart.current = selectionStart;
|
|
127
|
+
props.onInput == null ? void 0 : props.onInput(e);
|
|
51
128
|
}
|
|
52
129
|
|
|
53
130
|
function handleFocus(e) {
|
|
131
|
+
var _inputRef$current2;
|
|
132
|
+
|
|
54
133
|
setFocused(true);
|
|
55
|
-
props.onFocus
|
|
134
|
+
props.onFocus == null ? void 0 : props.onFocus(e); // Если value из пропов отличается от value, которое получит input после обработки,
|
|
135
|
+
// то imask будет ставить каретку за последним валидным символом.
|
|
136
|
+
|
|
137
|
+
props.selectAllOnFocus && ((_inputRef$current2 = inputRef.current) == null ? void 0 : _inputRef$current2.delaySelectAll());
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function handleUnexpectedInput(value) {
|
|
141
|
+
var _inputRef$current3;
|
|
142
|
+
|
|
143
|
+
var blink = ((_inputRef$current3 = inputRef.current) == null ? void 0 : _inputRef$current3.blink.bind(inputRef.current)) || function () {
|
|
144
|
+
return undefined;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
onUnexpectedInput ? onUnexpectedInput(value, blink) : blink();
|
|
56
148
|
}
|
|
57
149
|
|
|
58
150
|
function handleBlur(e) {
|
|
59
151
|
setFocused(false);
|
|
60
|
-
props.onBlur
|
|
152
|
+
props.onBlur == null ? void 0 : props.onBlur(e);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function handleKeyDown(e) {
|
|
156
|
+
var _e$currentTarget2 = e.currentTarget,
|
|
157
|
+
value = _e$currentTarget2.value,
|
|
158
|
+
selectionStart = _e$currentTarget2.selectionStart,
|
|
159
|
+
selectionEnd = _e$currentTarget2.selectionEnd;
|
|
160
|
+
|
|
161
|
+
if (isKeyBackspace(e) && selectionStart === 0 && selectionEnd === 0 || isKeyDelete(e) && prevSelectionStart.current === value.length) {
|
|
162
|
+
// Случаи, когда нажатие клавиш не тригерит `onInput`
|
|
163
|
+
handleUnexpectedInput(value);
|
|
164
|
+
prevValue.current = e.currentTarget.value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
prevSelectionStart.current = selectionStart;
|
|
168
|
+
props.onKeyDown == null ? void 0 : props.onKeyDown(e);
|
|
61
169
|
}
|
|
62
170
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["MaskedInput.tsx"],"names":["React","useImperativeHandle","useRef","useState","Input","MaskedInputElement","forwardRefAndName","MaskedInput","props","ref","mask","maskChar","formatChars","alwaysShowMask","placeholder","inputProps","focused","setFocused","showPlaceholder","innerRef","current","undefined","handleFocus","handleBlur","handleUnexpectedInput","value","onUnexpectedInput","blink","e","onFocus","onBlur"],"mappings":"mPAAA,OAAOA,KAAP,IAAqBC,mBAArB,EAA0CC,MAA1C,EAAkDC,QAAlD,QAAkE,OAAlE;;AAEA,SAASC,KAAT,QAA6C,UAA7C;;AAEA,SAASC,kBAAT,QAAmC,mCAAnC;AACA,SAASC,iBAAT,QAAkC,6BAAlC;;;;;;;;;;;;;;;;;;;;;;AAsBA;AACA;AACA;AACA;AACA,OAAO,IAAMC,WAAW,GAAGD,iBAAiB;AAC1C,aAD0C;AAE1C,SAASC,WAAT,CAAqBC,KAArB,EAA8CC,GAA9C,EAAsE;AACpE,MAAQC,IAAR,GAAoFF,KAApF,CAAQE,IAAR,CAAcC,QAAd,GAAoFH,KAApF,CAAcG,QAAd,CAAwBC,WAAxB,GAAoFJ,KAApF,CAAwBI,WAAxB,CAAqCC,cAArC,GAAoFL,KAApF,CAAqCK,cAArC,CAAqDC,WAArD,GAAoFN,KAApF,CAAqDM,WAArD,CAAqEC,UAArE,iCAAoFP,KAApF;AACA,kBAA8BL,QAAQ,CAAC,KAAD,CAAtC,CAAOa,OAAP,gBAAgBC,UAAhB;AACA,MAAMC,eAAe,GAAG,EAAEL,cAAc,IAAIG,OAApB,CAAxB;AACA,MAAMG,QAAQ,GAAGjB,MAAM,CAAQ,IAAR,CAAvB;;AAEAD,EAAAA,mBAAmB,CAACQ,GAAD,EAAM,oBAAMU,QAAQ,CAACC,OAAf,EAAN,CAAnB;;AAEA;AACE,wBAAC,KAAD;AACE,MAAA,GAAG,EAAED,QADP;AAEMJ,IAAAA,UAFN;AAGE,MAAA,WAAW,EAAEG,eAAe,GAAGJ,WAAH,GAAiBO,SAH/C;AAIE,MAAA,OAAO,EAAEC,WAJX;AAKE,MAAA,MAAM,EAAEC,UALV;AAME,MAAA,OAAO;AACL,0BAAC,kBAAD;AACE,QAAA,IAAI,EAAEb,IADR;AAEE,QAAA,QAAQ,EAAEC,QAFZ;AAGE,QAAA,WAAW,EAAEC,WAHf;AAIE,QAAA,cAAc,EAAEC,cAJlB;AAKE,QAAA,iBAAiB,EAAEW,qBALrB,GAPJ,IADF;;;;;;AAmBA,WAASA,qBAAT,CAA+BC,KAA/B,EAA8C;AAC5C,QAAIjB,KAAK,CAACkB,iBAAV,EAA6B;AAC3BlB,MAAAA,KAAK,CAACkB,iBAAN,CAAwBD,KAAxB;AACD,KAFD,MAEO,IAAIN,QAAQ,CAACC,OAAb,EAAsB;AAC3BD,MAAAA,QAAQ,CAACC,OAAT,CAAiBO,KAAjB;AACD;AACF;;AAED,WAASL,WAAT,CAAqBM,CAArB,EAA4D;AAC1DX,IAAAA,UAAU,CAAC,IAAD,CAAV;AACAT,IAAAA,KAAK,CAACqB,OAAN,IAAiBrB,KAAK,CAACqB,OAAN,CAAcD,CAAd,CAAjB;AACD;;AAED,WAASL,UAAT,CAAoBK,CAApB,EAA2D;AACzDX,IAAAA,UAAU,CAAC,KAAD,CAAV;AACAT,IAAAA,KAAK,CAACsB,MAAN,IAAgBtB,KAAK,CAACsB,MAAN,CAAaF,CAAb,CAAhB;AACD;AACF,CA9CyC,CAArC","sourcesContent":["import React, { Ref, useImperativeHandle, useRef, useState } from 'react';\n\nimport { Input, InputProps, InputType } from '../Input';\nimport { Nullable } from '../../typings/utility-types';\nimport { MaskedInputElement } from '../../internal/MaskedInputElement';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName';\n\nexport interface MaskedProps {\n /** Паттерн маски */\n mask: string;\n /** Символ маски */\n maskChar?: Nullable<string>;\n /**\n * Словарь символов-регулярок для маски\n * @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' }\n */\n formatChars?: Record<string, string>;\n /** Показывать символы маски */\n alwaysShowMask?: boolean;\n}\n\nexport type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;\n\nexport interface MaskedInputProps extends MaskedProps, Omit<InputProps, 'mask' | 'maxLength' | 'type' | 'element'> {\n type?: MaskInputType;\n}\n\n/**\n * Интерфейс пропсов наследуется от `Input`.\n * Из пропсов `Input` исключены некоторые не применимые к полю с маской пропсы и сокращен список возможных значений в type.\n */\nexport const MaskedInput = forwardRefAndName(\n 'MaskedInput',\n function MaskedInput(props: MaskedInputProps, ref: Ref<Input | null>) {\n const { mask, maskChar, formatChars, alwaysShowMask, placeholder, ...inputProps } = props;\n const [focused, setFocused] = useState(false);\n const showPlaceholder = !(alwaysShowMask || focused);\n const innerRef = useRef<Input>(null);\n\n useImperativeHandle(ref, () => innerRef.current);\n\n return (\n <Input\n ref={innerRef}\n {...inputProps}\n placeholder={showPlaceholder ? placeholder : undefined}\n onFocus={handleFocus}\n onBlur={handleBlur}\n element={\n <MaskedInputElement\n mask={mask}\n maskChar={maskChar}\n formatChars={formatChars}\n alwaysShowMask={alwaysShowMask}\n onUnexpectedInput={handleUnexpectedInput}\n />\n }\n />\n );\n\n function handleUnexpectedInput(value: string) {\n if (props.onUnexpectedInput) {\n props.onUnexpectedInput(value);\n } else if (innerRef.current) {\n innerRef.current.blink();\n }\n }\n\n function handleFocus(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(true);\n props.onFocus && props.onFocus(e);\n }\n\n function handleBlur(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(false);\n props.onBlur && props.onBlur(e);\n }\n },\n);\n"]}
|
|
1
|
+
{"version":3,"sources":["MaskedInput.tsx"],"names":["React","useImperativeHandle","useRef","useState","useEffect","forwardRefAndName","cx","uiFontGlobalClasses","Input","isKeyBackspace","isKeyDelete","globalClasses","getDefinitions","getMaskChar","ColorableInputElement","FixedIMaskInput","MaskedInput","props","ref","mask","maskChar","formatChars","alwaysShowMask","colored","imaskProps","customIMaskProps","unmask","onValueChange","onUnexpectedInput","onChange","element","className","inputProps","inputRef","focused","setFocused","prevValue","value","String","defaultValue","prevSelectionStart","current","Object","assign","selectAll","delaySelectAll","input","selectionStart","getCompatibleIMaskProps","handleFocus","handleBlur","handleInput","handleKeyDown","root","handleAccept","replace","placeholderChar","definitions","eager","overwrite","lazy","disabled","args","e","currentTarget","handleUnexpectedInput","onInput","onFocus","selectAllOnFocus","blink","bind","undefined","onBlur","selectionEnd","length","onKeyDown"],"mappings":"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","sourcesContent":["import React, { Ref, useImperativeHandle, useRef, useState, useEffect } from 'react';\nimport { IMaskInputProps } from 'react-imask';\n\nimport { Nullable } from '../../typings/utility-types';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName';\nimport { cx } from '../../lib/theming/Emotion';\nimport { uiFontGlobalClasses } from '../../lib/styles/UiFont';\nimport { Input, InputProps, InputType } from '../Input';\nimport { isKeyBackspace, isKeyDelete } from '../../lib/events/keyboard/identifiers';\n\nimport { globalClasses } from './MaskedInput.styles';\nimport { getDefinitions, getMaskChar } from './MaskedInput.helpers';\nimport { ColorableInputElement } from './ColorableInputElement';\nimport { FixedIMaskInput } from './FixedIMaskInput';\n\nexport interface MaskedProps {\n /** Паттерн маски */\n mask: string;\n /**\n * Символ маски\n *\n * @default _\n */\n maskChar?: Nullable<string>;\n /**\n * Словарь символов-регулярок для маски\n *\n * @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' }\n */\n formatChars?: Record<string, string>;\n /**\n * Всегда показывать символы маски\n *\n * @default false\n */\n alwaysShowMask?: boolean;\n /**\n * Обработчик неправильного ввода.\n * Вторым агрументом будет передан метод вспыхивания акцентным цветом.\n *\n * Если обработчик не задан, то инпут вспыхивает по-умолчанию.\n *\n * @param value значение инпута.\n * @param blink вспыхнуть акцентным цвтетом.\n */\n onUnexpectedInput?: (value: string, blink: () => void) => void;\n /**\n * Убирать из value символы, не введённые пользователем\n *\n * @default false\n */\n unmask?: boolean;\n /**\n * Раскрашивать символы маски\n *\n * @default true\n * @ignore\n */\n colored?: boolean;\n /**\n * Пропы для компонента `IMaskInput`. Необходимы для юнит-тестов\n *\n * @ignore\n */\n imaskProps?: IMaskInputProps<HTMLInputElement>;\n}\n\nexport type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;\n\nexport interface MaskedInputProps\n extends MaskedProps,\n Omit<InputProps, 'mask' | 'maxLength' | 'type' | 'alwaysShowMask' | 'onUnexpectedInput'> {\n type?: MaskInputType;\n}\n\n/**\n * Интерфейс пропсов наследуется от `Input`.\n * Из пропсов `Input` исключены некоторые не применимые к полю с маской пропсы и сокращен список возможных значений в type.\n */\nexport const MaskedInput = forwardRefAndName(\n 'MaskedInput',\n function MaskedInput(props: MaskedInputProps, ref: Ref<Input | null>) {\n const {\n mask,\n maskChar,\n formatChars,\n alwaysShowMask = false,\n colored = true,\n imaskProps: customIMaskProps = {},\n unmask = false,\n onValueChange,\n onUnexpectedInput,\n onChange,\n element,\n className,\n ...inputProps\n } = props;\n\n const inputRef = useRef<Input>(null);\n\n const [focused, setFocused] = useState(false);\n const prevValue = useRef<string>(props.value || String(props.defaultValue) || '');\n const prevSelectionStart = useRef<number | null>(null);\n\n useImperativeHandle(\n ref,\n () =>\n inputRef.current &&\n Object.assign(inputRef.current, {\n selectAll: inputRef.current.delaySelectAll,\n }),\n [],\n );\n\n useEffect(() => {\n // Для корректной работы onUnexpectedInput надо знать предыдущий value,\n // но imask при монтировании не вызывает onAccept, если value невалиден или laze=false.\n // Поэтому актуальный value при монтировании надо получать вручную\n if (inputRef.current?.input) {\n prevValue.current = inputRef.current.input.value;\n prevSelectionStart.current = inputRef.current.input.selectionStart;\n }\n }, []);\n\n const imaskProps = getCompatibleIMaskProps();\n\n return (\n <Input\n ref={inputRef}\n {...inputProps}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onInput={handleInput}\n onKeyDown={handleKeyDown}\n className={cx(globalClasses.root, uiFontGlobalClasses.root, className)}\n element={\n colored ? (\n <ColorableInputElement showOnFocus={false}>\n <FixedIMaskInput {...imaskProps} onAccept={handleAccept} />\n </ColorableInputElement>\n ) : (\n <FixedIMaskInput {...imaskProps} onAccept={handleAccept} />\n )\n }\n />\n );\n\n function getCompatibleIMaskProps(): IMaskInputProps<HTMLInputElement> {\n return {\n mask: mask.replace(/0/g, '{\\\\0}') as any,\n placeholderChar: getMaskChar(maskChar),\n definitions: getDefinitions(formatChars),\n // FIXME: Должно быть eager=true, но в imask ломается удаление по delete\n eager: 'append',\n overwrite: 'shift',\n lazy: !alwaysShowMask && (props.disabled || !focused),\n unmask,\n ...customIMaskProps,\n } as IMaskInputProps<HTMLInputElement>;\n }\n\n function handleAccept(...args: Parameters<Required<IMaskInputProps<HTMLInputElement>>['onAccept']>) {\n const [value, , e] = args;\n\n // Метод onAccept может вызываться при монтировании, если не задан проп defaultValue.\n // Но нативный input никогда не вызывает onChange при монтировании.\n // Наше событие onValueChange в Input вывается в тех же случаях, что и нативный onChange,\n // поэтому чтобы сохранить консинстентность будем ориентироваться на наличие аргумента e.\n // Он содержит нативное событие, вызвавшее изменение.\n e && onValueChange?.(value);\n !e && (prevValue.current = value);\n }\n\n /**\n * Отслеживаем неожиданные нажатия\n * handleAccept не вызывается когда значение с маской не меняется\n * Сначала вызывается handleAccept, затем handleInput\n */\n function handleInput(e: React.ChangeEvent<HTMLInputElement>) {\n const { value, selectionStart } = e.currentTarget;\n\n // При вводе неожиданных символов или удалении каретка может перепрыгивать фиксированные символы.\n // Такие случаи не расцениваем как неожиданный ввод, т.к. пользователь может намеренно их вводить.\n if (prevValue.current === value && selectionStart === prevSelectionStart.current) {\n handleUnexpectedInput(value);\n }\n prevValue.current = value;\n prevSelectionStart.current = selectionStart;\n\n props.onInput?.(e);\n }\n\n function handleFocus(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(true);\n props.onFocus?.(e);\n\n // Если value из пропов отличается от value, которое получит input после обработки,\n // то imask будет ставить каретку за последним валидным символом.\n props.selectAllOnFocus && inputRef.current?.delaySelectAll();\n }\n\n function handleUnexpectedInput(value: string) {\n const blink = inputRef.current?.blink.bind(inputRef.current) || (() => undefined);\n onUnexpectedInput ? onUnexpectedInput(value, blink) : blink();\n }\n\n function handleBlur(e: React.FocusEvent<HTMLInputElement>) {\n setFocused(false);\n props.onBlur?.(e);\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n const { value, selectionStart, selectionEnd } = e.currentTarget;\n\n if (\n (isKeyBackspace(e) && selectionStart === 0 && selectionEnd === 0) ||\n (isKeyDelete(e) && prevSelectionStart.current === value.length)\n ) {\n // Случаи, когда нажатие клавиш не тригерит `onInput`\n handleUnexpectedInput(value);\n prevValue.current = e.currentTarget.value;\n }\n prevSelectionStart.current = selectionStart;\n\n props.onKeyDown?.(e);\n }\n },\n);\n"]}
|
|
@@ -1,20 +1,59 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IMaskInputProps } from 'react-imask';
|
|
2
2
|
import { Nullable } from '../../typings/utility-types';
|
|
3
|
+
import { Input, InputProps, InputType } from '../Input';
|
|
3
4
|
export interface MaskedProps {
|
|
4
5
|
/** Паттерн маски */
|
|
5
6
|
mask: string;
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Символ маски
|
|
9
|
+
*
|
|
10
|
+
* @default _
|
|
11
|
+
*/
|
|
7
12
|
maskChar?: Nullable<string>;
|
|
8
13
|
/**
|
|
9
14
|
* Словарь символов-регулярок для маски
|
|
15
|
+
*
|
|
10
16
|
* @default { '9': '[0-9]', 'a': '[A-Za-z]', '*': '[A-Za-z0-9]' }
|
|
11
17
|
*/
|
|
12
18
|
formatChars?: Record<string, string>;
|
|
13
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Всегда показывать символы маски
|
|
21
|
+
*
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
14
24
|
alwaysShowMask?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Обработчик неправильного ввода.
|
|
27
|
+
* Вторым агрументом будет передан метод вспыхивания акцентным цветом.
|
|
28
|
+
*
|
|
29
|
+
* Если обработчик не задан, то инпут вспыхивает по-умолчанию.
|
|
30
|
+
*
|
|
31
|
+
* @param value значение инпута.
|
|
32
|
+
* @param blink вспыхнуть акцентным цвтетом.
|
|
33
|
+
*/
|
|
34
|
+
onUnexpectedInput?: (value: string, blink: () => void) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Убирать из value символы, не введённые пользователем
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
unmask?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Раскрашивать символы маски
|
|
43
|
+
*
|
|
44
|
+
* @default true
|
|
45
|
+
* @ignore
|
|
46
|
+
*/
|
|
47
|
+
colored?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Пропы для компонента `IMaskInput`. Необходимы для юнит-тестов
|
|
50
|
+
*
|
|
51
|
+
* @ignore
|
|
52
|
+
*/
|
|
53
|
+
imaskProps?: IMaskInputProps<HTMLInputElement>;
|
|
15
54
|
}
|
|
16
55
|
export declare type MaskInputType = Exclude<InputType, 'number' | 'date' | 'time' | 'password'>;
|
|
17
|
-
export interface MaskedInputProps extends MaskedProps, Omit<InputProps, 'mask' | 'maxLength' | 'type' | '
|
|
56
|
+
export interface MaskedInputProps extends MaskedProps, Omit<InputProps, 'mask' | 'maxLength' | 'type' | 'alwaysShowMask' | 'onUnexpectedInput'> {
|
|
18
57
|
type?: MaskInputType;
|
|
19
58
|
}
|
|
20
59
|
/**
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isNonNullable } from "../../../lib/utils";
|
|
2
|
+
export var DEFAULT_MASK_CHAR = '_';
|
|
3
|
+
export var DEFINITIONS = Object.freeze({
|
|
4
|
+
'9': /[0-9]/,
|
|
5
|
+
a: /[A-Za-z]/,
|
|
6
|
+
'*': /[A-Za-z0-9]/
|
|
7
|
+
});
|
|
8
|
+
export function getDefinitions(formatChars) {
|
|
9
|
+
if (isNonNullable(formatChars)) {
|
|
10
|
+
var chars = {};
|
|
11
|
+
|
|
12
|
+
for (var key in formatChars) {
|
|
13
|
+
chars[key] = new RegExp(formatChars[key]);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return chars;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return DEFINITIONS;
|
|
20
|
+
}
|
|
21
|
+
export function getMaskChar(maskChar) {
|
|
22
|
+
if (maskChar === null) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return maskChar === undefined ? DEFAULT_MASK_CHAR : maskChar;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["MaskedInput.helpers.ts"],"names":["isNonNullable","DEFAULT_MASK_CHAR","DEFINITIONS","Object","freeze","a","getDefinitions","formatChars","chars","key","RegExp","getMaskChar","maskChar","undefined"],"mappings":";;AAEA,SAASA,aAAT,QAA8B,iBAA9B;;;;AAIA,OAAO,IAAMC,iBAAiB,GAAG,GAA1B;AACP,OAAO,IAAMC,WAAW,GAAGC,MAAM,CAACC,MAAP,CAAc,EAAE,KAAK,OAAP,EAAgBC,CAAC,EAAE,UAAnB,EAA+B,KAAK,aAApC,EAAd,CAApB;;AAEP,OAAO,SAASC,cAAT,CAAwBC,WAAxB,EAAsF;AAC3F,MAAIP,aAAa,CAACO,WAAD,CAAjB,EAAgC;AAC9B,QAAMC,KAA6B,GAAG,EAAtC;;AAEA,SAAK,IAAMC,GAAX,IAAkBF,WAAlB,EAA+B;AAC7BC,MAAAA,KAAK,CAACC,GAAD,CAAL,GAAa,IAAIC,MAAJ,CAAWH,WAAW,CAACE,GAAD,CAAtB,CAAb;AACD;;AAED,WAAOD,KAAP;AACD;;AAED,SAAON,WAAP;AACD;;AAED,OAAO,SAASS,WAAT,CAAqBC,QAArB,EAAkE;AACvE,MAAIA,QAAQ,KAAK,IAAjB,EAAuB;AACrB,WAAO,EAAP;AACD;;AAED,SAAOA,QAAQ,KAAKC,SAAb,GAAyBZ,iBAAzB,GAA6CW,QAApD;AACD","sourcesContent":["import IMask, { Definitions } from 'imask';\n\nimport { isNonNullable } from '../../lib/utils';\n\nexport type AnyIMaskType = ReturnType<typeof IMask.createMask>;\n\nexport const DEFAULT_MASK_CHAR = '_';\nexport const DEFINITIONS = Object.freeze({ '9': /[0-9]/, a: /[A-Za-z]/, '*': /[A-Za-z0-9]/ });\n\nexport function getDefinitions(formatChars: Record<string, string> | undefined): Definitions {\n if (isNonNullable(formatChars)) {\n const chars: Record<string, RegExp> = {};\n\n for (const key in formatChars) {\n chars[key] = new RegExp(formatChars[key]);\n }\n\n return chars;\n }\n\n return DEFINITIONS;\n}\n\nexport function getMaskChar(maskChar: string | null | undefined): string {\n if (maskChar === null) {\n return '';\n }\n\n return maskChar === undefined ? DEFAULT_MASK_CHAR : maskChar;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import IMask, { Definitions } from 'imask';
|
|
2
|
+
export declare type AnyIMaskType = ReturnType<typeof IMask.createMask>;
|
|
3
|
+
export declare const DEFAULT_MASK_CHAR = "_";
|
|
4
|
+
export declare const DEFINITIONS: Readonly<{
|
|
5
|
+
'9': RegExp;
|
|
6
|
+
a: RegExp;
|
|
7
|
+
'*': RegExp;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function getDefinitions(formatChars: Record<string, string> | undefined): Definitions;
|
|
10
|
+
export declare function getMaskChar(maskChar: string | null | undefined): string;
|
|
@@ -1,21 +1,112 @@
|
|
|
1
|
+
#### `mask`
|
|
2
|
+
|
|
3
|
+
Паттерн ввода. Пример с номером телефона.
|
|
4
|
+
|
|
1
5
|
```jsx harmony
|
|
2
|
-
|
|
6
|
+
const [value, setValue] = React.useState('');
|
|
7
|
+
|
|
8
|
+
<>
|
|
9
|
+
<span>value: "{value}"</span>
|
|
10
|
+
<br />
|
|
11
|
+
<br />
|
|
12
|
+
<MaskedInput
|
|
13
|
+
mask="+7 (999) 999-99-99"
|
|
14
|
+
placeholder="Номер телефона"
|
|
15
|
+
value={value}
|
|
16
|
+
onValueChange={setValue}
|
|
17
|
+
/>
|
|
18
|
+
</>
|
|
3
19
|
```
|
|
4
20
|
|
|
5
|
-
|
|
21
|
+
#### `alwaysShowMask`
|
|
22
|
+
|
|
23
|
+
Показывает маску всегда.
|
|
24
|
+
|
|
6
25
|
```jsx harmony
|
|
7
|
-
<MaskedInput mask=
|
|
26
|
+
<MaskedInput mask="+7 (999) 999-99-99" alwaysShowMask />
|
|
8
27
|
```
|
|
9
28
|
|
|
10
|
-
|
|
29
|
+
#### `maskChar`
|
|
30
|
+
|
|
31
|
+
Символом маски может быть любой символ.
|
|
32
|
+
|
|
11
33
|
```jsx harmony
|
|
12
|
-
|
|
34
|
+
const [value, setValue] = React.useState('');
|
|
35
|
+
|
|
36
|
+
<>
|
|
37
|
+
<span>value: "{value}"</span>
|
|
38
|
+
<br />
|
|
39
|
+
<br />
|
|
40
|
+
<MaskedInput
|
|
41
|
+
mask="9999 9999 9999 9999"
|
|
42
|
+
maskChar="X"
|
|
43
|
+
placeholder="Номер карты"
|
|
44
|
+
alwaysShowMask
|
|
45
|
+
value={value}
|
|
46
|
+
onValueChange={setValue}
|
|
47
|
+
/>
|
|
48
|
+
</>
|
|
13
49
|
```
|
|
14
50
|
|
|
15
|
-
|
|
51
|
+
#### `formatChars`
|
|
16
52
|
|
|
17
|
-
|
|
53
|
+
При необходимости можно настроить собственный словарь.
|
|
18
54
|
|
|
19
|
-
|
|
55
|
+
```jsx harmony
|
|
56
|
+
const [value, setValue] = React.useState('');
|
|
57
|
+
|
|
58
|
+
<MaskedInput
|
|
59
|
+
mask="Hh:Mm:Ss"
|
|
60
|
+
alwaysShowMask
|
|
61
|
+
formatChars={{
|
|
62
|
+
H: '[0-2]',
|
|
63
|
+
h: value.startsWith('2') ? '[0-3]' : '[0-9]',
|
|
64
|
+
M: '[0-5]',
|
|
65
|
+
m: '[0-9]',
|
|
66
|
+
S: '[0-5]',
|
|
67
|
+
s: '[0-9]',
|
|
68
|
+
}}
|
|
69
|
+
value={value}
|
|
70
|
+
onValueChange={setValue}
|
|
71
|
+
/>
|
|
72
|
+
```
|
|
20
73
|
|
|
21
|
-
|
|
74
|
+
#### `unmask`
|
|
75
|
+
|
|
76
|
+
Можно сразу получать очищенный value, содержащий только введённый пользователем символы.
|
|
77
|
+
|
|
78
|
+
```jsx harmony
|
|
79
|
+
const [value, setValue] = React.useState('');
|
|
80
|
+
|
|
81
|
+
<>
|
|
82
|
+
<span>value: "{value}"</span>
|
|
83
|
+
<br />
|
|
84
|
+
<br />
|
|
85
|
+
<MaskedInput
|
|
86
|
+
mask="+7 (999) 999-99-99"
|
|
87
|
+
unmask
|
|
88
|
+
alwaysShowMask
|
|
89
|
+
value={value}
|
|
90
|
+
onValueChange={setValue}
|
|
91
|
+
/>
|
|
92
|
+
</>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Если обернуть фиксированные символы в фигурные скобки, то они попадут в `value` при `unmask = true`.
|
|
96
|
+
|
|
97
|
+
```jsx harmony
|
|
98
|
+
const [value, setValue] = React.useState('');
|
|
99
|
+
|
|
100
|
+
<>
|
|
101
|
+
<span>value: "{value}"</span>
|
|
102
|
+
<br />
|
|
103
|
+
<br />
|
|
104
|
+
<MaskedInput
|
|
105
|
+
mask="+{7} (999) 999-99-99"
|
|
106
|
+
unmask
|
|
107
|
+
alwaysShowMask
|
|
108
|
+
value={value}
|
|
109
|
+
onValueChange={setValue}
|
|
110
|
+
/>
|
|
111
|
+
</>
|
|
112
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["MaskedInput.styles.ts"],"names":["prefix","globalClasses","root"],"mappings":"AAAA,SAASA,MAAT,QAAuB,2BAAvB;;AAEA,OAAO,IAAMC,aAAa,GAAGD,MAAM,CAAC,cAAD,CAAN,CAAuB;AAClDE,EAAAA,IAAI,EAAE,MAD4C,EAAvB,CAAtB","sourcesContent":["import { prefix } from '../../lib/theming/Emotion';\n\nexport const globalClasses = prefix('masked-input')({\n root: 'root',\n});\n"]}
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
```jsx harmony
|
|
2
|
-
import { Gapped, Radio } from '@skbkontur/react-ui';
|
|
3
|
-
|
|
4
|
-
let items = ['One', 'Two', 'Three', 'Four'];
|
|
5
|
-
|
|
6
|
-
let simpleRadioGroup = (
|
|
7
|
-
<div>
|
|
8
|
-
<h2>Numbers</h2>
|
|
9
|
-
<RadioGroup name="number-simple" items={items} defaultValue="One" />
|
|
10
|
-
</div>
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
let complexRadioGroup = (
|
|
14
|
-
<div>
|
|
15
|
-
<h2>Numbers</h2>
|
|
16
|
-
<RadioGroup name="number-complex" defaultValue="3">
|
|
17
|
-
<Gapped gap={40}>
|
|
18
|
-
<Gapped vertical gap={0}>
|
|
19
|
-
<b>Odd</b>
|
|
20
|
-
<Radio value="1">One</Radio>
|
|
21
|
-
<Radio value="3">Three</Radio>
|
|
22
|
-
<Radio value="5" disabled>
|
|
23
|
-
Five
|
|
24
|
-
</Radio>
|
|
25
|
-
<Radio value="7">Seven</Radio>
|
|
26
|
-
</Gapped>
|
|
27
|
-
<Gapped vertical gap={0}>
|
|
28
|
-
<b>Even</b>
|
|
29
|
-
<Radio value="2">Two</Radio>
|
|
30
|
-
<Radio value="4">Four</Radio>
|
|
31
|
-
<Radio value="6">Six</Radio>
|
|
32
|
-
<Radio value="8">Eight</Radio>
|
|
33
|
-
</Gapped>
|
|
34
|
-
</Gapped>
|
|
35
|
-
</RadioGroup>
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
<div>
|
|
40
|
-
{simpleRadioGroup}
|
|
41
|
-
{complexRadioGroup}
|
|
42
|
-
</div>;
|
|
43
|
-
```
|
|
1
|
+
```jsx harmony
|
|
2
|
+
import { Gapped, Radio } from '@skbkontur/react-ui';
|
|
3
|
+
|
|
4
|
+
let items = ['One', 'Two', 'Three', 'Four'];
|
|
5
|
+
|
|
6
|
+
let simpleRadioGroup = (
|
|
7
|
+
<div>
|
|
8
|
+
<h2>Numbers</h2>
|
|
9
|
+
<RadioGroup name="number-simple" items={items} defaultValue="One" />
|
|
10
|
+
</div>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
let complexRadioGroup = (
|
|
14
|
+
<div>
|
|
15
|
+
<h2>Numbers</h2>
|
|
16
|
+
<RadioGroup name="number-complex" defaultValue="3">
|
|
17
|
+
<Gapped gap={40}>
|
|
18
|
+
<Gapped vertical gap={0}>
|
|
19
|
+
<b>Odd</b>
|
|
20
|
+
<Radio value="1">One</Radio>
|
|
21
|
+
<Radio value="3">Three</Radio>
|
|
22
|
+
<Radio value="5" disabled>
|
|
23
|
+
Five
|
|
24
|
+
</Radio>
|
|
25
|
+
<Radio value="7">Seven</Radio>
|
|
26
|
+
</Gapped>
|
|
27
|
+
<Gapped vertical gap={0}>
|
|
28
|
+
<b>Even</b>
|
|
29
|
+
<Radio value="2">Two</Radio>
|
|
30
|
+
<Radio value="4">Four</Radio>
|
|
31
|
+
<Radio value="6">Six</Radio>
|
|
32
|
+
<Radio value="8">Eight</Radio>
|
|
33
|
+
</Gapped>
|
|
34
|
+
</Gapped>
|
|
35
|
+
</RadioGroup>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
<div>
|
|
40
|
+
{simpleRadioGroup}
|
|
41
|
+
{complexRadioGroup}
|
|
42
|
+
</div>;
|
|
43
|
+
```
|
|
@@ -16,6 +16,7 @@ import { rootNode } from "../../../lib/rootNode";
|
|
|
16
16
|
import { getDOMRect } from "../../../lib/dom/getDOMRect";
|
|
17
17
|
import { createPropsGetter } from "../../../lib/createPropsGetter";
|
|
18
18
|
import { isTestEnv } from "../../../lib/currentEnvironment";
|
|
19
|
+
import { callChildRef } from "../../../lib/callChildRef/callChildRef";
|
|
19
20
|
import { styles, globalClasses } from "../ScrollContainer.styles";
|
|
20
21
|
import { scrollSizeParametersNames } from "../ScrollContainer.constants";
|
|
21
22
|
import { getScrollYOffset, convertScrollbarXScrollState, convertScrollbarYScrollState } from "../ScrollContainer.helpers";
|
|
@@ -146,6 +147,10 @@ export var ScrollContainer = rootNode(_class = (_temp = _class2 = /*#__PURE__*/f
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
_this.inner = element;
|
|
150
|
+
|
|
151
|
+
if (_this.props.scrollRef) {
|
|
152
|
+
callChildRef(_this.props.scrollRef, element);
|
|
153
|
+
}
|
|
149
154
|
};
|
|
150
155
|
|
|
151
156
|
_this.handleNativeScroll = function (event) {
|