@phpsoftbox/react-softbox 0.5.2 → 0.5.3
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.
|
@@ -4,6 +4,7 @@ type Props = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChan
|
|
|
4
4
|
value?: string;
|
|
5
5
|
onChange?: (value: string) => void;
|
|
6
6
|
placeholderChar?: string;
|
|
7
|
+
escapeChar?: string;
|
|
7
8
|
};
|
|
8
|
-
export default function MaskedInput({ mask, value, onChange, placeholderChar, ...props }: Props): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default function MaskedInput({ mask, value, onChange, placeholderChar, escapeChar, onPaste, ...props }: Props): import("react/jsx-runtime").JSX.Element;
|
|
9
10
|
export {};
|
|
@@ -4,14 +4,23 @@ import InputField from './Field';
|
|
|
4
4
|
const isDigit = (char) => /\d/.test(char);
|
|
5
5
|
const isLetter = (char) => /[a-zA-Z]/.test(char);
|
|
6
6
|
const isAlphaNum = (char) => /[a-zA-Z0-9]/.test(char);
|
|
7
|
-
const
|
|
8
|
-
const applyMask = (raw, mask, placeholderChar) => {
|
|
7
|
+
const isToken = (char) => char === '9' || char === 'A' || char === '*';
|
|
8
|
+
const applyMask = (raw, mask, placeholderChar, escapeChar = '\\') => {
|
|
9
9
|
let rawIndex = 0;
|
|
10
10
|
let output = '';
|
|
11
11
|
for (let i = 0; i < mask.length; i += 1) {
|
|
12
12
|
const maskChar = mask[i];
|
|
13
|
+
if (maskChar === escapeChar) {
|
|
14
|
+
if (i + 1 < mask.length) {
|
|
15
|
+
output += mask[i + 1];
|
|
16
|
+
i += 1;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
output += maskChar;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
13
22
|
const rawChar = raw[rawIndex];
|
|
14
|
-
if (maskChar
|
|
23
|
+
if (isToken(maskChar)) {
|
|
15
24
|
if (!rawChar) {
|
|
16
25
|
if (placeholderChar) {
|
|
17
26
|
output += placeholderChar;
|
|
@@ -36,13 +45,24 @@ const applyMask = (raw, mask, placeholderChar) => {
|
|
|
36
45
|
}
|
|
37
46
|
return output;
|
|
38
47
|
};
|
|
39
|
-
const extractRaw = (masked, mask) => {
|
|
48
|
+
const extractRaw = (masked, mask, escapeChar = '\\') => {
|
|
40
49
|
let raw = '';
|
|
41
50
|
let maskIndex = 0;
|
|
42
51
|
for (let i = 0; i < masked.length && maskIndex < mask.length; i += 1) {
|
|
43
52
|
const maskChar = mask[maskIndex];
|
|
44
53
|
const char = masked[i];
|
|
45
|
-
if (maskChar ===
|
|
54
|
+
if (maskChar === escapeChar) {
|
|
55
|
+
const literal = maskIndex + 1 < mask.length ? mask[maskIndex + 1] : escapeChar;
|
|
56
|
+
if (char === literal) {
|
|
57
|
+
maskIndex += 2;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
maskIndex += 2;
|
|
61
|
+
i -= 1;
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (isToken(maskChar)) {
|
|
46
66
|
const matches = (maskChar === '9' && isDigit(char)) ||
|
|
47
67
|
(maskChar === 'A' && isLetter(char)) ||
|
|
48
68
|
(maskChar === '*' && isAlphaNum(char));
|
|
@@ -62,21 +82,41 @@ const extractRaw = (masked, mask) => {
|
|
|
62
82
|
}
|
|
63
83
|
return raw;
|
|
64
84
|
};
|
|
65
|
-
export default function MaskedInput({ mask, value, onChange, placeholderChar, ...props }) {
|
|
85
|
+
export default function MaskedInput({ mask, value, onChange, placeholderChar, escapeChar = '\\', onPaste, ...props }) {
|
|
66
86
|
const isControlled = value !== undefined;
|
|
67
87
|
const [internal, setInternal] = React.useState('');
|
|
68
88
|
const displayValue = React.useMemo(() => {
|
|
69
|
-
const raw =
|
|
70
|
-
return applyMask(raw, mask, placeholderChar);
|
|
71
|
-
}, [value, internal, mask, placeholderChar, isControlled]);
|
|
89
|
+
const raw = extractRaw(String(isControlled ? value ?? '' : internal), mask, escapeChar);
|
|
90
|
+
return applyMask(raw, mask, placeholderChar, escapeChar);
|
|
91
|
+
}, [value, internal, mask, placeholderChar, isControlled, escapeChar]);
|
|
72
92
|
const handleChange = (event) => {
|
|
73
93
|
const rawInput = event.target.value;
|
|
74
|
-
const raw = extractRaw(rawInput, mask);
|
|
94
|
+
const raw = extractRaw(rawInput, mask, escapeChar);
|
|
95
|
+
if (!isControlled) {
|
|
96
|
+
setInternal(raw);
|
|
97
|
+
}
|
|
98
|
+
onChange?.(raw);
|
|
99
|
+
};
|
|
100
|
+
const handlePaste = (event) => {
|
|
101
|
+
onPaste?.(event);
|
|
102
|
+
if (event.defaultPrevented) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const text = event.clipboardData?.getData('text');
|
|
106
|
+
if (!text) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const raw = extractRaw(text, mask, escapeChar);
|
|
110
|
+
console.log(raw);
|
|
111
|
+
if (!raw) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
event.preventDefault();
|
|
75
115
|
if (!isControlled) {
|
|
76
116
|
setInternal(raw);
|
|
77
117
|
}
|
|
78
118
|
onChange?.(raw);
|
|
79
119
|
};
|
|
80
|
-
return _jsx(InputField, { ...props, value: displayValue, onChange: handleChange });
|
|
120
|
+
return _jsx(InputField, { ...props, value: displayValue, onChange: handleChange, onPaste: handlePaste });
|
|
81
121
|
}
|
|
82
122
|
//# sourceMappingURL=MaskedInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MaskedInput.js","sourceRoot":"","sources":["../../../src/components/Input/MaskedInput.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,UAAU,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"MaskedInput.js","sourceRoot":"","sources":["../../../src/components/Input/MaskedInput.tsx"],"names":[],"mappings":"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"}
|
package/docs/forms.md
CHANGED
|
@@ -177,6 +177,14 @@ const statusOptions = [
|
|
|
177
177
|
</Input>
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
+
`value` можно передавать как в маске, так и в виде "сырых" символов — компонент сам нормализует.
|
|
181
|
+
|
|
182
|
+
Если нужно указать литеральный символ маски `9`/`A`/`*`, экранируйте его через `\`:
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<Input.MaskedInput mask="+7 (\\9 99) 999-99-99" />
|
|
186
|
+
```
|
|
187
|
+
|
|
180
188
|
## Number (money)
|
|
181
189
|
|
|
182
190
|
```tsx
|