@telus-uds/components-base 1.29.0 → 1.30.1
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 -2
- package/component-docs.json +69 -0
- package/lib/TextInput/TextInputBase.js +34 -11
- package/lib/TextInput/dictionary.js +6 -2
- package/lib/Validator/Validator.js +272 -0
- package/lib/Validator/index.js +13 -0
- package/lib/index.js +9 -0
- package/lib/utils/props/handlerProps.js +6 -1
- package/lib-module/TextInput/TextInputBase.js +34 -11
- package/lib-module/TextInput/dictionary.js +6 -2
- package/lib-module/Validator/Validator.js +246 -0
- package/lib-module/Validator/index.js +2 -0
- package/lib-module/index.js +1 -0
- package/lib-module/utils/props/handlerProps.js +6 -1
- package/package.json +2 -2
- package/src/TextInput/TextInputBase.jsx +44 -9
- package/src/TextInput/dictionary.js +6 -2
- package/src/Validator/Validator.jsx +217 -0
- package/src/Validator/index.js +3 -0
- package/src/index.js +1 -0
- package/src/utils/props/handlerProps.js +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
# Change Log - @telus-uds/components-base
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 23 Mar 2023 20:46:10 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 1.30.1
|
|
8
|
+
|
|
9
|
+
Thu, 23 Mar 2023 20:46:10 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- Bump @telus-uds/system-theme-tokens to v2.14.0
|
|
14
|
+
|
|
15
|
+
## 1.30.0
|
|
16
|
+
|
|
17
|
+
Mon, 20 Mar 2023 19:48:47 GMT
|
|
18
|
+
|
|
19
|
+
### Minor changes
|
|
20
|
+
|
|
21
|
+
- Password variant added to PM, koodo, Telus and Rebrand-PM (akshay.pandey1@telus.com)
|
|
22
|
+
- Bump @telus-uds/system-theme-tokens to v2.13.0
|
|
23
|
+
|
|
7
24
|
## 1.29.0
|
|
8
25
|
|
|
9
|
-
Tue, 07 Mar 2023 21:
|
|
26
|
+
Tue, 07 Mar 2023 21:13:39 GMT
|
|
10
27
|
|
|
11
28
|
### Minor changes
|
|
12
29
|
|
package/component-docs.json
CHANGED
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
"thickness": "border",
|
|
7
7
|
"color": "color"
|
|
8
8
|
},
|
|
9
|
+
"Badge": {
|
|
10
|
+
"fontWeight": "fontWeight",
|
|
11
|
+
"fontName": "fontName",
|
|
12
|
+
"backgroundColor": "color",
|
|
13
|
+
"borderColor": "color",
|
|
14
|
+
"borderRadius": "radius",
|
|
15
|
+
"borderWidth": "border",
|
|
16
|
+
"color": "color",
|
|
17
|
+
"gradient": "gradient",
|
|
18
|
+
"paddingLeft": "size",
|
|
19
|
+
"paddingRight": "size",
|
|
20
|
+
"paddingTop": "size",
|
|
21
|
+
"paddingBottom": "size"
|
|
22
|
+
},
|
|
9
23
|
"Box": {
|
|
10
24
|
"backgroundColor": "color",
|
|
11
25
|
"gradient": "gradient"
|
|
@@ -886,6 +900,8 @@
|
|
|
886
900
|
"borderWidth": "border",
|
|
887
901
|
"borderColor": "color",
|
|
888
902
|
"borderRadius": "radius",
|
|
903
|
+
"passwordShowButtonIcon": "icon",
|
|
904
|
+
"passwordHideButtonIcon": "icon",
|
|
889
905
|
"buttonSize": "size",
|
|
890
906
|
"buttonsGap": "size",
|
|
891
907
|
"buttonsPaddingRight": "size",
|
|
@@ -9716,6 +9732,55 @@
|
|
|
9716
9732
|
}
|
|
9717
9733
|
}
|
|
9718
9734
|
},
|
|
9735
|
+
"Validator": {
|
|
9736
|
+
"docs": {
|
|
9737
|
+
"description": "",
|
|
9738
|
+
"props": {
|
|
9739
|
+
"value": {
|
|
9740
|
+
"defaultValue": {
|
|
9741
|
+
"value": "''",
|
|
9742
|
+
"computed": false
|
|
9743
|
+
},
|
|
9744
|
+
"type": {
|
|
9745
|
+
"name": "string"
|
|
9746
|
+
},
|
|
9747
|
+
"required": false,
|
|
9748
|
+
"description": "The value is a 6-digit code, may be only numeric characters, non numeric character aren't renderize"
|
|
9749
|
+
},
|
|
9750
|
+
"tokens": {
|
|
9751
|
+
"defaultValue": {
|
|
9752
|
+
"value": "{}",
|
|
9753
|
+
"computed": false
|
|
9754
|
+
},
|
|
9755
|
+
"required": false
|
|
9756
|
+
},
|
|
9757
|
+
"variant": {
|
|
9758
|
+
"defaultValue": {
|
|
9759
|
+
"value": "{}",
|
|
9760
|
+
"computed": false
|
|
9761
|
+
},
|
|
9762
|
+
"required": false
|
|
9763
|
+
},
|
|
9764
|
+
"inactive": {
|
|
9765
|
+
"type": {
|
|
9766
|
+
"name": "bool"
|
|
9767
|
+
},
|
|
9768
|
+
"required": false,
|
|
9769
|
+
"description": "If true, the component is inactive and non editable."
|
|
9770
|
+
},
|
|
9771
|
+
"onChange": {
|
|
9772
|
+
"type": {
|
|
9773
|
+
"name": "func"
|
|
9774
|
+
},
|
|
9775
|
+
"required": false,
|
|
9776
|
+
"description": "Use to react upon input's value changes. Required when the `value` prop is set. Will receive the input's value as an argument."
|
|
9777
|
+
}
|
|
9778
|
+
},
|
|
9779
|
+
"attributes": {
|
|
9780
|
+
"acceptsRNA11yProps": false
|
|
9781
|
+
}
|
|
9782
|
+
}
|
|
9783
|
+
},
|
|
9719
9784
|
"ViewportProvider": {
|
|
9720
9785
|
"docs": {
|
|
9721
9786
|
"description": "Provides an up-to-date viewport value from system-constants, available via the `useViewport` hook",
|
|
@@ -13061,6 +13126,8 @@
|
|
|
13061
13126
|
"borderWidth": "border",
|
|
13062
13127
|
"borderColor": "color",
|
|
13063
13128
|
"borderRadius": "radius",
|
|
13129
|
+
"passwordShowButtonIcon": "icon",
|
|
13130
|
+
"passwordHideButtonIcon": "icon",
|
|
13064
13131
|
"buttonSize": "size",
|
|
13065
13132
|
"buttonsGap": "size",
|
|
13066
13133
|
"buttonsPaddingRight": "size",
|
|
@@ -13170,6 +13237,8 @@
|
|
|
13170
13237
|
"borderWidth": "border",
|
|
13171
13238
|
"borderColor": "color",
|
|
13172
13239
|
"borderRadius": "radius",
|
|
13240
|
+
"passwordShowButtonIcon": "icon",
|
|
13241
|
+
"passwordHideButtonIcon": "icon",
|
|
13173
13242
|
"buttonSize": "size",
|
|
13174
13243
|
"buttonsGap": "size",
|
|
13175
13244
|
"buttonsPaddingRight": "size",
|
|
@@ -183,6 +183,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
183
183
|
...rest
|
|
184
184
|
} = _ref6;
|
|
185
185
|
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
186
|
+
const [showPassword, setShowPassword] = (0, _react.useState)(false);
|
|
186
187
|
|
|
187
188
|
const handleFocus = event => {
|
|
188
189
|
setIsFocused(true);
|
|
@@ -244,27 +245,35 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
244
245
|
inactive
|
|
245
246
|
};
|
|
246
247
|
const themeTokens = (0, _ThemeProvider.useThemeTokens)('TextInput', tokens, variant, states);
|
|
248
|
+
|
|
249
|
+
const handleClear = event => {
|
|
250
|
+
var _inputRef$current;
|
|
251
|
+
|
|
252
|
+
onClear === null || onClear === void 0 ? void 0 : onClear(event);
|
|
253
|
+
resetValue(event);
|
|
254
|
+
inputRef === null || inputRef === void 0 ? void 0 : (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const handleShowOrHide = () => {
|
|
258
|
+
if (!variant.inactive) setShowPassword(!showPassword);
|
|
259
|
+
};
|
|
260
|
+
|
|
247
261
|
const {
|
|
248
262
|
buttonsGap,
|
|
249
263
|
clearButtonIcon: ClearButtonIcon,
|
|
250
|
-
icon: IconComponent
|
|
264
|
+
icon: IconComponent,
|
|
265
|
+
passwordShowButtonIcon,
|
|
266
|
+
passwordHideButtonIcon
|
|
251
267
|
} = themeTokens;
|
|
252
268
|
const buttonsGapSize = (0, _utils.useSpacingScale)(buttonsGap);
|
|
253
269
|
const getCopy = (0, _utils.useCopy)({
|
|
254
270
|
dictionary: _dictionary.default,
|
|
255
271
|
copy
|
|
256
272
|
});
|
|
273
|
+
const textInputButtons = buttons;
|
|
257
274
|
|
|
258
275
|
if (onClear && isDirty) {
|
|
259
|
-
|
|
260
|
-
var _inputRef$current;
|
|
261
|
-
|
|
262
|
-
onClear === null || onClear === void 0 ? void 0 : onClear(event);
|
|
263
|
-
resetValue(event);
|
|
264
|
-
inputRef === null || inputRef === void 0 ? void 0 : (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
buttons === null || buttons === void 0 ? void 0 : buttons.unshift( /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
|
|
276
|
+
textInputButtons === null || textInputButtons === void 0 ? void 0 : textInputButtons.unshift( /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
|
|
268
277
|
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
269
278
|
icon: ClearButtonIcon,
|
|
270
279
|
onPress: handleClear,
|
|
@@ -274,6 +283,19 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
274
283
|
}, "clear"));
|
|
275
284
|
}
|
|
276
285
|
|
|
286
|
+
if (variant.password) {
|
|
287
|
+
textInputButtons === null || textInputButtons === void 0 ? void 0 : textInputButtons.unshift( /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
|
|
288
|
+
accessibilityLabel: !showPassword ? getCopy('hidePasswordAccessibilityLabel') : getCopy('showPasswordAccessibilityLabel'),
|
|
289
|
+
icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
|
|
290
|
+
onPress: handleShowOrHide,
|
|
291
|
+
variant: {
|
|
292
|
+
compact: true,
|
|
293
|
+
password: true,
|
|
294
|
+
inactive: !!variant.inactive
|
|
295
|
+
}
|
|
296
|
+
}, !showPassword ? 'hide' : 'show'));
|
|
297
|
+
}
|
|
298
|
+
|
|
277
299
|
const inputProps = { ...selectProps(rest),
|
|
278
300
|
editable: !inactive,
|
|
279
301
|
onFocus: handleFocus,
|
|
@@ -297,6 +319,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
297
319
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInput.default, {
|
|
298
320
|
ref: inputRef,
|
|
299
321
|
style: nativeInputStyle,
|
|
322
|
+
secureTextEntry: variant.password && !showPassword,
|
|
300
323
|
...inputProps
|
|
301
324
|
}), IconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
302
325
|
pointerEvents: "none" // avoid hijacking input press events
|
|
@@ -311,7 +334,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
311
334
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
|
|
312
335
|
direction: "row",
|
|
313
336
|
space: buttonsGap,
|
|
314
|
-
children:
|
|
337
|
+
children: textInputButtons
|
|
315
338
|
})
|
|
316
339
|
})]
|
|
317
340
|
});
|
|
@@ -6,10 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _default = {
|
|
8
8
|
en: {
|
|
9
|
-
clearButtonAccessibilityLabel: 'Clear'
|
|
9
|
+
clearButtonAccessibilityLabel: 'Clear',
|
|
10
|
+
showPasswordAccessibilityLabel: 'Show Password',
|
|
11
|
+
hidePasswordAccessibilityLabel: 'Hide Password'
|
|
10
12
|
},
|
|
11
13
|
fr: {
|
|
12
|
-
clearButtonAccessibilityLabel: 'Effacer'
|
|
14
|
+
clearButtonAccessibilityLabel: 'Effacer',
|
|
15
|
+
showPasswordAccessibilityLabel: 'montrer le mot de passe',
|
|
16
|
+
hidePasswordAccessibilityLabel: 'masquer le mot de passe'
|
|
13
17
|
}
|
|
14
18
|
};
|
|
15
19
|
exports.default = _default;
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
|
|
13
|
+
|
|
14
|
+
var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
|
|
15
|
+
|
|
16
|
+
var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
|
|
17
|
+
|
|
18
|
+
var _utils = require("../utils");
|
|
19
|
+
|
|
20
|
+
var _TextInput = require("../TextInput");
|
|
21
|
+
|
|
22
|
+
var _StackView = _interopRequireDefault(require("../StackView"));
|
|
23
|
+
|
|
24
|
+
var _InputSupports = _interopRequireDefault(require("../InputSupports"));
|
|
25
|
+
|
|
26
|
+
var _ThemeProvider = require("../ThemeProvider");
|
|
27
|
+
|
|
28
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
29
|
+
|
|
30
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
|
+
|
|
32
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
33
|
+
|
|
34
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
35
|
+
|
|
36
|
+
const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.inputSupportsProps]);
|
|
37
|
+
|
|
38
|
+
const selectCodeTextInputTokens = _ref => {
|
|
39
|
+
let {
|
|
40
|
+
outerBorderColor,
|
|
41
|
+
outerBackgroundColor
|
|
42
|
+
} = _ref;
|
|
43
|
+
return {
|
|
44
|
+
outerBorderColor,
|
|
45
|
+
outerBackgroundColor,
|
|
46
|
+
icon: null
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
51
|
+
let {
|
|
52
|
+
value = '',
|
|
53
|
+
inactive,
|
|
54
|
+
onChange,
|
|
55
|
+
tokens = {},
|
|
56
|
+
variant = {},
|
|
57
|
+
...rest
|
|
58
|
+
} = _ref2;
|
|
59
|
+
const defaultRef = (0, _react.useRef)();
|
|
60
|
+
const codeRef = ref !== null && ref !== void 0 ? ref : defaultRef;
|
|
61
|
+
const {
|
|
62
|
+
supportsProps
|
|
63
|
+
} = selectProps(rest);
|
|
64
|
+
const strValidation = supportsProps.validation;
|
|
65
|
+
const [individualCodes, setIndividualCodes] = (0, _react.useState)({});
|
|
66
|
+
const [text, setText] = (0, _react.useState)(value);
|
|
67
|
+
const validatorsLength = 6;
|
|
68
|
+
const prefix = 'code';
|
|
69
|
+
const sufixValidation = 'Validation';
|
|
70
|
+
const [isHover, setIsHover] = (0, _react.useState)(false);
|
|
71
|
+
|
|
72
|
+
const handleMouseOver = () => {
|
|
73
|
+
setIsHover(true);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const handleMouseOut = () => {
|
|
77
|
+
setIsHover(false);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const themeTokens = (0, _ThemeProvider.useThemeTokens)('TextInput', tokens, variant, {
|
|
81
|
+
hover: isHover
|
|
82
|
+
});
|
|
83
|
+
const [codeReferences, singleCodes] = (0, _react.useMemo)(() => {
|
|
84
|
+
const codes = [];
|
|
85
|
+
const valueCodes = {};
|
|
86
|
+
|
|
87
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
88
|
+
codes[prefix + i] = /*#__PURE__*/(0, _react.createRef)();
|
|
89
|
+
valueCodes[prefix + i] = '';
|
|
90
|
+
valueCodes[prefix + i + sufixValidation] = '';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return [codes, valueCodes];
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
const handleSingleCodes = (codeId, val, validation) => {
|
|
97
|
+
singleCodes[codeId] = val;
|
|
98
|
+
singleCodes[codeId + sufixValidation] = validation;
|
|
99
|
+
/* eslint-disable no-unused-expressions */
|
|
100
|
+
|
|
101
|
+
setIndividualCodes({ ...individualCodes,
|
|
102
|
+
[codeId]: val
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleChangeCode = () => {
|
|
107
|
+
let code = '';
|
|
108
|
+
|
|
109
|
+
for (let i = 0; i < validatorsLength; i += 1) code += singleCodes[prefix + i];
|
|
110
|
+
|
|
111
|
+
if (typeof onChange === 'function') onChange(code, singleCodes);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const handleChangeCodeValues = (event, codeId, nextIndex) => {
|
|
115
|
+
var _codeReferences$codeI, _event$nativeEvent, _event$target, _codeElement$value, _codeElement$value2, _codeElement$value3;
|
|
116
|
+
|
|
117
|
+
const codeElement = (_codeReferences$codeI = codeReferences[codeId]) === null || _codeReferences$codeI === void 0 ? void 0 : _codeReferences$codeI.current;
|
|
118
|
+
const val = ((_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : _event$nativeEvent.value) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.value);
|
|
119
|
+
|
|
120
|
+
if (Number(val).toString() === 'NaN') {
|
|
121
|
+
var _singleCodes$codeId;
|
|
122
|
+
|
|
123
|
+
codeElement.value = (_singleCodes$codeId = singleCodes[codeId]) !== null && _singleCodes$codeId !== void 0 ? _singleCodes$codeId : '';
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$value = codeElement.value) === null || _codeElement$value === void 0 ? void 0 : _codeElement$value.length) > 1) {
|
|
128
|
+
const oldValue = singleCodes[codeId];
|
|
129
|
+
const newValue = codeElement.value.replace(oldValue, '');
|
|
130
|
+
codeElement.value = newValue;
|
|
131
|
+
handleSingleCodes(codeId, codeElement.value, 'success');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
handleSingleCodes(codeId, (_codeElement$value2 = codeElement === null || codeElement === void 0 ? void 0 : codeElement.value) !== null && _codeElement$value2 !== void 0 ? _codeElement$value2 : singleCodes[codeId], 'success');
|
|
135
|
+
handleChangeCode();
|
|
136
|
+
|
|
137
|
+
if (nextIndex === validatorsLength) {
|
|
138
|
+
codeElement.blur();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$value3 = codeElement.value) === null || _codeElement$value3 === void 0 ? void 0 : _codeElement$value3.length) > 0) codeReferences[prefix + nextIndex].current.focus();
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleKeyPress = (event, currentIndex, previousIndex) => {
|
|
146
|
+
if (!(event.keyCode === 8 || event.code === 'Backspace')) return;
|
|
147
|
+
|
|
148
|
+
if (currentIndex > 0) {
|
|
149
|
+
codeReferences[prefix + currentIndex].current.value = '';
|
|
150
|
+
codeReferences[prefix + previousIndex].current.focus();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
handleSingleCodes(prefix + currentIndex, '', '');
|
|
154
|
+
handleChangeCode();
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const getCodeComponents = () => {
|
|
158
|
+
const components = [];
|
|
159
|
+
|
|
160
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
161
|
+
var _codeReferences$codeI2;
|
|
162
|
+
|
|
163
|
+
const codeId = prefix + i;
|
|
164
|
+
const codeInputProps = {
|
|
165
|
+
nativeID: codeId,
|
|
166
|
+
ref: (_codeReferences$codeI2 = codeReferences[codeId]) !== null && _codeReferences$codeI2 !== void 0 ? _codeReferences$codeI2 : null,
|
|
167
|
+
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
168
|
+
tokens: selectCodeTextInputTokens(themeTokens),
|
|
169
|
+
onFocus: () => codeReferences[codeId].current.select(),
|
|
170
|
+
onKeyPress: event => handleKeyPress(event, i, i - 1),
|
|
171
|
+
onMouseOver: handleMouseOver,
|
|
172
|
+
onMouseOut: handleMouseOut,
|
|
173
|
+
inactive
|
|
174
|
+
};
|
|
175
|
+
codeInputProps.validation || delete codeInputProps.validation;
|
|
176
|
+
components.push( /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
177
|
+
style: staticStyles.codeInputWidth,
|
|
178
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextInput.TextInput, { ...codeInputProps
|
|
179
|
+
})
|
|
180
|
+
}, codeId));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return components;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
(0, _react.useEffect)(() => {
|
|
187
|
+
/* eslint-disable no-unused-expressions */
|
|
188
|
+
if (Number(value).toString() !== 'NaN') setText(value);
|
|
189
|
+
}, [value]);
|
|
190
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
191
|
+
|
|
192
|
+
(0, _react.useEffect)(() => {
|
|
193
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
194
|
+
var _text$i, _text$i2;
|
|
195
|
+
|
|
196
|
+
codeReferences[prefix + i].current.value = (_text$i = text[i]) !== null && _text$i !== void 0 ? _text$i : '';
|
|
197
|
+
handleSingleCodes(prefix + i, (_text$i2 = text[i]) !== null && _text$i2 !== void 0 ? _text$i2 : '', text[i] ? 'success' : '');
|
|
198
|
+
}
|
|
199
|
+
}, [text]);
|
|
200
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
201
|
+
|
|
202
|
+
(0, _react.useEffect)(() => {
|
|
203
|
+
const handlePasteCode = event => {
|
|
204
|
+
setText('');
|
|
205
|
+
const clipBoardText = event.clipboardData.getData('text');
|
|
206
|
+
if (Number(clipBoardText).toString() !== 'NaN') setText(clipBoardText);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const handleCopy = event => {
|
|
210
|
+
let clipBoardText = '';
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < validatorsLength; i += 1) singleCodes[prefix + i] && (clipBoardText += singleCodes[prefix + i]);
|
|
213
|
+
|
|
214
|
+
event.clipboardData.setData('text/plain', clipBoardText);
|
|
215
|
+
event.preventDefault();
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
if (_Platform.default.OS === 'web') {
|
|
219
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
220
|
+
codeReferences[prefix + i].current.addEventListener('paste', handlePasteCode);
|
|
221
|
+
codeReferences[prefix + i].current.addEventListener('copy', handleCopy);
|
|
222
|
+
codeReferences[prefix + i].current.addEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return () => {
|
|
227
|
+
if (_Platform.default.oldValue === 'web') {
|
|
228
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
229
|
+
var _codeReferences, _codeReferences$curre, _codeReferences2, _codeReferences2$curr, _codeReferences3, _codeReferences3$curr;
|
|
230
|
+
|
|
231
|
+
(_codeReferences = codeReferences[prefix + i]) === null || _codeReferences === void 0 ? void 0 : (_codeReferences$curre = _codeReferences.current) === null || _codeReferences$curre === void 0 ? void 0 : _codeReferences$curre.removeEventListener('paste', handlePasteCode);
|
|
232
|
+
(_codeReferences2 = codeReferences[prefix + i]) === null || _codeReferences2 === void 0 ? void 0 : (_codeReferences2$curr = _codeReferences2.current) === null || _codeReferences2$curr === void 0 ? void 0 : _codeReferences2$curr.removeEventListener('copy', handleCopy);
|
|
233
|
+
(_codeReferences3 = codeReferences[prefix + i]) === null || _codeReferences3 === void 0 ? void 0 : (_codeReferences3$curr = _codeReferences3.current) === null || _codeReferences3$curr === void 0 ? void 0 : _codeReferences3$curr.removeEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}, []);
|
|
238
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputSupports.default, { ...supportsProps,
|
|
239
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
|
|
240
|
+
space: 2,
|
|
241
|
+
direction: "row",
|
|
242
|
+
ref: codeRef,
|
|
243
|
+
children: getCodeComponents()
|
|
244
|
+
})
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
Validator.displayName = 'Validator';
|
|
248
|
+
Validator.propTypes = { ...selectedSystemPropTypes,
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* The value is a 6-digit code, may be only numeric characters, non numeric character aren't renderize
|
|
252
|
+
*/
|
|
253
|
+
value: _propTypes.default.string,
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* If true, the component is inactive and non editable.
|
|
257
|
+
*/
|
|
258
|
+
inactive: _propTypes.default.bool,
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Use to react upon input's value changes. Required when the `value` prop is set. Will receive the input's value as an argument.
|
|
262
|
+
*/
|
|
263
|
+
onChange: _propTypes.default.func
|
|
264
|
+
};
|
|
265
|
+
var _default = Validator;
|
|
266
|
+
exports.default = _default;
|
|
267
|
+
|
|
268
|
+
const staticStyles = _StyleSheet.default.create({
|
|
269
|
+
codeInputWidth: {
|
|
270
|
+
width: 43
|
|
271
|
+
}
|
|
272
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _Validator = _interopRequireDefault(require("./Validator"));
|
|
9
|
+
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
|
|
12
|
+
var _default = _Validator.default;
|
|
13
|
+
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -52,6 +52,7 @@ var _exportNames = {
|
|
|
52
52
|
useA11yInfo: true,
|
|
53
53
|
BaseProvider: true,
|
|
54
54
|
useHydrationContext: true,
|
|
55
|
+
Validator: true,
|
|
55
56
|
ViewportProvider: true,
|
|
56
57
|
useViewport: true,
|
|
57
58
|
ViewportContext: true,
|
|
@@ -353,6 +354,12 @@ Object.defineProperty(exports, "Typography", {
|
|
|
353
354
|
return _Typography.default;
|
|
354
355
|
}
|
|
355
356
|
});
|
|
357
|
+
Object.defineProperty(exports, "Validator", {
|
|
358
|
+
enumerable: true,
|
|
359
|
+
get: function () {
|
|
360
|
+
return _Validator.default;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
356
363
|
Object.defineProperty(exports, "ViewportContext", {
|
|
357
364
|
enumerable: true,
|
|
358
365
|
get: function () {
|
|
@@ -654,6 +661,8 @@ var _BaseProvider = _interopRequireDefault(require("./BaseProvider"));
|
|
|
654
661
|
|
|
655
662
|
var _HydrationContext = require("./BaseProvider/HydrationContext");
|
|
656
663
|
|
|
664
|
+
var _Validator = _interopRequireDefault(require("./Validator"));
|
|
665
|
+
|
|
657
666
|
var _ViewportProvider = _interopRequireWildcard(require("./ViewportProvider"));
|
|
658
667
|
|
|
659
668
|
var _ThemeProvider = _interopRequireWildcard(require("./ThemeProvider"));
|
|
@@ -88,7 +88,12 @@ const textInputHandlerProps = {
|
|
|
88
88
|
/**
|
|
89
89
|
* onKeyDown handler (only supported on Web)
|
|
90
90
|
*/
|
|
91
|
-
|
|
91
|
+
onMouseOver: _propTypes.default.func,
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* onKeyDown handler (only supported on Web)
|
|
95
|
+
*/
|
|
96
|
+
onMouseOut: _propTypes.default.func
|
|
92
97
|
}
|
|
93
98
|
};
|
|
94
99
|
exports.textInputHandlerProps = textInputHandlerProps;
|
|
@@ -157,6 +157,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
|
157
157
|
...rest
|
|
158
158
|
} = _ref6;
|
|
159
159
|
const [isFocused, setIsFocused] = useState(false);
|
|
160
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
160
161
|
|
|
161
162
|
const handleFocus = event => {
|
|
162
163
|
setIsFocused(true);
|
|
@@ -218,27 +219,35 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
|
218
219
|
inactive
|
|
219
220
|
};
|
|
220
221
|
const themeTokens = useThemeTokens('TextInput', tokens, variant, states);
|
|
222
|
+
|
|
223
|
+
const handleClear = event => {
|
|
224
|
+
var _inputRef$current;
|
|
225
|
+
|
|
226
|
+
onClear === null || onClear === void 0 ? void 0 : onClear(event);
|
|
227
|
+
resetValue(event);
|
|
228
|
+
inputRef === null || inputRef === void 0 ? void 0 : (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
const handleShowOrHide = () => {
|
|
232
|
+
if (!variant.inactive) setShowPassword(!showPassword);
|
|
233
|
+
};
|
|
234
|
+
|
|
221
235
|
const {
|
|
222
236
|
buttonsGap,
|
|
223
237
|
clearButtonIcon: ClearButtonIcon,
|
|
224
|
-
icon: IconComponent
|
|
238
|
+
icon: IconComponent,
|
|
239
|
+
passwordShowButtonIcon,
|
|
240
|
+
passwordHideButtonIcon
|
|
225
241
|
} = themeTokens;
|
|
226
242
|
const buttonsGapSize = useSpacingScale(buttonsGap);
|
|
227
243
|
const getCopy = useCopy({
|
|
228
244
|
dictionary,
|
|
229
245
|
copy
|
|
230
246
|
});
|
|
247
|
+
const textInputButtons = buttons;
|
|
231
248
|
|
|
232
249
|
if (onClear && isDirty) {
|
|
233
|
-
|
|
234
|
-
var _inputRef$current;
|
|
235
|
-
|
|
236
|
-
onClear === null || onClear === void 0 ? void 0 : onClear(event);
|
|
237
|
-
resetValue(event);
|
|
238
|
-
inputRef === null || inputRef === void 0 ? void 0 : (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.focus();
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
buttons === null || buttons === void 0 ? void 0 : buttons.unshift( /*#__PURE__*/_jsx(IconButton, {
|
|
250
|
+
textInputButtons === null || textInputButtons === void 0 ? void 0 : textInputButtons.unshift( /*#__PURE__*/_jsx(IconButton, {
|
|
242
251
|
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
243
252
|
icon: ClearButtonIcon,
|
|
244
253
|
onPress: handleClear,
|
|
@@ -248,6 +257,19 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
|
248
257
|
}, "clear"));
|
|
249
258
|
}
|
|
250
259
|
|
|
260
|
+
if (variant.password) {
|
|
261
|
+
textInputButtons === null || textInputButtons === void 0 ? void 0 : textInputButtons.unshift( /*#__PURE__*/_jsx(IconButton, {
|
|
262
|
+
accessibilityLabel: !showPassword ? getCopy('hidePasswordAccessibilityLabel') : getCopy('showPasswordAccessibilityLabel'),
|
|
263
|
+
icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
|
|
264
|
+
onPress: handleShowOrHide,
|
|
265
|
+
variant: {
|
|
266
|
+
compact: true,
|
|
267
|
+
password: true,
|
|
268
|
+
inactive: !!variant.inactive
|
|
269
|
+
}
|
|
270
|
+
}, !showPassword ? 'hide' : 'show'));
|
|
271
|
+
}
|
|
272
|
+
|
|
251
273
|
const inputProps = { ...selectProps(rest),
|
|
252
274
|
editable: !inactive,
|
|
253
275
|
onFocus: handleFocus,
|
|
@@ -271,6 +293,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
|
271
293
|
children: [/*#__PURE__*/_jsx(NativeTextInput, {
|
|
272
294
|
ref: inputRef,
|
|
273
295
|
style: nativeInputStyle,
|
|
296
|
+
secureTextEntry: variant.password && !showPassword,
|
|
274
297
|
...inputProps
|
|
275
298
|
}), IconComponent && /*#__PURE__*/_jsx(View, {
|
|
276
299
|
pointerEvents: "none" // avoid hijacking input press events
|
|
@@ -285,7 +308,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
|
285
308
|
children: /*#__PURE__*/_jsx(StackView, {
|
|
286
309
|
direction: "row",
|
|
287
310
|
space: buttonsGap,
|
|
288
|
-
children:
|
|
311
|
+
children: textInputButtons
|
|
289
312
|
})
|
|
290
313
|
})]
|
|
291
314
|
});
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
en: {
|
|
3
|
-
clearButtonAccessibilityLabel: 'Clear'
|
|
3
|
+
clearButtonAccessibilityLabel: 'Clear',
|
|
4
|
+
showPasswordAccessibilityLabel: 'Show Password',
|
|
5
|
+
hidePasswordAccessibilityLabel: 'Hide Password'
|
|
4
6
|
},
|
|
5
7
|
fr: {
|
|
6
|
-
clearButtonAccessibilityLabel: 'Effacer'
|
|
8
|
+
clearButtonAccessibilityLabel: 'Effacer',
|
|
9
|
+
showPasswordAccessibilityLabel: 'montrer le mot de passe',
|
|
10
|
+
hidePasswordAccessibilityLabel: 'masquer le mot de passe'
|
|
7
11
|
}
|
|
8
12
|
};
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import React, { forwardRef, createRef, useRef, useMemo, useEffect, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import View from "react-native-web/dist/exports/View";
|
|
4
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
6
|
+
import { inputSupportsProps, selectSystemProps } from '../utils';
|
|
7
|
+
import { TextInput } from '../TextInput';
|
|
8
|
+
import StackView from '../StackView';
|
|
9
|
+
import InputSupports from '../InputSupports';
|
|
10
|
+
import { useThemeTokens } from '../ThemeProvider';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([inputSupportsProps]);
|
|
13
|
+
|
|
14
|
+
const selectCodeTextInputTokens = _ref => {
|
|
15
|
+
let {
|
|
16
|
+
outerBorderColor,
|
|
17
|
+
outerBackgroundColor
|
|
18
|
+
} = _ref;
|
|
19
|
+
return {
|
|
20
|
+
outerBorderColor,
|
|
21
|
+
outerBackgroundColor,
|
|
22
|
+
icon: null
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const Validator = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
27
|
+
let {
|
|
28
|
+
value = '',
|
|
29
|
+
inactive,
|
|
30
|
+
onChange,
|
|
31
|
+
tokens = {},
|
|
32
|
+
variant = {},
|
|
33
|
+
...rest
|
|
34
|
+
} = _ref2;
|
|
35
|
+
const defaultRef = useRef();
|
|
36
|
+
const codeRef = ref !== null && ref !== void 0 ? ref : defaultRef;
|
|
37
|
+
const {
|
|
38
|
+
supportsProps
|
|
39
|
+
} = selectProps(rest);
|
|
40
|
+
const strValidation = supportsProps.validation;
|
|
41
|
+
const [individualCodes, setIndividualCodes] = useState({});
|
|
42
|
+
const [text, setText] = useState(value);
|
|
43
|
+
const validatorsLength = 6;
|
|
44
|
+
const prefix = 'code';
|
|
45
|
+
const sufixValidation = 'Validation';
|
|
46
|
+
const [isHover, setIsHover] = useState(false);
|
|
47
|
+
|
|
48
|
+
const handleMouseOver = () => {
|
|
49
|
+
setIsHover(true);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handleMouseOut = () => {
|
|
53
|
+
setIsHover(false);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const themeTokens = useThemeTokens('TextInput', tokens, variant, {
|
|
57
|
+
hover: isHover
|
|
58
|
+
});
|
|
59
|
+
const [codeReferences, singleCodes] = useMemo(() => {
|
|
60
|
+
const codes = [];
|
|
61
|
+
const valueCodes = {};
|
|
62
|
+
|
|
63
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
64
|
+
codes[prefix + i] = /*#__PURE__*/createRef();
|
|
65
|
+
valueCodes[prefix + i] = '';
|
|
66
|
+
valueCodes[prefix + i + sufixValidation] = '';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return [codes, valueCodes];
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
72
|
+
const handleSingleCodes = (codeId, val, validation) => {
|
|
73
|
+
singleCodes[codeId] = val;
|
|
74
|
+
singleCodes[codeId + sufixValidation] = validation;
|
|
75
|
+
/* eslint-disable no-unused-expressions */
|
|
76
|
+
|
|
77
|
+
setIndividualCodes({ ...individualCodes,
|
|
78
|
+
[codeId]: val
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const handleChangeCode = () => {
|
|
83
|
+
let code = '';
|
|
84
|
+
|
|
85
|
+
for (let i = 0; i < validatorsLength; i += 1) code += singleCodes[prefix + i];
|
|
86
|
+
|
|
87
|
+
if (typeof onChange === 'function') onChange(code, singleCodes);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const handleChangeCodeValues = (event, codeId, nextIndex) => {
|
|
91
|
+
var _codeReferences$codeI, _event$nativeEvent, _event$target, _codeElement$value, _codeElement$value2, _codeElement$value3;
|
|
92
|
+
|
|
93
|
+
const codeElement = (_codeReferences$codeI = codeReferences[codeId]) === null || _codeReferences$codeI === void 0 ? void 0 : _codeReferences$codeI.current;
|
|
94
|
+
const val = ((_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : _event$nativeEvent.value) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.value);
|
|
95
|
+
|
|
96
|
+
if (Number(val).toString() === 'NaN') {
|
|
97
|
+
var _singleCodes$codeId;
|
|
98
|
+
|
|
99
|
+
codeElement.value = (_singleCodes$codeId = singleCodes[codeId]) !== null && _singleCodes$codeId !== void 0 ? _singleCodes$codeId : '';
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$value = codeElement.value) === null || _codeElement$value === void 0 ? void 0 : _codeElement$value.length) > 1) {
|
|
104
|
+
const oldValue = singleCodes[codeId];
|
|
105
|
+
const newValue = codeElement.value.replace(oldValue, '');
|
|
106
|
+
codeElement.value = newValue;
|
|
107
|
+
handleSingleCodes(codeId, codeElement.value, 'success');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
handleSingleCodes(codeId, (_codeElement$value2 = codeElement === null || codeElement === void 0 ? void 0 : codeElement.value) !== null && _codeElement$value2 !== void 0 ? _codeElement$value2 : singleCodes[codeId], 'success');
|
|
111
|
+
handleChangeCode();
|
|
112
|
+
|
|
113
|
+
if (nextIndex === validatorsLength) {
|
|
114
|
+
codeElement.blur();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$value3 = codeElement.value) === null || _codeElement$value3 === void 0 ? void 0 : _codeElement$value3.length) > 0) codeReferences[prefix + nextIndex].current.focus();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleKeyPress = (event, currentIndex, previousIndex) => {
|
|
122
|
+
if (!(event.keyCode === 8 || event.code === 'Backspace')) return;
|
|
123
|
+
|
|
124
|
+
if (currentIndex > 0) {
|
|
125
|
+
codeReferences[prefix + currentIndex].current.value = '';
|
|
126
|
+
codeReferences[prefix + previousIndex].current.focus();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
handleSingleCodes(prefix + currentIndex, '', '');
|
|
130
|
+
handleChangeCode();
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const getCodeComponents = () => {
|
|
134
|
+
const components = [];
|
|
135
|
+
|
|
136
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
137
|
+
var _codeReferences$codeI2;
|
|
138
|
+
|
|
139
|
+
const codeId = prefix + i;
|
|
140
|
+
const codeInputProps = {
|
|
141
|
+
nativeID: codeId,
|
|
142
|
+
ref: (_codeReferences$codeI2 = codeReferences[codeId]) !== null && _codeReferences$codeI2 !== void 0 ? _codeReferences$codeI2 : null,
|
|
143
|
+
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
144
|
+
tokens: selectCodeTextInputTokens(themeTokens),
|
|
145
|
+
onFocus: () => codeReferences[codeId].current.select(),
|
|
146
|
+
onKeyPress: event => handleKeyPress(event, i, i - 1),
|
|
147
|
+
onMouseOver: handleMouseOver,
|
|
148
|
+
onMouseOut: handleMouseOut,
|
|
149
|
+
inactive
|
|
150
|
+
};
|
|
151
|
+
codeInputProps.validation || delete codeInputProps.validation;
|
|
152
|
+
components.push( /*#__PURE__*/_jsx(View, {
|
|
153
|
+
style: staticStyles.codeInputWidth,
|
|
154
|
+
children: /*#__PURE__*/_jsx(TextInput, { ...codeInputProps
|
|
155
|
+
})
|
|
156
|
+
}, codeId));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return components;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
/* eslint-disable no-unused-expressions */
|
|
164
|
+
if (Number(value).toString() !== 'NaN') setText(value);
|
|
165
|
+
}, [value]);
|
|
166
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
167
|
+
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
170
|
+
var _text$i, _text$i2;
|
|
171
|
+
|
|
172
|
+
codeReferences[prefix + i].current.value = (_text$i = text[i]) !== null && _text$i !== void 0 ? _text$i : '';
|
|
173
|
+
handleSingleCodes(prefix + i, (_text$i2 = text[i]) !== null && _text$i2 !== void 0 ? _text$i2 : '', text[i] ? 'success' : '');
|
|
174
|
+
}
|
|
175
|
+
}, [text]);
|
|
176
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
177
|
+
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
const handlePasteCode = event => {
|
|
180
|
+
setText('');
|
|
181
|
+
const clipBoardText = event.clipboardData.getData('text');
|
|
182
|
+
if (Number(clipBoardText).toString() !== 'NaN') setText(clipBoardText);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const handleCopy = event => {
|
|
186
|
+
let clipBoardText = '';
|
|
187
|
+
|
|
188
|
+
for (let i = 0; i < validatorsLength; i += 1) singleCodes[prefix + i] && (clipBoardText += singleCodes[prefix + i]);
|
|
189
|
+
|
|
190
|
+
event.clipboardData.setData('text/plain', clipBoardText);
|
|
191
|
+
event.preventDefault();
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
if (Platform.OS === 'web') {
|
|
195
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
196
|
+
codeReferences[prefix + i].current.addEventListener('paste', handlePasteCode);
|
|
197
|
+
codeReferences[prefix + i].current.addEventListener('copy', handleCopy);
|
|
198
|
+
codeReferences[prefix + i].current.addEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return () => {
|
|
203
|
+
if (Platform.oldValue === 'web') {
|
|
204
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
205
|
+
var _codeReferences, _codeReferences$curre, _codeReferences2, _codeReferences2$curr, _codeReferences3, _codeReferences3$curr;
|
|
206
|
+
|
|
207
|
+
(_codeReferences = codeReferences[prefix + i]) === null || _codeReferences === void 0 ? void 0 : (_codeReferences$curre = _codeReferences.current) === null || _codeReferences$curre === void 0 ? void 0 : _codeReferences$curre.removeEventListener('paste', handlePasteCode);
|
|
208
|
+
(_codeReferences2 = codeReferences[prefix + i]) === null || _codeReferences2 === void 0 ? void 0 : (_codeReferences2$curr = _codeReferences2.current) === null || _codeReferences2$curr === void 0 ? void 0 : _codeReferences2$curr.removeEventListener('copy', handleCopy);
|
|
209
|
+
(_codeReferences3 = codeReferences[prefix + i]) === null || _codeReferences3 === void 0 ? void 0 : (_codeReferences3$curr = _codeReferences3.current) === null || _codeReferences3$curr === void 0 ? void 0 : _codeReferences3$curr.removeEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}, []);
|
|
214
|
+
return /*#__PURE__*/_jsx(InputSupports, { ...supportsProps,
|
|
215
|
+
children: /*#__PURE__*/_jsx(StackView, {
|
|
216
|
+
space: 2,
|
|
217
|
+
direction: "row",
|
|
218
|
+
ref: codeRef,
|
|
219
|
+
children: getCodeComponents()
|
|
220
|
+
})
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
Validator.displayName = 'Validator';
|
|
224
|
+
Validator.propTypes = { ...selectedSystemPropTypes,
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The value is a 6-digit code, may be only numeric characters, non numeric character aren't renderize
|
|
228
|
+
*/
|
|
229
|
+
value: PropTypes.string,
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* If true, the component is inactive and non editable.
|
|
233
|
+
*/
|
|
234
|
+
inactive: PropTypes.bool,
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Use to react upon input's value changes. Required when the `value` prop is set. Will receive the input's value as an argument.
|
|
238
|
+
*/
|
|
239
|
+
onChange: PropTypes.func
|
|
240
|
+
};
|
|
241
|
+
export default Validator;
|
|
242
|
+
const staticStyles = StyleSheet.create({
|
|
243
|
+
codeInputWidth: {
|
|
244
|
+
width: 43
|
|
245
|
+
}
|
|
246
|
+
});
|
package/lib-module/index.js
CHANGED
|
@@ -52,6 +52,7 @@ export { default as Typography } from './Typography';
|
|
|
52
52
|
export { default as A11yInfoProvider, useA11yInfo } from './A11yInfoProvider';
|
|
53
53
|
export { default as BaseProvider } from './BaseProvider';
|
|
54
54
|
export { useHydrationContext } from './BaseProvider/HydrationContext';
|
|
55
|
+
export { default as Validator } from './Validator';
|
|
55
56
|
export { default as ViewportProvider, useViewport, ViewportContext } from './ViewportProvider';
|
|
56
57
|
export { default as ThemeProvider, useTheme, useSetTheme, useThemeTokens, getThemeTokens, applyOuterBorder, applyTextStyles, applyShadowToken } from './ThemeProvider';
|
|
57
58
|
export * from './utils';
|
|
@@ -75,7 +75,12 @@ const textInputHandlerProps = {
|
|
|
75
75
|
/**
|
|
76
76
|
* onKeyDown handler (only supported on Web)
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
onMouseOver: PropTypes.func,
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* onKeyDown handler (only supported on Web)
|
|
82
|
+
*/
|
|
83
|
+
onMouseOut: PropTypes.func
|
|
79
84
|
}
|
|
80
85
|
};
|
|
81
86
|
const selectTextInputHandlers = getPropSelector(textInputHandlerProps.types);
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@floating-ui/react-native": "^0.8.1",
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@telus-uds/system-constants": "^1.2.0",
|
|
14
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
14
|
+
"@telus-uds/system-theme-tokens": "^2.14.0",
|
|
15
15
|
"airbnb-prop-types": "^2.16.0",
|
|
16
16
|
"lodash.debounce": "^4.0.8",
|
|
17
17
|
"lodash.merge": "^4.6.2",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"standard-engine": {
|
|
73
73
|
"skip": true
|
|
74
74
|
},
|
|
75
|
-
"version": "1.
|
|
75
|
+
"version": "1.30.1"
|
|
76
76
|
}
|
|
@@ -157,6 +157,7 @@ const TextInputBase = forwardRef(
|
|
|
157
157
|
ref
|
|
158
158
|
) => {
|
|
159
159
|
const [isFocused, setIsFocused] = useState(false)
|
|
160
|
+
const [showPassword, setShowPassword] = useState(false)
|
|
160
161
|
const handleFocus = (event) => {
|
|
161
162
|
setIsFocused(true)
|
|
162
163
|
if (typeof onFocus === 'function') onFocus(event)
|
|
@@ -206,16 +207,29 @@ const TextInputBase = forwardRef(
|
|
|
206
207
|
|
|
207
208
|
const themeTokens = useThemeTokens('TextInput', tokens, variant, states)
|
|
208
209
|
|
|
209
|
-
const
|
|
210
|
+
const handleClear = (event) => {
|
|
211
|
+
onClear?.(event)
|
|
212
|
+
resetValue(event)
|
|
213
|
+
inputRef?.current?.focus()
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const handleShowOrHide = () => {
|
|
217
|
+
if (!variant.inactive) setShowPassword(!showPassword)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const {
|
|
221
|
+
buttonsGap,
|
|
222
|
+
clearButtonIcon: ClearButtonIcon,
|
|
223
|
+
icon: IconComponent,
|
|
224
|
+
passwordShowButtonIcon,
|
|
225
|
+
passwordHideButtonIcon
|
|
226
|
+
} = themeTokens
|
|
210
227
|
const buttonsGapSize = useSpacingScale(buttonsGap)
|
|
211
228
|
const getCopy = useCopy({ dictionary, copy })
|
|
229
|
+
const textInputButtons = buttons
|
|
230
|
+
|
|
212
231
|
if (onClear && isDirty) {
|
|
213
|
-
|
|
214
|
-
onClear?.(event)
|
|
215
|
-
resetValue(event)
|
|
216
|
-
inputRef?.current?.focus()
|
|
217
|
-
}
|
|
218
|
-
buttons?.unshift(
|
|
232
|
+
textInputButtons?.unshift(
|
|
219
233
|
<IconButton
|
|
220
234
|
accessibilityLabel={getCopy('clearButtonAccessibilityLabel')}
|
|
221
235
|
icon={ClearButtonIcon}
|
|
@@ -226,6 +240,22 @@ const TextInputBase = forwardRef(
|
|
|
226
240
|
)
|
|
227
241
|
}
|
|
228
242
|
|
|
243
|
+
if (variant.password) {
|
|
244
|
+
textInputButtons?.unshift(
|
|
245
|
+
<IconButton
|
|
246
|
+
accessibilityLabel={
|
|
247
|
+
!showPassword
|
|
248
|
+
? getCopy('hidePasswordAccessibilityLabel')
|
|
249
|
+
: getCopy('showPasswordAccessibilityLabel')
|
|
250
|
+
}
|
|
251
|
+
icon={!showPassword ? passwordShowButtonIcon : passwordHideButtonIcon}
|
|
252
|
+
key={!showPassword ? 'hide' : 'show'}
|
|
253
|
+
onPress={handleShowOrHide}
|
|
254
|
+
variant={{ compact: true, password: true, inactive: !!variant.inactive }}
|
|
255
|
+
/>
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
229
259
|
const inputProps = {
|
|
230
260
|
...selectProps(rest),
|
|
231
261
|
editable: !inactive,
|
|
@@ -245,7 +275,12 @@ const TextInputBase = forwardRef(
|
|
|
245
275
|
|
|
246
276
|
return (
|
|
247
277
|
<View style={selectOuterBorderStyles(themeTokens)}>
|
|
248
|
-
<NativeTextInput
|
|
278
|
+
<NativeTextInput
|
|
279
|
+
ref={inputRef}
|
|
280
|
+
style={nativeInputStyle}
|
|
281
|
+
secureTextEntry={variant.password && !showPassword}
|
|
282
|
+
{...inputProps}
|
|
283
|
+
/>
|
|
249
284
|
{IconComponent && (
|
|
250
285
|
<View
|
|
251
286
|
pointerEvents="none" // avoid hijacking input press events
|
|
@@ -260,7 +295,7 @@ const TextInputBase = forwardRef(
|
|
|
260
295
|
{buttons?.length > 0 && (
|
|
261
296
|
<View style={[staticStyles.buttonsContainer, selectButtonsContainerStyle(themeTokens)]}>
|
|
262
297
|
<StackView direction="row" space={buttonsGap}>
|
|
263
|
-
{
|
|
298
|
+
{textInputButtons}
|
|
264
299
|
</StackView>
|
|
265
300
|
</View>
|
|
266
301
|
)}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
en: {
|
|
3
|
-
clearButtonAccessibilityLabel: 'Clear'
|
|
3
|
+
clearButtonAccessibilityLabel: 'Clear',
|
|
4
|
+
showPasswordAccessibilityLabel: 'Show Password',
|
|
5
|
+
hidePasswordAccessibilityLabel: 'Hide Password'
|
|
4
6
|
},
|
|
5
7
|
fr: {
|
|
6
|
-
clearButtonAccessibilityLabel: 'Effacer'
|
|
8
|
+
clearButtonAccessibilityLabel: 'Effacer',
|
|
9
|
+
showPasswordAccessibilityLabel: 'montrer le mot de passe',
|
|
10
|
+
hidePasswordAccessibilityLabel: 'masquer le mot de passe'
|
|
7
11
|
}
|
|
8
12
|
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import React, { forwardRef, createRef, useRef, useMemo, useEffect, useState } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { View, StyleSheet, Platform } from 'react-native'
|
|
4
|
+
import { inputSupportsProps, selectSystemProps } from '../utils'
|
|
5
|
+
import { TextInput } from '../TextInput'
|
|
6
|
+
import StackView from '../StackView'
|
|
7
|
+
import InputSupports from '../InputSupports'
|
|
8
|
+
import { useThemeTokens } from '../ThemeProvider'
|
|
9
|
+
|
|
10
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([inputSupportsProps])
|
|
11
|
+
|
|
12
|
+
const selectCodeTextInputTokens = ({ outerBorderColor, outerBackgroundColor }) => {
|
|
13
|
+
return {
|
|
14
|
+
outerBorderColor,
|
|
15
|
+
outerBackgroundColor,
|
|
16
|
+
icon: null
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const Validator = forwardRef(
|
|
21
|
+
({ value = '', inactive, onChange, tokens = {}, variant = {}, ...rest }, ref) => {
|
|
22
|
+
const defaultRef = useRef()
|
|
23
|
+
const codeRef = ref ?? defaultRef
|
|
24
|
+
|
|
25
|
+
const { supportsProps } = selectProps(rest)
|
|
26
|
+
const strValidation = supportsProps.validation
|
|
27
|
+
const [individualCodes, setIndividualCodes] = useState({})
|
|
28
|
+
const [text, setText] = useState(value)
|
|
29
|
+
const validatorsLength = 6
|
|
30
|
+
const prefix = 'code'
|
|
31
|
+
const sufixValidation = 'Validation'
|
|
32
|
+
|
|
33
|
+
const [isHover, setIsHover] = useState(false)
|
|
34
|
+
const handleMouseOver = () => {
|
|
35
|
+
setIsHover(true)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const handleMouseOut = () => {
|
|
39
|
+
setIsHover(false)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const themeTokens = useThemeTokens('TextInput', tokens, variant, { hover: isHover })
|
|
43
|
+
|
|
44
|
+
const [codeReferences, singleCodes] = useMemo(() => {
|
|
45
|
+
const codes = []
|
|
46
|
+
const valueCodes = {}
|
|
47
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
48
|
+
codes[prefix + i] = createRef()
|
|
49
|
+
valueCodes[prefix + i] = ''
|
|
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
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const handleChangeCode = () => {
|
|
66
|
+
let code = ''
|
|
67
|
+
for (let i = 0; i < validatorsLength; i += 1) code += singleCodes[prefix + i]
|
|
68
|
+
if (typeof onChange === 'function') onChange(code, singleCodes)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const handleChangeCodeValues = (event, codeId, nextIndex) => {
|
|
72
|
+
const codeElement = codeReferences[codeId]?.current
|
|
73
|
+
const val = event.nativeEvent?.value || event.target?.value
|
|
74
|
+
|
|
75
|
+
if (Number(val).toString() === 'NaN') {
|
|
76
|
+
codeElement.value = singleCodes[codeId] ?? ''
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
if (codeElement?.value?.length > 1) {
|
|
80
|
+
const oldValue = singleCodes[codeId]
|
|
81
|
+
const newValue = codeElement.value.replace(oldValue, '')
|
|
82
|
+
codeElement.value = newValue
|
|
83
|
+
handleSingleCodes(codeId, codeElement.value, 'success')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
handleSingleCodes(codeId, codeElement?.value ?? singleCodes[codeId], 'success')
|
|
87
|
+
handleChangeCode()
|
|
88
|
+
if (nextIndex === validatorsLength) {
|
|
89
|
+
codeElement.blur()
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
if (codeElement?.value?.length > 0) codeReferences[prefix + nextIndex].current.focus()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const handleKeyPress = (event, currentIndex, previousIndex) => {
|
|
96
|
+
if (!(event.keyCode === 8 || event.code === 'Backspace')) return
|
|
97
|
+
if (currentIndex > 0) {
|
|
98
|
+
codeReferences[prefix + currentIndex].current.value = ''
|
|
99
|
+
codeReferences[prefix + previousIndex].current.focus()
|
|
100
|
+
}
|
|
101
|
+
handleSingleCodes(prefix + currentIndex, '', '')
|
|
102
|
+
handleChangeCode()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const getCodeComponents = () => {
|
|
106
|
+
const components = []
|
|
107
|
+
|
|
108
|
+
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
109
|
+
const codeId = prefix + i
|
|
110
|
+
const codeInputProps = {
|
|
111
|
+
nativeID: codeId,
|
|
112
|
+
ref: codeReferences[codeId] ?? null,
|
|
113
|
+
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
114
|
+
tokens: selectCodeTextInputTokens(themeTokens),
|
|
115
|
+
onFocus: () => codeReferences[codeId].current.select(),
|
|
116
|
+
onKeyPress: (event) => handleKeyPress(event, i, i - 1),
|
|
117
|
+
onMouseOver: handleMouseOver,
|
|
118
|
+
onMouseOut: handleMouseOut,
|
|
119
|
+
inactive
|
|
120
|
+
}
|
|
121
|
+
codeInputProps.validation || delete codeInputProps.validation
|
|
122
|
+
|
|
123
|
+
components.push(
|
|
124
|
+
<View key={codeId} style={staticStyles.codeInputWidth}>
|
|
125
|
+
<TextInput {...codeInputProps} />
|
|
126
|
+
</View>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
return components
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
/* eslint-disable no-unused-expressions */
|
|
134
|
+
if (Number(value).toString() !== 'NaN') setText(value)
|
|
135
|
+
}, [value])
|
|
136
|
+
|
|
137
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
140
|
+
codeReferences[prefix + i].current.value = text[i] ?? ''
|
|
141
|
+
handleSingleCodes(prefix + i, text[i] ?? '', text[i] ? 'success' : '')
|
|
142
|
+
}
|
|
143
|
+
}, [text])
|
|
144
|
+
|
|
145
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
const handlePasteCode = (event) => {
|
|
148
|
+
setText('')
|
|
149
|
+
const clipBoardText = event.clipboardData.getData('text')
|
|
150
|
+
if (Number(clipBoardText).toString() !== 'NaN') setText(clipBoardText)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const handleCopy = (event) => {
|
|
154
|
+
let clipBoardText = ''
|
|
155
|
+
for (let i = 0; i < validatorsLength; i += 1)
|
|
156
|
+
singleCodes[prefix + i] && (clipBoardText += singleCodes[prefix + i])
|
|
157
|
+
event.clipboardData.setData('text/plain', clipBoardText)
|
|
158
|
+
event.preventDefault()
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (Platform.OS === 'web') {
|
|
162
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
163
|
+
codeReferences[prefix + i].current.addEventListener('paste', handlePasteCode)
|
|
164
|
+
codeReferences[prefix + i].current.addEventListener('copy', handleCopy)
|
|
165
|
+
codeReferences[prefix + i].current.addEventListener('input', (event) =>
|
|
166
|
+
handleChangeCodeValues(event, prefix + i, i + 1)
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return () => {
|
|
172
|
+
if (Platform.oldValue === 'web') {
|
|
173
|
+
for (let i = 0; i < validatorsLength; i += 1) {
|
|
174
|
+
codeReferences[prefix + i]?.current?.removeEventListener('paste', handlePasteCode)
|
|
175
|
+
codeReferences[prefix + i]?.current?.removeEventListener('copy', handleCopy)
|
|
176
|
+
codeReferences[prefix + i]?.current?.removeEventListener('input', (event) =>
|
|
177
|
+
handleChangeCodeValues(event, prefix + i, i + 1)
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}, [])
|
|
183
|
+
|
|
184
|
+
return (
|
|
185
|
+
<InputSupports {...supportsProps}>
|
|
186
|
+
<StackView space={2} direction="row" ref={codeRef}>
|
|
187
|
+
{getCodeComponents()}
|
|
188
|
+
</StackView>
|
|
189
|
+
</InputSupports>
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
Validator.displayName = 'Validator'
|
|
194
|
+
|
|
195
|
+
Validator.propTypes = {
|
|
196
|
+
...selectedSystemPropTypes,
|
|
197
|
+
/**
|
|
198
|
+
* The value is a 6-digit code, may be only numeric characters, non numeric character aren't renderize
|
|
199
|
+
*/
|
|
200
|
+
value: PropTypes.string,
|
|
201
|
+
/**
|
|
202
|
+
* If true, the component is inactive and non editable.
|
|
203
|
+
*/
|
|
204
|
+
inactive: PropTypes.bool,
|
|
205
|
+
/**
|
|
206
|
+
* Use to react upon input's value changes. Required when the `value` prop is set. Will receive the input's value as an argument.
|
|
207
|
+
*/
|
|
208
|
+
onChange: PropTypes.func
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export default Validator
|
|
212
|
+
|
|
213
|
+
const staticStyles = StyleSheet.create({
|
|
214
|
+
codeInputWidth: {
|
|
215
|
+
width: 43
|
|
216
|
+
}
|
|
217
|
+
})
|
package/src/index.js
CHANGED
|
@@ -53,6 +53,7 @@ export { default as Typography } from './Typography'
|
|
|
53
53
|
export { default as A11yInfoProvider, useA11yInfo } from './A11yInfoProvider'
|
|
54
54
|
export { default as BaseProvider } from './BaseProvider'
|
|
55
55
|
export { useHydrationContext } from './BaseProvider/HydrationContext'
|
|
56
|
+
export { default as Validator } from './Validator'
|
|
56
57
|
export { default as ViewportProvider, useViewport, ViewportContext } from './ViewportProvider'
|
|
57
58
|
export {
|
|
58
59
|
default as ThemeProvider,
|
|
@@ -65,7 +65,11 @@ const textInputHandlerProps = {
|
|
|
65
65
|
/**
|
|
66
66
|
* onKeyDown handler (only supported on Web)
|
|
67
67
|
*/
|
|
68
|
-
|
|
68
|
+
onMouseOver: PropTypes.func,
|
|
69
|
+
/**
|
|
70
|
+
* onKeyDown handler (only supported on Web)
|
|
71
|
+
*/
|
|
72
|
+
onMouseOut: PropTypes.func
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
const selectTextInputHandlers = getPropSelector(textInputHandlerProps.types)
|