@space-uy/pulsar-ui 0.11.1 → 0.11.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.
- package/lib/module/components/Header.js +82 -14
- package/lib/module/components/Header.js.map +1 -1
- package/lib/module/components/Input.js +2 -0
- package/lib/module/components/Input.js.map +1 -1
- package/lib/module/components/InputContainer.js +3 -0
- package/lib/module/components/InputContainer.js.map +1 -1
- package/lib/module/components/OtpInput.js +173 -65
- package/lib/module/components/OtpInput.js.map +1 -1
- package/lib/module/components/TextArea.js +2 -0
- package/lib/module/components/TextArea.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/Header.d.ts +6 -1
- package/lib/typescript/src/components/Header.d.ts.map +1 -1
- package/lib/typescript/src/components/Input.d.ts +1 -0
- package/lib/typescript/src/components/Input.d.ts.map +1 -1
- package/lib/typescript/src/components/InputContainer.d.ts +2 -1
- package/lib/typescript/src/components/InputContainer.d.ts.map +1 -1
- package/lib/typescript/src/components/OtpInput.d.ts +9 -2
- package/lib/typescript/src/components/OtpInput.d.ts.map +1 -1
- package/lib/typescript/src/components/TextArea.d.ts +1 -0
- package/lib/typescript/src/components/TextArea.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +0 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Header.tsx +141 -36
- package/src/components/Input.tsx +3 -0
- package/src/components/InputContainer.tsx +8 -0
- package/src/components/OtpInput.tsx +222 -93
- package/src/components/TextArea.tsx +3 -0
- package/src/index.tsx +0 -2
- package/lib/module/components/OtpInputContainer.js +0 -148
- package/lib/module/components/OtpInputContainer.js.map +0 -1
- package/lib/typescript/src/components/OtpInputContainer.d.ts +0 -17
- package/lib/typescript/src/components/OtpInputContainer.d.ts.map +0 -1
- package/src/components/OtpInputContainer.tsx +0 -196
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { forwardRef, useCallback, useRef, useState } from 'react';
|
|
2
|
-
import { Platform, StyleSheet } from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
View,
|
|
5
|
-
Keyboard,
|
|
6
|
-
type TextInputKeyPressEventData,
|
|
7
|
-
type NativeSyntheticEvent,
|
|
8
|
-
type ViewProps,
|
|
9
|
-
type TextInputProps,
|
|
10
|
-
type TextInput,
|
|
11
|
-
} from 'react-native';
|
|
12
|
-
import { OtpInput } from './OtpInput';
|
|
13
|
-
import useTheme from '../hooks/useTheme';
|
|
14
|
-
export type OtpInputContainerRef = {
|
|
15
|
-
clear: () => void;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
type OtpInputContainerProps = {
|
|
19
|
-
inputProps?: Omit<
|
|
20
|
-
TextInputProps,
|
|
21
|
-
| 'style'
|
|
22
|
-
| 'onChangeText'
|
|
23
|
-
| 'onKeyPress'
|
|
24
|
-
| 'autoComplete'
|
|
25
|
-
| 'keyboardType'
|
|
26
|
-
| 'autoFocus'
|
|
27
|
-
>;
|
|
28
|
-
inputStyle?: TextInputProps['style'];
|
|
29
|
-
containerProps?: Omit<ViewProps, 'style'>;
|
|
30
|
-
containerStyle?: ViewProps['style'];
|
|
31
|
-
length?: number;
|
|
32
|
-
onFillEnded?: (otp: string) => void;
|
|
33
|
-
autoFocus?: boolean;
|
|
34
|
-
editable?: boolean;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const OtpInputContainer = forwardRef<
|
|
38
|
-
OtpInputContainerRef,
|
|
39
|
-
OtpInputContainerProps
|
|
40
|
-
>(
|
|
41
|
-
(
|
|
42
|
-
{
|
|
43
|
-
length = 4,
|
|
44
|
-
inputProps,
|
|
45
|
-
inputStyle,
|
|
46
|
-
containerProps,
|
|
47
|
-
containerStyle,
|
|
48
|
-
onFillEnded,
|
|
49
|
-
autoFocus = true,
|
|
50
|
-
editable = true,
|
|
51
|
-
},
|
|
52
|
-
_
|
|
53
|
-
) => {
|
|
54
|
-
const isIOS = Platform.OS === 'ios';
|
|
55
|
-
const pins = Array.from({ length }).map((__, i) => i);
|
|
56
|
-
const inputRefs = useRef<TextInput[]>([]);
|
|
57
|
-
const pinsValues = useRef<string[]>([]);
|
|
58
|
-
const iosOTP = useRef<{
|
|
59
|
-
key: string;
|
|
60
|
-
index: number | null;
|
|
61
|
-
}>({ key: '', index: null });
|
|
62
|
-
const timeoutRefs = useRef<ReturnType<typeof setTimeout>[]>([]);
|
|
63
|
-
|
|
64
|
-
const [maskedPins, setMaskedPins] = useState<boolean[]>(
|
|
65
|
-
new Array(length).fill(false)
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const { colors } = useTheme();
|
|
69
|
-
|
|
70
|
-
const maskPin = useCallback((index: number) => {
|
|
71
|
-
setMaskedPins((prev) => {
|
|
72
|
-
const newMasked = [...prev];
|
|
73
|
-
newMasked[index] = true;
|
|
74
|
-
return newMasked;
|
|
75
|
-
});
|
|
76
|
-
}, []);
|
|
77
|
-
|
|
78
|
-
const handleOTP = useCallback(
|
|
79
|
-
(otp: string): boolean => {
|
|
80
|
-
const regexp = new RegExp(`[0-9]{${length}}`);
|
|
81
|
-
const otps = otp.match(regexp);
|
|
82
|
-
if (otps?.length) {
|
|
83
|
-
const otpSplits = otp.split('');
|
|
84
|
-
otpSplits.forEach((otpSplit, i) =>
|
|
85
|
-
inputRefs?.current[i]?.setNativeProps({ text: otpSplit })
|
|
86
|
-
);
|
|
87
|
-
onFillEnded?.(otp);
|
|
88
|
-
iosOTP.current = { key: '', index: null };
|
|
89
|
-
Keyboard.dismiss();
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
return false;
|
|
93
|
-
},
|
|
94
|
-
[length, onFillEnded]
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
const handleChangeText = useCallback(
|
|
98
|
-
async (text: string, index: number) => {
|
|
99
|
-
pinsValues.current[index] = text;
|
|
100
|
-
|
|
101
|
-
if (timeoutRefs.current[index]) {
|
|
102
|
-
clearTimeout(timeoutRefs.current[index]);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
setMaskedPins((prev) => {
|
|
106
|
-
const newMasked = [...prev];
|
|
107
|
-
newMasked[index] = false;
|
|
108
|
-
return newMasked;
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
timeoutRefs.current[index] = setTimeout(() => {
|
|
112
|
-
maskPin(index);
|
|
113
|
-
}, 500);
|
|
114
|
-
|
|
115
|
-
if (index + 1 <= pins.length - 1) {
|
|
116
|
-
inputRefs?.current[index + 1]?.focus();
|
|
117
|
-
} else {
|
|
118
|
-
onFillEnded?.(pinsValues.current.join(''));
|
|
119
|
-
Keyboard.dismiss();
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
[maskPin, pins.length, onFillEnded]
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const onKeyPress = useCallback(
|
|
126
|
-
(
|
|
127
|
-
event: NativeSyntheticEvent<TextInputKeyPressEventData>,
|
|
128
|
-
index: number
|
|
129
|
-
) => {
|
|
130
|
-
event.persist();
|
|
131
|
-
if (isIOS && Number.isInteger(Number(event.nativeEvent.key))) {
|
|
132
|
-
if (iosOTP.current.index === null) {
|
|
133
|
-
iosOTP.current = { key: event.nativeEvent.key, index };
|
|
134
|
-
} else {
|
|
135
|
-
if (iosOTP.current.index === index) {
|
|
136
|
-
iosOTP.current = {
|
|
137
|
-
key: `${iosOTP.current.key}${event.nativeEvent.key}`,
|
|
138
|
-
index,
|
|
139
|
-
};
|
|
140
|
-
} else {
|
|
141
|
-
iosOTP.current = { key: '', index: null };
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (iosOTP.current.key.length === length) {
|
|
145
|
-
handleOTP(iosOTP.current.key);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (event.nativeEvent.key === 'Backspace') {
|
|
151
|
-
onFillEnded?.('');
|
|
152
|
-
iosOTP.current = { key: '', index: null };
|
|
153
|
-
if (index - 1 >= 0) {
|
|
154
|
-
inputRefs?.current[index - 1]?.focus();
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
[handleOTP, length, onFillEnded, isIOS]
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
return (
|
|
162
|
-
<View style={[styles.container, containerStyle]} {...containerProps}>
|
|
163
|
-
{pins.map((pin) => {
|
|
164
|
-
return (
|
|
165
|
-
<OtpInput
|
|
166
|
-
{...inputProps}
|
|
167
|
-
autoFocus={autoFocus && pin === 0}
|
|
168
|
-
ref={(input) => inputRefs?.current.push(input as TextInput)}
|
|
169
|
-
key={pin}
|
|
170
|
-
style={[
|
|
171
|
-
inputStyle,
|
|
172
|
-
{ borderColor: colors.border, color: colors.foreground },
|
|
173
|
-
]}
|
|
174
|
-
onChangeText={(text) => handleChangeText(text, pin)}
|
|
175
|
-
onKeyPress={(event) => onKeyPress(event, pin)}
|
|
176
|
-
autoComplete="sms-otp"
|
|
177
|
-
textContentType="oneTimeCode"
|
|
178
|
-
keyboardType="numeric"
|
|
179
|
-
secureTextEntry={maskedPins[pin]}
|
|
180
|
-
editable={editable}
|
|
181
|
-
/>
|
|
182
|
-
);
|
|
183
|
-
})}
|
|
184
|
-
</View>
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
const styles = StyleSheet.create({
|
|
190
|
-
container: {
|
|
191
|
-
display: 'flex',
|
|
192
|
-
flexDirection: 'row',
|
|
193
|
-
alignItems: 'center',
|
|
194
|
-
justifyContent: 'center',
|
|
195
|
-
},
|
|
196
|
-
});
|