@juspay/svelte-ui-components 2.111.3 → 2.111.4
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.
|
@@ -56,6 +56,32 @@
|
|
|
56
56
|
|
|
57
57
|
// ── Input handler ───────────────────────────────────────────────
|
|
58
58
|
|
|
59
|
+
// Multi-char cleanup for the distribute paths: tel fields keep digits only
|
|
60
|
+
// (an OTP autofilled/pasted as "123-456" or "123 456" must land as 123456,
|
|
61
|
+
// never distribute a separator into a field); other dataTypes keep the old
|
|
62
|
+
// whitespace-strip behavior.
|
|
63
|
+
function sanitizeChars(config: FieldConfig, raw: string): string {
|
|
64
|
+
if ((config.dataType ?? 'text') === 'tel') {
|
|
65
|
+
return raw.replace(/\D/g, '');
|
|
66
|
+
}
|
|
67
|
+
return raw.replace(/\s/g, '');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Single-char autoAdvance fields widen the inner Input's maxLength to the
|
|
71
|
+
// whole code length: Input's dataType='tel' sanitizer truncates an overflowing
|
|
72
|
+
// value to its LAST maxLength digits BEFORE onInput fires, so with the literal
|
|
73
|
+
// maxLength of 1 a WebOTP / Android-SMS autofill that drops the whole code
|
|
74
|
+
// into one field reached handleFieldInput as a single wrong digit and the
|
|
75
|
+
// distribute branch below could never run. One-char-per-field semantics are
|
|
76
|
+
// enforced by handleFieldInput itself, not by the inner Input.
|
|
77
|
+
function innerMaxLength(config: FieldConfig): number {
|
|
78
|
+
const configured = config.maxLength ?? 1000;
|
|
79
|
+
if (autoAdvance && configured === 1) {
|
|
80
|
+
return fieldCount;
|
|
81
|
+
}
|
|
82
|
+
return configured;
|
|
83
|
+
}
|
|
84
|
+
|
|
59
85
|
function handleFieldInput(index: number, inputValue: string) {
|
|
60
86
|
const config = fieldConfigs.at(index);
|
|
61
87
|
if (typeof config === 'undefined') {
|
|
@@ -64,11 +90,25 @@
|
|
|
64
90
|
const maxLen = config.maxLength ?? 1000;
|
|
65
91
|
|
|
66
92
|
if (autoAdvance && maxLen === 1 && inputValue.length > 1) {
|
|
67
|
-
const chars =
|
|
68
|
-
|
|
69
|
-
values[
|
|
93
|
+
const chars = sanitizeChars(config, inputValue);
|
|
94
|
+
if (chars.length === 0) {
|
|
95
|
+
values[index] = '';
|
|
96
|
+
} else if (index === 0 || chars.length >= fieldCount) {
|
|
97
|
+
// Autofill / OS-level insertion of a whole code: distribute from the
|
|
98
|
+
// start. Only provided characters are written — a partial string must
|
|
99
|
+
// not clear fields beyond it.
|
|
100
|
+
for (let i = 0; i < Math.min(chars.length, fieldCount); i++) {
|
|
101
|
+
values[i] = chars.charAt(i);
|
|
102
|
+
}
|
|
103
|
+
focusField(Math.min(chars.length, fieldCount) - 1);
|
|
104
|
+
} else {
|
|
105
|
+
// Overtyping an already-filled field: keep the newest character and
|
|
106
|
+
// advance, mirroring single-char entry.
|
|
107
|
+
values[index] = chars.slice(-1);
|
|
108
|
+
if (index < fieldCount - 1) {
|
|
109
|
+
focusField(index + 1);
|
|
110
|
+
}
|
|
70
111
|
}
|
|
71
|
-
focusField(Math.min(chars.length, fieldCount) - 1);
|
|
72
112
|
} else {
|
|
73
113
|
values[index] = inputValue;
|
|
74
114
|
if (autoAdvance && maxLen === 1 && inputValue.length > 0 && index < fieldCount - 1) {
|
|
@@ -111,9 +151,10 @@
|
|
|
111
151
|
}
|
|
112
152
|
e.preventDefault();
|
|
113
153
|
const pasted = e.clipboardData.getData('text').trim();
|
|
154
|
+
const config = fieldConfigs.at(index);
|
|
114
155
|
|
|
115
|
-
if (autoAdvance) {
|
|
116
|
-
const chars =
|
|
156
|
+
if (autoAdvance && typeof config !== 'undefined') {
|
|
157
|
+
const chars = sanitizeChars(config, pasted);
|
|
117
158
|
for (let i = index; i < fieldCount; i++) {
|
|
118
159
|
const charIdx = i - index;
|
|
119
160
|
if (charIdx >= chars.length) {
|
|
@@ -153,7 +194,8 @@
|
|
|
153
194
|
<Input
|
|
154
195
|
value={getFieldValue(index)}
|
|
155
196
|
dataType={config.dataType ?? 'text'}
|
|
156
|
-
maxLength={config
|
|
197
|
+
maxLength={innerMaxLength(config)}
|
|
198
|
+
testId={config.testId}
|
|
157
199
|
min={config.min}
|
|
158
200
|
max={config.max}
|
|
159
201
|
placeholder={config.placeholder}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OptionalInputProperties } from '../Input/properties';
|
|
2
|
-
export type FieldConfig = Pick<OptionalInputProperties, 'dataType' | 'maxLength' | 'min' | 'max' | 'placeholder' | 'validationPattern' | 'validators' | 'label' | 'autoComplete' | 'inputMode'>;
|
|
2
|
+
export type FieldConfig = Pick<OptionalInputProperties, 'dataType' | 'maxLength' | 'min' | 'max' | 'placeholder' | 'validationPattern' | 'validators' | 'label' | 'autoComplete' | 'inputMode' | 'testId'>;
|
|
3
3
|
export type SplitInputProperties = MandatorySplitInputProperties & OptionalSplitInputProperties & SplitInputEventProperties;
|
|
4
4
|
export type MandatorySplitInputProperties = {
|
|
5
5
|
values: string[];
|