@telus-uds/components-base 3.8.0 → 3.9.0
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 +18 -3
- package/lib/cjs/MultiSelectFilter/ModalOverlay.js +7 -2
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +13 -7
- package/lib/cjs/ToggleSwitch/ToggleSwitch.js +13 -2
- package/lib/cjs/Validator/Validator.js +135 -64
- package/lib/esm/MultiSelectFilter/ModalOverlay.js +7 -2
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +13 -7
- package/lib/esm/ToggleSwitch/ToggleSwitch.js +13 -2
- package/lib/esm/Validator/Validator.js +135 -64
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/MultiSelectFilter/ModalOverlay.jsx +3 -2
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +12 -8
- package/src/ToggleSwitch/ToggleSwitch.jsx +17 -2
- package/src/Validator/Validator.jsx +172 -85
|
@@ -24,7 +24,7 @@ const Validator = React.forwardRef(
|
|
|
24
24
|
|
|
25
25
|
const { supportsProps } = selectProps(rest)
|
|
26
26
|
const strValidation = supportsProps.validation
|
|
27
|
-
const [
|
|
27
|
+
const [, setIndividualCodes] = React.useState({})
|
|
28
28
|
const [text, setText] = React.useState(value)
|
|
29
29
|
const validatorsLength = 6
|
|
30
30
|
const prefix = 'code'
|
|
@@ -44,75 +44,110 @@ const Validator = React.forwardRef(
|
|
|
44
44
|
const [codeReferences, singleCodes] = React.useMemo(() => {
|
|
45
45
|
const codes = []
|
|
46
46
|
const valueCodes = {}
|
|
47
|
-
|
|
47
|
+
Array.from({ length: validatorsLength }, (_, i) => {
|
|
48
48
|
codes[prefix + i] = React.createRef()
|
|
49
49
|
valueCodes[prefix + i] = ''
|
|
50
50
|
valueCodes[prefix + i + sufixValidation] = ''
|
|
51
|
-
|
|
52
|
-
return [codes, valueCodes]
|
|
53
|
-
}, [])
|
|
54
|
-
|
|
55
|
-
const handleSingleCodes = (codeId, val, validation) => {
|
|
56
|
-
singleCodes[codeId] = val
|
|
57
|
-
singleCodes[codeId + sufixValidation] = validation
|
|
58
|
-
/* eslint-disable no-unused-expressions */
|
|
59
|
-
setIndividualCodes({
|
|
60
|
-
...individualCodes,
|
|
61
|
-
[codeId]: val
|
|
51
|
+
return null
|
|
62
52
|
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const changeDataMasking = (boxElement) => {
|
|
66
|
-
let charMasking = ''
|
|
67
|
-
const element = boxElement
|
|
68
|
-
if (mask && mask.length === 1) charMasking = mask
|
|
69
|
-
else if (mask && mask.length > 1) charMasking = mask.substring(0, 1)
|
|
53
|
+
return [codes, valueCodes]
|
|
54
|
+
}, [validatorsLength, prefix, sufixValidation])
|
|
70
55
|
|
|
71
|
-
|
|
72
|
-
|
|
56
|
+
const handleSingleCodes = React.useCallback(
|
|
57
|
+
(codeId, val, validation) => {
|
|
58
|
+
singleCodes[codeId] = val
|
|
59
|
+
singleCodes[codeId + sufixValidation] = validation
|
|
60
|
+
setIndividualCodes((prev) => ({
|
|
61
|
+
...prev,
|
|
62
|
+
[codeId]: val
|
|
63
|
+
}))
|
|
64
|
+
},
|
|
65
|
+
[singleCodes, sufixValidation]
|
|
66
|
+
)
|
|
73
67
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
68
|
+
const changeDataMasking = React.useCallback(
|
|
69
|
+
(boxElement) => {
|
|
70
|
+
let charMasking = ''
|
|
71
|
+
const element = boxElement
|
|
72
|
+
if (mask && mask.length === 1) {
|
|
73
|
+
charMasking = mask
|
|
74
|
+
} else if (mask && mask.length > 1) {
|
|
75
|
+
charMasking = mask.substring(0, 1)
|
|
76
|
+
}
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
if (charMasking && element) {
|
|
79
|
+
element.value = charMasking
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
[mask]
|
|
83
|
+
)
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const handleChangeCode = React.useCallback(() => {
|
|
86
|
+
const code = Array.from(
|
|
87
|
+
{ length: validatorsLength },
|
|
88
|
+
(_, i) => singleCodes[prefix + i] || ''
|
|
89
|
+
).join('')
|
|
90
|
+
if (typeof onChange === 'function') {
|
|
91
|
+
onChange(code, singleCodes)
|
|
87
92
|
}
|
|
93
|
+
}, [validatorsLength, singleCodes, prefix, onChange])
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
const handleChangeCodeValues = React.useCallback(
|
|
96
|
+
(event, codeId, nextIndex) => {
|
|
97
|
+
const codeElement = codeReferences[codeId]?.current
|
|
98
|
+
const val = event.nativeEvent?.value || event.target?.value
|
|
99
|
+
|
|
100
|
+
// Only allow numeric characters and limit to single digit
|
|
101
|
+
const numericOnly = val.replace(/\D/g, '').substring(0, 1)
|
|
102
|
+
|
|
103
|
+
if (codeElement && codeElement.value) {
|
|
104
|
+
codeElement.value = numericOnly
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
handleSingleCodes(codeId, numericOnly, numericOnly ? 'success' : '')
|
|
108
|
+
handleChangeCode()
|
|
109
|
+
|
|
110
|
+
if (nextIndex === validatorsLength) {
|
|
111
|
+
codeElement?.blur()
|
|
112
|
+
changeDataMasking(codeElement)
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (numericOnly.length > 0) {
|
|
117
|
+
const nextElement = codeReferences[prefix + nextIndex]?.current
|
|
118
|
+
nextElement?.focus()
|
|
119
|
+
changeDataMasking(codeElement)
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
[
|
|
123
|
+
codeReferences,
|
|
124
|
+
handleSingleCodes,
|
|
125
|
+
handleChangeCode,
|
|
126
|
+
validatorsLength,
|
|
127
|
+
changeDataMasking,
|
|
128
|
+
prefix
|
|
129
|
+
]
|
|
130
|
+
)
|
|
101
131
|
|
|
102
132
|
const handleKeyPress = (event, currentIndex, previousIndex) => {
|
|
103
|
-
if (!(event.keyCode === 8 || event.code === 'Backspace'))
|
|
133
|
+
if (!(event.keyCode === 8 || event.code === 'Backspace')) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
104
136
|
if (currentIndex > 0) {
|
|
105
|
-
codeReferences[prefix + currentIndex]
|
|
106
|
-
codeReferences[prefix + previousIndex]
|
|
137
|
+
const currentElement = codeReferences[prefix + currentIndex]?.current
|
|
138
|
+
const previousElement = codeReferences[prefix + previousIndex]?.current
|
|
139
|
+
|
|
140
|
+
if (currentElement && currentElement.value) {
|
|
141
|
+
currentElement.value = ''
|
|
142
|
+
}
|
|
143
|
+
previousElement?.focus()
|
|
107
144
|
}
|
|
108
145
|
handleSingleCodes(prefix + currentIndex, '', '')
|
|
109
146
|
handleChangeCode()
|
|
110
147
|
}
|
|
111
148
|
|
|
112
149
|
const getCodeComponents = () => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
150
|
+
return Array.from({ length: validatorsLength }, (_, i) => {
|
|
116
151
|
const codeId = prefix + i
|
|
117
152
|
const codeInputProps = {
|
|
118
153
|
nativeID: codeId,
|
|
@@ -120,75 +155,127 @@ const Validator = React.forwardRef(
|
|
|
120
155
|
ref: codeReferences[codeId] ?? null,
|
|
121
156
|
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
122
157
|
tokens: selectCodeTextInputTokens(themeTokens),
|
|
123
|
-
onFocus: () =>
|
|
158
|
+
onFocus: () => {
|
|
159
|
+
const element = codeReferences[codeId]?.current
|
|
160
|
+
if (Platform.OS === 'web' && element?.select) {
|
|
161
|
+
return element.select() ?? null
|
|
162
|
+
}
|
|
163
|
+
if (element?.focus) {
|
|
164
|
+
return element.focus() ?? null
|
|
165
|
+
}
|
|
166
|
+
return null
|
|
167
|
+
},
|
|
124
168
|
onKeyPress: (event) => handleKeyPress(event, i, i - 1),
|
|
125
169
|
onMouseOver: handleMouseOver,
|
|
126
170
|
onMouseOut: handleMouseOut,
|
|
127
171
|
inactive
|
|
128
172
|
}
|
|
129
|
-
codeInputProps.validation
|
|
173
|
+
if (!codeInputProps.validation) {
|
|
174
|
+
delete codeInputProps.validation
|
|
175
|
+
}
|
|
130
176
|
|
|
131
|
-
|
|
177
|
+
return (
|
|
132
178
|
<View key={codeId} style={staticStyles.codeInputWidth}>
|
|
133
179
|
<TextInput {...codeInputProps} />
|
|
134
180
|
</View>
|
|
135
181
|
)
|
|
136
|
-
}
|
|
137
|
-
return components
|
|
182
|
+
})
|
|
138
183
|
}
|
|
139
184
|
|
|
140
185
|
React.useEffect(() => {
|
|
141
|
-
|
|
142
|
-
|
|
186
|
+
if (Number(value).toString() !== 'NaN') {
|
|
187
|
+
setText(value)
|
|
188
|
+
}
|
|
143
189
|
}, [value])
|
|
144
190
|
|
|
145
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
146
191
|
React.useEffect(() => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
192
|
+
Array.from({ length: validatorsLength }, (_, i) => {
|
|
193
|
+
const element = codeReferences[prefix + i]?.current
|
|
194
|
+
if (element && element.value !== undefined) {
|
|
195
|
+
if (mask && text[i]) {
|
|
196
|
+
element.value = mask
|
|
197
|
+
} else {
|
|
198
|
+
element.value = text[i] ?? ''
|
|
199
|
+
}
|
|
200
|
+
}
|
|
150
201
|
handleSingleCodes(prefix + i, text[i] ?? '', text[i] ? 'success' : '')
|
|
151
|
-
|
|
152
|
-
|
|
202
|
+
return null
|
|
203
|
+
})
|
|
204
|
+
}, [text, mask, validatorsLength, prefix, codeReferences, handleSingleCodes])
|
|
153
205
|
|
|
154
|
-
/* eslint-disable react-hooks/exhaustive-deps */
|
|
155
206
|
React.useEffect(() => {
|
|
156
207
|
const handlePasteCode = (event) => {
|
|
208
|
+
event.preventDefault()
|
|
209
|
+
|
|
210
|
+
// Clear current state first
|
|
157
211
|
setText('')
|
|
212
|
+
|
|
213
|
+
// Clear all individual input fields and their state
|
|
214
|
+
Array.from({ length: validatorsLength }, (_, i) => {
|
|
215
|
+
const element = codeReferences[prefix + i]?.current
|
|
216
|
+
if (element && element.value !== undefined) {
|
|
217
|
+
element.value = ''
|
|
218
|
+
}
|
|
219
|
+
handleSingleCodes(prefix + i, '', '')
|
|
220
|
+
return null
|
|
221
|
+
})
|
|
222
|
+
|
|
158
223
|
const clipBoardText = event.clipboardData.getData('text')
|
|
159
|
-
|
|
224
|
+
|
|
225
|
+
// Validate that input contains only digits and truncate to 6 characters
|
|
226
|
+
const numericOnly = clipBoardText.replace(/\D/g, '').substring(0, validatorsLength)
|
|
227
|
+
|
|
228
|
+
if (numericOnly.length > 0) {
|
|
229
|
+
setText(numericOnly)
|
|
230
|
+
}
|
|
160
231
|
}
|
|
161
232
|
|
|
162
233
|
const handleCopy = (event) => {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
234
|
+
const clipBoardText = Array.from(
|
|
235
|
+
{ length: validatorsLength },
|
|
236
|
+
(_, i) => singleCodes[prefix + i] || ''
|
|
237
|
+
).join('')
|
|
166
238
|
event.clipboardData.setData('text/plain', clipBoardText)
|
|
167
239
|
event.preventDefault()
|
|
168
240
|
}
|
|
169
241
|
|
|
170
242
|
if (Platform.OS === 'web') {
|
|
171
|
-
|
|
172
|
-
codeReferences[prefix + i]
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
return () => {
|
|
181
|
-
if (Platform.oldValue === 'web') {
|
|
182
|
-
for (let i = 0; i < validatorsLength; i += 1) {
|
|
183
|
-
codeReferences[prefix + i]?.current?.removeEventListener('paste', handlePasteCode)
|
|
184
|
-
codeReferences[prefix + i]?.current?.removeEventListener('copy', handleCopy)
|
|
185
|
-
codeReferences[prefix + i]?.current?.removeEventListener('input', (event) =>
|
|
243
|
+
Array.from({ length: validatorsLength }, (_, i) => {
|
|
244
|
+
const element = codeReferences[prefix + i]?.current
|
|
245
|
+
if (element && typeof element.addEventListener === 'function') {
|
|
246
|
+
element.addEventListener('paste', handlePasteCode)
|
|
247
|
+
element.addEventListener('copy', handleCopy)
|
|
248
|
+
element.addEventListener('input', (event) =>
|
|
186
249
|
handleChangeCodeValues(event, prefix + i, i + 1)
|
|
187
250
|
)
|
|
188
251
|
}
|
|
252
|
+
return null
|
|
253
|
+
})
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return () => {
|
|
257
|
+
if (Platform.OS === 'web') {
|
|
258
|
+
Array.from({ length: validatorsLength }, (_, i) => {
|
|
259
|
+
const element = codeReferences[prefix + i]?.current
|
|
260
|
+
if (element && typeof element.removeEventListener === 'function') {
|
|
261
|
+
element.removeEventListener('paste', handlePasteCode)
|
|
262
|
+
element.removeEventListener('copy', handleCopy)
|
|
263
|
+
element.removeEventListener('input', (event) =>
|
|
264
|
+
handleChangeCodeValues(event, prefix + i, i + 1)
|
|
265
|
+
)
|
|
266
|
+
}
|
|
267
|
+
return null
|
|
268
|
+
})
|
|
189
269
|
}
|
|
190
270
|
}
|
|
191
|
-
}, [
|
|
271
|
+
}, [
|
|
272
|
+
validatorsLength,
|
|
273
|
+
prefix,
|
|
274
|
+
codeReferences,
|
|
275
|
+
handleChangeCodeValues,
|
|
276
|
+
handleSingleCodes,
|
|
277
|
+
singleCodes
|
|
278
|
+
])
|
|
192
279
|
|
|
193
280
|
return (
|
|
194
281
|
<InputSupports
|